aboutsummaryrefslogtreecommitdiffstats
path: root/apps/user_status
diff options
context:
space:
mode:
Diffstat (limited to 'apps/user_status')
-rw-r--r--apps/user_status/.l10nignore2
-rw-r--r--apps/user_status/appinfo/info.xml15
-rw-r--r--apps/user_status/appinfo/routes.php43
-rw-r--r--apps/user_status/composer/autoload.php17
-rw-r--r--apps/user_status/composer/composer/ClassLoader.php137
-rw-r--r--apps/user_status/composer/composer/InstalledVersions.php31
-rw-r--r--apps/user_status/composer/composer/autoload_classmap.php7
-rw-r--r--apps/user_status/composer/composer/autoload_static.php7
-rw-r--r--apps/user_status/composer/composer/installed.php6
-rw-r--r--apps/user_status/css/user-status-menu.css4
-rw-r--r--apps/user_status/css/user-status-menu.css.map1
-rw-r--r--apps/user_status/css/user-status-menu.css.map.license2
-rw-r--r--apps/user_status/css/user-status-menu.scss52
-rw-r--r--apps/user_status/img/app-dark.svg1
-rw-r--r--apps/user_status/img/app.svg2
-rw-r--r--apps/user_status/img/user-status-away.svg1
-rw-r--r--apps/user_status/img/user-status-dnd.svg1
-rw-r--r--apps/user_status/img/user-status-invisible.svg1
-rw-r--r--apps/user_status/img/user-status-online.svg1
-rw-r--r--apps/user_status/l10n/af.js18
-rw-r--r--apps/user_status/l10n/af.json18
-rw-r--r--apps/user_status/l10n/ar.js38
-rw-r--r--apps/user_status/l10n/ar.json38
-rw-r--r--apps/user_status/l10n/ast.js48
-rw-r--r--apps/user_status/l10n/ast.json46
-rw-r--r--apps/user_status/l10n/bg.js40
-rw-r--r--apps/user_status/l10n/bg.json40
-rw-r--r--apps/user_status/l10n/ca.js48
-rw-r--r--apps/user_status/l10n/ca.json48
-rw-r--r--apps/user_status/l10n/cs.js36
-rw-r--r--apps/user_status/l10n/cs.json36
-rw-r--r--apps/user_status/l10n/da.js38
-rw-r--r--apps/user_status/l10n/da.json38
-rw-r--r--apps/user_status/l10n/de.js35
-rw-r--r--apps/user_status/l10n/de.json35
-rw-r--r--apps/user_status/l10n/de_DE.js33
-rw-r--r--apps/user_status/l10n/de_DE.json33
-rw-r--r--apps/user_status/l10n/el.js21
-rw-r--r--apps/user_status/l10n/el.json21
-rw-r--r--apps/user_status/l10n/en_GB.js37
-rw-r--r--apps/user_status/l10n/en_GB.json37
-rw-r--r--apps/user_status/l10n/es.js32
-rw-r--r--apps/user_status/l10n/es.json32
-rw-r--r--apps/user_status/l10n/es_AR.js23
-rw-r--r--apps/user_status/l10n/es_AR.json21
-rw-r--r--apps/user_status/l10n/es_EC.js48
-rw-r--r--apps/user_status/l10n/es_EC.json46
-rw-r--r--apps/user_status/l10n/es_MX.js48
-rw-r--r--apps/user_status/l10n/es_MX.json46
-rw-r--r--apps/user_status/l10n/et_EE.js51
-rw-r--r--apps/user_status/l10n/et_EE.json49
-rw-r--r--apps/user_status/l10n/eu.js32
-rw-r--r--apps/user_status/l10n/eu.json32
-rw-r--r--apps/user_status/l10n/fa.js40
-rw-r--r--apps/user_status/l10n/fa.json40
-rw-r--r--apps/user_status/l10n/fi.js32
-rw-r--r--apps/user_status/l10n/fi.json32
-rw-r--r--apps/user_status/l10n/fr.js40
-rw-r--r--apps/user_status/l10n/fr.json40
-rw-r--r--apps/user_status/l10n/ga.js51
-rw-r--r--apps/user_status/l10n/ga.json49
-rw-r--r--apps/user_status/l10n/gl.js37
-rw-r--r--apps/user_status/l10n/gl.json37
-rw-r--r--apps/user_status/l10n/he.js22
-rw-r--r--apps/user_status/l10n/he.json22
-rw-r--r--apps/user_status/l10n/hr.js21
-rw-r--r--apps/user_status/l10n/hr.json21
-rw-r--r--apps/user_status/l10n/hu.js32
-rw-r--r--apps/user_status/l10n/hu.json32
-rw-r--r--apps/user_status/l10n/is.js34
-rw-r--r--apps/user_status/l10n/is.json34
-rw-r--r--apps/user_status/l10n/it.js34
-rw-r--r--apps/user_status/l10n/it.json34
-rw-r--r--apps/user_status/l10n/ja.js34
-rw-r--r--apps/user_status/l10n/ja.json34
-rw-r--r--apps/user_status/l10n/ko.js25
-rw-r--r--apps/user_status/l10n/ko.json25
-rw-r--r--apps/user_status/l10n/lo.js25
-rw-r--r--apps/user_status/l10n/lo.json23
-rw-r--r--apps/user_status/l10n/lt_LT.js26
-rw-r--r--apps/user_status/l10n/lt_LT.json26
-rw-r--r--apps/user_status/l10n/mk.js21
-rw-r--r--apps/user_status/l10n/mk.json21
-rw-r--r--apps/user_status/l10n/nb.js34
-rw-r--r--apps/user_status/l10n/nb.json34
-rw-r--r--apps/user_status/l10n/nl.js37
-rw-r--r--apps/user_status/l10n/nl.json37
-rw-r--r--apps/user_status/l10n/oc.js21
-rw-r--r--apps/user_status/l10n/oc.json21
-rw-r--r--apps/user_status/l10n/pl.js33
-rw-r--r--apps/user_status/l10n/pl.json33
-rw-r--r--apps/user_status/l10n/pt_BR.js45
-rw-r--r--apps/user_status/l10n/pt_BR.json45
-rw-r--r--apps/user_status/l10n/pt_PT.js23
-rw-r--r--apps/user_status/l10n/pt_PT.json23
-rw-r--r--apps/user_status/l10n/ro.js35
-rw-r--r--apps/user_status/l10n/ro.json35
-rw-r--r--apps/user_status/l10n/ru.js55
-rw-r--r--apps/user_status/l10n/ru.json55
-rw-r--r--apps/user_status/l10n/sc.js22
-rw-r--r--apps/user_status/l10n/sc.json22
-rw-r--r--apps/user_status/l10n/sk.js36
-rw-r--r--apps/user_status/l10n/sk.json36
-rw-r--r--apps/user_status/l10n/sl.js32
-rw-r--r--apps/user_status/l10n/sl.json32
-rw-r--r--apps/user_status/l10n/sr.js50
-rw-r--r--apps/user_status/l10n/sr.json48
-rw-r--r--apps/user_status/l10n/sr@latin.js47
-rw-r--r--apps/user_status/l10n/sr@latin.json45
-rw-r--r--apps/user_status/l10n/sv.js32
-rw-r--r--apps/user_status/l10n/sv.json32
-rw-r--r--apps/user_status/l10n/sw.js51
-rw-r--r--apps/user_status/l10n/sw.json49
-rw-r--r--apps/user_status/l10n/th.js19
-rw-r--r--apps/user_status/l10n/th.json19
-rw-r--r--apps/user_status/l10n/tr.js42
-rw-r--r--apps/user_status/l10n/tr.json42
-rw-r--r--apps/user_status/l10n/ug.js50
-rw-r--r--apps/user_status/l10n/ug.json48
-rw-r--r--apps/user_status/l10n/uk.js52
-rw-r--r--apps/user_status/l10n/uk.json52
-rw-r--r--apps/user_status/l10n/uz.js50
-rw-r--r--apps/user_status/l10n/uz.json48
-rw-r--r--apps/user_status/l10n/vi.js33
-rw-r--r--apps/user_status/l10n/vi.json33
-rw-r--r--apps/user_status/l10n/zh_CN.js41
-rw-r--r--apps/user_status/l10n/zh_CN.json41
-rw-r--r--apps/user_status/l10n/zh_HK.js33
-rw-r--r--apps/user_status/l10n/zh_HK.json33
-rw-r--r--apps/user_status/l10n/zh_TW.js51
-rw-r--r--apps/user_status/l10n/zh_TW.json51
-rw-r--r--apps/user_status/lib/AppInfo/Application.php34
-rw-r--r--apps/user_status/lib/BackgroundJob/ClearOldStatusesBackgroundJob.php34
-rw-r--r--apps/user_status/lib/Capabilities.php43
-rw-r--r--apps/user_status/lib/Connector/UserStatus.php45
-rw-r--r--apps/user_status/lib/Connector/UserStatusProvider.php39
-rw-r--r--apps/user_status/lib/ContactsMenu/StatusProvider.php53
-rw-r--r--apps/user_status/lib/Controller/HeartbeatController.php89
-rw-r--r--apps/user_status/lib/Controller/PredefinedStatusController.php53
-rw-r--r--apps/user_status/lib/Controller/StatusesController.php73
-rw-r--r--apps/user_status/lib/Controller/UserStatusController.php168
-rw-r--r--apps/user_status/lib/Dashboard/UserStatusWidget.php149
-rw-r--r--apps/user_status/lib/Db/UserStatus.php42
-rw-r--r--apps/user_status/lib/Db/UserStatusMapper.php58
-rw-r--r--apps/user_status/lib/Exception/InvalidClearAtException.php21
-rw-r--r--apps/user_status/lib/Exception/InvalidMessageIdException.php21
-rw-r--r--apps/user_status/lib/Exception/InvalidStatusIconException.php21
-rw-r--r--apps/user_status/lib/Exception/InvalidStatusTypeException.php21
-rw-r--r--apps/user_status/lib/Exception/StatusMessageTooLongException.php21
-rw-r--r--apps/user_status/lib/Listener/BeforeTemplateRenderedListener.php46
-rw-r--r--apps/user_status/lib/Listener/OutOfOfficeStatusListener.php57
-rw-r--r--apps/user_status/lib/Listener/UserDeletedListener.php32
-rw-r--r--apps/user_status/lib/Listener/UserLiveStatusListener.php72
-rw-r--r--apps/user_status/lib/Migration/Version0001Date20200602134824.php25
-rw-r--r--apps/user_status/lib/Migration/Version0002Date20200902144824.php21
-rw-r--r--apps/user_status/lib/Migration/Version1000Date20201111130204.php21
-rw-r--r--apps/user_status/lib/Migration/Version1003Date20210809144824.php43
-rw-r--r--apps/user_status/lib/Migration/Version1008Date20230921144701.php54
-rw-r--r--apps/user_status/lib/Migration/Version2301Date20210809144824.php58
-rw-r--r--apps/user_status/lib/ResponseDefinitions.php44
-rw-r--r--apps/user_status/lib/Service/EmojiService.php102
-rw-r--r--apps/user_status/lib/Service/JSDataService.php35
-rw-r--r--apps/user_status/lib/Service/PredefinedStatusService.php71
-rw-r--r--apps/user_status/lib/Service/StatusService.php246
-rw-r--r--apps/user_status/openapi.json1195
-rw-r--r--apps/user_status/openapi.json.license2
-rw-r--r--apps/user_status/src/UserStatus.vue229
-rw-r--r--apps/user_status/src/components/ClearAtSelect.vue58
-rw-r--r--apps/user_status/src/components/CustomMessageInput.vue103
-rw-r--r--apps/user_status/src/components/OnlineStatusSelect.vue94
-rw-r--r--apps/user_status/src/components/PredefinedStatus.vue134
-rw-r--r--apps/user_status/src/components/PredefinedStatusesList.vue65
-rw-r--r--apps/user_status/src/components/PreviousStatus.vue106
-rw-r--r--apps/user_status/src/components/SetStatusModal.vue330
-rw-r--r--apps/user_status/src/dashboard.js44
-rw-r--r--apps/user_status/src/filters/clearAtFilter.js23
-rw-r--r--apps/user_status/src/menu.js74
-rw-r--r--apps/user_status/src/mixins/OnlineStatusMixin.js46
-rw-r--r--apps/user_status/src/services/clearAtOptionsService.js21
-rw-r--r--apps/user_status/src/services/clearAtService.js23
-rw-r--r--apps/user_status/src/services/dateService.js21
-rw-r--r--apps/user_status/src/services/heartbeatService.js27
-rw-r--r--apps/user_status/src/services/predefinedStatusService.js21
-rw-r--r--apps/user_status/src/services/statusOptionsService.js30
-rw-r--r--apps/user_status/src/services/statusService.js49
-rw-r--r--apps/user_status/src/store/index.js27
-rw-r--r--apps/user_status/src/store/predefinedStatuses.js31
-rw-r--r--apps/user_status/src/store/userBackupStatus.js102
-rw-r--r--apps/user_status/src/store/userStatus.js48
-rw-r--r--apps/user_status/src/views/Dashboard.vue122
-rw-r--r--apps/user_status/tests/Integration/Service/StatusServiceIntegrationTest.php196
-rw-r--r--apps/user_status/tests/Unit/BackgroundJob/ClearOldStatusesBackgroundJobTest.php39
-rw-r--r--apps/user_status/tests/Unit/CapabilitiesTest.php48
-rw-r--r--apps/user_status/tests/Unit/Connector/UserStatusProviderTest.php30
-rw-r--r--apps/user_status/tests/Unit/Connector/UserStatusTest.php27
-rw-r--r--apps/user_status/tests/Unit/Controller/PredefinedStatusControllerTest.php35
-rw-r--r--apps/user_status/tests/Unit/Controller/StatusesControllerTest.php30
-rw-r--r--apps/user_status/tests/Unit/Controller/UserStatusControllerTest.php198
-rw-r--r--apps/user_status/tests/Unit/Dashboard/UserStatusWidgetTest.php231
-rw-r--r--apps/user_status/tests/Unit/Db/UserStatusMapperTest.php67
-rw-r--r--apps/user_status/tests/Unit/Listener/UserDeletedListenerTest.php30
-rw-r--r--apps/user_status/tests/Unit/Listener/UserLiveStatusListenerTest.php90
-rw-r--r--apps/user_status/tests/Unit/Service/EmojiServiceTest.php100
-rw-r--r--apps/user_status/tests/Unit/Service/PredefinedStatusServiceTest.php114
-rw-r--r--apps/user_status/tests/Unit/Service/StatusServiceTest.php278
-rw-r--r--apps/user_status/tests/bootstrap.php34
206 files changed, 6493 insertions, 4346 deletions
diff --git a/apps/user_status/.l10nignore b/apps/user_status/.l10nignore
index ea53c49c185..91aefac85dc 100644
--- a/apps/user_status/.l10nignore
+++ b/apps/user_status/.l10nignore
@@ -1,2 +1,4 @@
+# SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+# SPDX-License-Identifier: AGPL-3.0-or-later
#webpack bundled files
js/
diff --git a/apps/user_status/appinfo/info.xml b/apps/user_status/appinfo/info.xml
index c385886e946..0f9b5235f7c 100644
--- a/apps/user_status/appinfo/info.xml
+++ b/apps/user_status/appinfo/info.xml
@@ -1,30 +1,35 @@
<?xml version="1.0"?>
+<!--
+ - SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
+ -->
<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>user_status</id>
<name>User status</name>
<summary>User status</summary>
<description><![CDATA[User status]]></description>
- <version>1.5.0</version>
+ <version>1.12.0</version>
<licence>agpl</licence>
<author mail="oc.list@georgehrke.com" >Georg Ehrke</author>
<namespace>UserStatus</namespace>
- <default_enable/>
<category>social</category>
<bugs>https://github.com/nextcloud/server</bugs>
<navigations>
<navigation>
- <id>user_status-menuitem</id>
+ <id>user_status-menu-entry</id>
<name>User status</name>
- <route />
<order>1</order>
<type>settings</type>
</navigation>
</navigations>
<dependencies>
- <nextcloud min-version="25" max-version="25"/>
+ <nextcloud min-version="32" max-version="32"/>
</dependencies>
<background-jobs>
<job>OCA\UserStatus\BackgroundJob\ClearOldStatusesBackgroundJob</job>
</background-jobs>
+ <contactsmenu>
+ <provider>OCA\UserStatus\ContactsMenu\StatusProvider</provider>
+ </contactsmenu>
</info>
diff --git a/apps/user_status/appinfo/routes.php b/apps/user_status/appinfo/routes.php
deleted file mode 100644
index d360dc1ebd5..00000000000
--- a/apps/user_status/appinfo/routes.php
+++ /dev/null
@@ -1,43 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-return [
- 'ocs' => [
- // Routes for querying statuses
- ['name' => 'Statuses#findAll', 'url' => '/api/v1/statuses', 'verb' => 'GET'],
- ['name' => 'Statuses#find', 'url' => '/api/v1/statuses/{userId}', 'verb' => 'GET'],
- // Routes for manipulating your own status
- ['name' => 'UserStatus#getStatus', 'url' => '/api/v1/user_status', 'verb' => 'GET'],
- ['name' => 'UserStatus#setStatus', 'url' => '/api/v1/user_status/status', 'verb' => 'PUT'],
- ['name' => 'UserStatus#setPredefinedMessage', 'url' => '/api/v1/user_status/message/predefined', 'verb' => 'PUT'],
- ['name' => 'UserStatus#setCustomMessage', 'url' => '/api/v1/user_status/message/custom', 'verb' => 'PUT'],
- ['name' => 'UserStatus#clearMessage', 'url' => '/api/v1/user_status/message', 'verb' => 'DELETE'],
- // Routes for listing default routes
- ['name' => 'PredefinedStatus#findAll', 'url' => '/api/v1/predefined_statuses/', 'verb' => 'GET']
- ],
- 'routes' => [
- ['name' => 'Heartbeat#heartbeat', 'url' => '/heartbeat', 'verb' => 'PUT'],
- ],
-];
diff --git a/apps/user_status/composer/autoload.php b/apps/user_status/composer/autoload.php
index a82d4105451..afd560d3ae9 100644
--- a/apps/user_status/composer/autoload.php
+++ b/apps/user_status/composer/autoload.php
@@ -3,8 +3,21 @@
// autoload.php @generated by Composer
if (PHP_VERSION_ID < 50600) {
- echo '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;
- exit(1);
+ 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';
diff --git a/apps/user_status/composer/composer/ClassLoader.php b/apps/user_status/composer/composer/ClassLoader.php
index afef3fa2ad8..7824d8f7eaf 100644
--- a/apps/user_status/composer/composer/ClassLoader.php
+++ b/apps/user_status/composer/composer/ClassLoader.php
@@ -42,35 +42,37 @@ namespace Composer\Autoload;
*/
class ClassLoader
{
- /** @var ?string */
+ /** @var \Closure(string):void */
+ private static $includeFile;
+
+ /** @var string|null */
private $vendorDir;
// PSR-4
/**
- * @var array[]
- * @psalm-var array<string, array<string, int>>
+ * @var array<string, array<string, int>>
*/
private $prefixLengthsPsr4 = array();
/**
- * @var array[]
- * @psalm-var array<string, array<int, string>>
+ * @var array<string, list<string>>
*/
private $prefixDirsPsr4 = array();
/**
- * @var array[]
- * @psalm-var array<string, string>
+ * @var list<string>
*/
private $fallbackDirsPsr4 = array();
// PSR-0
/**
- * @var array[]
- * @psalm-var array<string, array<string, string[]>>
+ * 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 array[]
- * @psalm-var array<string, string>
+ * @var list<string>
*/
private $fallbackDirsPsr0 = array();
@@ -78,8 +80,7 @@ class ClassLoader
private $useIncludePath = false;
/**
- * @var string[]
- * @psalm-var array<string, string>
+ * @var array<string, string>
*/
private $classMap = array();
@@ -87,29 +88,29 @@ class ClassLoader
private $classMapAuthoritative = false;
/**
- * @var bool[]
- * @psalm-var array<string, bool>
+ * @var array<string, bool>
*/
private $missingClasses = array();
- /** @var ?string */
+ /** @var string|null */
private $apcuPrefix;
/**
- * @var self[]
+ * @var array<string, self>
*/
private static $registeredLoaders = array();
/**
- * @param ?string $vendorDir
+ * @param string|null $vendorDir
*/
public function __construct($vendorDir = null)
{
$this->vendorDir = $vendorDir;
+ self::initializeIncludeClosure();
}
/**
- * @return string[]
+ * @return array<string, list<string>>
*/
public function getPrefixes()
{
@@ -121,8 +122,7 @@ class ClassLoader
}
/**
- * @return array[]
- * @psalm-return array<string, array<int, string>>
+ * @return array<string, list<string>>
*/
public function getPrefixesPsr4()
{
@@ -130,8 +130,7 @@ class ClassLoader
}
/**
- * @return array[]
- * @psalm-return array<string, string>
+ * @return list<string>
*/
public function getFallbackDirs()
{
@@ -139,8 +138,7 @@ class ClassLoader
}
/**
- * @return array[]
- * @psalm-return array<string, string>
+ * @return list<string>
*/
public function getFallbackDirsPsr4()
{
@@ -148,8 +146,7 @@ class ClassLoader
}
/**
- * @return string[] Array of classname => path
- * @psalm-return array<string, string>
+ * @return array<string, string> Array of classname => path
*/
public function getClassMap()
{
@@ -157,8 +154,7 @@ class ClassLoader
}
/**
- * @param string[] $classMap Class to filename map
- * @psalm-param array<string, string> $classMap
+ * @param array<string, string> $classMap Class to filename map
*
* @return void
*/
@@ -175,24 +171,25 @@ class ClassLoader
* 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 string[]|string $paths The PSR-0 root directories
- * @param bool $prepend Whether to prepend the directories
+ * @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(
- (array) $paths,
+ $paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
- (array) $paths
+ $paths
);
}
@@ -201,19 +198,19 @@ class ClassLoader
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
- $this->prefixesPsr0[$first][$prefix] = (array) $paths;
+ $this->prefixesPsr0[$first][$prefix] = $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
- (array) $paths,
+ $paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
- (array) $paths
+ $paths
);
}
}
@@ -222,9 +219,9 @@ class ClassLoader
* 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 string[]|string $paths The PSR-4 base directories
- * @param bool $prepend Whether to prepend the directories
+ * @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
*
@@ -232,17 +229,18 @@ class ClassLoader
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
+ $paths = (array) $paths;
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
- (array) $paths,
+ $paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
- (array) $paths
+ $paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
@@ -252,18 +250,18 @@ class ClassLoader
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;
+ $this->prefixDirsPsr4[$prefix] = $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
- (array) $paths,
+ $paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
- (array) $paths
+ $paths
);
}
}
@@ -272,8 +270,8 @@ class ClassLoader
* 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 string[]|string $paths The PSR-0 base directories
+ * @param string $prefix The prefix
+ * @param list<string>|string $paths The PSR-0 base directories
*
* @return void
*/
@@ -290,8 +288,8 @@ class ClassLoader
* 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 string[]|string $paths The PSR-4 base directories
+ * @param string $prefix The prefix/namespace, with trailing '\\'
+ * @param list<string>|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*
@@ -425,7 +423,8 @@ class ClassLoader
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
- includeFile($file);
+ $includeFile = self::$includeFile;
+ $includeFile($file);
return true;
}
@@ -476,9 +475,9 @@ class ClassLoader
}
/**
- * Returns the currently registered loaders indexed by their corresponding vendor directories.
+ * Returns the currently registered loaders keyed by their corresponding vendor directories.
*
- * @return self[]
+ * @return array<string, self>
*/
public static function getRegisteredLoaders()
{
@@ -555,18 +554,26 @@ class ClassLoader
return false;
}
-}
-/**
- * Scope isolated include.
- *
- * Prevents access to $this/self from included files.
- *
- * @param string $file
- * @return void
- * @private
- */
-function includeFile($file)
-{
- include $file;
+ /**
+ * @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/user_status/composer/composer/InstalledVersions.php b/apps/user_status/composer/composer/InstalledVersions.php
index 41bc143c114..51e734a774b 100644
--- a/apps/user_status/composer/composer/InstalledVersions.php
+++ b/apps/user_status/composer/composer/InstalledVersions.php
@@ -28,7 +28,7 @@ class InstalledVersions
{
/**
* @var mixed[]|null
- * @psalm-var array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}|array{}|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;
@@ -39,7 +39,7 @@ class InstalledVersions
/**
* @var array[]
- * @psalm-var array<string, array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
+ * @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();
@@ -98,7 +98,7 @@ class InstalledVersions
{
foreach (self::getInstalled() as $installed) {
if (isset($installed['versions'][$packageName])) {
- return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
+ return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
}
}
@@ -119,7 +119,7 @@ class InstalledVersions
*/
public static function satisfies(VersionParser $parser, $packageName, $constraint)
{
- $constraint = $parser->parseConstraints($constraint);
+ $constraint = $parser->parseConstraints((string) $constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
return $provided->matches($constraint);
@@ -243,7 +243,7 @@ class InstalledVersions
/**
* @return array
- * @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}
+ * @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()
{
@@ -257,7 +257,7 @@ class InstalledVersions
*
* @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, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}
+ * @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()
{
@@ -280,7 +280,7 @@ class InstalledVersions
* 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, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
+ * @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()
{
@@ -303,7 +303,7 @@ class InstalledVersions
* @param array[] $data A vendor/composer/installed.php data set
* @return void
*
- * @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>} $data
+ * @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)
{
@@ -313,7 +313,7 @@ class InstalledVersions
/**
* @return array[]
- * @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
+ * @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()
{
@@ -328,7 +328,9 @@ class InstalledVersions
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
- $installed[] = self::$installedByVendor[$vendorDir] = require $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];
}
@@ -340,12 +342,17 @@ class InstalledVersions
// 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 = require __DIR__ . '/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 __DIR__ . '/installed.php';
+ self::$installed = $required;
} else {
self::$installed = array();
}
}
- $installed[] = self::$installed;
+
+ if (self::$installed !== array()) {
+ $installed[] = self::$installed;
+ }
return $installed;
}
diff --git a/apps/user_status/composer/composer/autoload_classmap.php b/apps/user_status/composer/composer/autoload_classmap.php
index 64da04fb8ba..b57df813bc9 100644
--- a/apps/user_status/composer/composer/autoload_classmap.php
+++ b/apps/user_status/composer/composer/autoload_classmap.php
@@ -12,6 +12,7 @@ return array(
'OCA\\UserStatus\\Capabilities' => $baseDir . '/../lib/Capabilities.php',
'OCA\\UserStatus\\Connector\\UserStatus' => $baseDir . '/../lib/Connector/UserStatus.php',
'OCA\\UserStatus\\Connector\\UserStatusProvider' => $baseDir . '/../lib/Connector/UserStatusProvider.php',
+ 'OCA\\UserStatus\\ContactsMenu\\StatusProvider' => $baseDir . '/../lib/ContactsMenu/StatusProvider.php',
'OCA\\UserStatus\\Controller\\HeartbeatController' => $baseDir . '/../lib/Controller/HeartbeatController.php',
'OCA\\UserStatus\\Controller\\PredefinedStatusController' => $baseDir . '/../lib/Controller/PredefinedStatusController.php',
'OCA\\UserStatus\\Controller\\StatusesController' => $baseDir . '/../lib/Controller/StatusesController.php',
@@ -25,13 +26,15 @@ return array(
'OCA\\UserStatus\\Exception\\InvalidStatusTypeException' => $baseDir . '/../lib/Exception/InvalidStatusTypeException.php',
'OCA\\UserStatus\\Exception\\StatusMessageTooLongException' => $baseDir . '/../lib/Exception/StatusMessageTooLongException.php',
'OCA\\UserStatus\\Listener\\BeforeTemplateRenderedListener' => $baseDir . '/../lib/Listener/BeforeTemplateRenderedListener.php',
+ 'OCA\\UserStatus\\Listener\\OutOfOfficeStatusListener' => $baseDir . '/../lib/Listener/OutOfOfficeStatusListener.php',
'OCA\\UserStatus\\Listener\\UserDeletedListener' => $baseDir . '/../lib/Listener/UserDeletedListener.php',
'OCA\\UserStatus\\Listener\\UserLiveStatusListener' => $baseDir . '/../lib/Listener/UserLiveStatusListener.php',
'OCA\\UserStatus\\Migration\\Version0001Date20200602134824' => $baseDir . '/../lib/Migration/Version0001Date20200602134824.php',
'OCA\\UserStatus\\Migration\\Version0002Date20200902144824' => $baseDir . '/../lib/Migration/Version0002Date20200902144824.php',
'OCA\\UserStatus\\Migration\\Version1000Date20201111130204' => $baseDir . '/../lib/Migration/Version1000Date20201111130204.php',
- 'OCA\\UserStatus\\Migration\\Version2301Date20210809144824' => $baseDir . '/../lib/Migration/Version2301Date20210809144824.php',
- 'OCA\\UserStatus\\Service\\EmojiService' => $baseDir . '/../lib/Service/EmojiService.php',
+ 'OCA\\UserStatus\\Migration\\Version1003Date20210809144824' => $baseDir . '/../lib/Migration/Version1003Date20210809144824.php',
+ 'OCA\\UserStatus\\Migration\\Version1008Date20230921144701' => $baseDir . '/../lib/Migration/Version1008Date20230921144701.php',
+ 'OCA\\UserStatus\\ResponseDefinitions' => $baseDir . '/../lib/ResponseDefinitions.php',
'OCA\\UserStatus\\Service\\JSDataService' => $baseDir . '/../lib/Service/JSDataService.php',
'OCA\\UserStatus\\Service\\PredefinedStatusService' => $baseDir . '/../lib/Service/PredefinedStatusService.php',
'OCA\\UserStatus\\Service\\StatusService' => $baseDir . '/../lib/Service/StatusService.php',
diff --git a/apps/user_status/composer/composer/autoload_static.php b/apps/user_status/composer/composer/autoload_static.php
index c4ee7d031b5..7e494344490 100644
--- a/apps/user_status/composer/composer/autoload_static.php
+++ b/apps/user_status/composer/composer/autoload_static.php
@@ -27,6 +27,7 @@ class ComposerStaticInitUserStatus
'OCA\\UserStatus\\Capabilities' => __DIR__ . '/..' . '/../lib/Capabilities.php',
'OCA\\UserStatus\\Connector\\UserStatus' => __DIR__ . '/..' . '/../lib/Connector/UserStatus.php',
'OCA\\UserStatus\\Connector\\UserStatusProvider' => __DIR__ . '/..' . '/../lib/Connector/UserStatusProvider.php',
+ 'OCA\\UserStatus\\ContactsMenu\\StatusProvider' => __DIR__ . '/..' . '/../lib/ContactsMenu/StatusProvider.php',
'OCA\\UserStatus\\Controller\\HeartbeatController' => __DIR__ . '/..' . '/../lib/Controller/HeartbeatController.php',
'OCA\\UserStatus\\Controller\\PredefinedStatusController' => __DIR__ . '/..' . '/../lib/Controller/PredefinedStatusController.php',
'OCA\\UserStatus\\Controller\\StatusesController' => __DIR__ . '/..' . '/../lib/Controller/StatusesController.php',
@@ -40,13 +41,15 @@ class ComposerStaticInitUserStatus
'OCA\\UserStatus\\Exception\\InvalidStatusTypeException' => __DIR__ . '/..' . '/../lib/Exception/InvalidStatusTypeException.php',
'OCA\\UserStatus\\Exception\\StatusMessageTooLongException' => __DIR__ . '/..' . '/../lib/Exception/StatusMessageTooLongException.php',
'OCA\\UserStatus\\Listener\\BeforeTemplateRenderedListener' => __DIR__ . '/..' . '/../lib/Listener/BeforeTemplateRenderedListener.php',
+ 'OCA\\UserStatus\\Listener\\OutOfOfficeStatusListener' => __DIR__ . '/..' . '/../lib/Listener/OutOfOfficeStatusListener.php',
'OCA\\UserStatus\\Listener\\UserDeletedListener' => __DIR__ . '/..' . '/../lib/Listener/UserDeletedListener.php',
'OCA\\UserStatus\\Listener\\UserLiveStatusListener' => __DIR__ . '/..' . '/../lib/Listener/UserLiveStatusListener.php',
'OCA\\UserStatus\\Migration\\Version0001Date20200602134824' => __DIR__ . '/..' . '/../lib/Migration/Version0001Date20200602134824.php',
'OCA\\UserStatus\\Migration\\Version0002Date20200902144824' => __DIR__ . '/..' . '/../lib/Migration/Version0002Date20200902144824.php',
'OCA\\UserStatus\\Migration\\Version1000Date20201111130204' => __DIR__ . '/..' . '/../lib/Migration/Version1000Date20201111130204.php',
- 'OCA\\UserStatus\\Migration\\Version2301Date20210809144824' => __DIR__ . '/..' . '/../lib/Migration/Version2301Date20210809144824.php',
- 'OCA\\UserStatus\\Service\\EmojiService' => __DIR__ . '/..' . '/../lib/Service/EmojiService.php',
+ 'OCA\\UserStatus\\Migration\\Version1003Date20210809144824' => __DIR__ . '/..' . '/../lib/Migration/Version1003Date20210809144824.php',
+ 'OCA\\UserStatus\\Migration\\Version1008Date20230921144701' => __DIR__ . '/..' . '/../lib/Migration/Version1008Date20230921144701.php',
+ 'OCA\\UserStatus\\ResponseDefinitions' => __DIR__ . '/..' . '/../lib/ResponseDefinitions.php',
'OCA\\UserStatus\\Service\\JSDataService' => __DIR__ . '/..' . '/../lib/Service/JSDataService.php',
'OCA\\UserStatus\\Service\\PredefinedStatusService' => __DIR__ . '/..' . '/../lib/Service/PredefinedStatusService.php',
'OCA\\UserStatus\\Service\\StatusService' => __DIR__ . '/..' . '/../lib/Service/StatusService.php',
diff --git a/apps/user_status/composer/composer/installed.php b/apps/user_status/composer/composer/installed.php
index 5440719fa40..1a66c7f2416 100644
--- a/apps/user_status/composer/composer/installed.php
+++ b/apps/user_status/composer/composer/installed.php
@@ -1,22 +1,22 @@
<?php return array(
'root' => array(
+ 'name' => '__root__',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
+ 'reference' => 'b1797842784b250fb01ed5e3bf130705eb94751b',
'type' => 'library',
'install_path' => __DIR__ . '/../',
'aliases' => array(),
- 'reference' => 'c6429e6cd19c57582364338362e543580821cf99',
- 'name' => '__root__',
'dev' => false,
),
'versions' => array(
'__root__' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
+ 'reference' => 'b1797842784b250fb01ed5e3bf130705eb94751b',
'type' => 'library',
'install_path' => __DIR__ . '/../',
'aliases' => array(),
- 'reference' => 'c6429e6cd19c57582364338362e543580821cf99',
'dev_requirement' => false,
),
),
diff --git a/apps/user_status/css/user-status-menu.css b/apps/user_status/css/user-status-menu.css
new file mode 100644
index 00000000000..5bdbdf01cb4
--- /dev/null
+++ b/apps/user_status/css/user-status-menu.css
@@ -0,0 +1,4 @@
+/*!
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */.icon-user-status{background-image:url("../img/app.svg")}.icon-user-status-dark{background-image:url("../img/app-dark.svg");filter:var(--background-invert-if-dark)}/*# sourceMappingURL=user-status-menu.css.map */
diff --git a/apps/user_status/css/user-status-menu.css.map b/apps/user_status/css/user-status-menu.css.map
new file mode 100644
index 00000000000..d8e862f7108
--- /dev/null
+++ b/apps/user_status/css/user-status-menu.css.map
@@ -0,0 +1 @@
+{"version":3,"sourceRoot":"","sources":["user-status-menu.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAAA,GAIA,kBACC,uCAGD,uBACC,4CACA","file":"user-status-menu.css"} \ No newline at end of file
diff --git a/apps/user_status/css/user-status-menu.css.map.license b/apps/user_status/css/user-status-menu.css.map.license
new file mode 100644
index 00000000000..7e235b60091
--- /dev/null
+++ b/apps/user_status/css/user-status-menu.css.map.license
@@ -0,0 +1,2 @@
+SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+SPDX-License-Identifier: AGPL-3.0-or-later
diff --git a/apps/user_status/css/user-status-menu.scss b/apps/user_status/css/user-status-menu.scss
index 09dfd3124f8..10d761e5dff 100644
--- a/apps/user_status/css/user-status-menu.scss
+++ b/apps/user_status/css/user-status-menu.scss
@@ -1,50 +1,12 @@
-/**
- * @copyright Copyright (c) 2020 Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+/*!
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
-
.icon-user-status {
- @include icon-color('app', 'user_status', $color-black, 1);
-}
-
-body.theme--dark .icon-user-status {
- @include icon-color('app', 'user_status', $color-white, 1);
-}
-
-.icon-user-status-online {
- background-image: url('../img/user-status-online.svg');
-}
-
-.icon-user-status-away {
- background-image: url('../img/user-status-away.svg');
-}
-
-.icon-user-status-dnd {
- background-image: url('../img/user-status-dnd.svg');
-}
-
-// TODO: debug why icon-black-white does not work here
-.icon-user-status-invisible {
- @include icon-color('user-status-invisible', 'user_status', $color-black, 1);
+ background-image: url("../img/app.svg");
}
-body.theme--dark .icon-user-status-invisible {
- @include icon-color('user-status-invisible', 'user_status', $color-white, 1);
+.icon-user-status-dark {
+ background-image: url("../img/app-dark.svg");
+ filter: var(--background-invert-if-dark);
}
diff --git a/apps/user_status/img/app-dark.svg b/apps/user_status/img/app-dark.svg
new file mode 100644
index 00000000000..292424a68ec
--- /dev/null
+++ b/apps/user_status/img/app-dark.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px"><path d="M479.96-144Q340-144 242-242t-98-238q0-140 97.93-238t237.83-98q13.06 0 25.65 1 12.59 1 25.59 3-39 29-62 72t-23 92q0 85 58.5 143.5T648-446q49 0 92-23t72-62q2 13 3 25.59t1 25.65q0 139.9-98.04 237.83t-238 97.93Z"/></svg> \ No newline at end of file
diff --git a/apps/user_status/img/app.svg b/apps/user_status/img/app.svg
index eaf87d52ecf..d7fdef622fd 100644
--- a/apps/user_status/img/app.svg
+++ b/apps/user_status/img/app.svg
@@ -1 +1 @@
-<svg width="24" height="24" enable-background="new 0 0 24 24" version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><rect width="24" height="24" fill="none"/><path d="m10.615 2.1094c-4.8491 0.68106-8.6152 4.8615-8.6152 9.8906 0 5.5 4.5 10 10 10 5.0292 0 9.2096-3.7661 9.8906-8.6152-1.4654 1.601-3.5625 2.6152-5.8906 2.6152-4.4 0-8-3.6-8-8 0-2.3281 1.0143-4.4252 2.6152-5.8906z" fill="#ffffff"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px" fill="#fff"><path d="M479.96-144Q340-144 242-242t-98-238q0-140 97.93-238t237.83-98q13.06 0 25.65 1 12.59 1 25.59 3-39 29-62 72t-23 92q0 85 58.5 143.5T648-446q49 0 92-23t72-62q2 13 3 25.59t1 25.65q0 139.9-98.04 237.83t-238 97.93Z"/></svg> \ No newline at end of file
diff --git a/apps/user_status/img/user-status-away.svg b/apps/user_status/img/user-status-away.svg
deleted file mode 100644
index ab308c29efa..00000000000
--- a/apps/user_status/img/user-status-away.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg width="24" height="24" enable-background="new 0 0 24 24" version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><rect width="24" height="24" fill="none"/><path d="m10.615 2.1094c-4.8491 0.68106-8.6152 4.8615-8.6152 9.8906 0 5.5 4.5 10 10 10 5.0292 0 9.2096-3.7661 9.8906-8.6152-1.4654 1.601-3.5625 2.6152-5.8906 2.6152-4.4 0-8-3.6-8-8 0-2.3281 1.0143-4.4252 2.6152-5.8906z" fill="#f4a331"/></svg>
diff --git a/apps/user_status/img/user-status-dnd.svg b/apps/user_status/img/user-status-dnd.svg
deleted file mode 100644
index d28e52c1293..00000000000
--- a/apps/user_status/img/user-status-dnd.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg width="24" height="24" version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"/><path d="m12 2c-5.52 0-10 4.48-10 10s4.48 10 10 10 10-4.48 10-10-4.48-10-10-10z" fill="#ed484c"/><path d="m8 10h8c1.108 0 2 0.892 2 2s-0.892 2-2 2h-8c-1.108 0-2-0.892-2-2s0.892-2 2-2z" fill="#fdffff" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" style="paint-order:stroke markers fill"/></svg>
diff --git a/apps/user_status/img/user-status-invisible.svg b/apps/user_status/img/user-status-invisible.svg
deleted file mode 100644
index a5dc34cc976..00000000000
--- a/apps/user_status/img/user-status-invisible.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg width="24" height="24" version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"/><path d="m12 2c-5.52 0-10 4.48-10 10s4.48 10 10 10 10-4.48 10-10-4.48-10-10-10zm0 4a6 6 0 0 1 6 6 6 6 0 0 1-6 6 6 6 0 0 1-6-6 6 6 0 0 1 6-6z"/></svg>
diff --git a/apps/user_status/img/user-status-online.svg b/apps/user_status/img/user-status-online.svg
deleted file mode 100644
index baf93c22b6a..00000000000
--- a/apps/user_status/img/user-status-online.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg width="24" height="24" enable-background="new 0 0 24 24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m8 16h8v-8h-8v8zm4-14c-5.52 0-10 4.48-10 10s4.48 10 10 10 10-4.48 10-10-4.48-10-10-10z" fill="#49B382"/></svg>
diff --git a/apps/user_status/l10n/af.js b/apps/user_status/l10n/af.js
index 0159c29095d..8a4bdf0be20 100644
--- a/apps/user_status/l10n/af.js
+++ b/apps/user_status/l10n/af.js
@@ -2,36 +2,34 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Onlangse statusse",
+ "No recent status changes" : "Geen onlangse statusverandering nie",
"In a meeting" : "In ’n vergadering",
"Commuting" : "In die verkeer",
"Out sick" : "Siek tuis",
"Vacationing" : "Met vakansie",
"Working remotely" : "Werk in die veld",
"User status" : "Gebruikerstatus",
- "Clear status message after" : "Wis statusboodskap na",
- "Set status" : "Stel status",
+ "Clear status after" : "Wis status na",
+ "There was an error saving the status" : "Daar was ’n fout toe status bewaar is",
+ "There was an error clearing the status" : "Daar was ’n fout toe die status gewis is",
"Online status" : "Aanlyn status",
"Status message" : "Statusboodskap",
"Clear status message" : "Wis statusboodskap",
"Set status message" : "Stel statusboodskap",
- "There was an error saving the status" : "Daar was ’n fout toe status bewaar is",
- "There was an error clearing the status" : "Daar was ’n fout toe die status gewis is",
- "No recent status changes" : "Geen onlangse statusverandering nie",
- "Away" : "Weg",
- "Do not disturb" : "Moenie pla nie",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Moenie wis nie",
"Today" : "Vandag",
"This week" : "Vandeesweek",
"Online" : "Aanlyn",
+ "Away" : "Weg",
+ "Do not disturb" : "Moenie pla nie",
"Invisible" : "Onsigbaar",
"Offline" : "Vanlyn",
+ "Set status" : "Stel status",
"There was an error saving the new status" : "Daar was ’n fout toe nuwe status bewaar is",
"30 minutes" : "30 minute",
"1 hour" : "1 uur",
"4 hours" : "4 uur",
"Mute all notifications" : "Demp alle kennisgewings",
- "Appear offline" : "Toon as vanlyn",
- "What's your status?" : "Wat is u status"
+ "Appear offline" : "Toon as vanlyn"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/user_status/l10n/af.json b/apps/user_status/l10n/af.json
index 48b425b4586..0a92dd9ab7d 100644
--- a/apps/user_status/l10n/af.json
+++ b/apps/user_status/l10n/af.json
@@ -1,35 +1,33 @@
{ "translations": {
"Recent statuses" : "Onlangse statusse",
+ "No recent status changes" : "Geen onlangse statusverandering nie",
"In a meeting" : "In ’n vergadering",
"Commuting" : "In die verkeer",
"Out sick" : "Siek tuis",
"Vacationing" : "Met vakansie",
"Working remotely" : "Werk in die veld",
"User status" : "Gebruikerstatus",
- "Clear status message after" : "Wis statusboodskap na",
- "Set status" : "Stel status",
+ "Clear status after" : "Wis status na",
+ "There was an error saving the status" : "Daar was ’n fout toe status bewaar is",
+ "There was an error clearing the status" : "Daar was ’n fout toe die status gewis is",
"Online status" : "Aanlyn status",
"Status message" : "Statusboodskap",
"Clear status message" : "Wis statusboodskap",
"Set status message" : "Stel statusboodskap",
- "There was an error saving the status" : "Daar was ’n fout toe status bewaar is",
- "There was an error clearing the status" : "Daar was ’n fout toe die status gewis is",
- "No recent status changes" : "Geen onlangse statusverandering nie",
- "Away" : "Weg",
- "Do not disturb" : "Moenie pla nie",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Moenie wis nie",
"Today" : "Vandag",
"This week" : "Vandeesweek",
"Online" : "Aanlyn",
+ "Away" : "Weg",
+ "Do not disturb" : "Moenie pla nie",
"Invisible" : "Onsigbaar",
"Offline" : "Vanlyn",
+ "Set status" : "Stel status",
"There was an error saving the new status" : "Daar was ’n fout toe nuwe status bewaar is",
"30 minutes" : "30 minute",
"1 hour" : "1 uur",
"4 hours" : "4 uur",
"Mute all notifications" : "Demp alle kennisgewings",
- "Appear offline" : "Toon as vanlyn",
- "What's your status?" : "Wat is u status"
+ "Appear offline" : "Toon as vanlyn"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/ar.js b/apps/user_status/l10n/ar.js
index f161cbd3eb4..9557ff74546 100644
--- a/apps/user_status/l10n/ar.js
+++ b/apps/user_status/l10n/ar.js
@@ -2,37 +2,49 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "آخر الحالات",
+ "No recent status changes" : "لم يتم تغيير الحالة مؤخراً",
"In a meeting" : "في اجتماع",
"Commuting" : "تجوال",
- "Out sick" : "مريض",
+ "Out sick" : "إجازة مرضية",
"Vacationing" : "في اجازة",
- "Working remotely" : "العمل عن بعد",
+ "Out of office" : "خارج المكتب",
+ "Working remotely" : "عمل عن بعد",
+ "In a call" : "على الهاتف",
"User status" : "حالة العضو",
- "Clear status message after" : "احذف الحالة بعد",
+ "Clear status after" : "مسح رسالة الحالة بعد",
+ "Emoji for your status message" : "رسم تعبيري \"إيموجي\" لرسالة الحالة الخاصة بك",
"What is your status?" : "ماهي حالتك؟",
- "Set status" : "تعيين الحالة",
+ "Predefined statuses" : "حالات مُعرّفة مُسبقاً",
+ "Previously set" : "سبق تعيينها",
+ "Reset status" : "إعادة تعيين الحالة",
+ "Reset status to \"{icon} {message}\"" : "إعادة تعيين الحالة إلى \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "إعادة تعيين الحالة إلى \"{message}\"",
+ "Reset status to \"{icon}\"" : "إعادة تعيين الحالة إلى \"{icon}\"",
+ "There was an error saving the status" : "حدث خطأ اثناء حفظ الحالة",
+ "There was an error clearing the status" : "حدث خطأ اثناء حذف الحالة",
+ "There was an error reverting the status" : "حدث خطأ أثناء استرجاع الحالة",
"Online status" : "حالة الاتصال",
"Status message" : "رسالة الحالة",
+ "Set absence period" : "تعيين فترة التغيّب",
+ "Set absence period and replacement" : "تعيين فترة التّغيُّب و البديل",
+ "Your status was set automatically" : "تمّ تعيين حالتك تلقائيّاً",
"Clear status message" : "حذف رسالة الحالة",
"Set status message" : "تعيين رسالة الحالة",
- "There was an error saving the status" : "حدث خطأ اثناء حفظ الحالة",
- "There was an error clearing the status" : "حدث خطأ اثناء حذف الحالة",
- "No recent status changes" : "لم يتم تغيير الحالة",
- "Away" : "بالخارج",
- "Do not disturb" : "عدم الازعاج",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "غير محدد",
"Today" : "اليوم",
"This week" : "هذا الأسبوع",
"Online" : "متصل",
+ "Away" : "بالخارج",
+ "Do not disturb" : "عدم الازعاج",
"Invisible" : "عدم الظهور",
"Offline" : "غير متصل",
+ "Set status" : "تعيين الحالة",
"There was an error saving the new status" : "حدث خطأ اثناء حفظ الحالة الجديدة",
"30 minutes" : "30 دقيقة",
"1 hour" : "1 ساعة",
"4 hours" : "4 ساعات",
- "Mute all notifications" : "عدم اظهار جميع التنبيهات",
- "Appear offline" : "الحالة غير متصل",
- "What's your status?" : "ماهي حالتك؟"
+ "Busy" : "مشغول",
+ "Mute all notifications" : "عدم إظهار جميع التنبيهات",
+ "Appear offline" : "الحالة غير متصل"
},
"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/user_status/l10n/ar.json b/apps/user_status/l10n/ar.json
index 31a953a830e..79c8c2d184c 100644
--- a/apps/user_status/l10n/ar.json
+++ b/apps/user_status/l10n/ar.json
@@ -1,36 +1,48 @@
{ "translations": {
"Recent statuses" : "آخر الحالات",
+ "No recent status changes" : "لم يتم تغيير الحالة مؤخراً",
"In a meeting" : "في اجتماع",
"Commuting" : "تجوال",
- "Out sick" : "مريض",
+ "Out sick" : "إجازة مرضية",
"Vacationing" : "في اجازة",
- "Working remotely" : "العمل عن بعد",
+ "Out of office" : "خارج المكتب",
+ "Working remotely" : "عمل عن بعد",
+ "In a call" : "على الهاتف",
"User status" : "حالة العضو",
- "Clear status message after" : "احذف الحالة بعد",
+ "Clear status after" : "مسح رسالة الحالة بعد",
+ "Emoji for your status message" : "رسم تعبيري \"إيموجي\" لرسالة الحالة الخاصة بك",
"What is your status?" : "ماهي حالتك؟",
- "Set status" : "تعيين الحالة",
+ "Predefined statuses" : "حالات مُعرّفة مُسبقاً",
+ "Previously set" : "سبق تعيينها",
+ "Reset status" : "إعادة تعيين الحالة",
+ "Reset status to \"{icon} {message}\"" : "إعادة تعيين الحالة إلى \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "إعادة تعيين الحالة إلى \"{message}\"",
+ "Reset status to \"{icon}\"" : "إعادة تعيين الحالة إلى \"{icon}\"",
+ "There was an error saving the status" : "حدث خطأ اثناء حفظ الحالة",
+ "There was an error clearing the status" : "حدث خطأ اثناء حذف الحالة",
+ "There was an error reverting the status" : "حدث خطأ أثناء استرجاع الحالة",
"Online status" : "حالة الاتصال",
"Status message" : "رسالة الحالة",
+ "Set absence period" : "تعيين فترة التغيّب",
+ "Set absence period and replacement" : "تعيين فترة التّغيُّب و البديل",
+ "Your status was set automatically" : "تمّ تعيين حالتك تلقائيّاً",
"Clear status message" : "حذف رسالة الحالة",
"Set status message" : "تعيين رسالة الحالة",
- "There was an error saving the status" : "حدث خطأ اثناء حفظ الحالة",
- "There was an error clearing the status" : "حدث خطأ اثناء حذف الحالة",
- "No recent status changes" : "لم يتم تغيير الحالة",
- "Away" : "بالخارج",
- "Do not disturb" : "عدم الازعاج",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "غير محدد",
"Today" : "اليوم",
"This week" : "هذا الأسبوع",
"Online" : "متصل",
+ "Away" : "بالخارج",
+ "Do not disturb" : "عدم الازعاج",
"Invisible" : "عدم الظهور",
"Offline" : "غير متصل",
+ "Set status" : "تعيين الحالة",
"There was an error saving the new status" : "حدث خطأ اثناء حفظ الحالة الجديدة",
"30 minutes" : "30 دقيقة",
"1 hour" : "1 ساعة",
"4 hours" : "4 ساعات",
- "Mute all notifications" : "عدم اظهار جميع التنبيهات",
- "Appear offline" : "الحالة غير متصل",
- "What's your status?" : "ماهي حالتك؟"
+ "Busy" : "مشغول",
+ "Mute all notifications" : "عدم إظهار جميع التنبيهات",
+ "Appear offline" : "الحالة غير متصل"
},"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/user_status/l10n/ast.js b/apps/user_status/l10n/ast.js
new file mode 100644
index 00000000000..ac09b5ac733
--- /dev/null
+++ b/apps/user_status/l10n/ast.js
@@ -0,0 +1,48 @@
+OC.L10N.register(
+ "user_status",
+ {
+ "Recent statuses" : "Estaos de recién",
+ "No recent status changes" : "Nun hai nengún cambéu d'estáu recién",
+ "In a meeting" : "Nuna reunión",
+ "Commuting" : "En desplazamientu",
+ "Out sick" : "Non disponible por enfermedá",
+ "Vacationing" : "De vacaciones",
+ "Out of office" : "Fuera de la oficina",
+ "Working remotely" : "Trabayando en remoto",
+ "In a call" : "Nuna llamada",
+ "User status" : "Estáu del usuariu",
+ "Clear status after" : "Borrar l'estúa dempués de",
+ "Emoji for your status message" : "Fustaxes pa los mensaxes d'estáu",
+ "What is your status?" : "¿Cuál ye'l to estáu?",
+ "Predefined statuses" : "Estaos predefiníos",
+ "Previously set" : "Afitóse con anterioridá",
+ "Reset status" : "Reafitar l'estáu",
+ "Reset status to \"{icon} {message}\"" : "Reafitar l'estáu a «{icon} {message}»",
+ "Reset status to \"{message}\"" : "Reafitar l'estáu a «{message}»",
+ "Reset status to \"{icon}\"" : "Reafitar l'estáu a «{icon}»",
+ "There was an error saving the status" : "Hebo un error al guardar l'estáu",
+ "There was an error clearing the status" : "Hebo un error al borrar l'estáu",
+ "There was an error reverting the status" : "Hebo un error al recuperar l'estáu anterior",
+ "Online status" : "Estáu en llinia",
+ "Status message" : "Mensaxe del estáu",
+ "Your status was set automatically" : "L'estáu afitóse automáticamente",
+ "Clear status message" : "Borrar el mensaxe del estáu",
+ "Set status message" : "Afitar el mensaxe del estáu",
+ "Don't clear" : "Nun borrar",
+ "Today" : "Güei",
+ "This week" : "Esta selmana",
+ "Online" : "En llinia",
+ "Away" : "Ausente",
+ "Do not disturb" : "Nun molestar",
+ "Invisible" : "Invisible",
+ "Offline" : "Desconectáu",
+ "Set status" : "Afitar l'estáu",
+ "There was an error saving the new status" : "Hebo un error al guardar l'estáu nuevu",
+ "30 minutes" : "30 minutos",
+ "1 hour" : "1 hora",
+ "4 hours" : "4 hores",
+ "Busy" : "Ocupáu",
+ "Mute all notifications" : "Desactivar tolos avisos",
+ "Appear offline" : "Apaecer desconectáu"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/user_status/l10n/ast.json b/apps/user_status/l10n/ast.json
new file mode 100644
index 00000000000..0a6e2ee9681
--- /dev/null
+++ b/apps/user_status/l10n/ast.json
@@ -0,0 +1,46 @@
+{ "translations": {
+ "Recent statuses" : "Estaos de recién",
+ "No recent status changes" : "Nun hai nengún cambéu d'estáu recién",
+ "In a meeting" : "Nuna reunión",
+ "Commuting" : "En desplazamientu",
+ "Out sick" : "Non disponible por enfermedá",
+ "Vacationing" : "De vacaciones",
+ "Out of office" : "Fuera de la oficina",
+ "Working remotely" : "Trabayando en remoto",
+ "In a call" : "Nuna llamada",
+ "User status" : "Estáu del usuariu",
+ "Clear status after" : "Borrar l'estúa dempués de",
+ "Emoji for your status message" : "Fustaxes pa los mensaxes d'estáu",
+ "What is your status?" : "¿Cuál ye'l to estáu?",
+ "Predefined statuses" : "Estaos predefiníos",
+ "Previously set" : "Afitóse con anterioridá",
+ "Reset status" : "Reafitar l'estáu",
+ "Reset status to \"{icon} {message}\"" : "Reafitar l'estáu a «{icon} {message}»",
+ "Reset status to \"{message}\"" : "Reafitar l'estáu a «{message}»",
+ "Reset status to \"{icon}\"" : "Reafitar l'estáu a «{icon}»",
+ "There was an error saving the status" : "Hebo un error al guardar l'estáu",
+ "There was an error clearing the status" : "Hebo un error al borrar l'estáu",
+ "There was an error reverting the status" : "Hebo un error al recuperar l'estáu anterior",
+ "Online status" : "Estáu en llinia",
+ "Status message" : "Mensaxe del estáu",
+ "Your status was set automatically" : "L'estáu afitóse automáticamente",
+ "Clear status message" : "Borrar el mensaxe del estáu",
+ "Set status message" : "Afitar el mensaxe del estáu",
+ "Don't clear" : "Nun borrar",
+ "Today" : "Güei",
+ "This week" : "Esta selmana",
+ "Online" : "En llinia",
+ "Away" : "Ausente",
+ "Do not disturb" : "Nun molestar",
+ "Invisible" : "Invisible",
+ "Offline" : "Desconectáu",
+ "Set status" : "Afitar l'estáu",
+ "There was an error saving the new status" : "Hebo un error al guardar l'estáu nuevu",
+ "30 minutes" : "30 minutos",
+ "1 hour" : "1 hora",
+ "4 hours" : "4 hores",
+ "Busy" : "Ocupáu",
+ "Mute all notifications" : "Desactivar tolos avisos",
+ "Appear offline" : "Apaecer desconectáu"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/user_status/l10n/bg.js b/apps/user_status/l10n/bg.js
index 6f0ea7d1c58..e799fa1f212 100644
--- a/apps/user_status/l10n/bg.js
+++ b/apps/user_status/l10n/bg.js
@@ -2,39 +2,47 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Последни състояния",
+ "No recent status changes" : "Няма скорошни промени в състоянието",
"In a meeting" : "В среща",
- "Commuting" : "Работно пътуване",
+ "Commuting" : "Пътувам до работа",
"Out sick" : "Болничен",
"Vacationing" : "Отпуск",
+ "Out of office" : "Извън офиса",
"Working remotely" : "Работа от разстояние",
"In a call" : "В обаждане",
"User status" : "Потребителско състояние",
- "View profile" : "Преглед на профил",
- "Clear status message after" : "Изчистване на съобщение за състоянието след",
- "What is your status?" : "Какъв е вашият статус?",
- "Set status" : "Задаване на състояние",
- "Online status" : "Състояние на линия",
- "Status message" : "Съобщение за състояние",
- "Clear status message" : "Изчистване на съобщението за състояние",
- "Set status message" : "Задаване на съобщение за състояние",
+ "Clear status after" : "Изчистване на състоянието след",
+ "What is your status?" : "Какво е вашето състояние?",
+ "Previously set" : "Предишно зададени",
+ "Reset status" : "Възстановяване на състоянието",
+ "Reset status to \"{icon} {message}\"" : "Възстановяване на състоянието на „{icon} {message}“",
+ "Reset status to \"{message}\"" : "Възстановяване на състоянието на „{message}“",
+ "Reset status to \"{icon}\"" : "Възстановяване на състоянието на „{icon}“",
"There was an error saving the status" : "Възникна грешка при запазване на състоянието",
"There was an error clearing the status" : "Възникна грешка при изчистване на състоянието",
- "No recent status changes" : "Няма скорошни промени в състоянието",
- "Away" : "Отсъстващ",
- "Do not disturb" : "Не безпокойте",
- "{status}, {timestamp}" : "{status}, {timestamp}",
+ "There was an error reverting the status" : "Имаше грешка при връщане на състоянието",
+ "Online status" : "Състояние",
+ "Status message" : "Съобщение за състояние",
+ "Set absence period" : "Задай период на отсъствие",
+ "Set absence period and replacement" : "Задай период на отсъствие и заместник.",
+ "Your status was set automatically" : "Състоянието ви беше зададено автоматично",
+ "Clear status message" : "Изчисти състоянието",
+ "Set status message" : "Задай състояние",
"Don't clear" : "Да не се изчиства",
"Today" : "Днес",
"This week" : "Тази седмица",
"Online" : "На линия",
+ "Away" : "Отсъстващ",
+ "Do not disturb" : "Не безпокойте",
"Invisible" : "Невидим",
"Offline" : "Офлайн",
+ "Set status" : "Задаване на състояние",
"There was an error saving the new status" : "Възникна грешка при запазване на новото състояние",
"30 minutes" : "30 минути",
"1 hour" : "1 час",
- "4 hours" : "4 часа",
+ "4 hours" : "4 чàса",
+ "Busy" : "Зает",
"Mute all notifications" : "Заглушаване на всички известия",
- "Appear offline" : "Показване като офлайн",
- "What's your status?" : "Какъв е вашият статус?"
+ "Appear offline" : "Показване като офлайн"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/user_status/l10n/bg.json b/apps/user_status/l10n/bg.json
index f2eb04be680..639aab4a411 100644
--- a/apps/user_status/l10n/bg.json
+++ b/apps/user_status/l10n/bg.json
@@ -1,38 +1,46 @@
{ "translations": {
"Recent statuses" : "Последни състояния",
+ "No recent status changes" : "Няма скорошни промени в състоянието",
"In a meeting" : "В среща",
- "Commuting" : "Работно пътуване",
+ "Commuting" : "Пътувам до работа",
"Out sick" : "Болничен",
"Vacationing" : "Отпуск",
+ "Out of office" : "Извън офиса",
"Working remotely" : "Работа от разстояние",
"In a call" : "В обаждане",
"User status" : "Потребителско състояние",
- "View profile" : "Преглед на профил",
- "Clear status message after" : "Изчистване на съобщение за състоянието след",
- "What is your status?" : "Какъв е вашият статус?",
- "Set status" : "Задаване на състояние",
- "Online status" : "Състояние на линия",
- "Status message" : "Съобщение за състояние",
- "Clear status message" : "Изчистване на съобщението за състояние",
- "Set status message" : "Задаване на съобщение за състояние",
+ "Clear status after" : "Изчистване на състоянието след",
+ "What is your status?" : "Какво е вашето състояние?",
+ "Previously set" : "Предишно зададени",
+ "Reset status" : "Възстановяване на състоянието",
+ "Reset status to \"{icon} {message}\"" : "Възстановяване на състоянието на „{icon} {message}“",
+ "Reset status to \"{message}\"" : "Възстановяване на състоянието на „{message}“",
+ "Reset status to \"{icon}\"" : "Възстановяване на състоянието на „{icon}“",
"There was an error saving the status" : "Възникна грешка при запазване на състоянието",
"There was an error clearing the status" : "Възникна грешка при изчистване на състоянието",
- "No recent status changes" : "Няма скорошни промени в състоянието",
- "Away" : "Отсъстващ",
- "Do not disturb" : "Не безпокойте",
- "{status}, {timestamp}" : "{status}, {timestamp}",
+ "There was an error reverting the status" : "Имаше грешка при връщане на състоянието",
+ "Online status" : "Състояние",
+ "Status message" : "Съобщение за състояние",
+ "Set absence period" : "Задай период на отсъствие",
+ "Set absence period and replacement" : "Задай период на отсъствие и заместник.",
+ "Your status was set automatically" : "Състоянието ви беше зададено автоматично",
+ "Clear status message" : "Изчисти състоянието",
+ "Set status message" : "Задай състояние",
"Don't clear" : "Да не се изчиства",
"Today" : "Днес",
"This week" : "Тази седмица",
"Online" : "На линия",
+ "Away" : "Отсъстващ",
+ "Do not disturb" : "Не безпокойте",
"Invisible" : "Невидим",
"Offline" : "Офлайн",
+ "Set status" : "Задаване на състояние",
"There was an error saving the new status" : "Възникна грешка при запазване на новото състояние",
"30 minutes" : "30 минути",
"1 hour" : "1 час",
- "4 hours" : "4 часа",
+ "4 hours" : "4 чàса",
+ "Busy" : "Зает",
"Mute all notifications" : "Заглушаване на всички известия",
- "Appear offline" : "Показване като офлайн",
- "What's your status?" : "Какъв е вашият статус?"
+ "Appear offline" : "Показване като офлайн"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/ca.js b/apps/user_status/l10n/ca.js
index d40a3b143a4..8fa53f7f41b 100644
--- a/apps/user_status/l10n/ca.js
+++ b/apps/user_status/l10n/ca.js
@@ -2,37 +2,49 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Estats recents",
+ "No recent status changes" : "No hi ha cap canvi d'estat recent",
"In a meeting" : "En una reunió",
- "Commuting" : "Trajecte",
- "Out sick" : "Fora malalt",
- "Vacationing" : "Vacances",
- "Working remotely" : "Treballant a distància",
+ "Commuting" : "En desplaçament",
+ "Out sick" : "No disponible per malaltia",
+ "Vacationing" : "De vacances",
+ "Out of office" : "Fora de l'oficina",
+ "Working remotely" : "Treballant en remot",
+ "In a call" : "En una trucada",
"User status" : "Estat de l'usuari",
- "Clear status message after" : "Esborra el missatge d'estat després",
+ "Clear status after" : "Esborra l'estat després de",
+ "Emoji for your status message" : "Emoji per al missatge d'estat",
"What is your status?" : "Quin és el vostre estat?",
- "Set status" : "Estableix l'estat",
- "Online status" : "Estat en línia",
- "Status message" : "Missatge d'estat",
- "Clear status message" : "Esborrar el missatge d'estat",
- "Set status message" : "Estableix un missatge d'estat",
+ "Predefined statuses" : "Estats predefinits",
+ "Previously set" : "Definits anteriorment",
+ "Reset status" : "Reinicialitza l'estat",
+ "Reset status to \"{icon} {message}\"" : "Reinicialitza l'estat a «{icon} {message}»",
+ "Reset status to \"{message}\"" : "Reinicialitza l'estat a «{message}»",
+ "Reset status to \"{icon}\"" : "Reinicialitza l'estat a «{icon}»",
"There was an error saving the status" : "S'ha produït un error en desar l'estat",
"There was an error clearing the status" : "S'ha produït un error en esborrar l'estat",
- "No recent status changes" : "No hi ha canvis d'estat recents",
- "Away" : "Absent",
- "Do not disturb" : "No molesteu",
- "{status}, {timestamp}" : "{status}, {timestamp}",
- "Don't clear" : "No esborrar",
+ "There was an error reverting the status" : "S'ha produït un error en recuperar l'estat anterior",
+ "Online status" : "Estat en línia",
+ "Status message" : "Missatge d'estat",
+ "Set absence period" : "Establir període d'absència",
+ "Set absence period and replacement" : "Establir període d'absència i substitució",
+ "Your status was set automatically" : "S'ha indicat l'estat automàticament",
+ "Clear status message" : "Esborra el missatge d'estat",
+ "Set status message" : "Indica el missatge d'estat",
+ "Don't clear" : "No l'esborris",
"Today" : "Avui",
"This week" : "Aquesta setmana",
"Online" : "En línia",
+ "Away" : "Absent",
+ "Do not disturb" : "No molesteu",
"Invisible" : "Invisible",
"Offline" : "Fora de línia",
+ "Set status" : "Indica l'estat",
"There was an error saving the new status" : "S'ha produït un error en desar l'estat nou",
"30 minutes" : "30 minuts",
"1 hour" : "1 hora",
"4 hours" : "4 hores",
- "Mute all notifications" : "Silenciar totes les notificacions",
- "Appear offline" : "Apareix com \"desconnectat\"",
- "What's your status?" : "Quin és el teu estat?"
+ "Busy" : "Ocupat",
+ "Mute all notifications" : "Silencieu totes les notificacions",
+ "Appear offline" : "Apareixeu fora de línia"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/user_status/l10n/ca.json b/apps/user_status/l10n/ca.json
index c88c2284aee..c40c658b992 100644
--- a/apps/user_status/l10n/ca.json
+++ b/apps/user_status/l10n/ca.json
@@ -1,36 +1,48 @@
{ "translations": {
"Recent statuses" : "Estats recents",
+ "No recent status changes" : "No hi ha cap canvi d'estat recent",
"In a meeting" : "En una reunió",
- "Commuting" : "Trajecte",
- "Out sick" : "Fora malalt",
- "Vacationing" : "Vacances",
- "Working remotely" : "Treballant a distància",
+ "Commuting" : "En desplaçament",
+ "Out sick" : "No disponible per malaltia",
+ "Vacationing" : "De vacances",
+ "Out of office" : "Fora de l'oficina",
+ "Working remotely" : "Treballant en remot",
+ "In a call" : "En una trucada",
"User status" : "Estat de l'usuari",
- "Clear status message after" : "Esborra el missatge d'estat després",
+ "Clear status after" : "Esborra l'estat després de",
+ "Emoji for your status message" : "Emoji per al missatge d'estat",
"What is your status?" : "Quin és el vostre estat?",
- "Set status" : "Estableix l'estat",
- "Online status" : "Estat en línia",
- "Status message" : "Missatge d'estat",
- "Clear status message" : "Esborrar el missatge d'estat",
- "Set status message" : "Estableix un missatge d'estat",
+ "Predefined statuses" : "Estats predefinits",
+ "Previously set" : "Definits anteriorment",
+ "Reset status" : "Reinicialitza l'estat",
+ "Reset status to \"{icon} {message}\"" : "Reinicialitza l'estat a «{icon} {message}»",
+ "Reset status to \"{message}\"" : "Reinicialitza l'estat a «{message}»",
+ "Reset status to \"{icon}\"" : "Reinicialitza l'estat a «{icon}»",
"There was an error saving the status" : "S'ha produït un error en desar l'estat",
"There was an error clearing the status" : "S'ha produït un error en esborrar l'estat",
- "No recent status changes" : "No hi ha canvis d'estat recents",
- "Away" : "Absent",
- "Do not disturb" : "No molesteu",
- "{status}, {timestamp}" : "{status}, {timestamp}",
- "Don't clear" : "No esborrar",
+ "There was an error reverting the status" : "S'ha produït un error en recuperar l'estat anterior",
+ "Online status" : "Estat en línia",
+ "Status message" : "Missatge d'estat",
+ "Set absence period" : "Establir període d'absència",
+ "Set absence period and replacement" : "Establir període d'absència i substitució",
+ "Your status was set automatically" : "S'ha indicat l'estat automàticament",
+ "Clear status message" : "Esborra el missatge d'estat",
+ "Set status message" : "Indica el missatge d'estat",
+ "Don't clear" : "No l'esborris",
"Today" : "Avui",
"This week" : "Aquesta setmana",
"Online" : "En línia",
+ "Away" : "Absent",
+ "Do not disturb" : "No molesteu",
"Invisible" : "Invisible",
"Offline" : "Fora de línia",
+ "Set status" : "Indica l'estat",
"There was an error saving the new status" : "S'ha produït un error en desar l'estat nou",
"30 minutes" : "30 minuts",
"1 hour" : "1 hora",
"4 hours" : "4 hores",
- "Mute all notifications" : "Silenciar totes les notificacions",
- "Appear offline" : "Apareix com \"desconnectat\"",
- "What's your status?" : "Quin és el teu estat?"
+ "Busy" : "Ocupat",
+ "Mute all notifications" : "Silencieu totes les notificacions",
+ "Appear offline" : "Apareixeu fora de línia"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/cs.js b/apps/user_status/l10n/cs.js
index 6a4997b6fd7..9d21e89f539 100644
--- a/apps/user_status/l10n/cs.js
+++ b/apps/user_status/l10n/cs.js
@@ -2,39 +2,49 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Nedávné stavy",
+ "No recent status changes" : "Žádné nedávné změny stavu",
"In a meeting" : "Na poradě",
"Commuting" : "Dojíždění",
"Out sick" : "Nemoc",
"Vacationing" : "Dovolená",
+ "Out of office" : "Mimo kancelář",
"Working remotely" : "Pracuje na dálku",
"In a call" : "Má hovor",
"User status" : "Stav uživatele",
- "View profile" : "Zobrazit profil ",
- "Clear status message after" : "Vyčistit stavovou zprávu po uplynutí",
+ "Clear status after" : "Vyčistit stav po uplynutí",
+ "Emoji for your status message" : "Emotikona pro vaší stavovou zprávu",
"What is your status?" : "Jaký je váš stav?",
- "Set status" : "Nastavit stav",
+ "Predefined statuses" : "Předdefinované stavy",
+ "Previously set" : "Dříve nastavené",
+ "Reset status" : "Resetovat stav",
+ "Reset status to \"{icon} {message}\"" : "Resetovat stav na „{icon} {message}“",
+ "Reset status to \"{message}\"" : "Resetovat stav na „{message}“",
+ "Reset status to \"{icon}\"" : "Resetovat stav na „{icon}“",
+ "There was an error saving the status" : "Došlo k chybě při ukládání stavu",
+ "There was an error clearing the status" : "Při čištění stavu došlo k chybě",
+ "There was an error reverting the status" : "Při vracení stavu nazpět došlo k chybě",
"Online status" : "Stav online",
"Status message" : "Stavová zpráva",
+ "Set absence period" : "Nastavit období nepřítomnosti",
+ "Set absence period and replacement" : "Nastavit období nepřítomnosti a zástup",
+ "Your status was set automatically" : "Váš stav byl nastaven automaticky",
"Clear status message" : "Vyčistit stavovou zprávu",
"Set status message" : "Nastavit stavovou zprávu",
- "There was an error saving the status" : "Došlo k chybě při ukládání stavu",
- "There was an error clearing the status" : "Při čištění stavu došlo k chybě",
- "No recent status changes" : "Žádné nedávné změny stavu",
- "Away" : "Pryč",
- "Do not disturb" : "Nerušit",
- "{status}, {timestamp}" : "{status}, {timestamp}",
- "Don't clear" : "Nikdy",
+ "Don't clear" : "Do odvolání",
"Today" : "Dnes",
"This week" : "Tento týden",
"Online" : "Online",
- "Invisible" : "Neviditelný",
+ "Away" : "Pryč",
+ "Do not disturb" : "Nerušit",
+ "Invisible" : "Není vidět",
"Offline" : "Offline",
+ "Set status" : "Nastavit stav",
"There was an error saving the new status" : "Při ukládání nového stavu došlo k chybě",
"30 minutes" : "30 minut",
"1 hour" : "1 hodina",
"4 hours" : "4 hodiny",
+ "Busy" : "Zaneprázdněn(a)",
"Mute all notifications" : "Ztlumit veškerá upozornění",
- "Appear offline" : "Jevit se offline",
- "What's your status?" : "Jaký je váš stav?"
+ "Appear offline" : "Jevit se offline"
},
"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/user_status/l10n/cs.json b/apps/user_status/l10n/cs.json
index 7febf6f0aa5..c6c875d3454 100644
--- a/apps/user_status/l10n/cs.json
+++ b/apps/user_status/l10n/cs.json
@@ -1,38 +1,48 @@
{ "translations": {
"Recent statuses" : "Nedávné stavy",
+ "No recent status changes" : "Žádné nedávné změny stavu",
"In a meeting" : "Na poradě",
"Commuting" : "Dojíždění",
"Out sick" : "Nemoc",
"Vacationing" : "Dovolená",
+ "Out of office" : "Mimo kancelář",
"Working remotely" : "Pracuje na dálku",
"In a call" : "Má hovor",
"User status" : "Stav uživatele",
- "View profile" : "Zobrazit profil ",
- "Clear status message after" : "Vyčistit stavovou zprávu po uplynutí",
+ "Clear status after" : "Vyčistit stav po uplynutí",
+ "Emoji for your status message" : "Emotikona pro vaší stavovou zprávu",
"What is your status?" : "Jaký je váš stav?",
- "Set status" : "Nastavit stav",
+ "Predefined statuses" : "Předdefinované stavy",
+ "Previously set" : "Dříve nastavené",
+ "Reset status" : "Resetovat stav",
+ "Reset status to \"{icon} {message}\"" : "Resetovat stav na „{icon} {message}“",
+ "Reset status to \"{message}\"" : "Resetovat stav na „{message}“",
+ "Reset status to \"{icon}\"" : "Resetovat stav na „{icon}“",
+ "There was an error saving the status" : "Došlo k chybě při ukládání stavu",
+ "There was an error clearing the status" : "Při čištění stavu došlo k chybě",
+ "There was an error reverting the status" : "Při vracení stavu nazpět došlo k chybě",
"Online status" : "Stav online",
"Status message" : "Stavová zpráva",
+ "Set absence period" : "Nastavit období nepřítomnosti",
+ "Set absence period and replacement" : "Nastavit období nepřítomnosti a zástup",
+ "Your status was set automatically" : "Váš stav byl nastaven automaticky",
"Clear status message" : "Vyčistit stavovou zprávu",
"Set status message" : "Nastavit stavovou zprávu",
- "There was an error saving the status" : "Došlo k chybě při ukládání stavu",
- "There was an error clearing the status" : "Při čištění stavu došlo k chybě",
- "No recent status changes" : "Žádné nedávné změny stavu",
- "Away" : "Pryč",
- "Do not disturb" : "Nerušit",
- "{status}, {timestamp}" : "{status}, {timestamp}",
- "Don't clear" : "Nikdy",
+ "Don't clear" : "Do odvolání",
"Today" : "Dnes",
"This week" : "Tento týden",
"Online" : "Online",
- "Invisible" : "Neviditelný",
+ "Away" : "Pryč",
+ "Do not disturb" : "Nerušit",
+ "Invisible" : "Není vidět",
"Offline" : "Offline",
+ "Set status" : "Nastavit stav",
"There was an error saving the new status" : "Při ukládání nového stavu došlo k chybě",
"30 minutes" : "30 minut",
"1 hour" : "1 hodina",
"4 hours" : "4 hodiny",
+ "Busy" : "Zaneprázdněn(a)",
"Mute all notifications" : "Ztlumit veškerá upozornění",
- "Appear offline" : "Jevit se offline",
- "What's your status?" : "Jaký je váš stav?"
+ "Appear offline" : "Jevit se offline"
},"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/user_status/l10n/da.js b/apps/user_status/l10n/da.js
index 786c91b3992..43b4560d086 100644
--- a/apps/user_status/l10n/da.js
+++ b/apps/user_status/l10n/da.js
@@ -1,24 +1,50 @@
OC.L10N.register(
"user_status",
{
- "Clear status message after" : "Ryd status notifikationer efter",
+ "Recent statuses" : "Senestestatus",
+ "No recent status changes" : "Ingen ændringer i status",
+ "In a meeting" : "I et møde",
+ "Commuting" : "Undervejs",
+ "Out sick" : "Sygemeldt",
+ "Vacationing" : "Holder ferie",
+ "Out of office" : "Ikke på kontoret",
+ "Working remotely" : "Arbejder hjemmefra",
+ "In a call" : "Taler i telefon",
+ "User status" : "Brugerstatus",
+ "Clear status after" : "Ryd status efter",
+ "Emoji for your status message" : "Emoji til din statusbesked",
"What is your status?" : "Hvad er din status",
- "Set status" : "Sæt status",
+ "Predefined statuses" : "Foruddefinerede status",
+ "Previously set" : "Tidligere sat",
+ "Reset status" : "Nulstil status",
+ "Reset status to \"{icon} {message}\"" : "Nulstil status til \"{icon}{message}\"",
+ "Reset status to \"{message}\"" : "Nulstil status til \"{message}\"",
+ "Reset status to \"{icon}\"" : "Nulstil status til \"{icon}\"",
+ "There was an error saving the status" : "Der opstod en fejl ved lagring af status",
+ "There was an error clearing the status" : "Der opstod en fejl ved rydning af status",
+ "There was an error reverting the status" : "Der opstod en fejl ved indstillingen af status",
"Online status" : "Online status",
"Status message" : "Statusbesked",
- "Clear status message" : "Ryd status notifikation",
+ "Set absence period" : "Indstil fraværs periode",
+ "Set absence period and replacement" : "Indstil fraværs periode og angiv afløser",
+ "Your status was set automatically" : "Status sat automatisk",
+ "Clear status message" : "Ryd statusnotifikation",
"Set status message" : "Sæt statusbesked",
- "Away" : "Ikke tilstede",
- "Do not disturb" : "Forstyr ikke",
"Don't clear" : "Ryd ikke",
"Today" : "I dag",
"This week" : "Denne uge",
"Online" : "Online",
+ "Away" : "Ikke tilstede",
+ "Do not disturb" : "Forstyr ikke",
"Invisible" : "Usynlig",
"Offline" : "Offline",
+ "Set status" : "Sæt status",
+ "There was an error saving the new status" : "Der opstod en fejl ved lagring af den nye status",
"30 minutes" : "30 minutter",
"1 hour" : "1 time",
"4 hours" : "4 timer",
- "What's your status?" : "Hvad er din status"
+ "Busy" : "Optaget",
+ "Mute all notifications" : "Vis ikke notifikationer",
+ "Appear offline" : "Er offline"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/user_status/l10n/da.json b/apps/user_status/l10n/da.json
index a3bdd3c01a7..67708311d7b 100644
--- a/apps/user_status/l10n/da.json
+++ b/apps/user_status/l10n/da.json
@@ -1,22 +1,48 @@
{ "translations": {
- "Clear status message after" : "Ryd status notifikationer efter",
+ "Recent statuses" : "Senestestatus",
+ "No recent status changes" : "Ingen ændringer i status",
+ "In a meeting" : "I et møde",
+ "Commuting" : "Undervejs",
+ "Out sick" : "Sygemeldt",
+ "Vacationing" : "Holder ferie",
+ "Out of office" : "Ikke på kontoret",
+ "Working remotely" : "Arbejder hjemmefra",
+ "In a call" : "Taler i telefon",
+ "User status" : "Brugerstatus",
+ "Clear status after" : "Ryd status efter",
+ "Emoji for your status message" : "Emoji til din statusbesked",
"What is your status?" : "Hvad er din status",
- "Set status" : "Sæt status",
+ "Predefined statuses" : "Foruddefinerede status",
+ "Previously set" : "Tidligere sat",
+ "Reset status" : "Nulstil status",
+ "Reset status to \"{icon} {message}\"" : "Nulstil status til \"{icon}{message}\"",
+ "Reset status to \"{message}\"" : "Nulstil status til \"{message}\"",
+ "Reset status to \"{icon}\"" : "Nulstil status til \"{icon}\"",
+ "There was an error saving the status" : "Der opstod en fejl ved lagring af status",
+ "There was an error clearing the status" : "Der opstod en fejl ved rydning af status",
+ "There was an error reverting the status" : "Der opstod en fejl ved indstillingen af status",
"Online status" : "Online status",
"Status message" : "Statusbesked",
- "Clear status message" : "Ryd status notifikation",
+ "Set absence period" : "Indstil fraværs periode",
+ "Set absence period and replacement" : "Indstil fraværs periode og angiv afløser",
+ "Your status was set automatically" : "Status sat automatisk",
+ "Clear status message" : "Ryd statusnotifikation",
"Set status message" : "Sæt statusbesked",
- "Away" : "Ikke tilstede",
- "Do not disturb" : "Forstyr ikke",
"Don't clear" : "Ryd ikke",
"Today" : "I dag",
"This week" : "Denne uge",
"Online" : "Online",
+ "Away" : "Ikke tilstede",
+ "Do not disturb" : "Forstyr ikke",
"Invisible" : "Usynlig",
"Offline" : "Offline",
+ "Set status" : "Sæt status",
+ "There was an error saving the new status" : "Der opstod en fejl ved lagring af den nye status",
"30 minutes" : "30 minutter",
"1 hour" : "1 time",
"4 hours" : "4 timer",
- "What's your status?" : "Hvad er din status"
+ "Busy" : "Optaget",
+ "Mute all notifications" : "Vis ikke notifikationer",
+ "Appear offline" : "Er offline"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/de.js b/apps/user_status/l10n/de.js
index 791da791c28..b59906d6135 100644
--- a/apps/user_status/l10n/de.js
+++ b/apps/user_status/l10n/de.js
@@ -2,39 +2,50 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Letzter Status",
+ "No recent status changes" : "Keine kürzlichen Statusänderungen",
"In a meeting" : "In einer Besprechung",
"Commuting" : "Pendelt",
"Out sick" : "Krankgeschrieben",
"Vacationing" : "Im Urlaub",
+ "Out of office" : "Nicht im Büro",
"Working remotely" : "Arbeitet aus der Ferne",
"In a call" : "In einem Anruf",
+ "Be right back" : "Bin gleich zurück",
"User status" : "Benutzerstatus",
- "View profile" : "Profil ansehen",
- "Clear status message after" : "Statusnachricht löschen nach",
- "What is your status?" : "Wie ist Dein Status?",
- "Set status" : "Status setzen",
+ "Clear status after" : "Status löschen nach",
+ "Emoji for your status message" : "Emoji für deine Statusnachricht",
+ "What is your status?" : "Wie ist dein Status?",
+ "Predefined statuses" : "Vordefinierte Status",
+ "Previously set" : "Zuvor eingestellt",
+ "Reset status" : "Status zurücksetzen",
+ "Reset status to \"{icon} {message}\"" : "Status auf \"{icon} {message}\" zurücksetzen",
+ "Reset status to \"{message}\"" : "Status auf \"{message}\" zurücksetzen",
+ "Reset status to \"{icon}\"" : "Status auf \"{icon}\" zurücksetzen",
+ "There was an error saving the status" : "Es gab einen Fehler beim Speichern des Status",
+ "There was an error clearing the status" : "Es gab einen Fehler beim Löschen des Status",
+ "There was an error reverting the status" : "Es ist ein Fehler beim Zurücksetzen des Status aufgetreten",
"Online status" : "Online-Status",
"Status message" : "Statusnachricht",
+ "Set absence period" : "Abwesenheitszeitraum festlegen",
+ "Set absence period and replacement" : "Abwesenheitszeitraum und Vertretung festlegen",
+ "Your status was set automatically" : "Dein Status wurde automatisch gesetzt",
"Clear status message" : "Statusnachricht löschen",
"Set status message" : "Statusnachricht setzen",
- "There was an error saving the status" : "Es gab einen Fehler beim Speichern des Status",
- "There was an error clearing the status" : "Es gab einen Fehler beim Löschen des Status",
- "No recent status changes" : "Keine kürzlichen Statusänderungen",
- "Away" : "Abwesend",
- "Do not disturb" : "Bitte nicht stören",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Nicht löschen",
"Today" : "Heute",
"This week" : "Diese Woche",
"Online" : "Online",
+ "Away" : "Abwesend",
+ "Do not disturb" : "Bitte nicht stören",
"Invisible" : "Unsichtbar",
"Offline" : "Offline",
+ "Set status" : "Status setzen",
"There was an error saving the new status" : "Es gab einen Fehler beim Speichern des neuen Status",
"30 minutes" : "30 Minuten",
"1 hour" : "1 Stunde",
"4 hours" : "4 Stunden",
+ "Busy" : "Beschäftigt",
"Mute all notifications" : "Alle Benachrichtigungen stummschalten",
- "Appear offline" : "Offline erscheinen",
- "What's your status?" : "Wie ist Dein Status?"
+ "Appear offline" : "Offline erscheinen"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/user_status/l10n/de.json b/apps/user_status/l10n/de.json
index 7cf652ab8f0..2badd82476c 100644
--- a/apps/user_status/l10n/de.json
+++ b/apps/user_status/l10n/de.json
@@ -1,38 +1,49 @@
{ "translations": {
"Recent statuses" : "Letzter Status",
+ "No recent status changes" : "Keine kürzlichen Statusänderungen",
"In a meeting" : "In einer Besprechung",
"Commuting" : "Pendelt",
"Out sick" : "Krankgeschrieben",
"Vacationing" : "Im Urlaub",
+ "Out of office" : "Nicht im Büro",
"Working remotely" : "Arbeitet aus der Ferne",
"In a call" : "In einem Anruf",
+ "Be right back" : "Bin gleich zurück",
"User status" : "Benutzerstatus",
- "View profile" : "Profil ansehen",
- "Clear status message after" : "Statusnachricht löschen nach",
- "What is your status?" : "Wie ist Dein Status?",
- "Set status" : "Status setzen",
+ "Clear status after" : "Status löschen nach",
+ "Emoji for your status message" : "Emoji für deine Statusnachricht",
+ "What is your status?" : "Wie ist dein Status?",
+ "Predefined statuses" : "Vordefinierte Status",
+ "Previously set" : "Zuvor eingestellt",
+ "Reset status" : "Status zurücksetzen",
+ "Reset status to \"{icon} {message}\"" : "Status auf \"{icon} {message}\" zurücksetzen",
+ "Reset status to \"{message}\"" : "Status auf \"{message}\" zurücksetzen",
+ "Reset status to \"{icon}\"" : "Status auf \"{icon}\" zurücksetzen",
+ "There was an error saving the status" : "Es gab einen Fehler beim Speichern des Status",
+ "There was an error clearing the status" : "Es gab einen Fehler beim Löschen des Status",
+ "There was an error reverting the status" : "Es ist ein Fehler beim Zurücksetzen des Status aufgetreten",
"Online status" : "Online-Status",
"Status message" : "Statusnachricht",
+ "Set absence period" : "Abwesenheitszeitraum festlegen",
+ "Set absence period and replacement" : "Abwesenheitszeitraum und Vertretung festlegen",
+ "Your status was set automatically" : "Dein Status wurde automatisch gesetzt",
"Clear status message" : "Statusnachricht löschen",
"Set status message" : "Statusnachricht setzen",
- "There was an error saving the status" : "Es gab einen Fehler beim Speichern des Status",
- "There was an error clearing the status" : "Es gab einen Fehler beim Löschen des Status",
- "No recent status changes" : "Keine kürzlichen Statusänderungen",
- "Away" : "Abwesend",
- "Do not disturb" : "Bitte nicht stören",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Nicht löschen",
"Today" : "Heute",
"This week" : "Diese Woche",
"Online" : "Online",
+ "Away" : "Abwesend",
+ "Do not disturb" : "Bitte nicht stören",
"Invisible" : "Unsichtbar",
"Offline" : "Offline",
+ "Set status" : "Status setzen",
"There was an error saving the new status" : "Es gab einen Fehler beim Speichern des neuen Status",
"30 minutes" : "30 Minuten",
"1 hour" : "1 Stunde",
"4 hours" : "4 Stunden",
+ "Busy" : "Beschäftigt",
"Mute all notifications" : "Alle Benachrichtigungen stummschalten",
- "Appear offline" : "Offline erscheinen",
- "What's your status?" : "Wie ist Dein Status?"
+ "Appear offline" : "Offline erscheinen"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/de_DE.js b/apps/user_status/l10n/de_DE.js
index a2226851f9e..23d86b06643 100644
--- a/apps/user_status/l10n/de_DE.js
+++ b/apps/user_status/l10n/de_DE.js
@@ -2,39 +2,50 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Letzter Status",
+ "No recent status changes" : "Keine kürzlichen Statusänderungen",
"In a meeting" : "In einer Besprechung",
"Commuting" : "Pendelt",
"Out sick" : "Krank geschrieben",
"Vacationing" : "Im Urlaub",
+ "Out of office" : "Nicht im Büro",
"Working remotely" : "Arbeitet aus der Ferne",
"In a call" : "In einem Anruf",
+ "Be right back" : "Bin gleich zurück",
"User status" : "Benutzerstatus",
- "View profile" : "Profil ansehen",
- "Clear status message after" : "Statusnachricht löschen nach",
+ "Clear status after" : "Status löschen nach",
+ "Emoji for your status message" : "Emoji für Ihre Statusnachricht",
"What is your status?" : "Wie ist Ihr Status?",
- "Set status" : "Status setzen",
+ "Predefined statuses" : "Vordefinierte Status",
+ "Previously set" : "Zuvor eingestellt",
+ "Reset status" : "Status zurücksetzen",
+ "Reset status to \"{icon} {message}\"" : "Status auf \"{icon} {message}\" zurücksetzen",
+ "Reset status to \"{message}\"" : "Status auf \"{message}\" zurücksetzen",
+ "Reset status to \"{icon}\"" : "Status auf \"{icon}\" zurücksetzen",
+ "There was an error saving the status" : "Es gab einen Fehler beim Speichern des Status",
+ "There was an error clearing the status" : "Es gab einen Fehler beim Löschen des Status",
+ "There was an error reverting the status" : "Es ist ein Fehler beim Zurücksetzen des Status aufgetreten",
"Online status" : "Online-Status",
"Status message" : "Statusnachricht",
+ "Set absence period" : "Abwesenheitszeitraum festlegen",
+ "Set absence period and replacement" : "Abwesenheitszeitraum und Vertretung festlegen",
+ "Your status was set automatically" : "Ihr Status wurde automatisch gesetzt",
"Clear status message" : "Statusnachricht löschen",
"Set status message" : "Statusnachricht setzen",
- "There was an error saving the status" : "Es gab einen Fehler beim Speichern des Status",
- "There was an error clearing the status" : "Es gab einen Fehler beim Löschen des Status",
- "No recent status changes" : "Keine kürzlichen Statusänderungen",
- "Away" : "Abwesend",
- "Do not disturb" : "Bitte nicht stören",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Nicht löschen",
"Today" : "Heute",
"This week" : "Diese Woche",
"Online" : "Online",
+ "Away" : "Abwesend",
+ "Do not disturb" : "Nicht stören",
"Invisible" : "Unsichtbar",
"Offline" : "Offline",
+ "Set status" : "Status setzen",
"There was an error saving the new status" : "Es gab einen Fehler beim Speichern des neuen Status",
"30 minutes" : "30 Minuten",
"1 hour" : "1 Stunde",
"4 hours" : "4 Stunden",
+ "Busy" : "Beschäftigt",
"Mute all notifications" : "Alle Benachrichtigungen stummschalten",
- "Appear offline" : "Offline erscheinen",
- "What's your status?" : "Wie ist Ihr Status?"
+ "Appear offline" : "Offline erscheinen"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/user_status/l10n/de_DE.json b/apps/user_status/l10n/de_DE.json
index b6951e4789a..9be300f0e29 100644
--- a/apps/user_status/l10n/de_DE.json
+++ b/apps/user_status/l10n/de_DE.json
@@ -1,38 +1,49 @@
{ "translations": {
"Recent statuses" : "Letzter Status",
+ "No recent status changes" : "Keine kürzlichen Statusänderungen",
"In a meeting" : "In einer Besprechung",
"Commuting" : "Pendelt",
"Out sick" : "Krank geschrieben",
"Vacationing" : "Im Urlaub",
+ "Out of office" : "Nicht im Büro",
"Working remotely" : "Arbeitet aus der Ferne",
"In a call" : "In einem Anruf",
+ "Be right back" : "Bin gleich zurück",
"User status" : "Benutzerstatus",
- "View profile" : "Profil ansehen",
- "Clear status message after" : "Statusnachricht löschen nach",
+ "Clear status after" : "Status löschen nach",
+ "Emoji for your status message" : "Emoji für Ihre Statusnachricht",
"What is your status?" : "Wie ist Ihr Status?",
- "Set status" : "Status setzen",
+ "Predefined statuses" : "Vordefinierte Status",
+ "Previously set" : "Zuvor eingestellt",
+ "Reset status" : "Status zurücksetzen",
+ "Reset status to \"{icon} {message}\"" : "Status auf \"{icon} {message}\" zurücksetzen",
+ "Reset status to \"{message}\"" : "Status auf \"{message}\" zurücksetzen",
+ "Reset status to \"{icon}\"" : "Status auf \"{icon}\" zurücksetzen",
+ "There was an error saving the status" : "Es gab einen Fehler beim Speichern des Status",
+ "There was an error clearing the status" : "Es gab einen Fehler beim Löschen des Status",
+ "There was an error reverting the status" : "Es ist ein Fehler beim Zurücksetzen des Status aufgetreten",
"Online status" : "Online-Status",
"Status message" : "Statusnachricht",
+ "Set absence period" : "Abwesenheitszeitraum festlegen",
+ "Set absence period and replacement" : "Abwesenheitszeitraum und Vertretung festlegen",
+ "Your status was set automatically" : "Ihr Status wurde automatisch gesetzt",
"Clear status message" : "Statusnachricht löschen",
"Set status message" : "Statusnachricht setzen",
- "There was an error saving the status" : "Es gab einen Fehler beim Speichern des Status",
- "There was an error clearing the status" : "Es gab einen Fehler beim Löschen des Status",
- "No recent status changes" : "Keine kürzlichen Statusänderungen",
- "Away" : "Abwesend",
- "Do not disturb" : "Bitte nicht stören",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Nicht löschen",
"Today" : "Heute",
"This week" : "Diese Woche",
"Online" : "Online",
+ "Away" : "Abwesend",
+ "Do not disturb" : "Nicht stören",
"Invisible" : "Unsichtbar",
"Offline" : "Offline",
+ "Set status" : "Status setzen",
"There was an error saving the new status" : "Es gab einen Fehler beim Speichern des neuen Status",
"30 minutes" : "30 Minuten",
"1 hour" : "1 Stunde",
"4 hours" : "4 Stunden",
+ "Busy" : "Beschäftigt",
"Mute all notifications" : "Alle Benachrichtigungen stummschalten",
- "Appear offline" : "Offline erscheinen",
- "What's your status?" : "Wie ist Ihr Status?"
+ "Appear offline" : "Offline erscheinen"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/el.js b/apps/user_status/l10n/el.js
index 8462de725ba..0818d00d791 100644
--- a/apps/user_status/l10n/el.js
+++ b/apps/user_status/l10n/el.js
@@ -2,39 +2,38 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Πρόσφατες καταστάσεις",
+ "No recent status changes" : "Δεν υπάρχουν πρόσφατες αλλαγές κατάστασης",
"In a meeting" : "Σε συνάντηση",
"Commuting" : "Μετακίνηση προς την εργασία",
"Out sick" : "Αναρρωτική άδεια",
"Vacationing" : "Διακοπάρω",
+ "Out of office" : "Εκτός γραφείου",
"Working remotely" : "Εργασία εξ αποστάσεως",
"In a call" : "Σε μια κλήση",
"User status" : "Κατάσταση χρήστη",
- "View profile" : "Προβολή προφίλ",
- "Clear status message after" : "Εκκαθάριση μηνύματος κατάστασης μετά από",
+ "Clear status after" : "Εκκαθάριση κατάστασης μετά από",
"What is your status?" : "Ποια είναι η κατάστασή σας;",
- "Set status" : "Ορισμός κατάστασης",
+ "There was an error saving the status" : "Παρουσιάστηκε σφάλμα κατά την αποθήκευση της κατάστασης",
+ "There was an error clearing the status" : "Παρουσιάστηκε σφάλμα κατά την εκκαθάριση της κατάστασης",
"Online status" : "Κατάσταση σε σύνδεση",
"Status message" : "Μήνυμα κατάστασης",
"Clear status message" : "Εκκαθάριση μηνύματος κατάστασης",
"Set status message" : "Ορισμός μηνύματος κατάστασης",
- "There was an error saving the status" : "Παρουσιάστηκε σφάλμα κατά την αποθήκευση της κατάστασης",
- "There was an error clearing the status" : "Παρουσιάστηκε σφάλμα κατά την εκκαθάριση της κατάστασης",
- "No recent status changes" : "Δεν υπάρχουν πρόσφατες αλλαγές κατάστασης",
- "Away" : "Λείπω",
- "Do not disturb" : "Μην ενοχλείτε",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Να μη γίνεται εκκαθάριση",
"Today" : "Σήμερα",
"This week" : "Αυτή την εβδομάδα",
"Online" : "Σε σύνδεση",
+ "Away" : "Λείπω",
+ "Do not disturb" : "Μην ενοχλείτε",
"Invisible" : "Αόρατος",
"Offline" : "Εκτός σύνδεσης",
+ "Set status" : "Ορισμός κατάστασης",
"There was an error saving the new status" : "Παρουσιάστηκε σφάλμα κατά την αποθήκευση της νέας κατάστασης",
"30 minutes" : "30 λεπτά",
"1 hour" : "1 ώρα",
"4 hours" : "4 ώρες",
+ "Busy" : "Απασχολημένος",
"Mute all notifications" : "Σίγαση όλων των ειδοποιήσεων",
- "Appear offline" : "Εμφάνιση εκτός σύνδεσης",
- "What's your status?" : "Ποια είναι η κατάστασή σας;"
+ "Appear offline" : "Εμφάνιση εκτός σύνδεσης"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/user_status/l10n/el.json b/apps/user_status/l10n/el.json
index beb3728768d..bef6486de08 100644
--- a/apps/user_status/l10n/el.json
+++ b/apps/user_status/l10n/el.json
@@ -1,38 +1,37 @@
{ "translations": {
"Recent statuses" : "Πρόσφατες καταστάσεις",
+ "No recent status changes" : "Δεν υπάρχουν πρόσφατες αλλαγές κατάστασης",
"In a meeting" : "Σε συνάντηση",
"Commuting" : "Μετακίνηση προς την εργασία",
"Out sick" : "Αναρρωτική άδεια",
"Vacationing" : "Διακοπάρω",
+ "Out of office" : "Εκτός γραφείου",
"Working remotely" : "Εργασία εξ αποστάσεως",
"In a call" : "Σε μια κλήση",
"User status" : "Κατάσταση χρήστη",
- "View profile" : "Προβολή προφίλ",
- "Clear status message after" : "Εκκαθάριση μηνύματος κατάστασης μετά από",
+ "Clear status after" : "Εκκαθάριση κατάστασης μετά από",
"What is your status?" : "Ποια είναι η κατάστασή σας;",
- "Set status" : "Ορισμός κατάστασης",
+ "There was an error saving the status" : "Παρουσιάστηκε σφάλμα κατά την αποθήκευση της κατάστασης",
+ "There was an error clearing the status" : "Παρουσιάστηκε σφάλμα κατά την εκκαθάριση της κατάστασης",
"Online status" : "Κατάσταση σε σύνδεση",
"Status message" : "Μήνυμα κατάστασης",
"Clear status message" : "Εκκαθάριση μηνύματος κατάστασης",
"Set status message" : "Ορισμός μηνύματος κατάστασης",
- "There was an error saving the status" : "Παρουσιάστηκε σφάλμα κατά την αποθήκευση της κατάστασης",
- "There was an error clearing the status" : "Παρουσιάστηκε σφάλμα κατά την εκκαθάριση της κατάστασης",
- "No recent status changes" : "Δεν υπάρχουν πρόσφατες αλλαγές κατάστασης",
- "Away" : "Λείπω",
- "Do not disturb" : "Μην ενοχλείτε",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Να μη γίνεται εκκαθάριση",
"Today" : "Σήμερα",
"This week" : "Αυτή την εβδομάδα",
"Online" : "Σε σύνδεση",
+ "Away" : "Λείπω",
+ "Do not disturb" : "Μην ενοχλείτε",
"Invisible" : "Αόρατος",
"Offline" : "Εκτός σύνδεσης",
+ "Set status" : "Ορισμός κατάστασης",
"There was an error saving the new status" : "Παρουσιάστηκε σφάλμα κατά την αποθήκευση της νέας κατάστασης",
"30 minutes" : "30 λεπτά",
"1 hour" : "1 ώρα",
"4 hours" : "4 ώρες",
+ "Busy" : "Απασχολημένος",
"Mute all notifications" : "Σίγαση όλων των ειδοποιήσεων",
- "Appear offline" : "Εμφάνιση εκτός σύνδεσης",
- "What's your status?" : "Ποια είναι η κατάστασή σας;"
+ "Appear offline" : "Εμφάνιση εκτός σύνδεσης"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/en_GB.js b/apps/user_status/l10n/en_GB.js
index 2eb26c16667..2ef82ebed8a 100644
--- a/apps/user_status/l10n/en_GB.js
+++ b/apps/user_status/l10n/en_GB.js
@@ -1,24 +1,51 @@
OC.L10N.register(
"user_status",
{
- "Clear status message after" : "Clear status message after",
+ "Recent statuses" : "Recent statuses",
+ "No recent status changes" : "No recent status changes",
+ "In a meeting" : "In a meeting",
+ "Commuting" : "Commuting",
+ "Out sick" : "Out sick",
+ "Vacationing" : "Vacationing",
+ "Out of office" : "Out of office",
+ "Working remotely" : "Working remotely",
+ "In a call" : "In a call",
+ "Be right back" : "Be right back",
+ "User status" : "User status",
+ "Clear status after" : "Clear status after",
+ "Emoji for your status message" : "Emoji for your status message",
"What is your status?" : "What is your status?",
- "Set status" : "Set status",
+ "Predefined statuses" : "Predefined statuses",
+ "Previously set" : "Previously set",
+ "Reset status" : "Reset status",
+ "Reset status to \"{icon} {message}\"" : "Reset status to \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Reset status to \"{message}\"",
+ "Reset status to \"{icon}\"" : "Reset status to \"{icon}\"",
+ "There was an error saving the status" : "There was an error saving the status",
+ "There was an error clearing the status" : "There was an error clearing the status",
+ "There was an error reverting the status" : "There was an error reverting the status",
"Online status" : "Online status",
"Status message" : "Status message",
+ "Set absence period" : "Set absence period",
+ "Set absence period and replacement" : "Set absence period and replacement",
+ "Your status was set automatically" : "Your status was set automatically",
"Clear status message" : "Clear status message",
"Set status message" : "Set status message",
- "Away" : "Away",
- "Do not disturb" : "Do not disturb",
"Don't clear" : "Don't clear",
"Today" : "Today",
"This week" : "This week",
"Online" : "Online",
+ "Away" : "Away",
+ "Do not disturb" : "Do not disturb",
"Invisible" : "Invisible",
"Offline" : "Offline",
+ "Set status" : "Set status",
+ "There was an error saving the new status" : "There was an error saving the new status",
"30 minutes" : "30 minutes",
"1 hour" : "1 hour",
"4 hours" : "4 hours",
- "What's your status?" : "What's your status?"
+ "Busy" : "Busy",
+ "Mute all notifications" : "Mute all notifications",
+ "Appear offline" : "Appear offline"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/user_status/l10n/en_GB.json b/apps/user_status/l10n/en_GB.json
index d2709baf623..0e646a02599 100644
--- a/apps/user_status/l10n/en_GB.json
+++ b/apps/user_status/l10n/en_GB.json
@@ -1,22 +1,49 @@
{ "translations": {
- "Clear status message after" : "Clear status message after",
+ "Recent statuses" : "Recent statuses",
+ "No recent status changes" : "No recent status changes",
+ "In a meeting" : "In a meeting",
+ "Commuting" : "Commuting",
+ "Out sick" : "Out sick",
+ "Vacationing" : "Vacationing",
+ "Out of office" : "Out of office",
+ "Working remotely" : "Working remotely",
+ "In a call" : "In a call",
+ "Be right back" : "Be right back",
+ "User status" : "User status",
+ "Clear status after" : "Clear status after",
+ "Emoji for your status message" : "Emoji for your status message",
"What is your status?" : "What is your status?",
- "Set status" : "Set status",
+ "Predefined statuses" : "Predefined statuses",
+ "Previously set" : "Previously set",
+ "Reset status" : "Reset status",
+ "Reset status to \"{icon} {message}\"" : "Reset status to \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Reset status to \"{message}\"",
+ "Reset status to \"{icon}\"" : "Reset status to \"{icon}\"",
+ "There was an error saving the status" : "There was an error saving the status",
+ "There was an error clearing the status" : "There was an error clearing the status",
+ "There was an error reverting the status" : "There was an error reverting the status",
"Online status" : "Online status",
"Status message" : "Status message",
+ "Set absence period" : "Set absence period",
+ "Set absence period and replacement" : "Set absence period and replacement",
+ "Your status was set automatically" : "Your status was set automatically",
"Clear status message" : "Clear status message",
"Set status message" : "Set status message",
- "Away" : "Away",
- "Do not disturb" : "Do not disturb",
"Don't clear" : "Don't clear",
"Today" : "Today",
"This week" : "This week",
"Online" : "Online",
+ "Away" : "Away",
+ "Do not disturb" : "Do not disturb",
"Invisible" : "Invisible",
"Offline" : "Offline",
+ "Set status" : "Set status",
+ "There was an error saving the new status" : "There was an error saving the new status",
"30 minutes" : "30 minutes",
"1 hour" : "1 hour",
"4 hours" : "4 hours",
- "What's your status?" : "What's your status?"
+ "Busy" : "Busy",
+ "Mute all notifications" : "Mute all notifications",
+ "Appear offline" : "Appear offline"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/es.js b/apps/user_status/l10n/es.js
index 2772f05eb84..d76dd2511f5 100644
--- a/apps/user_status/l10n/es.js
+++ b/apps/user_status/l10n/es.js
@@ -2,39 +2,47 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Estados recientes",
+ "No recent status changes" : "No hay cambios de estado recientes",
"In a meeting" : "En una reunión",
"Commuting" : "De viaje",
"Out sick" : "Ausente por enfermedad",
"Vacationing" : "De vacaciones",
+ "Out of office" : "Fuera de la oficina",
"Working remotely" : "Teletrabajando",
"In a call" : "En una llamada",
"User status" : "Estado del usuario",
- "View profile" : "Ver perfil",
- "Clear status message after" : "Borrar mensaje de estado después de",
+ "Clear status after" : "Eliminar el estado después de",
+ "Emoji for your status message" : "Emoji para sus mensaje de estado",
"What is your status?" : "¿Cuál es su estado?",
- "Set status" : "Configurar estado",
+ "Predefined statuses" : "Estados predefinidos",
+ "Previously set" : "Previamente definido",
+ "Reset status" : "Re-inicializar estado",
+ "Reset status to \"{icon} {message}\"" : "Re-inicializar estado a \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Re-inicializar estado a \"{message}\"",
+ "Reset status to \"{icon}\"" : "Re-inicializar estado a \"{icon}\"",
+ "There was an error saving the status" : "Ha habido un error al guardar el estado",
+ "There was an error clearing the status" : "Ha habido un error al eliminar el estado",
+ "There was an error reverting the status" : "Ocurrió un error al revertir el estado",
"Online status" : "Estado en línea",
"Status message" : "Mensaje de estado",
+ "Your status was set automatically" : "Su estado fue definido automáticamente",
"Clear status message" : "Borrar mensaje de estado",
"Set status message" : "Ajustar el mensaje de estado",
- "There was an error saving the status" : "Ha habido un error al guardar el estado",
- "There was an error clearing the status" : "Ha habido un error al eliminar el estado",
- "No recent status changes" : "No hay cambios de estado recientes",
- "Away" : "Ausente",
- "Do not disturb" : "No molestar",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "No eliminar",
"Today" : "Hoy",
"This week" : "Esta semana",
"Online" : "En línea",
+ "Away" : "Ausente",
+ "Do not disturb" : "No molestar",
"Invisible" : "Invisible",
"Offline" : "Sin conexión",
+ "Set status" : "Configurar estado",
"There was an error saving the new status" : "Ha habido un error al guardar el nuevo estado",
"30 minutes" : "30 minutos",
"1 hour" : "1 hora",
"4 hours" : "4 horas",
+ "Busy" : "Ocupado",
"Mute all notifications" : "Silenciar todas las notificaciones",
- "Appear offline" : "Aparecer sin conexión",
- "What's your status?" : "¿Cuál es tu estado?"
+ "Appear offline" : "Aparecer sin conexión"
},
-"nplurals=2; plural=(n != 1);");
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/user_status/l10n/es.json b/apps/user_status/l10n/es.json
index 689eca66c74..d743ee8a033 100644
--- a/apps/user_status/l10n/es.json
+++ b/apps/user_status/l10n/es.json
@@ -1,38 +1,46 @@
{ "translations": {
"Recent statuses" : "Estados recientes",
+ "No recent status changes" : "No hay cambios de estado recientes",
"In a meeting" : "En una reunión",
"Commuting" : "De viaje",
"Out sick" : "Ausente por enfermedad",
"Vacationing" : "De vacaciones",
+ "Out of office" : "Fuera de la oficina",
"Working remotely" : "Teletrabajando",
"In a call" : "En una llamada",
"User status" : "Estado del usuario",
- "View profile" : "Ver perfil",
- "Clear status message after" : "Borrar mensaje de estado después de",
+ "Clear status after" : "Eliminar el estado después de",
+ "Emoji for your status message" : "Emoji para sus mensaje de estado",
"What is your status?" : "¿Cuál es su estado?",
- "Set status" : "Configurar estado",
+ "Predefined statuses" : "Estados predefinidos",
+ "Previously set" : "Previamente definido",
+ "Reset status" : "Re-inicializar estado",
+ "Reset status to \"{icon} {message}\"" : "Re-inicializar estado a \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Re-inicializar estado a \"{message}\"",
+ "Reset status to \"{icon}\"" : "Re-inicializar estado a \"{icon}\"",
+ "There was an error saving the status" : "Ha habido un error al guardar el estado",
+ "There was an error clearing the status" : "Ha habido un error al eliminar el estado",
+ "There was an error reverting the status" : "Ocurrió un error al revertir el estado",
"Online status" : "Estado en línea",
"Status message" : "Mensaje de estado",
+ "Your status was set automatically" : "Su estado fue definido automáticamente",
"Clear status message" : "Borrar mensaje de estado",
"Set status message" : "Ajustar el mensaje de estado",
- "There was an error saving the status" : "Ha habido un error al guardar el estado",
- "There was an error clearing the status" : "Ha habido un error al eliminar el estado",
- "No recent status changes" : "No hay cambios de estado recientes",
- "Away" : "Ausente",
- "Do not disturb" : "No molestar",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "No eliminar",
"Today" : "Hoy",
"This week" : "Esta semana",
"Online" : "En línea",
+ "Away" : "Ausente",
+ "Do not disturb" : "No molestar",
"Invisible" : "Invisible",
"Offline" : "Sin conexión",
+ "Set status" : "Configurar estado",
"There was an error saving the new status" : "Ha habido un error al guardar el nuevo estado",
"30 minutes" : "30 minutos",
"1 hour" : "1 hora",
"4 hours" : "4 horas",
+ "Busy" : "Ocupado",
"Mute all notifications" : "Silenciar todas las notificaciones",
- "Appear offline" : "Aparecer sin conexión",
- "What's your status?" : "¿Cuál es tu estado?"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
+ "Appear offline" : "Aparecer sin conexión"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/es_AR.js b/apps/user_status/l10n/es_AR.js
deleted file mode 100644
index b5430541548..00000000000
--- a/apps/user_status/l10n/es_AR.js
+++ /dev/null
@@ -1,23 +0,0 @@
-OC.L10N.register(
- "user_status",
- {
- "Clear status message after" : "Limpiar mensaje de estado después",
- "Set status" : "Establecer estado",
- "Online status" : "Estado en línea",
- "Status message" : "Mensaje de estado",
- "Clear status message" : "Limpiar mensaje de estado",
- "Set status message" : "Establecer mensaje de estado",
- "Away" : "Lejos",
- "Do not disturb" : "No molestar",
- "Don't clear" : "No vaciar",
- "Today" : "Hoy",
- "This week" : "Esta semana",
- "Online" : "En línea",
- "Invisible" : "Invisible",
- "Offline" : "Sin conexión",
- "30 minutes" : "30 minutos",
- "1 hour" : "1 hora",
- "4 hours" : "4 horas",
- "What's your status?" : "¿Cual es tu estado?"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/user_status/l10n/es_AR.json b/apps/user_status/l10n/es_AR.json
deleted file mode 100644
index fb7502e9499..00000000000
--- a/apps/user_status/l10n/es_AR.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{ "translations": {
- "Clear status message after" : "Limpiar mensaje de estado después",
- "Set status" : "Establecer estado",
- "Online status" : "Estado en línea",
- "Status message" : "Mensaje de estado",
- "Clear status message" : "Limpiar mensaje de estado",
- "Set status message" : "Establecer mensaje de estado",
- "Away" : "Lejos",
- "Do not disturb" : "No molestar",
- "Don't clear" : "No vaciar",
- "Today" : "Hoy",
- "This week" : "Esta semana",
- "Online" : "En línea",
- "Invisible" : "Invisible",
- "Offline" : "Sin conexión",
- "30 minutes" : "30 minutos",
- "1 hour" : "1 hora",
- "4 hours" : "4 horas",
- "What's your status?" : "¿Cual es tu estado?"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/user_status/l10n/es_EC.js b/apps/user_status/l10n/es_EC.js
new file mode 100644
index 00000000000..6500afa7c5a
--- /dev/null
+++ b/apps/user_status/l10n/es_EC.js
@@ -0,0 +1,48 @@
+OC.L10N.register(
+ "user_status",
+ {
+ "Recent statuses" : "Estados recientes",
+ "No recent status changes" : "No hay cambios recientes de estado",
+ "In a meeting" : "En una reunión",
+ "Commuting" : "Desplazamiento",
+ "Out sick" : "Ausente por enfermedad",
+ "Vacationing" : "De vacaciones",
+ "Out of office" : "Fuera de la oficina",
+ "Working remotely" : "Trabajando de forma remota",
+ "In a call" : "En una llamada",
+ "User status" : "Estado de usuario",
+ "Clear status after" : "Borrar estado después de",
+ "Emoji for your status message" : "Emoji para tu mensaje de estado",
+ "What is your status?" : "¿Cuál es tu estado?",
+ "Predefined statuses" : "Estados predefinidos",
+ "Previously set" : "Previamente establecido",
+ "Reset status" : "Restablecer estado",
+ "Reset status to \"{icon} {message}\"" : "Restablecer estado a \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Restablecer estado a \"{message}\"",
+ "Reset status to \"{icon}\"" : "Restablecer estado a \"{icon}\"",
+ "There was an error saving the status" : "Hubo un error al guardar el estado",
+ "There was an error clearing the status" : "Hubo un error al borrar el estado",
+ "There was an error reverting the status" : "Hubo un error al revertir el estado",
+ "Online status" : "Estado en línea",
+ "Status message" : "Mensaje de estado",
+ "Your status was set automatically" : "Tu estado se estableció automáticamente",
+ "Clear status message" : "Borrar mensaje de estado",
+ "Set status message" : "Establecer mensaje de estado",
+ "Don't clear" : "No borrar",
+ "Today" : "Hoy",
+ "This week" : "Esta semana",
+ "Online" : "En línea",
+ "Away" : "Ausente",
+ "Do not disturb" : "No molestar",
+ "Invisible" : "Invisible",
+ "Offline" : "Sin conexión",
+ "Set status" : "Establecer estado",
+ "There was an error saving the new status" : "Hubo un error al guardar el nuevo estado",
+ "30 minutes" : "30 minutos",
+ "1 hour" : "1 hora",
+ "4 hours" : "4 horas",
+ "Busy" : "Ocupado",
+ "Mute all notifications" : "Silenciar todas las notificaciones",
+ "Appear offline" : "Aparecer como desconectado"
+},
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/user_status/l10n/es_EC.json b/apps/user_status/l10n/es_EC.json
new file mode 100644
index 00000000000..4d6f3df54ec
--- /dev/null
+++ b/apps/user_status/l10n/es_EC.json
@@ -0,0 +1,46 @@
+{ "translations": {
+ "Recent statuses" : "Estados recientes",
+ "No recent status changes" : "No hay cambios recientes de estado",
+ "In a meeting" : "En una reunión",
+ "Commuting" : "Desplazamiento",
+ "Out sick" : "Ausente por enfermedad",
+ "Vacationing" : "De vacaciones",
+ "Out of office" : "Fuera de la oficina",
+ "Working remotely" : "Trabajando de forma remota",
+ "In a call" : "En una llamada",
+ "User status" : "Estado de usuario",
+ "Clear status after" : "Borrar estado después de",
+ "Emoji for your status message" : "Emoji para tu mensaje de estado",
+ "What is your status?" : "¿Cuál es tu estado?",
+ "Predefined statuses" : "Estados predefinidos",
+ "Previously set" : "Previamente establecido",
+ "Reset status" : "Restablecer estado",
+ "Reset status to \"{icon} {message}\"" : "Restablecer estado a \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Restablecer estado a \"{message}\"",
+ "Reset status to \"{icon}\"" : "Restablecer estado a \"{icon}\"",
+ "There was an error saving the status" : "Hubo un error al guardar el estado",
+ "There was an error clearing the status" : "Hubo un error al borrar el estado",
+ "There was an error reverting the status" : "Hubo un error al revertir el estado",
+ "Online status" : "Estado en línea",
+ "Status message" : "Mensaje de estado",
+ "Your status was set automatically" : "Tu estado se estableció automáticamente",
+ "Clear status message" : "Borrar mensaje de estado",
+ "Set status message" : "Establecer mensaje de estado",
+ "Don't clear" : "No borrar",
+ "Today" : "Hoy",
+ "This week" : "Esta semana",
+ "Online" : "En línea",
+ "Away" : "Ausente",
+ "Do not disturb" : "No molestar",
+ "Invisible" : "Invisible",
+ "Offline" : "Sin conexión",
+ "Set status" : "Establecer estado",
+ "There was an error saving the new status" : "Hubo un error al guardar el nuevo estado",
+ "30 minutes" : "30 minutos",
+ "1 hour" : "1 hora",
+ "4 hours" : "4 horas",
+ "Busy" : "Ocupado",
+ "Mute all notifications" : "Silenciar todas las notificaciones",
+ "Appear offline" : "Aparecer como desconectado"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/user_status/l10n/es_MX.js b/apps/user_status/l10n/es_MX.js
new file mode 100644
index 00000000000..1b5aae7f116
--- /dev/null
+++ b/apps/user_status/l10n/es_MX.js
@@ -0,0 +1,48 @@
+OC.L10N.register(
+ "user_status",
+ {
+ "Recent statuses" : "Estados recientes",
+ "No recent status changes" : "No hay cambios recientes de estado",
+ "In a meeting" : "En una reunión",
+ "Commuting" : "Trasladándose",
+ "Out sick" : "Enfermo",
+ "Vacationing" : "De vacaciones",
+ "Out of office" : "Fuera de la oficina",
+ "Working remotely" : "Trabajando remotamente",
+ "In a call" : "En una llamada",
+ "User status" : "Estado de usuario",
+ "Clear status after" : "Limpiar el estado después de",
+ "Emoji for your status message" : "Emoji para su mensaje de estado",
+ "What is your status?" : "¿Cuál es su estado?",
+ "Predefined statuses" : "Estados predefinidos",
+ "Previously set" : "Previamente establecido",
+ "Reset status" : "Restablecer estado",
+ "Reset status to \"{icon} {message}\"" : "Restablecer estado a \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Restablecer estado a \"{message}\"",
+ "Reset status to \"{icon}\"" : "Restablecer estado a \"{icon}\"",
+ "There was an error saving the status" : "Hubo un error al guardar el estado",
+ "There was an error clearing the status" : "Hubo un error al limpiar el estado",
+ "There was an error reverting the status" : "Hubo un error al revertir el estado",
+ "Online status" : "Estado en línea",
+ "Status message" : "Mensaje de estado",
+ "Your status was set automatically" : "Su estado se estableció automáticamente",
+ "Clear status message" : "Borrar mensaje de estado",
+ "Set status message" : "Establecer mensaje de estado",
+ "Don't clear" : "No borrar",
+ "Today" : "Hoy",
+ "This week" : "Esta semana",
+ "Online" : "En línea",
+ "Away" : "Ausente",
+ "Do not disturb" : "No molestar",
+ "Invisible" : "Invisible",
+ "Offline" : "Sin conexión",
+ "Set status" : "Establecer estado",
+ "There was an error saving the new status" : "Hubo un error al guardar el nuevo estado",
+ "30 minutes" : "30 minutos",
+ "1 hour" : "1 hora",
+ "4 hours" : "4 horas",
+ "Busy" : "Ocupado",
+ "Mute all notifications" : "Silenciar todas las notificaciones",
+ "Appear offline" : "Aparecer como desconectado"
+},
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/user_status/l10n/es_MX.json b/apps/user_status/l10n/es_MX.json
new file mode 100644
index 00000000000..26f418adc7f
--- /dev/null
+++ b/apps/user_status/l10n/es_MX.json
@@ -0,0 +1,46 @@
+{ "translations": {
+ "Recent statuses" : "Estados recientes",
+ "No recent status changes" : "No hay cambios recientes de estado",
+ "In a meeting" : "En una reunión",
+ "Commuting" : "Trasladándose",
+ "Out sick" : "Enfermo",
+ "Vacationing" : "De vacaciones",
+ "Out of office" : "Fuera de la oficina",
+ "Working remotely" : "Trabajando remotamente",
+ "In a call" : "En una llamada",
+ "User status" : "Estado de usuario",
+ "Clear status after" : "Limpiar el estado después de",
+ "Emoji for your status message" : "Emoji para su mensaje de estado",
+ "What is your status?" : "¿Cuál es su estado?",
+ "Predefined statuses" : "Estados predefinidos",
+ "Previously set" : "Previamente establecido",
+ "Reset status" : "Restablecer estado",
+ "Reset status to \"{icon} {message}\"" : "Restablecer estado a \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Restablecer estado a \"{message}\"",
+ "Reset status to \"{icon}\"" : "Restablecer estado a \"{icon}\"",
+ "There was an error saving the status" : "Hubo un error al guardar el estado",
+ "There was an error clearing the status" : "Hubo un error al limpiar el estado",
+ "There was an error reverting the status" : "Hubo un error al revertir el estado",
+ "Online status" : "Estado en línea",
+ "Status message" : "Mensaje de estado",
+ "Your status was set automatically" : "Su estado se estableció automáticamente",
+ "Clear status message" : "Borrar mensaje de estado",
+ "Set status message" : "Establecer mensaje de estado",
+ "Don't clear" : "No borrar",
+ "Today" : "Hoy",
+ "This week" : "Esta semana",
+ "Online" : "En línea",
+ "Away" : "Ausente",
+ "Do not disturb" : "No molestar",
+ "Invisible" : "Invisible",
+ "Offline" : "Sin conexión",
+ "Set status" : "Establecer estado",
+ "There was an error saving the new status" : "Hubo un error al guardar el nuevo estado",
+ "30 minutes" : "30 minutos",
+ "1 hour" : "1 hora",
+ "4 hours" : "4 horas",
+ "Busy" : "Ocupado",
+ "Mute all notifications" : "Silenciar todas las notificaciones",
+ "Appear offline" : "Aparecer como desconectado"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/user_status/l10n/et_EE.js b/apps/user_status/l10n/et_EE.js
new file mode 100644
index 00000000000..18c3c88e824
--- /dev/null
+++ b/apps/user_status/l10n/et_EE.js
@@ -0,0 +1,51 @@
+OC.L10N.register(
+ "user_status",
+ {
+ "Recent statuses" : "Hiljutised olekud",
+ "No recent status changes" : "Pole hiljutisi olekumuudatusi",
+ "In a meeting" : "Koosolekul",
+ "Commuting" : "Sõidus",
+ "Out sick" : "Haige",
+ "Vacationing" : "Puhkusel",
+ "Out of office" : "Kontorist väljas",
+ "Working remotely" : "Kaugtööl",
+ "In a call" : "Kõnes",
+ "Be right back" : "Kohe jõuan tagasi",
+ "User status" : "Kasutaja olek",
+ "Clear status after" : "Eemalda olekuteade peale",
+ "Emoji for your status message" : "Sinu olekuteate emoji",
+ "What is your status?" : "Mis on su olek?",
+ "Predefined statuses" : "Eeldefineeritud olekud",
+ "Previously set" : "Varasemalt seatud",
+ "Reset status" : "Lähesta olek",
+ "Reset status to \"{icon} {message}\"" : "Lähesta olek „{icon} {message}“-ks",
+ "Reset status to \"{message}\"" : "Lähesta olek „{message}“-ks",
+ "Reset status to \"{icon}\"" : "Lähesta olek „{icon}“-ks",
+ "There was an error saving the status" : "Oleku salvestamisel tekkis viga",
+ "There was an error clearing the status" : "Oleku eemaldamisel tekkis viga",
+ "There was an error reverting the status" : "Oleku taastamisel tekkis viga",
+ "Online status" : "Olek võrgus",
+ "Status message" : "Olekuteade",
+ "Set absence period" : "Määra eemaloleku periood",
+ "Set absence period and replacement" : "Määra eemaloleku periood ja asendaja",
+ "Your status was set automatically" : "Su olek määrati automaatselt",
+ "Clear status message" : "Eemalda olekuteade",
+ "Set status message" : "Lisa olekusõnum",
+ "Don't clear" : "Ära kustuta",
+ "Today" : "Tänast",
+ "This week" : "Käesoleval nädalal",
+ "Online" : "Võrgus",
+ "Away" : "Eemal",
+ "Do not disturb" : "Ära sega",
+ "Invisible" : "Nähtamatu",
+ "Offline" : "Pole võrgus",
+ "Set status" : "Määra olek",
+ "There was an error saving the new status" : "Uue oleku salvestamisel esines viga",
+ "30 minutes" : "30 minutit",
+ "1 hour" : "1 tundi",
+ "4 hours" : "4 tundi",
+ "Busy" : "Hõivatud",
+ "Mute all notifications" : "Sellega summutad teavitused",
+ "Appear offline" : "Sellega paistad olema võrgust väljas"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/user_status/l10n/et_EE.json b/apps/user_status/l10n/et_EE.json
new file mode 100644
index 00000000000..903466eef24
--- /dev/null
+++ b/apps/user_status/l10n/et_EE.json
@@ -0,0 +1,49 @@
+{ "translations": {
+ "Recent statuses" : "Hiljutised olekud",
+ "No recent status changes" : "Pole hiljutisi olekumuudatusi",
+ "In a meeting" : "Koosolekul",
+ "Commuting" : "Sõidus",
+ "Out sick" : "Haige",
+ "Vacationing" : "Puhkusel",
+ "Out of office" : "Kontorist väljas",
+ "Working remotely" : "Kaugtööl",
+ "In a call" : "Kõnes",
+ "Be right back" : "Kohe jõuan tagasi",
+ "User status" : "Kasutaja olek",
+ "Clear status after" : "Eemalda olekuteade peale",
+ "Emoji for your status message" : "Sinu olekuteate emoji",
+ "What is your status?" : "Mis on su olek?",
+ "Predefined statuses" : "Eeldefineeritud olekud",
+ "Previously set" : "Varasemalt seatud",
+ "Reset status" : "Lähesta olek",
+ "Reset status to \"{icon} {message}\"" : "Lähesta olek „{icon} {message}“-ks",
+ "Reset status to \"{message}\"" : "Lähesta olek „{message}“-ks",
+ "Reset status to \"{icon}\"" : "Lähesta olek „{icon}“-ks",
+ "There was an error saving the status" : "Oleku salvestamisel tekkis viga",
+ "There was an error clearing the status" : "Oleku eemaldamisel tekkis viga",
+ "There was an error reverting the status" : "Oleku taastamisel tekkis viga",
+ "Online status" : "Olek võrgus",
+ "Status message" : "Olekuteade",
+ "Set absence period" : "Määra eemaloleku periood",
+ "Set absence period and replacement" : "Määra eemaloleku periood ja asendaja",
+ "Your status was set automatically" : "Su olek määrati automaatselt",
+ "Clear status message" : "Eemalda olekuteade",
+ "Set status message" : "Lisa olekusõnum",
+ "Don't clear" : "Ära kustuta",
+ "Today" : "Tänast",
+ "This week" : "Käesoleval nädalal",
+ "Online" : "Võrgus",
+ "Away" : "Eemal",
+ "Do not disturb" : "Ära sega",
+ "Invisible" : "Nähtamatu",
+ "Offline" : "Pole võrgus",
+ "Set status" : "Määra olek",
+ "There was an error saving the new status" : "Uue oleku salvestamisel esines viga",
+ "30 minutes" : "30 minutit",
+ "1 hour" : "1 tundi",
+ "4 hours" : "4 tundi",
+ "Busy" : "Hõivatud",
+ "Mute all notifications" : "Sellega summutad teavitused",
+ "Appear offline" : "Sellega paistad olema võrgust väljas"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/user_status/l10n/eu.js b/apps/user_status/l10n/eu.js
index 3570ea6f8f1..b10e38ec09e 100644
--- a/apps/user_status/l10n/eu.js
+++ b/apps/user_status/l10n/eu.js
@@ -2,39 +2,49 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Azken egoerak",
+ "No recent status changes" : "Azken egoera-aldaketarik ez",
"In a meeting" : "Bilera batean",
"Commuting" : "Lanerako bidean",
"Out sick" : "Gaixorik",
"Vacationing" : "Oporretan",
+ "Out of office" : "Bulegotik kanpo",
"Working remotely" : "Urrutitik lanean",
"In a call" : "Dei batean",
"User status" : "Erabiltzaile-egoera",
- "View profile" : "Ikusi profila",
- "Clear status message after" : "Garbitu egoera mezua ondoren",
+ "Clear status after" : "Garbitu egoera honen ondoren",
+ "Emoji for your status message" : "Zure egoera-mezurako emojia",
"What is your status?" : "Zein da zure egoera?",
- "Set status" : "Ezarri egoera",
+ "Predefined statuses" : "Aurrez definitutako egoerak",
+ "Previously set" : "Lehendik ezarrita",
+ "Reset status" : "Berrezarri egoera",
+ "Reset status to \"{icon} {message}\"" : "Berrezarri egoera \"{icon} {message}\"(e)ra",
+ "Reset status to \"{message}\"" : "Berrezarri egoera \"{message}\"(e)ra",
+ "Reset status to \"{icon}\"" : "Berrezarri egoera \"{icon}\"(e)ra",
+ "There was an error saving the status" : "Errore bat gertatu da egoera gordetzean",
+ "There was an error clearing the status" : "Errore bat gertatu da egoera garbitzean",
+ "There was an error reverting the status" : "Errore bat gertatu da egoera berrezartzean",
"Online status" : "Lineako egoera",
"Status message" : "Egoera-mezua",
+ "Set absence period" : "Ezarri absentzia aldia",
+ "Set absence period and replacement" : "Ezarri absentzia aldia eta ordezkoa",
+ "Your status was set automatically" : "Zure egoera automatikoki ezarriko dira",
"Clear status message" : "Garbitu egoera-mezua",
"Set status message" : "Ezarri egoera-mezua",
- "There was an error saving the status" : "Errore bat gertatu da egoera gordetzean",
- "There was an error clearing the status" : "Errore bat gertatu da egoera garbitzean",
- "No recent status changes" : "Azken egoera-aldaketarik ez",
- "Away" : "Kanpoan",
- "Do not disturb" : "Ez molestatu",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Ez garbitu",
"Today" : "Gaur",
"This week" : "Aste honetan",
"Online" : "Linean",
+ "Away" : "Kanpoan",
+ "Do not disturb" : "Ez molestatu",
"Invisible" : "Ikusezina",
"Offline" : "Lineaz kanpo",
+ "Set status" : "Ezarri egoera",
"There was an error saving the new status" : "Errore bat gertatu da egoera berria gordetzean",
"30 minutes" : "30 minutu",
"1 hour" : "Ordu 1",
"4 hours" : "4 ordu",
+ "Busy" : "Lanpetua",
"Mute all notifications" : "Mututu jakinarazpen guztiak",
- "Appear offline" : "Lineaz kanpo agertu",
- "What's your status?" : "Zein da zure egoera?"
+ "Appear offline" : "Lineaz kanpo agertu"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/user_status/l10n/eu.json b/apps/user_status/l10n/eu.json
index 61b8ec3bee0..3362581d9f5 100644
--- a/apps/user_status/l10n/eu.json
+++ b/apps/user_status/l10n/eu.json
@@ -1,38 +1,48 @@
{ "translations": {
"Recent statuses" : "Azken egoerak",
+ "No recent status changes" : "Azken egoera-aldaketarik ez",
"In a meeting" : "Bilera batean",
"Commuting" : "Lanerako bidean",
"Out sick" : "Gaixorik",
"Vacationing" : "Oporretan",
+ "Out of office" : "Bulegotik kanpo",
"Working remotely" : "Urrutitik lanean",
"In a call" : "Dei batean",
"User status" : "Erabiltzaile-egoera",
- "View profile" : "Ikusi profila",
- "Clear status message after" : "Garbitu egoera mezua ondoren",
+ "Clear status after" : "Garbitu egoera honen ondoren",
+ "Emoji for your status message" : "Zure egoera-mezurako emojia",
"What is your status?" : "Zein da zure egoera?",
- "Set status" : "Ezarri egoera",
+ "Predefined statuses" : "Aurrez definitutako egoerak",
+ "Previously set" : "Lehendik ezarrita",
+ "Reset status" : "Berrezarri egoera",
+ "Reset status to \"{icon} {message}\"" : "Berrezarri egoera \"{icon} {message}\"(e)ra",
+ "Reset status to \"{message}\"" : "Berrezarri egoera \"{message}\"(e)ra",
+ "Reset status to \"{icon}\"" : "Berrezarri egoera \"{icon}\"(e)ra",
+ "There was an error saving the status" : "Errore bat gertatu da egoera gordetzean",
+ "There was an error clearing the status" : "Errore bat gertatu da egoera garbitzean",
+ "There was an error reverting the status" : "Errore bat gertatu da egoera berrezartzean",
"Online status" : "Lineako egoera",
"Status message" : "Egoera-mezua",
+ "Set absence period" : "Ezarri absentzia aldia",
+ "Set absence period and replacement" : "Ezarri absentzia aldia eta ordezkoa",
+ "Your status was set automatically" : "Zure egoera automatikoki ezarriko dira",
"Clear status message" : "Garbitu egoera-mezua",
"Set status message" : "Ezarri egoera-mezua",
- "There was an error saving the status" : "Errore bat gertatu da egoera gordetzean",
- "There was an error clearing the status" : "Errore bat gertatu da egoera garbitzean",
- "No recent status changes" : "Azken egoera-aldaketarik ez",
- "Away" : "Kanpoan",
- "Do not disturb" : "Ez molestatu",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Ez garbitu",
"Today" : "Gaur",
"This week" : "Aste honetan",
"Online" : "Linean",
+ "Away" : "Kanpoan",
+ "Do not disturb" : "Ez molestatu",
"Invisible" : "Ikusezina",
"Offline" : "Lineaz kanpo",
+ "Set status" : "Ezarri egoera",
"There was an error saving the new status" : "Errore bat gertatu da egoera berria gordetzean",
"30 minutes" : "30 minutu",
"1 hour" : "Ordu 1",
"4 hours" : "4 ordu",
+ "Busy" : "Lanpetua",
"Mute all notifications" : "Mututu jakinarazpen guztiak",
- "Appear offline" : "Lineaz kanpo agertu",
- "What's your status?" : "Zein da zure egoera?"
+ "Appear offline" : "Lineaz kanpo agertu"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/fa.js b/apps/user_status/l10n/fa.js
index 1c366ee07ce..e3e600eb696 100644
--- a/apps/user_status/l10n/fa.js
+++ b/apps/user_status/l10n/fa.js
@@ -1,24 +1,48 @@
OC.L10N.register(
"user_status",
{
- "Clear status message after" : "بعد از آن پیام وضعیت را پاک کن ",
+ "Recent statuses" : "وضعیت های اخیر",
+ "No recent status changes" : "هیچ تغییر وضعیت جدیدی وجود ندارد",
+ "In a meeting" : "در جلسه",
+ "Commuting" : "در رفت و آمد",
+ "Out sick" : "مرخصی استعلاجی",
+ "Vacationing" : "تعطیلات",
+ "Out of office" : "بیرون از دفتر",
+ "Working remotely" : "دورکاری",
+ "In a call" : "در حال تماس تلفنی",
+ "User status" : "وضعبت کاربر",
+ "Clear status after" : "پاک کردن وضعیت بعدی",
+ "Emoji for your status message" : "Emoji for your status message",
"What is your status?" : "وضعیت شما چیست؟",
- "Set status" : "تنظیم وضعیت",
+ "Predefined statuses" : "Predefined statuses",
+ "Previously set" : "Previously set",
+ "Reset status" : "Reset status",
+ "Reset status to \"{icon} {message}\"" : "Reset status to \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Reset status to \"{message}\"",
+ "Reset status to \"{icon}\"" : "Reset status to \"{icon}\"",
+ "There was an error saving the status" : "مشکلی در ذخیره سازی وضعیت پیش آمده",
+ "There was an error clearing the status" : "مشکلی در پاک کردن وضعیت پیش آمده",
+ "There was an error reverting the status" : "There was an error reverting the status",
"Online status" : "وضعیت آنلاین",
"Status message" : "پیغام وضعیت",
+ "Your status was set automatically" : "Your status was set automatically",
"Clear status message" : "پیام وضعیت را پاک کن",
"Set status message" : "تنظیم پیام وضعیت",
- "Away" : "دور",
- "Do not disturb" : "مزاحم نشوید",
"Don't clear" : "پاک نکن",
- "Today" : "Today",
+ "Today" : "امروز",
"This week" : "این هفته",
"Online" : "آنلاین",
- "Invisible" : "نامرئی",
+ "Away" : "بیرون",
+ "Do not disturb" : "مزاحم نشوید",
+ "Invisible" : "غیر قابل مشاهده",
"Offline" : "آفلاین",
+ "Set status" : "تنظیم وضعیت",
+ "There was an error saving the new status" : "مشکلی در ذخیره سازی وضعیت جدید پیش آمده",
"30 minutes" : "۳۰ دقیقه",
- "1 hour" : "1 ساعت",
+ "1 hour" : "۱ ساعت",
"4 hours" : "۴ ساعت",
- "What's your status?" : "وضعیت شما چیست؟"
+ "Busy" : "مشغول",
+ "Mute all notifications" : "خاموش کردن همه اعلانات",
+ "Appear offline" : "نمایش آفلاین"
},
"nplurals=2; plural=(n > 1);");
diff --git a/apps/user_status/l10n/fa.json b/apps/user_status/l10n/fa.json
index 798741ed37d..ab997e0a8a7 100644
--- a/apps/user_status/l10n/fa.json
+++ b/apps/user_status/l10n/fa.json
@@ -1,22 +1,46 @@
{ "translations": {
- "Clear status message after" : "بعد از آن پیام وضعیت را پاک کن ",
+ "Recent statuses" : "وضعیت های اخیر",
+ "No recent status changes" : "هیچ تغییر وضعیت جدیدی وجود ندارد",
+ "In a meeting" : "در جلسه",
+ "Commuting" : "در رفت و آمد",
+ "Out sick" : "مرخصی استعلاجی",
+ "Vacationing" : "تعطیلات",
+ "Out of office" : "بیرون از دفتر",
+ "Working remotely" : "دورکاری",
+ "In a call" : "در حال تماس تلفنی",
+ "User status" : "وضعبت کاربر",
+ "Clear status after" : "پاک کردن وضعیت بعدی",
+ "Emoji for your status message" : "Emoji for your status message",
"What is your status?" : "وضعیت شما چیست؟",
- "Set status" : "تنظیم وضعیت",
+ "Predefined statuses" : "Predefined statuses",
+ "Previously set" : "Previously set",
+ "Reset status" : "Reset status",
+ "Reset status to \"{icon} {message}\"" : "Reset status to \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Reset status to \"{message}\"",
+ "Reset status to \"{icon}\"" : "Reset status to \"{icon}\"",
+ "There was an error saving the status" : "مشکلی در ذخیره سازی وضعیت پیش آمده",
+ "There was an error clearing the status" : "مشکلی در پاک کردن وضعیت پیش آمده",
+ "There was an error reverting the status" : "There was an error reverting the status",
"Online status" : "وضعیت آنلاین",
"Status message" : "پیغام وضعیت",
+ "Your status was set automatically" : "Your status was set automatically",
"Clear status message" : "پیام وضعیت را پاک کن",
"Set status message" : "تنظیم پیام وضعیت",
- "Away" : "دور",
- "Do not disturb" : "مزاحم نشوید",
"Don't clear" : "پاک نکن",
- "Today" : "Today",
+ "Today" : "امروز",
"This week" : "این هفته",
"Online" : "آنلاین",
- "Invisible" : "نامرئی",
+ "Away" : "بیرون",
+ "Do not disturb" : "مزاحم نشوید",
+ "Invisible" : "غیر قابل مشاهده",
"Offline" : "آفلاین",
+ "Set status" : "تنظیم وضعیت",
+ "There was an error saving the new status" : "مشکلی در ذخیره سازی وضعیت جدید پیش آمده",
"30 minutes" : "۳۰ دقیقه",
- "1 hour" : "1 ساعت",
+ "1 hour" : "۱ ساعت",
"4 hours" : "۴ ساعت",
- "What's your status?" : "وضعیت شما چیست؟"
+ "Busy" : "مشغول",
+ "Mute all notifications" : "خاموش کردن همه اعلانات",
+ "Appear offline" : "نمایش آفلاین"
},"pluralForm" :"nplurals=2; plural=(n > 1);"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/fi.js b/apps/user_status/l10n/fi.js
index 248b2793723..db936384ff9 100644
--- a/apps/user_status/l10n/fi.js
+++ b/apps/user_status/l10n/fi.js
@@ -2,39 +2,49 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Viimeisimmät tilatiedot",
+ "No recent status changes" : "Ei viimeisimpiä tilatietomuutoksia",
"In a meeting" : "Tapaamisessa",
"Commuting" : "Työmatkalla",
"Out sick" : "Sairaana",
"Vacationing" : "Lomailemassa",
+ "Out of office" : "Poissa työpaikalta",
"Working remotely" : "Etätyössä",
"In a call" : "Puhelussa",
"User status" : "Käyttäjän tilatieto",
- "View profile" : "Näytä profiili",
- "Clear status message after" : "Tyhjennä tilaviesti, kun on kulunut",
+ "Clear status after" : "Tyhjennä tilatieto",
+ "Emoji for your status message" : "Emoji tilaviestiisi",
"What is your status?" : "Mikä on tilatietosi?",
- "Set status" : "Aseta tilatieto",
+ "Predefined statuses" : "Ennalta määritellyt tilatiedot",
+ "Previously set" : "Aiemmin asetettu",
+ "Reset status" : "Palauta tilatieto",
+ "Reset status to \"{icon} {message}\"" : "Palauta tilatiedoksi \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Palauta tilatiedoksi \"{message}\"",
+ "Reset status to \"{icon}\"" : "Palauta tilatiedoksi \"{icon}\"",
+ "There was an error saving the status" : "Tilatiedon tallentamisessa tapahtui virhe",
+ "There was an error clearing the status" : "Tilatietoa tyhjentäessä tapahtui virhe",
+ "There was an error reverting the status" : "Tilatietoa palauttaessa tapahtui virhe",
"Online status" : "Online-tila",
"Status message" : "Tilaviesti",
+ "Set absence period" : "Aseta poissaoloaika",
+ "Set absence period and replacement" : "Aseta poissaoloaika ja sijainen",
+ "Your status was set automatically" : "Tilatietosi asetettiin automaattisesti",
"Clear status message" : "Tyhjennä tilaviesti",
"Set status message" : "Aseta tilaviesti",
- "There was an error saving the status" : "Tilatiedon tallentamisessa tapahtui virhe",
- "There was an error clearing the status" : "Tilatietoa tyhjentäessä tapahtui virhe",
- "No recent status changes" : "Ei viimeisimpiä tilatietomuutoksia",
- "Away" : "Poissa",
- "Do not disturb" : "Älä häiritse",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Älä tyhjennä",
"Today" : "Tänään",
"This week" : "Tällä viikolla",
"Online" : "Paikalla",
+ "Away" : "Poissa",
+ "Do not disturb" : "Älä häiritse",
"Invisible" : "Näkymätön",
"Offline" : "Poissa",
+ "Set status" : "Aseta tilatieto",
"There was an error saving the new status" : "Uuden tilatiedon tallentamisessa tapahtui virhe",
"30 minutes" : "30 minuuttia",
"1 hour" : "1 tunti",
"4 hours" : "4 tuntia",
+ "Busy" : "Varattu",
"Mute all notifications" : "Mykistä kaikki ilmoitukset",
- "Appear offline" : "Näytä olevan poissa",
- "What's your status?" : "Mikä on tilatietosi?"
+ "Appear offline" : "Näytä olevan poissa"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/user_status/l10n/fi.json b/apps/user_status/l10n/fi.json
index 60ff001643c..5a7ad4fa685 100644
--- a/apps/user_status/l10n/fi.json
+++ b/apps/user_status/l10n/fi.json
@@ -1,38 +1,48 @@
{ "translations": {
"Recent statuses" : "Viimeisimmät tilatiedot",
+ "No recent status changes" : "Ei viimeisimpiä tilatietomuutoksia",
"In a meeting" : "Tapaamisessa",
"Commuting" : "Työmatkalla",
"Out sick" : "Sairaana",
"Vacationing" : "Lomailemassa",
+ "Out of office" : "Poissa työpaikalta",
"Working remotely" : "Etätyössä",
"In a call" : "Puhelussa",
"User status" : "Käyttäjän tilatieto",
- "View profile" : "Näytä profiili",
- "Clear status message after" : "Tyhjennä tilaviesti, kun on kulunut",
+ "Clear status after" : "Tyhjennä tilatieto",
+ "Emoji for your status message" : "Emoji tilaviestiisi",
"What is your status?" : "Mikä on tilatietosi?",
- "Set status" : "Aseta tilatieto",
+ "Predefined statuses" : "Ennalta määritellyt tilatiedot",
+ "Previously set" : "Aiemmin asetettu",
+ "Reset status" : "Palauta tilatieto",
+ "Reset status to \"{icon} {message}\"" : "Palauta tilatiedoksi \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Palauta tilatiedoksi \"{message}\"",
+ "Reset status to \"{icon}\"" : "Palauta tilatiedoksi \"{icon}\"",
+ "There was an error saving the status" : "Tilatiedon tallentamisessa tapahtui virhe",
+ "There was an error clearing the status" : "Tilatietoa tyhjentäessä tapahtui virhe",
+ "There was an error reverting the status" : "Tilatietoa palauttaessa tapahtui virhe",
"Online status" : "Online-tila",
"Status message" : "Tilaviesti",
+ "Set absence period" : "Aseta poissaoloaika",
+ "Set absence period and replacement" : "Aseta poissaoloaika ja sijainen",
+ "Your status was set automatically" : "Tilatietosi asetettiin automaattisesti",
"Clear status message" : "Tyhjennä tilaviesti",
"Set status message" : "Aseta tilaviesti",
- "There was an error saving the status" : "Tilatiedon tallentamisessa tapahtui virhe",
- "There was an error clearing the status" : "Tilatietoa tyhjentäessä tapahtui virhe",
- "No recent status changes" : "Ei viimeisimpiä tilatietomuutoksia",
- "Away" : "Poissa",
- "Do not disturb" : "Älä häiritse",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Älä tyhjennä",
"Today" : "Tänään",
"This week" : "Tällä viikolla",
"Online" : "Paikalla",
+ "Away" : "Poissa",
+ "Do not disturb" : "Älä häiritse",
"Invisible" : "Näkymätön",
"Offline" : "Poissa",
+ "Set status" : "Aseta tilatieto",
"There was an error saving the new status" : "Uuden tilatiedon tallentamisessa tapahtui virhe",
"30 minutes" : "30 minuuttia",
"1 hour" : "1 tunti",
"4 hours" : "4 tuntia",
+ "Busy" : "Varattu",
"Mute all notifications" : "Mykistä kaikki ilmoitukset",
- "Appear offline" : "Näytä olevan poissa",
- "What's your status?" : "Mikä on tilatietosi?"
+ "Appear offline" : "Näytä olevan poissa"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/fr.js b/apps/user_status/l10n/fr.js
index 01abc796d3c..a00b780a33d 100644
--- a/apps/user_status/l10n/fr.js
+++ b/apps/user_status/l10n/fr.js
@@ -2,39 +2,49 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Statuts récents",
+ "No recent status changes" : "Aucun changement de statut récent",
"In a meeting" : "En réunion",
- "Commuting" : "En transit",
+ "Commuting" : "Trajet",
"Out sick" : "En congé de maladie",
"Vacationing" : "En vacances",
+ "Out of office" : "Absent du bureau",
"Working remotely" : "Travail à distance",
"In a call" : "En communication",
"User status" : "Statut utilisateur",
- "View profile" : "Voir le profil",
- "Clear status message after" : "Effacer le message d'état après",
+ "Clear status after" : "Effacer l'état après",
+ "Emoji for your status message" : "Emoji pour votre message de statut",
"What is your status?" : "Quel est votre statut ?",
- "Set status" : "Définir le statut",
+ "Predefined statuses" : "Statuts prédéfinis",
+ "Previously set" : "Précédemment défini",
+ "Reset status" : "Réinitialiser l'état",
+ "Reset status to \"{icon} {message}\"" : "Réinitialiser l'état en \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Réinitialiser l'état en \"{message}\"",
+ "Reset status to \"{icon}\"" : "Réinitialiser l'état en \"{icon}\"",
+ "There was an error saving the status" : "Une erreur s'est produite lors de l'enregistrement de l'état",
+ "There was an error clearing the status" : "Une erreur s'est produite lors de l'effacement de l'état",
+ "There was an error reverting the status" : "Une erreur est survenue dans le rétablissement d'état",
"Online status" : "Statut en ligne",
"Status message" : "Message d'état",
+ "Set absence period" : "Définir une période d'absence",
+ "Set absence period and replacement" : "Définir une période d'absence et un remplaçant",
+ "Your status was set automatically" : "Votre état a été automatiquement défini",
"Clear status message" : "Effacer le message d'état",
- "Set status message" : "Message d'état",
- "There was an error saving the status" : "Une erreur s'est produite lors de l'enregistrement de l'état",
- "There was an error clearing the status" : "Une erreur s'est produite lors de l'effacement de l'état",
- "No recent status changes" : "Aucun changement de statut récent",
- "Away" : "Absent(e)",
- "Do not disturb" : "Ne pas déranger",
- "{status}, {timestamp}" : "{status}, {timestamp}",
+ "Set status message" : "Enregistrer le message d'état",
"Don't clear" : "Ne pas effacer",
"Today" : "Aujourd'hui",
"This week" : "Cette semaine",
"Online" : "En ligne",
+ "Away" : "Absent(e)",
+ "Do not disturb" : "Ne pas déranger",
"Invisible" : "Invisible",
"Offline" : "Hors-ligne",
+ "Set status" : "Définir le statut",
"There was an error saving the new status" : "Une erreur s'est produite lors de l'enregistrement du nouveau statut",
"30 minutes" : "30 minutes",
"1 hour" : "1 heure",
"4 hours" : "4 heures",
- "Mute all notifications" : "Désactiver toutes les notifications",
- "Appear offline" : "Apparaitre hors-ligne",
- "What's your status?" : "Quel est votre statut ?"
+ "Busy" : "Occupé",
+ "Mute all notifications" : "Désactiver les notifications",
+ "Appear offline" : "Apparaitre hors-ligne"
},
-"nplurals=2; plural=(n > 1);");
+"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/user_status/l10n/fr.json b/apps/user_status/l10n/fr.json
index a62900e8f1f..98c873a2060 100644
--- a/apps/user_status/l10n/fr.json
+++ b/apps/user_status/l10n/fr.json
@@ -1,38 +1,48 @@
{ "translations": {
"Recent statuses" : "Statuts récents",
+ "No recent status changes" : "Aucun changement de statut récent",
"In a meeting" : "En réunion",
- "Commuting" : "En transit",
+ "Commuting" : "Trajet",
"Out sick" : "En congé de maladie",
"Vacationing" : "En vacances",
+ "Out of office" : "Absent du bureau",
"Working remotely" : "Travail à distance",
"In a call" : "En communication",
"User status" : "Statut utilisateur",
- "View profile" : "Voir le profil",
- "Clear status message after" : "Effacer le message d'état après",
+ "Clear status after" : "Effacer l'état après",
+ "Emoji for your status message" : "Emoji pour votre message de statut",
"What is your status?" : "Quel est votre statut ?",
- "Set status" : "Définir le statut",
+ "Predefined statuses" : "Statuts prédéfinis",
+ "Previously set" : "Précédemment défini",
+ "Reset status" : "Réinitialiser l'état",
+ "Reset status to \"{icon} {message}\"" : "Réinitialiser l'état en \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Réinitialiser l'état en \"{message}\"",
+ "Reset status to \"{icon}\"" : "Réinitialiser l'état en \"{icon}\"",
+ "There was an error saving the status" : "Une erreur s'est produite lors de l'enregistrement de l'état",
+ "There was an error clearing the status" : "Une erreur s'est produite lors de l'effacement de l'état",
+ "There was an error reverting the status" : "Une erreur est survenue dans le rétablissement d'état",
"Online status" : "Statut en ligne",
"Status message" : "Message d'état",
+ "Set absence period" : "Définir une période d'absence",
+ "Set absence period and replacement" : "Définir une période d'absence et un remplaçant",
+ "Your status was set automatically" : "Votre état a été automatiquement défini",
"Clear status message" : "Effacer le message d'état",
- "Set status message" : "Message d'état",
- "There was an error saving the status" : "Une erreur s'est produite lors de l'enregistrement de l'état",
- "There was an error clearing the status" : "Une erreur s'est produite lors de l'effacement de l'état",
- "No recent status changes" : "Aucun changement de statut récent",
- "Away" : "Absent(e)",
- "Do not disturb" : "Ne pas déranger",
- "{status}, {timestamp}" : "{status}, {timestamp}",
+ "Set status message" : "Enregistrer le message d'état",
"Don't clear" : "Ne pas effacer",
"Today" : "Aujourd'hui",
"This week" : "Cette semaine",
"Online" : "En ligne",
+ "Away" : "Absent(e)",
+ "Do not disturb" : "Ne pas déranger",
"Invisible" : "Invisible",
"Offline" : "Hors-ligne",
+ "Set status" : "Définir le statut",
"There was an error saving the new status" : "Une erreur s'est produite lors de l'enregistrement du nouveau statut",
"30 minutes" : "30 minutes",
"1 hour" : "1 heure",
"4 hours" : "4 heures",
- "Mute all notifications" : "Désactiver toutes les notifications",
- "Appear offline" : "Apparaitre hors-ligne",
- "What's your status?" : "Quel est votre statut ?"
-},"pluralForm" :"nplurals=2; plural=(n > 1);"
+ "Busy" : "Occupé",
+ "Mute all notifications" : "Désactiver les notifications",
+ "Appear offline" : "Apparaitre hors-ligne"
+},"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/user_status/l10n/ga.js b/apps/user_status/l10n/ga.js
new file mode 100644
index 00000000000..d976c272537
--- /dev/null
+++ b/apps/user_status/l10n/ga.js
@@ -0,0 +1,51 @@
+OC.L10N.register(
+ "user_status",
+ {
+ "Recent statuses" : "Stádais le déanaí",
+ "No recent status changes" : "Níl aon athrú stádais le déanaí",
+ "In a meeting" : "I gcruinniú",
+ "Commuting" : "Comaitéireacht",
+ "Out sick" : "Amach tinn",
+ "Vacationing" : "Laethanta saoire",
+ "Out of office" : "As oifig",
+ "Working remotely" : "Ag obair go cianda",
+ "In a call" : "I nglao",
+ "Be right back" : "Ar ais láithreach",
+ "User status" : "Stádas úsáideora",
+ "Clear status after" : "Stádas soiléir tar éis",
+ "Emoji for your status message" : "Emoji do do theachtaireacht stádais",
+ "What is your status?" : "Cad é do stádas?",
+ "Predefined statuses" : "Stádais réamhshainithe",
+ "Previously set" : "Socraíodh roimhe seo",
+ "Reset status" : "Stádas a athshocrú",
+ "Reset status to \"{icon} {message}\"" : "Athshocraigh stádas go \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Athshocraigh stádas go \"{message}\"",
+ "Reset status to \"{icon}\"" : "Athshocraigh stádas go \"{icon}\"",
+ "There was an error saving the status" : "Tharla earráid agus an stádas á shábháil",
+ "There was an error clearing the status" : "Tharla earráid agus an stádas á ghlanadh",
+ "There was an error reverting the status" : "Tharla earráid agus an stádas á chur ar ais",
+ "Online status" : "Stádas ar líne",
+ "Status message" : "Teachtaireacht stádais",
+ "Set absence period" : "Socraigh tréimhse neamhláithreachta",
+ "Set absence period and replacement" : "Socraigh tréimhse neamhláithreachta agus athsholáthar",
+ "Your status was set automatically" : "Socraíodh do stádas go huathoibríoch",
+ "Clear status message" : "Glan teachtaireacht stádais",
+ "Set status message" : "Socraigh teachtaireacht stádais",
+ "Don't clear" : "Ná soiléir",
+ "Today" : "Inniu",
+ "This week" : "An tseachtain seo",
+ "Online" : "Ar líne",
+ "Away" : "Amach",
+ "Do not disturb" : "Ná cur as",
+ "Invisible" : "Dofheicthe",
+ "Offline" : "As líne",
+ "Set status" : "Socraigh stádas",
+ "There was an error saving the new status" : "Tharla earráid agus an stádas nua á shábháil",
+ "30 minutes" : "30 nóiméad",
+ "1 hour" : "1 uair",
+ "4 hours" : "4 uair an chloig",
+ "Busy" : "Gnóthach",
+ "Mute all notifications" : "Balbhaigh gach fógra",
+ "Appear offline" : "Le feiceáil as líne"
+},
+"nplurals=5; plural=(n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4);");
diff --git a/apps/user_status/l10n/ga.json b/apps/user_status/l10n/ga.json
new file mode 100644
index 00000000000..c672231aab3
--- /dev/null
+++ b/apps/user_status/l10n/ga.json
@@ -0,0 +1,49 @@
+{ "translations": {
+ "Recent statuses" : "Stádais le déanaí",
+ "No recent status changes" : "Níl aon athrú stádais le déanaí",
+ "In a meeting" : "I gcruinniú",
+ "Commuting" : "Comaitéireacht",
+ "Out sick" : "Amach tinn",
+ "Vacationing" : "Laethanta saoire",
+ "Out of office" : "As oifig",
+ "Working remotely" : "Ag obair go cianda",
+ "In a call" : "I nglao",
+ "Be right back" : "Ar ais láithreach",
+ "User status" : "Stádas úsáideora",
+ "Clear status after" : "Stádas soiléir tar éis",
+ "Emoji for your status message" : "Emoji do do theachtaireacht stádais",
+ "What is your status?" : "Cad é do stádas?",
+ "Predefined statuses" : "Stádais réamhshainithe",
+ "Previously set" : "Socraíodh roimhe seo",
+ "Reset status" : "Stádas a athshocrú",
+ "Reset status to \"{icon} {message}\"" : "Athshocraigh stádas go \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Athshocraigh stádas go \"{message}\"",
+ "Reset status to \"{icon}\"" : "Athshocraigh stádas go \"{icon}\"",
+ "There was an error saving the status" : "Tharla earráid agus an stádas á shábháil",
+ "There was an error clearing the status" : "Tharla earráid agus an stádas á ghlanadh",
+ "There was an error reverting the status" : "Tharla earráid agus an stádas á chur ar ais",
+ "Online status" : "Stádas ar líne",
+ "Status message" : "Teachtaireacht stádais",
+ "Set absence period" : "Socraigh tréimhse neamhláithreachta",
+ "Set absence period and replacement" : "Socraigh tréimhse neamhláithreachta agus athsholáthar",
+ "Your status was set automatically" : "Socraíodh do stádas go huathoibríoch",
+ "Clear status message" : "Glan teachtaireacht stádais",
+ "Set status message" : "Socraigh teachtaireacht stádais",
+ "Don't clear" : "Ná soiléir",
+ "Today" : "Inniu",
+ "This week" : "An tseachtain seo",
+ "Online" : "Ar líne",
+ "Away" : "Amach",
+ "Do not disturb" : "Ná cur as",
+ "Invisible" : "Dofheicthe",
+ "Offline" : "As líne",
+ "Set status" : "Socraigh stádas",
+ "There was an error saving the new status" : "Tharla earráid agus an stádas nua á shábháil",
+ "30 minutes" : "30 nóiméad",
+ "1 hour" : "1 uair",
+ "4 hours" : "4 uair an chloig",
+ "Busy" : "Gnóthach",
+ "Mute all notifications" : "Balbhaigh gach fógra",
+ "Appear offline" : "Le feiceáil as líne"
+},"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/user_status/l10n/gl.js b/apps/user_status/l10n/gl.js
index 043184c79a0..3045c22fb4a 100644
--- a/apps/user_status/l10n/gl.js
+++ b/apps/user_status/l10n/gl.js
@@ -2,38 +2,49 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Estados recentes",
+ "No recent status changes" : "Non hai cambios de estado recentes",
"In a meeting" : "Nunha xuntanza",
"Commuting" : "De casa ao traballo ou ao revés",
"Out sick" : "Enfermo",
"Vacationing" : "De vacacións",
+ "Out of office" : "Fóra da oficina",
"Working remotely" : "Traballando en remoto",
+ "In a call" : "Nunha chamada",
"User status" : "Estado do usuario",
- "View profile" : "Ver o perfil",
- "Clear status message after" : "Limpar a mensaxe de estado após",
+ "Clear status after" : "Limpar o estado após",
+ "Emoji for your status message" : "«Emoji» para a súa mensaxe de estado",
"What is your status?" : "Cal é o seu estado?",
- "Set status" : "Estabelecer o estado",
+ "Predefined statuses" : "Estados predefinidos",
+ "Previously set" : "Estabelecido previamente",
+ "Reset status" : "Restabelecer o estado",
+ "Reset status to \"{icon} {message}\"" : "Restabelecer o estado a «{icon} {message}»",
+ "Reset status to \"{message}\"" : "Restabelecer o estado a «{message}»",
+ "Reset status to \"{icon}\"" : "Restabelecer o estado a «{icon}»",
+ "There was an error saving the status" : "Produciuse un erro ao gardar o estado",
+ "There was an error clearing the status" : "Produciuse un erro ao limpar o estado",
+ "There was an error reverting the status" : "Produciuse un erro ao reverter o estado",
"Online status" : "Estado en liña",
"Status message" : "Mensaxe de estado",
+ "Set absence period" : "Definir o período de ausencia",
+ "Set absence period and replacement" : "Definir o período de ausencia e substitución",
+ "Your status was set automatically" : "O seu estado foi estabelecido automaticamente",
"Clear status message" : "Limpar a mensaxe de estado",
- "Set status message" : "Establecer a mensaxe de estado",
- "There was an error saving the status" : "Produciuse un erro ao gardar o estado",
- "There was an error clearing the status" : "Produciuse un erro ao limpar o estado",
- "No recent status changes" : "Non hai cambios de estado recentes",
- "Away" : "Ausente",
- "Do not disturb" : "Non molestar",
- "{status}, {timestamp}" : "{status} ás {timestamp}",
+ "Set status message" : "Definir a mensaxe de estado",
"Don't clear" : "Non limpar",
"Today" : "Hoxe",
"This week" : "Esta semana",
"Online" : "En liña",
+ "Away" : "Ausente",
+ "Do not disturb" : "Non molestar",
"Invisible" : "Invisíbel",
"Offline" : "Sen conexión",
+ "Set status" : "Definir o estado",
"There was an error saving the new status" : "Produciuse un erro ao gardar o novo estado",
"30 minutes" : "30 minutos",
"1 hour" : "1 hora",
"4 hours" : "4 horas",
- "Mute all notifications" : "Silenciar todas as notificacións",
- "Appear offline" : "Aparece coma sen conexión",
- "What's your status?" : "Cal é o seu estado?"
+ "Busy" : "Ocupado",
+ "Mute all notifications" : "Enmudecer todas as notificacións",
+ "Appear offline" : "Aparece coma sen conexión"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/user_status/l10n/gl.json b/apps/user_status/l10n/gl.json
index f96950bfd74..c90de4d4f13 100644
--- a/apps/user_status/l10n/gl.json
+++ b/apps/user_status/l10n/gl.json
@@ -1,37 +1,48 @@
{ "translations": {
"Recent statuses" : "Estados recentes",
+ "No recent status changes" : "Non hai cambios de estado recentes",
"In a meeting" : "Nunha xuntanza",
"Commuting" : "De casa ao traballo ou ao revés",
"Out sick" : "Enfermo",
"Vacationing" : "De vacacións",
+ "Out of office" : "Fóra da oficina",
"Working remotely" : "Traballando en remoto",
+ "In a call" : "Nunha chamada",
"User status" : "Estado do usuario",
- "View profile" : "Ver o perfil",
- "Clear status message after" : "Limpar a mensaxe de estado após",
+ "Clear status after" : "Limpar o estado após",
+ "Emoji for your status message" : "«Emoji» para a súa mensaxe de estado",
"What is your status?" : "Cal é o seu estado?",
- "Set status" : "Estabelecer o estado",
+ "Predefined statuses" : "Estados predefinidos",
+ "Previously set" : "Estabelecido previamente",
+ "Reset status" : "Restabelecer o estado",
+ "Reset status to \"{icon} {message}\"" : "Restabelecer o estado a «{icon} {message}»",
+ "Reset status to \"{message}\"" : "Restabelecer o estado a «{message}»",
+ "Reset status to \"{icon}\"" : "Restabelecer o estado a «{icon}»",
+ "There was an error saving the status" : "Produciuse un erro ao gardar o estado",
+ "There was an error clearing the status" : "Produciuse un erro ao limpar o estado",
+ "There was an error reverting the status" : "Produciuse un erro ao reverter o estado",
"Online status" : "Estado en liña",
"Status message" : "Mensaxe de estado",
+ "Set absence period" : "Definir o período de ausencia",
+ "Set absence period and replacement" : "Definir o período de ausencia e substitución",
+ "Your status was set automatically" : "O seu estado foi estabelecido automaticamente",
"Clear status message" : "Limpar a mensaxe de estado",
- "Set status message" : "Establecer a mensaxe de estado",
- "There was an error saving the status" : "Produciuse un erro ao gardar o estado",
- "There was an error clearing the status" : "Produciuse un erro ao limpar o estado",
- "No recent status changes" : "Non hai cambios de estado recentes",
- "Away" : "Ausente",
- "Do not disturb" : "Non molestar",
- "{status}, {timestamp}" : "{status} ás {timestamp}",
+ "Set status message" : "Definir a mensaxe de estado",
"Don't clear" : "Non limpar",
"Today" : "Hoxe",
"This week" : "Esta semana",
"Online" : "En liña",
+ "Away" : "Ausente",
+ "Do not disturb" : "Non molestar",
"Invisible" : "Invisíbel",
"Offline" : "Sen conexión",
+ "Set status" : "Definir o estado",
"There was an error saving the new status" : "Produciuse un erro ao gardar o novo estado",
"30 minutes" : "30 minutos",
"1 hour" : "1 hora",
"4 hours" : "4 horas",
- "Mute all notifications" : "Silenciar todas as notificacións",
- "Appear offline" : "Aparece coma sen conexión",
- "What's your status?" : "Cal é o seu estado?"
+ "Busy" : "Ocupado",
+ "Mute all notifications" : "Enmudecer todas as notificacións",
+ "Appear offline" : "Aparece coma sen conexión"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/he.js b/apps/user_status/l10n/he.js
index 05514060b59..c14e661e90c 100644
--- a/apps/user_status/l10n/he.js
+++ b/apps/user_status/l10n/he.js
@@ -2,37 +2,37 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "מצבים אחרונים",
+ "No recent status changes" : "אין שינויים אחרונים למצב",
"In a meeting" : "בפגישה",
"Commuting" : "בדרכים",
"Out sick" : "בחופשת מחלה",
"Vacationing" : "בחופש",
+ "Out of office" : "מחוץ למשרד",
"Working remotely" : "בעבודה מרחוק",
"User status" : "מצב משתמש",
- "Clear status message after" : "מחיקת הודעת מצב לאחר",
+ "Clear status after" : "לפנות את המצב לאחר",
"What is your status?" : "מה המצב שלך?",
- "Set status" : "הגדרת מצב",
+ "There was an error saving the status" : "אירעה שגיאה בשמירת המצב",
+ "There was an error clearing the status" : "אירעה שגיאה בפינוי המצב",
"Online status" : "מצב מקוון",
"Status message" : "הודעת מצב",
"Clear status message" : "פינוי הודעת המצב",
"Set status message" : "הגדרת הודעת מצב",
- "There was an error saving the status" : "אירעה שגיאה בשמירת המצב",
- "There was an error clearing the status" : "אירעה שגיאה בפינוי המצב",
- "No recent status changes" : "אין שינויים אחרונים למצב",
- "Away" : "לא פה",
- "Do not disturb" : "לא להפריע",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "לא לפנות",
"Today" : "היום",
"This week" : "השבוע",
"Online" : "מקוון",
+ "Away" : "לא פה",
+ "Do not disturb" : "לא להפריע",
"Invisible" : "נסתרת",
"Offline" : "בלתי מקוון",
+ "Set status" : "הגדרת מצב",
"There was an error saving the new status" : "אירעה שגיאה בשמירת המצב החדש",
"30 minutes" : "30 דקות",
"1 hour" : "שעה",
"4 hours" : "4 שעות",
+ "Busy" : "עסוק",
"Mute all notifications" : "השתקת כל ההתראות",
- "Appear offline" : "להופיע במצב בלתי מקוון",
- "What's your status?" : "מה המצב שלך?"
+ "Appear offline" : "להופיע במצב בלתי מקוון"
},
-"nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: (n % 10 == 0 && n % 1 == 0 && n > 10) ? 2 : 3;");
+"nplurals=3; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: 2;");
diff --git a/apps/user_status/l10n/he.json b/apps/user_status/l10n/he.json
index 80c8109ac84..1475c5c48e9 100644
--- a/apps/user_status/l10n/he.json
+++ b/apps/user_status/l10n/he.json
@@ -1,36 +1,36 @@
{ "translations": {
"Recent statuses" : "מצבים אחרונים",
+ "No recent status changes" : "אין שינויים אחרונים למצב",
"In a meeting" : "בפגישה",
"Commuting" : "בדרכים",
"Out sick" : "בחופשת מחלה",
"Vacationing" : "בחופש",
+ "Out of office" : "מחוץ למשרד",
"Working remotely" : "בעבודה מרחוק",
"User status" : "מצב משתמש",
- "Clear status message after" : "מחיקת הודעת מצב לאחר",
+ "Clear status after" : "לפנות את המצב לאחר",
"What is your status?" : "מה המצב שלך?",
- "Set status" : "הגדרת מצב",
+ "There was an error saving the status" : "אירעה שגיאה בשמירת המצב",
+ "There was an error clearing the status" : "אירעה שגיאה בפינוי המצב",
"Online status" : "מצב מקוון",
"Status message" : "הודעת מצב",
"Clear status message" : "פינוי הודעת המצב",
"Set status message" : "הגדרת הודעת מצב",
- "There was an error saving the status" : "אירעה שגיאה בשמירת המצב",
- "There was an error clearing the status" : "אירעה שגיאה בפינוי המצב",
- "No recent status changes" : "אין שינויים אחרונים למצב",
- "Away" : "לא פה",
- "Do not disturb" : "לא להפריע",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "לא לפנות",
"Today" : "היום",
"This week" : "השבוע",
"Online" : "מקוון",
+ "Away" : "לא פה",
+ "Do not disturb" : "לא להפריע",
"Invisible" : "נסתרת",
"Offline" : "בלתי מקוון",
+ "Set status" : "הגדרת מצב",
"There was an error saving the new status" : "אירעה שגיאה בשמירת המצב החדש",
"30 minutes" : "30 דקות",
"1 hour" : "שעה",
"4 hours" : "4 שעות",
+ "Busy" : "עסוק",
"Mute all notifications" : "השתקת כל ההתראות",
- "Appear offline" : "להופיע במצב בלתי מקוון",
- "What's your status?" : "מה המצב שלך?"
-},"pluralForm" :"nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: (n % 10 == 0 && n % 1 == 0 && n > 10) ? 2 : 3;"
+ "Appear offline" : "להופיע במצב בלתי מקוון"
+},"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/user_status/l10n/hr.js b/apps/user_status/l10n/hr.js
index cd986995419..32026e39816 100644
--- a/apps/user_status/l10n/hr.js
+++ b/apps/user_status/l10n/hr.js
@@ -2,39 +2,38 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Nedavni statusi",
+ "No recent status changes" : "Nema nedavnih promjena statusa",
"In a meeting" : "Na sastanku",
"Commuting" : "Na putu",
"Out sick" : "Na bolovanju",
"Vacationing" : "Na odmoru",
+ "Out of office" : "Izvan ureda",
"Working remotely" : "Rad na daljinu",
"In a call" : "U pozivu",
"User status" : "Status korisnika",
- "View profile" : "Prikaži profil",
- "Clear status message after" : "Izbriši poruku statusa nakon",
+ "Clear status after" : "Izbriši status nakon",
"What is your status?" : "Koji je vaš status?",
- "Set status" : "Postavi status",
+ "There was an error saving the status" : "Došlo je do pogreške pri spremanju statusa",
+ "There was an error clearing the status" : "Došlo je do pogreške pri brisanju statusa",
"Online status" : "Status na mreži",
"Status message" : "Poruka statusa",
"Clear status message" : "Izbriši poruku statusa",
"Set status message" : "Postavi poruku statusa",
- "There was an error saving the status" : "Došlo je do pogreške pri spremanju statusa",
- "There was an error clearing the status" : "Došlo je do pogreške pri brisanju statusa",
- "No recent status changes" : "Nema nedavnih promjena statusa",
- "Away" : "Odsutan",
- "Do not disturb" : "Ne ometaj",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Ne briši",
"Today" : "Danas",
"This week" : "Ovaj tjedan",
"Online" : "Na mreži",
+ "Away" : "Odsutan",
+ "Do not disturb" : "Ne ometaj",
"Invisible" : "Nevidljiva",
"Offline" : "Izvanmrežno",
+ "Set status" : "Postavi status",
"There was an error saving the new status" : "Došlo je do pogreške pri spremanju novog statusa",
"30 minutes" : "30 minuta",
"1 hour" : "1 sat",
"4 hours" : "4 sata",
+ "Busy" : "Zauzeto",
"Mute all notifications" : "Utišaj sve obavijesti",
- "Appear offline" : "Prikaži izvanmrežno",
- "What's your status?" : "Koji je vaš status?"
+ "Appear offline" : "Prikaži izvanmrežno"
},
"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/user_status/l10n/hr.json b/apps/user_status/l10n/hr.json
index b0270a29781..ba0a7d987f4 100644
--- a/apps/user_status/l10n/hr.json
+++ b/apps/user_status/l10n/hr.json
@@ -1,38 +1,37 @@
{ "translations": {
"Recent statuses" : "Nedavni statusi",
+ "No recent status changes" : "Nema nedavnih promjena statusa",
"In a meeting" : "Na sastanku",
"Commuting" : "Na putu",
"Out sick" : "Na bolovanju",
"Vacationing" : "Na odmoru",
+ "Out of office" : "Izvan ureda",
"Working remotely" : "Rad na daljinu",
"In a call" : "U pozivu",
"User status" : "Status korisnika",
- "View profile" : "Prikaži profil",
- "Clear status message after" : "Izbriši poruku statusa nakon",
+ "Clear status after" : "Izbriši status nakon",
"What is your status?" : "Koji je vaš status?",
- "Set status" : "Postavi status",
+ "There was an error saving the status" : "Došlo je do pogreške pri spremanju statusa",
+ "There was an error clearing the status" : "Došlo je do pogreške pri brisanju statusa",
"Online status" : "Status na mreži",
"Status message" : "Poruka statusa",
"Clear status message" : "Izbriši poruku statusa",
"Set status message" : "Postavi poruku statusa",
- "There was an error saving the status" : "Došlo je do pogreške pri spremanju statusa",
- "There was an error clearing the status" : "Došlo je do pogreške pri brisanju statusa",
- "No recent status changes" : "Nema nedavnih promjena statusa",
- "Away" : "Odsutan",
- "Do not disturb" : "Ne ometaj",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Ne briši",
"Today" : "Danas",
"This week" : "Ovaj tjedan",
"Online" : "Na mreži",
+ "Away" : "Odsutan",
+ "Do not disturb" : "Ne ometaj",
"Invisible" : "Nevidljiva",
"Offline" : "Izvanmrežno",
+ "Set status" : "Postavi status",
"There was an error saving the new status" : "Došlo je do pogreške pri spremanju novog statusa",
"30 minutes" : "30 minuta",
"1 hour" : "1 sat",
"4 hours" : "4 sata",
+ "Busy" : "Zauzeto",
"Mute all notifications" : "Utišaj sve obavijesti",
- "Appear offline" : "Prikaži izvanmrežno",
- "What's your status?" : "Koji je vaš status?"
+ "Appear offline" : "Prikaži izvanmrežno"
},"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/user_status/l10n/hu.js b/apps/user_status/l10n/hu.js
index 85021fe7809..9610f72b24e 100644
--- a/apps/user_status/l10n/hu.js
+++ b/apps/user_status/l10n/hu.js
@@ -2,39 +2,49 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Legutóbbi állapotok",
+ "No recent status changes" : "Nincsenek legutóbbi állapotváltozások",
"In a meeting" : "Találkozón",
"Commuting" : "Ingázás",
"Out sick" : "Betegszabadságon",
"Vacationing" : "Szabadságon",
+ "Out of office" : "Irodán kívül",
"Working remotely" : "Távoli munkavégzés",
"In a call" : "Hívásban",
"User status" : "Felhasználói állapot",
- "View profile" : "Profil megtekintése",
- "Clear status message after" : "Állapotüzenet törlése ennyi idő után:",
+ "Clear status after" : "Állapot törlése ennyi idő után",
+ "Emoji for your status message" : "Emodzsi az állapotüzenetéhez",
"What is your status?" : "Mi az állapota?",
- "Set status" : "Állapot beállítása",
+ "Predefined statuses" : "Előre meghatározott állapotok",
+ "Previously set" : "Előzőleg beállított",
+ "Reset status" : "Állapot visszaállítása",
+ "Reset status to \"{icon} {message}\"" : "Állapot visszaállítása erre: „{icon} {message}”",
+ "Reset status to \"{message}\"" : "Állapot visszaállítása erre: „{message}”",
+ "Reset status to \"{icon}\"" : "Állapot visszaállítása erre: „{icon}”",
+ "There was an error saving the status" : "Hiba történt az állapot mentése során",
+ "There was an error clearing the status" : "Hiba történt az állapot törlése sorá",
+ "There was an error reverting the status" : "Hiba történt az állapot visszaállítása során",
"Online status" : "Elérhető állapot",
"Status message" : "Állapotüzenet",
+ "Set absence period" : "Távolléti időszak beállítása",
+ "Set absence period and replacement" : "Távolléti időszak és helyettes beállítása",
+ "Your status was set automatically" : "Az állapota automatikusan lett beállítva",
"Clear status message" : "Állapotüzenet törlése",
"Set status message" : "Állapotüzenet beállítása",
- "There was an error saving the status" : "Hiba történt az állapot mentése során",
- "There was an error clearing the status" : "Hiba történt az állapot törlése sorá",
- "No recent status changes" : "Nincsenek legutóbbi állapotváltozások",
- "Away" : "Távol",
- "Do not disturb" : "Ne zavarjanak",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Ne törölje",
"Today" : "Ma",
"This week" : "Ezen a héten",
"Online" : "Elérhető",
+ "Away" : "Távol",
+ "Do not disturb" : "Ne zavarjanak",
"Invisible" : "Láthatatlan",
"Offline" : "Nem kapcsolódott",
+ "Set status" : "Állapot beállítása",
"There was an error saving the new status" : "Hiba történt az új állapot mentése sorá",
"30 minutes" : "30 perc",
"1 hour" : "1 óra",
"4 hours" : "4 óra",
+ "Busy" : "Foglalt",
"Mute all notifications" : "Összes értesítés némítása",
- "Appear offline" : "Megjelenés nem kapcsolódottként",
- "What's your status?" : "Mi az állapota?"
+ "Appear offline" : "Megjelenés nem kapcsolódottként"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/user_status/l10n/hu.json b/apps/user_status/l10n/hu.json
index a98cdefba11..9dbf642fc0d 100644
--- a/apps/user_status/l10n/hu.json
+++ b/apps/user_status/l10n/hu.json
@@ -1,38 +1,48 @@
{ "translations": {
"Recent statuses" : "Legutóbbi állapotok",
+ "No recent status changes" : "Nincsenek legutóbbi állapotváltozások",
"In a meeting" : "Találkozón",
"Commuting" : "Ingázás",
"Out sick" : "Betegszabadságon",
"Vacationing" : "Szabadságon",
+ "Out of office" : "Irodán kívül",
"Working remotely" : "Távoli munkavégzés",
"In a call" : "Hívásban",
"User status" : "Felhasználói állapot",
- "View profile" : "Profil megtekintése",
- "Clear status message after" : "Állapotüzenet törlése ennyi idő után:",
+ "Clear status after" : "Állapot törlése ennyi idő után",
+ "Emoji for your status message" : "Emodzsi az állapotüzenetéhez",
"What is your status?" : "Mi az állapota?",
- "Set status" : "Állapot beállítása",
+ "Predefined statuses" : "Előre meghatározott állapotok",
+ "Previously set" : "Előzőleg beállított",
+ "Reset status" : "Állapot visszaállítása",
+ "Reset status to \"{icon} {message}\"" : "Állapot visszaállítása erre: „{icon} {message}”",
+ "Reset status to \"{message}\"" : "Állapot visszaállítása erre: „{message}”",
+ "Reset status to \"{icon}\"" : "Állapot visszaállítása erre: „{icon}”",
+ "There was an error saving the status" : "Hiba történt az állapot mentése során",
+ "There was an error clearing the status" : "Hiba történt az állapot törlése sorá",
+ "There was an error reverting the status" : "Hiba történt az állapot visszaállítása során",
"Online status" : "Elérhető állapot",
"Status message" : "Állapotüzenet",
+ "Set absence period" : "Távolléti időszak beállítása",
+ "Set absence period and replacement" : "Távolléti időszak és helyettes beállítása",
+ "Your status was set automatically" : "Az állapota automatikusan lett beállítva",
"Clear status message" : "Állapotüzenet törlése",
"Set status message" : "Állapotüzenet beállítása",
- "There was an error saving the status" : "Hiba történt az állapot mentése során",
- "There was an error clearing the status" : "Hiba történt az állapot törlése sorá",
- "No recent status changes" : "Nincsenek legutóbbi állapotváltozások",
- "Away" : "Távol",
- "Do not disturb" : "Ne zavarjanak",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Ne törölje",
"Today" : "Ma",
"This week" : "Ezen a héten",
"Online" : "Elérhető",
+ "Away" : "Távol",
+ "Do not disturb" : "Ne zavarjanak",
"Invisible" : "Láthatatlan",
"Offline" : "Nem kapcsolódott",
+ "Set status" : "Állapot beállítása",
"There was an error saving the new status" : "Hiba történt az új állapot mentése sorá",
"30 minutes" : "30 perc",
"1 hour" : "1 óra",
"4 hours" : "4 óra",
+ "Busy" : "Foglalt",
"Mute all notifications" : "Összes értesítés némítása",
- "Appear offline" : "Megjelenés nem kapcsolódottként",
- "What's your status?" : "Mi az állapota?"
+ "Appear offline" : "Megjelenés nem kapcsolódottként"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/is.js b/apps/user_status/l10n/is.js
index 953e729b5bf..1f17415040b 100644
--- a/apps/user_status/l10n/is.js
+++ b/apps/user_status/l10n/is.js
@@ -2,37 +2,49 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Nýlegar stöður",
+ "No recent status changes" : "Engar nýlegar breytingar á stöðu",
"In a meeting" : "Á fundi",
"Commuting" : "Á ferðinni",
"Out sick" : "Veikindi",
"Vacationing" : "Í fríi",
+ "Out of office" : "Ekki á staðnum",
"Working remotely" : "Fjarvinna",
+ "In a call" : "Er í símtali",
"User status" : "Staða notanda",
- "Clear status message after" : "Hreinsa stöðuskilaboð eftir",
+ "Clear status after" : "Hreinsa stöðu eftir",
+ "Emoji for your status message" : "Tákn fyrir stöðufærsluna þína",
"What is your status?" : "Hver er staðan á þér?",
- "Set status" : "Setja stöðu",
+ "Predefined statuses" : "Forákvarðaðar stöður",
+ "Previously set" : "Áður stillt",
+ "Reset status" : "Endurstilla stöðu",
+ "Reset status to \"{icon} {message}\"" : "Endurstilla stöðu sem \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Endurstilla stöðu sem \"{message}\"",
+ "Reset status to \"{icon}\"" : "Endurstilla stöðu sem \"{icon}\"",
+ "There was an error saving the status" : "Það kom upp villa við að vista stöðuna",
+ "There was an error clearing the status" : "Það kom upp villa við að hreinsa stöðuna",
+ "There was an error reverting the status" : "Það kom upp villa við að afturkalla stöðuna",
"Online status" : "Staða á netinu",
"Status message" : "Stöðuskilaboð",
+ "Set absence period" : "Setja tímabil fjarveru",
+ "Set absence period and replacement" : "Setja tímabil fjarveru og afleysingu",
+ "Your status was set automatically" : "Staðan þín var stillt sjálfvirkt",
"Clear status message" : "Hreinsa stöðuskilaboð",
"Set status message" : "Setja stöðuskilaboð",
- "There was an error saving the status" : "Það kom upp villa við að vista stöðuna",
- "There was an error clearing the status" : "Það kom upp villa við að hreinsa stöðuna",
- "No recent status changes" : "Engar nýlegar breytingar á stöðu",
- "Away" : "Fjarverandi",
- "Do not disturb" : "Ónáðið ekki",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Ekki hreinsa",
"Today" : "Í dag",
"This week" : "Í þessari viku",
"Online" : "Á netinu",
+ "Away" : "Fjarverandi",
+ "Do not disturb" : "Ónáðið ekki",
"Invisible" : "Ósýnilegt",
- "Offline" : "Ótengt neti",
+ "Offline" : "Ótengdur neti",
+ "Set status" : "Setja stöðu",
"There was an error saving the new status" : "Það kom upp villa við að vista nýju stöðuna",
"30 minutes" : "30 mínútur",
"1 hour" : "1 klukkustund",
"4 hours" : "4 klukkustundir",
+ "Busy" : "Upptekinn",
"Mute all notifications" : "Þagga allar tilkynningar",
- "Appear offline" : "Birtast ótengt",
- "What's your status?" : "Hver er staðan á þér?"
+ "Appear offline" : "Birtast ótengt"
},
"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);");
diff --git a/apps/user_status/l10n/is.json b/apps/user_status/l10n/is.json
index 4f4784fa4f0..f081ed2745f 100644
--- a/apps/user_status/l10n/is.json
+++ b/apps/user_status/l10n/is.json
@@ -1,36 +1,48 @@
{ "translations": {
"Recent statuses" : "Nýlegar stöður",
+ "No recent status changes" : "Engar nýlegar breytingar á stöðu",
"In a meeting" : "Á fundi",
"Commuting" : "Á ferðinni",
"Out sick" : "Veikindi",
"Vacationing" : "Í fríi",
+ "Out of office" : "Ekki á staðnum",
"Working remotely" : "Fjarvinna",
+ "In a call" : "Er í símtali",
"User status" : "Staða notanda",
- "Clear status message after" : "Hreinsa stöðuskilaboð eftir",
+ "Clear status after" : "Hreinsa stöðu eftir",
+ "Emoji for your status message" : "Tákn fyrir stöðufærsluna þína",
"What is your status?" : "Hver er staðan á þér?",
- "Set status" : "Setja stöðu",
+ "Predefined statuses" : "Forákvarðaðar stöður",
+ "Previously set" : "Áður stillt",
+ "Reset status" : "Endurstilla stöðu",
+ "Reset status to \"{icon} {message}\"" : "Endurstilla stöðu sem \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Endurstilla stöðu sem \"{message}\"",
+ "Reset status to \"{icon}\"" : "Endurstilla stöðu sem \"{icon}\"",
+ "There was an error saving the status" : "Það kom upp villa við að vista stöðuna",
+ "There was an error clearing the status" : "Það kom upp villa við að hreinsa stöðuna",
+ "There was an error reverting the status" : "Það kom upp villa við að afturkalla stöðuna",
"Online status" : "Staða á netinu",
"Status message" : "Stöðuskilaboð",
+ "Set absence period" : "Setja tímabil fjarveru",
+ "Set absence period and replacement" : "Setja tímabil fjarveru og afleysingu",
+ "Your status was set automatically" : "Staðan þín var stillt sjálfvirkt",
"Clear status message" : "Hreinsa stöðuskilaboð",
"Set status message" : "Setja stöðuskilaboð",
- "There was an error saving the status" : "Það kom upp villa við að vista stöðuna",
- "There was an error clearing the status" : "Það kom upp villa við að hreinsa stöðuna",
- "No recent status changes" : "Engar nýlegar breytingar á stöðu",
- "Away" : "Fjarverandi",
- "Do not disturb" : "Ónáðið ekki",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Ekki hreinsa",
"Today" : "Í dag",
"This week" : "Í þessari viku",
"Online" : "Á netinu",
+ "Away" : "Fjarverandi",
+ "Do not disturb" : "Ónáðið ekki",
"Invisible" : "Ósýnilegt",
- "Offline" : "Ótengt neti",
+ "Offline" : "Ótengdur neti",
+ "Set status" : "Setja stöðu",
"There was an error saving the new status" : "Það kom upp villa við að vista nýju stöðuna",
"30 minutes" : "30 mínútur",
"1 hour" : "1 klukkustund",
"4 hours" : "4 klukkustundir",
+ "Busy" : "Upptekinn",
"Mute all notifications" : "Þagga allar tilkynningar",
- "Appear offline" : "Birtast ótengt",
- "What's your status?" : "Hver er staðan á þér?"
+ "Appear offline" : "Birtast ótengt"
},"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/it.js b/apps/user_status/l10n/it.js
index 491519dc102..9917b09972e 100644
--- a/apps/user_status/l10n/it.js
+++ b/apps/user_status/l10n/it.js
@@ -2,39 +2,49 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Stati recenti",
+ "No recent status changes" : "Nessun cambio di stato recente",
"In a meeting" : "In una riunione",
"Commuting" : "Pendolare",
"Out sick" : "In malattia",
"Vacationing" : "In vacanza",
+ "Out of office" : "Fuori sede",
"Working remotely" : "Lavoro da remoto",
"In a call" : "In una chiamata",
"User status" : "Stato utente",
- "View profile" : "Vedi profilo",
- "Clear status message after" : "Cancella il messaggio di stato dopo",
+ "Clear status after" : "Togli lo stato dopo",
+ "Emoji for your status message" : "Emoji per il tuo messaggio di stato",
"What is your status?" : "Qual è il tuo stato?",
- "Set status" : "Imposta stato",
+ "Predefined statuses" : "Stati predefiniti",
+ "Previously set" : "Impostato in precedenza",
+ "Reset status" : "Ripristina stato",
+ "Reset status to \"{icon} {message}\"" : "Ripristina stato a \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Ripristina stato a \"{message}\"",
+ "Reset status to \"{icon}\"" : "Ripristina stato a \"{icon}\"",
+ "There was an error saving the status" : "Si è verificato un errore durante il salvataggio dello stato",
+ "There was an error clearing the status" : "Si è verificato un errore durante la rimozione dello stato",
+ "There was an error reverting the status" : "Si è verificato un errore ripristinando lo stato",
"Online status" : "Stato in linea",
"Status message" : "Messaggio di stato",
+ "Set absence period" : "Imposta periodo di assenza",
+ "Set absence period and replacement" : "Imposta periodo di assenza e sostituzione",
+ "Your status was set automatically" : "Stato impostato automaticamente",
"Clear status message" : "Cancella il messaggio di stato",
"Set status message" : "Imposta messaggio di stato",
- "There was an error saving the status" : "Si è verificato un errore durante il salvataggio dello stato",
- "There was an error clearing the status" : "Si è verificato un errore durante la rimozione dello stato",
- "No recent status changes" : "Nessun cambio di stato recente",
- "Away" : "Assente",
- "Do not disturb" : "Non disturbare",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Non togliere",
"Today" : "Oggi",
"This week" : "Questa settimana",
"Online" : "In linea",
+ "Away" : "Assente",
+ "Do not disturb" : "Non disturbare",
"Invisible" : "Invisibile",
"Offline" : "Non in linea",
+ "Set status" : "Imposta stato",
"There was an error saving the new status" : "Si è verificato un errore durante il salvataggio del nuovo stato",
"30 minutes" : "30 minuti",
"1 hour" : "1 ora",
"4 hours" : "4 ore",
+ "Busy" : "Occupato",
"Mute all notifications" : "Silenzia tutte le notifiche",
- "Appear offline" : "Mostrati non in linea",
- "What's your status?" : "Qual è il tuo stato?"
+ "Appear offline" : "Mostrati non in linea"
},
-"nplurals=2; plural=(n != 1);");
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/user_status/l10n/it.json b/apps/user_status/l10n/it.json
index d1587ee699d..96a6af919a5 100644
--- a/apps/user_status/l10n/it.json
+++ b/apps/user_status/l10n/it.json
@@ -1,38 +1,48 @@
{ "translations": {
"Recent statuses" : "Stati recenti",
+ "No recent status changes" : "Nessun cambio di stato recente",
"In a meeting" : "In una riunione",
"Commuting" : "Pendolare",
"Out sick" : "In malattia",
"Vacationing" : "In vacanza",
+ "Out of office" : "Fuori sede",
"Working remotely" : "Lavoro da remoto",
"In a call" : "In una chiamata",
"User status" : "Stato utente",
- "View profile" : "Vedi profilo",
- "Clear status message after" : "Cancella il messaggio di stato dopo",
+ "Clear status after" : "Togli lo stato dopo",
+ "Emoji for your status message" : "Emoji per il tuo messaggio di stato",
"What is your status?" : "Qual è il tuo stato?",
- "Set status" : "Imposta stato",
+ "Predefined statuses" : "Stati predefiniti",
+ "Previously set" : "Impostato in precedenza",
+ "Reset status" : "Ripristina stato",
+ "Reset status to \"{icon} {message}\"" : "Ripristina stato a \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Ripristina stato a \"{message}\"",
+ "Reset status to \"{icon}\"" : "Ripristina stato a \"{icon}\"",
+ "There was an error saving the status" : "Si è verificato un errore durante il salvataggio dello stato",
+ "There was an error clearing the status" : "Si è verificato un errore durante la rimozione dello stato",
+ "There was an error reverting the status" : "Si è verificato un errore ripristinando lo stato",
"Online status" : "Stato in linea",
"Status message" : "Messaggio di stato",
+ "Set absence period" : "Imposta periodo di assenza",
+ "Set absence period and replacement" : "Imposta periodo di assenza e sostituzione",
+ "Your status was set automatically" : "Stato impostato automaticamente",
"Clear status message" : "Cancella il messaggio di stato",
"Set status message" : "Imposta messaggio di stato",
- "There was an error saving the status" : "Si è verificato un errore durante il salvataggio dello stato",
- "There was an error clearing the status" : "Si è verificato un errore durante la rimozione dello stato",
- "No recent status changes" : "Nessun cambio di stato recente",
- "Away" : "Assente",
- "Do not disturb" : "Non disturbare",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Non togliere",
"Today" : "Oggi",
"This week" : "Questa settimana",
"Online" : "In linea",
+ "Away" : "Assente",
+ "Do not disturb" : "Non disturbare",
"Invisible" : "Invisibile",
"Offline" : "Non in linea",
+ "Set status" : "Imposta stato",
"There was an error saving the new status" : "Si è verificato un errore durante il salvataggio del nuovo stato",
"30 minutes" : "30 minuti",
"1 hour" : "1 ora",
"4 hours" : "4 ore",
+ "Busy" : "Occupato",
"Mute all notifications" : "Silenzia tutte le notifiche",
- "Appear offline" : "Mostrati non in linea",
- "What's your status?" : "Qual è il tuo stato?"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
+ "Appear offline" : "Mostrati non in linea"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/ja.js b/apps/user_status/l10n/ja.js
index 35c87d0647f..74f480e0f36 100644
--- a/apps/user_status/l10n/ja.js
+++ b/apps/user_status/l10n/ja.js
@@ -2,38 +2,50 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "最近のステータス",
+ "No recent status changes" : "最近のステータスの変更はありません",
"In a meeting" : "会議中",
"Commuting" : "通勤中",
"Out sick" : "体調不良",
"Vacationing" : "休暇",
+ "Out of office" : "オフィス外",
"Working remotely" : "リモートワーク中",
+ "In a call" : "通話中",
+ "Be right back" : "すぐ戻ります",
"User status" : "ユーザーステータス",
- "View profile" : "プロフィールを表示",
- "Clear status message after" : "ステータスメッセージの有効期限",
+ "Clear status after" : "ステータスの有効期限",
+ "Emoji for your status message" : "あなたのステータスメッセージに絵文字を",
"What is your status?" : "現在のオンラインステータスは?",
- "Set status" : "ステータスを設定",
+ "Predefined statuses" : "事前定義されたステータス",
+ "Previously set" : "以前の設定",
+ "Reset status" : "ステータスをリセット",
+ "Reset status to \"{icon} {message}\"" : "ステータスを \"{icon} {message}\" にリセット",
+ "Reset status to \"{message}\"" : "ステータスを \"{message}\" にリセット",
+ "Reset status to \"{icon}\"" : "ステータスを \"{icon}\" にリセット",
+ "There was an error saving the status" : "ステータスの保存中にエラーが発生しました",
+ "There was an error clearing the status" : "ステータスの消去中にエラーが発生しました",
+ "There was an error reverting the status" : "ステータスを戻す際にエラーが発生しました",
"Online status" : "オンラインステータス",
"Status message" : "状態メッセージ",
+ "Set absence period" : "不在設定をセットする",
+ "Set absence period and replacement" : "不在期間と交代要員をセットする",
+ "Your status was set automatically" : "あなたのステータスは自動的に設定されました",
"Clear status message" : "ステータスメッセージを消去",
"Set status message" : "ステータスメッセージを設定",
- "There was an error saving the status" : "ステータスの保存中にエラーが発生しました",
- "There was an error clearing the status" : "ステータスの消去中にエラーが発生しました",
- "No recent status changes" : "最近のステータスの変更はありません",
- "Away" : "離席中",
- "Do not disturb" : "取り込み中",
- "{status}, {timestamp}" : "{status}、{timestamp}",
"Don't clear" : "消去しない",
"Today" : "今日",
"This week" : "今週",
"Online" : "オンライン",
+ "Away" : "離席中",
+ "Do not disturb" : "取り込み中",
"Invisible" : "ステータスを隠す",
"Offline" : "オフライン",
+ "Set status" : "ステータスを設定",
"There was an error saving the new status" : "新しいステータスの保存中にエラーが発生しました",
"30 minutes" : "30分",
"1 hour" : "1時間",
"4 hours" : "4時間",
+ "Busy" : "ビジー",
"Mute all notifications" : "全ての通知をミュート",
- "Appear offline" : "オフライン",
- "What's your status?" : "現在のオンラインステータスは?"
+ "Appear offline" : "オフライン"
},
"nplurals=1; plural=0;");
diff --git a/apps/user_status/l10n/ja.json b/apps/user_status/l10n/ja.json
index 9aea78f7969..183ed4f1c1e 100644
--- a/apps/user_status/l10n/ja.json
+++ b/apps/user_status/l10n/ja.json
@@ -1,37 +1,49 @@
{ "translations": {
"Recent statuses" : "最近のステータス",
+ "No recent status changes" : "最近のステータスの変更はありません",
"In a meeting" : "会議中",
"Commuting" : "通勤中",
"Out sick" : "体調不良",
"Vacationing" : "休暇",
+ "Out of office" : "オフィス外",
"Working remotely" : "リモートワーク中",
+ "In a call" : "通話中",
+ "Be right back" : "すぐ戻ります",
"User status" : "ユーザーステータス",
- "View profile" : "プロフィールを表示",
- "Clear status message after" : "ステータスメッセージの有効期限",
+ "Clear status after" : "ステータスの有効期限",
+ "Emoji for your status message" : "あなたのステータスメッセージに絵文字を",
"What is your status?" : "現在のオンラインステータスは?",
- "Set status" : "ステータスを設定",
+ "Predefined statuses" : "事前定義されたステータス",
+ "Previously set" : "以前の設定",
+ "Reset status" : "ステータスをリセット",
+ "Reset status to \"{icon} {message}\"" : "ステータスを \"{icon} {message}\" にリセット",
+ "Reset status to \"{message}\"" : "ステータスを \"{message}\" にリセット",
+ "Reset status to \"{icon}\"" : "ステータスを \"{icon}\" にリセット",
+ "There was an error saving the status" : "ステータスの保存中にエラーが発生しました",
+ "There was an error clearing the status" : "ステータスの消去中にエラーが発生しました",
+ "There was an error reverting the status" : "ステータスを戻す際にエラーが発生しました",
"Online status" : "オンラインステータス",
"Status message" : "状態メッセージ",
+ "Set absence period" : "不在設定をセットする",
+ "Set absence period and replacement" : "不在期間と交代要員をセットする",
+ "Your status was set automatically" : "あなたのステータスは自動的に設定されました",
"Clear status message" : "ステータスメッセージを消去",
"Set status message" : "ステータスメッセージを設定",
- "There was an error saving the status" : "ステータスの保存中にエラーが発生しました",
- "There was an error clearing the status" : "ステータスの消去中にエラーが発生しました",
- "No recent status changes" : "最近のステータスの変更はありません",
- "Away" : "離席中",
- "Do not disturb" : "取り込み中",
- "{status}, {timestamp}" : "{status}、{timestamp}",
"Don't clear" : "消去しない",
"Today" : "今日",
"This week" : "今週",
"Online" : "オンライン",
+ "Away" : "離席中",
+ "Do not disturb" : "取り込み中",
"Invisible" : "ステータスを隠す",
"Offline" : "オフライン",
+ "Set status" : "ステータスを設定",
"There was an error saving the new status" : "新しいステータスの保存中にエラーが発生しました",
"30 minutes" : "30分",
"1 hour" : "1時間",
"4 hours" : "4時間",
+ "Busy" : "ビジー",
"Mute all notifications" : "全ての通知をミュート",
- "Appear offline" : "オフライン",
- "What's your status?" : "現在のオンラインステータスは?"
+ "Appear offline" : "オフライン"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/ko.js b/apps/user_status/l10n/ko.js
index 2d270ed983a..3afaa412ee2 100644
--- a/apps/user_status/l10n/ko.js
+++ b/apps/user_status/l10n/ko.js
@@ -2,39 +2,38 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "최근 상태",
+ "No recent status changes" : "최근 상태 변경 없음",
"In a meeting" : "회의 중",
"Commuting" : "이동 중",
"Out sick" : "병가",
"Vacationing" : "휴가 중",
+ "Out of office" : "자리에 없음",
"Working remotely" : "원격 근무 중",
"In a call" : "통화중",
"User status" : "사용자 상태",
- "View profile" : "프로파일 보기",
- "Clear status message after" : "상태 메시지 지우기 예약",
+ "Clear status after" : "상태 메시지 지우기 예약",
"What is your status?" : "당신의 상태는?",
- "Set status" : "상태 설정",
+ "There was an error saving the status" : "상태 저장에 오류가 발생했습니다.",
+ "There was an error clearing the status" : "상태 해제에 오류가 발생했습니다.",
"Online status" : "접속 상태",
"Status message" : "상태 메시지",
"Clear status message" : "상태 메시지 지움",
"Set status message" : "상태 메시지 설정",
- "There was an error saving the status" : "상태 저장에 오류가 발생했습니다",
- "There was an error clearing the status" : "상태 해제에 오류가 발생했습니다",
- "No recent status changes" : "최근 상태 변경 없음",
- "Away" : "자리 비움",
- "Do not disturb" : "방해 금지",
- "{status}, {timestamp}" : "{status},{timestamp}",
"Don't clear" : "지우지 않음",
"Today" : "오늘",
"This week" : "이번 주",
"Online" : "접속 중",
+ "Away" : "자리 비움",
+ "Do not disturb" : "방해 금지",
"Invisible" : "숨겨짐",
"Offline" : "오프라인",
- "There was an error saving the new status" : "새로운 상태 저장에 오류가 발생했습니다",
+ "Set status" : "상태 설정",
+ "There was an error saving the new status" : "새로운 상태 저장에 오류가 발생했습니다.",
"30 minutes" : "30 분",
"1 hour" : "한 시간",
"4 hours" : "4 시간",
- "Mute all notifications" : "모든 알림을 무시합니다",
- "Appear offline" : "접속 안함으로 표시",
- "What's your status?" : "지금 무엇을 하나요?"
+ "Busy" : "바쁨",
+ "Mute all notifications" : "모든 알림을 음소거",
+ "Appear offline" : "접속 안함으로 표시"
},
"nplurals=1; plural=0;");
diff --git a/apps/user_status/l10n/ko.json b/apps/user_status/l10n/ko.json
index a5948eb8b61..4858bccd4e0 100644
--- a/apps/user_status/l10n/ko.json
+++ b/apps/user_status/l10n/ko.json
@@ -1,38 +1,37 @@
{ "translations": {
"Recent statuses" : "최근 상태",
+ "No recent status changes" : "최근 상태 변경 없음",
"In a meeting" : "회의 중",
"Commuting" : "이동 중",
"Out sick" : "병가",
"Vacationing" : "휴가 중",
+ "Out of office" : "자리에 없음",
"Working remotely" : "원격 근무 중",
"In a call" : "통화중",
"User status" : "사용자 상태",
- "View profile" : "프로파일 보기",
- "Clear status message after" : "상태 메시지 지우기 예약",
+ "Clear status after" : "상태 메시지 지우기 예약",
"What is your status?" : "당신의 상태는?",
- "Set status" : "상태 설정",
+ "There was an error saving the status" : "상태 저장에 오류가 발생했습니다.",
+ "There was an error clearing the status" : "상태 해제에 오류가 발생했습니다.",
"Online status" : "접속 상태",
"Status message" : "상태 메시지",
"Clear status message" : "상태 메시지 지움",
"Set status message" : "상태 메시지 설정",
- "There was an error saving the status" : "상태 저장에 오류가 발생했습니다",
- "There was an error clearing the status" : "상태 해제에 오류가 발생했습니다",
- "No recent status changes" : "최근 상태 변경 없음",
- "Away" : "자리 비움",
- "Do not disturb" : "방해 금지",
- "{status}, {timestamp}" : "{status},{timestamp}",
"Don't clear" : "지우지 않음",
"Today" : "오늘",
"This week" : "이번 주",
"Online" : "접속 중",
+ "Away" : "자리 비움",
+ "Do not disturb" : "방해 금지",
"Invisible" : "숨겨짐",
"Offline" : "오프라인",
- "There was an error saving the new status" : "새로운 상태 저장에 오류가 발생했습니다",
+ "Set status" : "상태 설정",
+ "There was an error saving the new status" : "새로운 상태 저장에 오류가 발생했습니다.",
"30 minutes" : "30 분",
"1 hour" : "한 시간",
"4 hours" : "4 시간",
- "Mute all notifications" : "모든 알림을 무시합니다",
- "Appear offline" : "접속 안함으로 표시",
- "What's your status?" : "지금 무엇을 하나요?"
+ "Busy" : "바쁨",
+ "Mute all notifications" : "모든 알림을 음소거",
+ "Appear offline" : "접속 안함으로 표시"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/lo.js b/apps/user_status/l10n/lo.js
deleted file mode 100644
index 969c89b381b..00000000000
--- a/apps/user_status/l10n/lo.js
+++ /dev/null
@@ -1,25 +0,0 @@
-OC.L10N.register(
- "user_status",
- {
- "Clear status message after" : "ລ້າງສະຖານະພາບຂໍ້ຄວາມພາຍຫຼັງ",
- "Set status" : "ຕັ້ງຄ່າສະຖານະພາບ",
- "Online status" : "ສະຖານະພາບອອນລາຍ",
- "Status message" : "ສະຖານະຂໍ້ຄວາມ",
- "Clear status message" : "ລ້າງສະຖານະພາບຂໍ້ຄວາມ",
- "Set status message" : "ຕັ້ງຄ່າສະຖານະພາບຂໍ້ຄວາມ",
- "Away" : "ອອກໄປ",
- "Do not disturb" : "ຫ້າມລົບກວນ",
- "Don't clear" : "ບໍ່ຈະແຈ້ງ",
- "Today" : "ມື້ນີ້",
- "This week" : "ທິດນີ້",
- "Online" : "ອອນລາຍ",
- "Invisible" : "ເບິ່ງບໍ່ເຫັນ",
- "Offline" : "ອັອບລາຍ",
- "30 minutes" : "30 ນາທີ",
- "1 hour" : "1 ຊົ່ວໂມງ",
- "4 hours" : "4 ຊົ່ວໂມງ",
- "Mute all notifications" : "ປິດການແຈ້ງເຕືອນທັງໝົດ",
- "Appear offline" : "ເປີດອັອບລາຍ",
- "What's your status?" : "ສະຖານະຂອງທ່ານແມ່ນຫຍັງ?"
-},
-"nplurals=1; plural=0;");
diff --git a/apps/user_status/l10n/lo.json b/apps/user_status/l10n/lo.json
deleted file mode 100644
index a9b070b83f0..00000000000
--- a/apps/user_status/l10n/lo.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{ "translations": {
- "Clear status message after" : "ລ້າງສະຖານະພາບຂໍ້ຄວາມພາຍຫຼັງ",
- "Set status" : "ຕັ້ງຄ່າສະຖານະພາບ",
- "Online status" : "ສະຖານະພາບອອນລາຍ",
- "Status message" : "ສະຖານະຂໍ້ຄວາມ",
- "Clear status message" : "ລ້າງສະຖານະພາບຂໍ້ຄວາມ",
- "Set status message" : "ຕັ້ງຄ່າສະຖານະພາບຂໍ້ຄວາມ",
- "Away" : "ອອກໄປ",
- "Do not disturb" : "ຫ້າມລົບກວນ",
- "Don't clear" : "ບໍ່ຈະແຈ້ງ",
- "Today" : "ມື້ນີ້",
- "This week" : "ທິດນີ້",
- "Online" : "ອອນລາຍ",
- "Invisible" : "ເບິ່ງບໍ່ເຫັນ",
- "Offline" : "ອັອບລາຍ",
- "30 minutes" : "30 ນາທີ",
- "1 hour" : "1 ຊົ່ວໂມງ",
- "4 hours" : "4 ຊົ່ວໂມງ",
- "Mute all notifications" : "ປິດການແຈ້ງເຕືອນທັງໝົດ",
- "Appear offline" : "ເປີດອັອບລາຍ",
- "What's your status?" : "ສະຖານະຂອງທ່ານແມ່ນຫຍັງ?"
-},"pluralForm" :"nplurals=1; plural=0;"
-} \ No newline at end of file
diff --git a/apps/user_status/l10n/lt_LT.js b/apps/user_status/l10n/lt_LT.js
index ae9823e1c0e..b440b3f1c05 100644
--- a/apps/user_status/l10n/lt_LT.js
+++ b/apps/user_status/l10n/lt_LT.js
@@ -2,38 +2,40 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Paskiausios būsenos",
+ "No recent status changes" : "Jokių paskiausių būsenos pasikeitimų",
"In a meeting" : "Susitikime",
"Commuting" : "Važinėju",
"Out sick" : "Sergu",
"Vacationing" : "Poilsiauju",
+ "Out of office" : "Ne darbo vietoje",
"Working remotely" : "Dirbu nuotoliniu būdu",
+ "In a call" : "Dalyvauju skambutyje",
"User status" : "Naudotojo būsena",
- "View profile" : "Rodyti profilį",
- "Clear status message after" : "Išvalyti būsenos žinutę po",
+ "Clear status after" : "Išvalyti būseną po",
"What is your status?" : "Kokia jūsų būsena?",
- "Set status" : "Nustatyti būseną",
+ "Predefined statuses" : "Iš anksto apibrėžtos būsenos",
+ "There was an error saving the status" : "Įrašant būseną, įvyko klaida",
+ "There was an error clearing the status" : "Išvalant būseną, įvyko klaida",
"Online status" : "Prisijungimo būsena",
"Status message" : "Būsenos žinutė",
+ "Your status was set automatically" : "Jūsų būsena buvo nustatyta automatiškai",
"Clear status message" : "Išvalyti būsenos žinutę",
"Set status message" : "Nustatyti būsenos žinutę",
- "There was an error saving the status" : "Įrašant būseną, įvyko klaida",
- "There was an error clearing the status" : "Išvalant būseną, įvyko klaida",
- "No recent status changes" : "Jokių paskiausių būsenos pasikeitimų",
- "Away" : "Atsitraukęs",
- "Do not disturb" : "Netrukdyti",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Neišvalyti",
"Today" : "Šiandien",
"This week" : "Šią savaitę",
"Online" : "Prisijungęs",
- "Invisible" : "Nematoma",
+ "Away" : "Atsitraukęs",
+ "Do not disturb" : "Netrukdyti",
+ "Invisible" : "Nematomas",
"Offline" : "Atsijungęs",
+ "Set status" : "Nustatyti būseną",
"There was an error saving the new status" : "Įrašant naują būseną, įvyko klaida",
"30 minutes" : "30 minučių",
"1 hour" : "1 valanda",
"4 hours" : "4 valandos",
+ "Busy" : "Užimtas laikas",
"Mute all notifications" : "Išjungti visus pranešimus",
- "Appear offline" : "Atrodyti atsijungusiu",
- "What's your status?" : "Kokia jūsų būsena?"
+ "Appear offline" : "Atrodyti atsijungusiu"
},
"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/user_status/l10n/lt_LT.json b/apps/user_status/l10n/lt_LT.json
index 37cc733d0a1..d1df46a90f2 100644
--- a/apps/user_status/l10n/lt_LT.json
+++ b/apps/user_status/l10n/lt_LT.json
@@ -1,37 +1,39 @@
{ "translations": {
"Recent statuses" : "Paskiausios būsenos",
+ "No recent status changes" : "Jokių paskiausių būsenos pasikeitimų",
"In a meeting" : "Susitikime",
"Commuting" : "Važinėju",
"Out sick" : "Sergu",
"Vacationing" : "Poilsiauju",
+ "Out of office" : "Ne darbo vietoje",
"Working remotely" : "Dirbu nuotoliniu būdu",
+ "In a call" : "Dalyvauju skambutyje",
"User status" : "Naudotojo būsena",
- "View profile" : "Rodyti profilį",
- "Clear status message after" : "Išvalyti būsenos žinutę po",
+ "Clear status after" : "Išvalyti būseną po",
"What is your status?" : "Kokia jūsų būsena?",
- "Set status" : "Nustatyti būseną",
+ "Predefined statuses" : "Iš anksto apibrėžtos būsenos",
+ "There was an error saving the status" : "Įrašant būseną, įvyko klaida",
+ "There was an error clearing the status" : "Išvalant būseną, įvyko klaida",
"Online status" : "Prisijungimo būsena",
"Status message" : "Būsenos žinutė",
+ "Your status was set automatically" : "Jūsų būsena buvo nustatyta automatiškai",
"Clear status message" : "Išvalyti būsenos žinutę",
"Set status message" : "Nustatyti būsenos žinutę",
- "There was an error saving the status" : "Įrašant būseną, įvyko klaida",
- "There was an error clearing the status" : "Išvalant būseną, įvyko klaida",
- "No recent status changes" : "Jokių paskiausių būsenos pasikeitimų",
- "Away" : "Atsitraukęs",
- "Do not disturb" : "Netrukdyti",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Neišvalyti",
"Today" : "Šiandien",
"This week" : "Šią savaitę",
"Online" : "Prisijungęs",
- "Invisible" : "Nematoma",
+ "Away" : "Atsitraukęs",
+ "Do not disturb" : "Netrukdyti",
+ "Invisible" : "Nematomas",
"Offline" : "Atsijungęs",
+ "Set status" : "Nustatyti būseną",
"There was an error saving the new status" : "Įrašant naują būseną, įvyko klaida",
"30 minutes" : "30 minučių",
"1 hour" : "1 valanda",
"4 hours" : "4 valandos",
+ "Busy" : "Užimtas laikas",
"Mute all notifications" : "Išjungti visus pranešimus",
- "Appear offline" : "Atrodyti atsijungusiu",
- "What's your status?" : "Kokia jūsų būsena?"
+ "Appear offline" : "Atrodyti atsijungusiu"
},"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/user_status/l10n/mk.js b/apps/user_status/l10n/mk.js
index ca6e5ae528d..64501b2f6df 100644
--- a/apps/user_status/l10n/mk.js
+++ b/apps/user_status/l10n/mk.js
@@ -2,39 +2,38 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Неодамнешни статуси",
+ "No recent status changes" : "Нема неодамнешна промена на статус",
"In a meeting" : "На состанок",
"Commuting" : "На пат",
"Out sick" : "На боледување",
"Vacationing" : "На одмор",
+ "Out of office" : "Надвор од канцеларија",
"Working remotely" : "Присутен од дома",
"In a call" : "Во разговор",
"User status" : "Статус на корисникот",
- "View profile" : "Прегледај профил",
- "Clear status message after" : "Тргни го статусот после",
+ "Clear status after" : "Тргни го статусот после",
"What is your status?" : "Кој е вашиот статус?",
- "Set status" : "Постави статус",
+ "There was an error saving the status" : "Грешка при зачувување на статус",
+ "There was an error clearing the status" : "Грешка при отстранување на статус",
"Online status" : "Присутен",
"Status message" : "Статус порака",
"Clear status message" : "Тргни ја статус пораката",
"Set status message" : "Постави статус порака",
- "There was an error saving the status" : "Грешка при зачувување на статус",
- "There was an error clearing the status" : "Грешка при отстранување на статус",
- "No recent status changes" : "Нема неодамнешна промена на статус",
- "Away" : "Неактивен",
- "Do not disturb" : "Не вознемирувај",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Не го тргај",
"Today" : "Денес",
"This week" : "Оваа недела",
"Online" : "Приклучен",
+ "Away" : "Неактивен",
+ "Do not disturb" : "Не вознемирувај",
"Invisible" : "Невидливо",
"Offline" : "Исклучен",
+ "Set status" : "Постави статус",
"There was an error saving the new status" : "Настана грешка при зачувување на нов статус",
"30 minutes" : "30 минути",
"1 hour" : "1 час",
"4 hours" : "4 часа",
+ "Busy" : "Зафатен",
"Mute all notifications" : "Занеми (Mute) ги сите известувања",
- "Appear offline" : "Прикажи исклучен",
- "What's your status?" : "Кој е вашиот статус?"
+ "Appear offline" : "Прикажи исклучен"
},
"nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;");
diff --git a/apps/user_status/l10n/mk.json b/apps/user_status/l10n/mk.json
index c1629cb8b51..393500ad5c5 100644
--- a/apps/user_status/l10n/mk.json
+++ b/apps/user_status/l10n/mk.json
@@ -1,38 +1,37 @@
{ "translations": {
"Recent statuses" : "Неодамнешни статуси",
+ "No recent status changes" : "Нема неодамнешна промена на статус",
"In a meeting" : "На состанок",
"Commuting" : "На пат",
"Out sick" : "На боледување",
"Vacationing" : "На одмор",
+ "Out of office" : "Надвор од канцеларија",
"Working remotely" : "Присутен од дома",
"In a call" : "Во разговор",
"User status" : "Статус на корисникот",
- "View profile" : "Прегледај профил",
- "Clear status message after" : "Тргни го статусот после",
+ "Clear status after" : "Тргни го статусот после",
"What is your status?" : "Кој е вашиот статус?",
- "Set status" : "Постави статус",
+ "There was an error saving the status" : "Грешка при зачувување на статус",
+ "There was an error clearing the status" : "Грешка при отстранување на статус",
"Online status" : "Присутен",
"Status message" : "Статус порака",
"Clear status message" : "Тргни ја статус пораката",
"Set status message" : "Постави статус порака",
- "There was an error saving the status" : "Грешка при зачувување на статус",
- "There was an error clearing the status" : "Грешка при отстранување на статус",
- "No recent status changes" : "Нема неодамнешна промена на статус",
- "Away" : "Неактивен",
- "Do not disturb" : "Не вознемирувај",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Не го тргај",
"Today" : "Денес",
"This week" : "Оваа недела",
"Online" : "Приклучен",
+ "Away" : "Неактивен",
+ "Do not disturb" : "Не вознемирувај",
"Invisible" : "Невидливо",
"Offline" : "Исклучен",
+ "Set status" : "Постави статус",
"There was an error saving the new status" : "Настана грешка при зачувување на нов статус",
"30 minutes" : "30 минути",
"1 hour" : "1 час",
"4 hours" : "4 часа",
+ "Busy" : "Зафатен",
"Mute all notifications" : "Занеми (Mute) ги сите известувања",
- "Appear offline" : "Прикажи исклучен",
- "What's your status?" : "Кој е вашиот статус?"
+ "Appear offline" : "Прикажи исклучен"
},"pluralForm" :"nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/nb.js b/apps/user_status/l10n/nb.js
index 78ae951ef19..f627aaa1e60 100644
--- a/apps/user_status/l10n/nb.js
+++ b/apps/user_status/l10n/nb.js
@@ -2,39 +2,49 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Nylige statuser",
+ "No recent status changes" : "Ingen nylige statusendringer",
"In a meeting" : "I et møte",
"Commuting" : "Pendler",
"Out sick" : "Syk",
"Vacationing" : "På ferie",
+ "Out of office" : "Fraværende",
"Working remotely" : "Jobber utenfra",
"In a call" : "I en samtale",
"User status" : "Brukerstatus",
- "View profile" : "Vis profil",
- "Clear status message after" : "Fjern statusmelding etter",
+ "Clear status after" : "Fjern status etter",
+ "Emoji for your status message" : "Emoji for statusmeldingene dine",
"What is your status?" : "Hva er din status?",
- "Set status" : "Velg status",
+ "Predefined statuses" : "Forhåndsdefinerte statuser",
+ "Previously set" : "Tidligere angitt",
+ "Reset status" : "Tilbakestill status",
+ "Reset status to \"{icon} {message}\"" : "Tilbakestill status til \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Tilbakestill status til \"{message}\"",
+ "Reset status to \"{icon}\"" : "Tilbakestill status til \"{icon}\"",
+ "There was an error saving the status" : "Det oppsto en feil ved lagring av status",
+ "There was an error clearing the status" : "Det oppsto en feil ved fjerning av status",
+ "There was an error reverting the status" : "Det oppstod en feil under tilbakestilling av statusen",
"Online status" : "Online-status",
"Status message" : "Statusmelding",
+ "Set absence period" : "Angi fraværsperiode",
+ "Set absence period and replacement" : "Angi fraværsperiode og erstatter",
+ "Your status was set automatically" : "Statusen din ble satt",
"Clear status message" : "Fjern statusmelding",
"Set status message" : "Velg statusmelding",
- "There was an error saving the status" : "Det oppstod en feil ved lagring av status",
- "There was an error clearing the status" : "Det oppstod en feil ved fjerning av status",
- "No recent status changes" : "Ingen nylige statusendringer",
- "Away" : "Borte",
- "Do not disturb" : "Ikke forstyrr",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Ikke fjern",
"Today" : "I dag",
"This week" : "Denne uken",
"Online" : "Pålogget",
+ "Away" : "Borte",
+ "Do not disturb" : "Ikke forstyrr",
"Invisible" : "Usynlig",
"Offline" : "Frakoblet",
- "There was an error saving the new status" : "Det oppstod en feil ved lagring av ny status",
+ "Set status" : "Velg status",
+ "There was an error saving the new status" : "Det oppsto en feil ved lagring av ny status",
"30 minutes" : "30 minutter",
"1 hour" : "1 time",
"4 hours" : "4 timer",
+ "Busy" : "Opptatt",
"Mute all notifications" : "Demp alle varslinger",
- "Appear offline" : "Vis som frakoblet",
- "What's your status?" : "Hva er din status?"
+ "Appear offline" : "Vis som frakoblet"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/user_status/l10n/nb.json b/apps/user_status/l10n/nb.json
index 0e2d5cb3824..4e47d91a20b 100644
--- a/apps/user_status/l10n/nb.json
+++ b/apps/user_status/l10n/nb.json
@@ -1,38 +1,48 @@
{ "translations": {
"Recent statuses" : "Nylige statuser",
+ "No recent status changes" : "Ingen nylige statusendringer",
"In a meeting" : "I et møte",
"Commuting" : "Pendler",
"Out sick" : "Syk",
"Vacationing" : "På ferie",
+ "Out of office" : "Fraværende",
"Working remotely" : "Jobber utenfra",
"In a call" : "I en samtale",
"User status" : "Brukerstatus",
- "View profile" : "Vis profil",
- "Clear status message after" : "Fjern statusmelding etter",
+ "Clear status after" : "Fjern status etter",
+ "Emoji for your status message" : "Emoji for statusmeldingene dine",
"What is your status?" : "Hva er din status?",
- "Set status" : "Velg status",
+ "Predefined statuses" : "Forhåndsdefinerte statuser",
+ "Previously set" : "Tidligere angitt",
+ "Reset status" : "Tilbakestill status",
+ "Reset status to \"{icon} {message}\"" : "Tilbakestill status til \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Tilbakestill status til \"{message}\"",
+ "Reset status to \"{icon}\"" : "Tilbakestill status til \"{icon}\"",
+ "There was an error saving the status" : "Det oppsto en feil ved lagring av status",
+ "There was an error clearing the status" : "Det oppsto en feil ved fjerning av status",
+ "There was an error reverting the status" : "Det oppstod en feil under tilbakestilling av statusen",
"Online status" : "Online-status",
"Status message" : "Statusmelding",
+ "Set absence period" : "Angi fraværsperiode",
+ "Set absence period and replacement" : "Angi fraværsperiode og erstatter",
+ "Your status was set automatically" : "Statusen din ble satt",
"Clear status message" : "Fjern statusmelding",
"Set status message" : "Velg statusmelding",
- "There was an error saving the status" : "Det oppstod en feil ved lagring av status",
- "There was an error clearing the status" : "Det oppstod en feil ved fjerning av status",
- "No recent status changes" : "Ingen nylige statusendringer",
- "Away" : "Borte",
- "Do not disturb" : "Ikke forstyrr",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Ikke fjern",
"Today" : "I dag",
"This week" : "Denne uken",
"Online" : "Pålogget",
+ "Away" : "Borte",
+ "Do not disturb" : "Ikke forstyrr",
"Invisible" : "Usynlig",
"Offline" : "Frakoblet",
- "There was an error saving the new status" : "Det oppstod en feil ved lagring av ny status",
+ "Set status" : "Velg status",
+ "There was an error saving the new status" : "Det oppsto en feil ved lagring av ny status",
"30 minutes" : "30 minutter",
"1 hour" : "1 time",
"4 hours" : "4 timer",
+ "Busy" : "Opptatt",
"Mute all notifications" : "Demp alle varslinger",
- "Appear offline" : "Vis som frakoblet",
- "What's your status?" : "Hva er din status?"
+ "Appear offline" : "Vis som frakoblet"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/nl.js b/apps/user_status/l10n/nl.js
index 7861577cbbc..745507c57c0 100644
--- a/apps/user_status/l10n/nl.js
+++ b/apps/user_status/l10n/nl.js
@@ -2,39 +2,50 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Recente statussen",
+ "No recent status changes" : "Geen recente statuswijzigingen",
"In a meeting" : "In een vergadering",
"Commuting" : "Woon-werk",
"Out sick" : "Ziek",
"Vacationing" : "Op vakantie",
+ "Out of office" : "Niet op kantoor",
"Working remotely" : "Thuiswerken",
"In a call" : "In gesprek",
+ "Be right back" : "Zo weer terug",
"User status" : "Gebruikersstatus",
- "View profile" : "Bekijk profiel",
- "Clear status message after" : "Statusbericht wissen na",
+ "Clear status after" : "Maak de status leeg na",
+ "Emoji for your status message" : "Emoji voor je statusbericht",
"What is your status?" : "Wat is jouw status?",
- "Set status" : "Instellen status",
- "Online status" : "Online status",
- "Status message" : "Statusbericht",
- "Clear status message" : "Opruimen statusbericht",
- "Set status message" : "Instellen statusbericht",
+ "Predefined statuses" : "Voorgedefinieerde statussen",
+ "Previously set" : "Eerder ingesteld",
+ "Reset status" : "Reset status",
+ "Reset status to \"{icon} {message}\"" : "Status terugzetten naar \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Status terugzetten naar \"{message}\"",
+ "Reset status to \"{icon}\"" : "Status terugzetten naar \"{icon}\"",
"There was an error saving the status" : "Er is een fout opgetreden bij het bewaren van de status",
"There was an error clearing the status" : "Er is een fout opgetreden bij het leegmaken van de status",
- "No recent status changes" : "Geen recente statuswijzigingen",
- "Away" : "Afwezig",
- "Do not disturb" : "Niet storen",
- "{status}, {timestamp}" : "{status}, {timestamp}",
+ "There was an error reverting the status" : "Er was een fout bij het terugdraaien van de status",
+ "Online status" : "Online status",
+ "Status message" : "Statusbericht",
+ "Set absence period" : "Afwezigheidsperiode instellen",
+ "Set absence period and replacement" : "Afwezigheidsperiode en vervanging instellen",
+ "Your status was set automatically" : "Uw status is automatisch ingesteld",
+ "Clear status message" : "Statusbericht wissen",
+ "Set status message" : "Statusbericht instellen",
"Don't clear" : "Niet schoonmaken",
"Today" : "Vandaag",
"This week" : "Deze week",
"Online" : "Online",
+ "Away" : "Afwezig",
+ "Do not disturb" : "Niet storen",
"Invisible" : "Verborgen",
"Offline" : "Off-line",
+ "Set status" : "Status instellen",
"There was an error saving the new status" : "Er is een fout opgetreden bij het bewaren van de nieuwe status",
"30 minutes" : "30 minuten",
"1 hour" : "1 uur",
"4 hours" : "4 uur",
+ "Busy" : "Bezet",
"Mute all notifications" : "Onderdruk alle meldingen",
- "Appear offline" : "Toon afwezig",
- "What's your status?" : "Wat is je status?"
+ "Appear offline" : "Toon afwezig"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/user_status/l10n/nl.json b/apps/user_status/l10n/nl.json
index 3c1adb39f68..643cf4c27fb 100644
--- a/apps/user_status/l10n/nl.json
+++ b/apps/user_status/l10n/nl.json
@@ -1,38 +1,49 @@
{ "translations": {
"Recent statuses" : "Recente statussen",
+ "No recent status changes" : "Geen recente statuswijzigingen",
"In a meeting" : "In een vergadering",
"Commuting" : "Woon-werk",
"Out sick" : "Ziek",
"Vacationing" : "Op vakantie",
+ "Out of office" : "Niet op kantoor",
"Working remotely" : "Thuiswerken",
"In a call" : "In gesprek",
+ "Be right back" : "Zo weer terug",
"User status" : "Gebruikersstatus",
- "View profile" : "Bekijk profiel",
- "Clear status message after" : "Statusbericht wissen na",
+ "Clear status after" : "Maak de status leeg na",
+ "Emoji for your status message" : "Emoji voor je statusbericht",
"What is your status?" : "Wat is jouw status?",
- "Set status" : "Instellen status",
- "Online status" : "Online status",
- "Status message" : "Statusbericht",
- "Clear status message" : "Opruimen statusbericht",
- "Set status message" : "Instellen statusbericht",
+ "Predefined statuses" : "Voorgedefinieerde statussen",
+ "Previously set" : "Eerder ingesteld",
+ "Reset status" : "Reset status",
+ "Reset status to \"{icon} {message}\"" : "Status terugzetten naar \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Status terugzetten naar \"{message}\"",
+ "Reset status to \"{icon}\"" : "Status terugzetten naar \"{icon}\"",
"There was an error saving the status" : "Er is een fout opgetreden bij het bewaren van de status",
"There was an error clearing the status" : "Er is een fout opgetreden bij het leegmaken van de status",
- "No recent status changes" : "Geen recente statuswijzigingen",
- "Away" : "Afwezig",
- "Do not disturb" : "Niet storen",
- "{status}, {timestamp}" : "{status}, {timestamp}",
+ "There was an error reverting the status" : "Er was een fout bij het terugdraaien van de status",
+ "Online status" : "Online status",
+ "Status message" : "Statusbericht",
+ "Set absence period" : "Afwezigheidsperiode instellen",
+ "Set absence period and replacement" : "Afwezigheidsperiode en vervanging instellen",
+ "Your status was set automatically" : "Uw status is automatisch ingesteld",
+ "Clear status message" : "Statusbericht wissen",
+ "Set status message" : "Statusbericht instellen",
"Don't clear" : "Niet schoonmaken",
"Today" : "Vandaag",
"This week" : "Deze week",
"Online" : "Online",
+ "Away" : "Afwezig",
+ "Do not disturb" : "Niet storen",
"Invisible" : "Verborgen",
"Offline" : "Off-line",
+ "Set status" : "Status instellen",
"There was an error saving the new status" : "Er is een fout opgetreden bij het bewaren van de nieuwe status",
"30 minutes" : "30 minuten",
"1 hour" : "1 uur",
"4 hours" : "4 uur",
+ "Busy" : "Bezet",
"Mute all notifications" : "Onderdruk alle meldingen",
- "Appear offline" : "Toon afwezig",
- "What's your status?" : "Wat is je status?"
+ "Appear offline" : "Toon afwezig"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/oc.js b/apps/user_status/l10n/oc.js
index dead048130f..bbd00e9e551 100644
--- a/apps/user_status/l10n/oc.js
+++ b/apps/user_status/l10n/oc.js
@@ -2,39 +2,38 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Estats recents",
+ "No recent status changes" : "Cap de cambiament recent d’estat",
"In a meeting" : "En reünion",
"Commuting" : "En comunicacion",
"Out sick" : "Malaut",
"Vacationing" : "En vacanças",
+ "Out of office" : "Fòra del burèu",
"Working remotely" : "En teletrabalh",
"In a call" : "Al telefòn",
"User status" : "Estat utilizaire",
- "View profile" : "Veire perfil",
- "Clear status message after" : "Escafar lo messatge d’estat aprèp",
+ "Clear status after" : "Escafar l’estat aprèp",
"What is your status?" : "Quin es vòstre estat ?",
- "Set status" : "Definir estat",
+ "There was an error saving the status" : "Error en enregistrant l’estat",
+ "There was an error clearing the status" : "Error en escafant l’estat",
"Online status" : "Estat en linha",
"Status message" : "Messatge d’estat",
"Clear status message" : "Escafar messatge d’estat",
"Set status message" : "Definir messatge d’estat",
- "There was an error saving the status" : "Error en enregistrant l’estat",
- "There was an error clearing the status" : "Error en escafant l’estat",
- "No recent status changes" : "Cap de cambiament recent d’estat",
- "Away" : "Absent",
- "Do not disturb" : "Me desrengar pas",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Escafar pas",
"Today" : "Uèi",
"This week" : "Aquesta setmana",
"Online" : "En linha",
+ "Away" : "Absent",
+ "Do not disturb" : "Me desrengar pas",
"Invisible" : "Invisible",
"Offline" : "Fòra linha",
+ "Set status" : "Definir estat",
"There was an error saving the new status" : "Error en enregistrant l’estat novèl",
"30 minutes" : "30 minutas",
"1 hour" : "1 ora",
"4 hours" : "4 oras",
+ "Busy" : "Ocupat",
"Mute all notifications" : "Amudir totas las notificacions",
- "Appear offline" : "Aparéisser fòra linha",
- "What's your status?" : "Quin es vòstre estat ?"
+ "Appear offline" : "Aparéisser fòra linha"
},
"nplurals=2; plural=(n > 1);");
diff --git a/apps/user_status/l10n/oc.json b/apps/user_status/l10n/oc.json
index 7a8ad9554f7..388df700e75 100644
--- a/apps/user_status/l10n/oc.json
+++ b/apps/user_status/l10n/oc.json
@@ -1,38 +1,37 @@
{ "translations": {
"Recent statuses" : "Estats recents",
+ "No recent status changes" : "Cap de cambiament recent d’estat",
"In a meeting" : "En reünion",
"Commuting" : "En comunicacion",
"Out sick" : "Malaut",
"Vacationing" : "En vacanças",
+ "Out of office" : "Fòra del burèu",
"Working remotely" : "En teletrabalh",
"In a call" : "Al telefòn",
"User status" : "Estat utilizaire",
- "View profile" : "Veire perfil",
- "Clear status message after" : "Escafar lo messatge d’estat aprèp",
+ "Clear status after" : "Escafar l’estat aprèp",
"What is your status?" : "Quin es vòstre estat ?",
- "Set status" : "Definir estat",
+ "There was an error saving the status" : "Error en enregistrant l’estat",
+ "There was an error clearing the status" : "Error en escafant l’estat",
"Online status" : "Estat en linha",
"Status message" : "Messatge d’estat",
"Clear status message" : "Escafar messatge d’estat",
"Set status message" : "Definir messatge d’estat",
- "There was an error saving the status" : "Error en enregistrant l’estat",
- "There was an error clearing the status" : "Error en escafant l’estat",
- "No recent status changes" : "Cap de cambiament recent d’estat",
- "Away" : "Absent",
- "Do not disturb" : "Me desrengar pas",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Escafar pas",
"Today" : "Uèi",
"This week" : "Aquesta setmana",
"Online" : "En linha",
+ "Away" : "Absent",
+ "Do not disturb" : "Me desrengar pas",
"Invisible" : "Invisible",
"Offline" : "Fòra linha",
+ "Set status" : "Definir estat",
"There was an error saving the new status" : "Error en enregistrant l’estat novèl",
"30 minutes" : "30 minutas",
"1 hour" : "1 ora",
"4 hours" : "4 oras",
+ "Busy" : "Ocupat",
"Mute all notifications" : "Amudir totas las notificacions",
- "Appear offline" : "Aparéisser fòra linha",
- "What's your status?" : "Quin es vòstre estat ?"
+ "Appear offline" : "Aparéisser fòra linha"
},"pluralForm" :"nplurals=2; plural=(n > 1);"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/pl.js b/apps/user_status/l10n/pl.js
index e77f95de04e..c25c92e27e1 100644
--- a/apps/user_status/l10n/pl.js
+++ b/apps/user_status/l10n/pl.js
@@ -2,39 +2,50 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Najnowsze statusy",
+ "No recent status changes" : "Brak ostatnich zmian statusu",
"In a meeting" : "Na spotkaniu",
"Commuting" : "W drodze",
"Out sick" : "Chory",
"Vacationing" : "Na wakacjach",
+ "Out of office" : "Biuro nie funkcjonuje",
"Working remotely" : "Praca zdalna",
"In a call" : "Rozmawia",
+ "Be right back" : "Zaraz wracam",
"User status" : "Status użytkownika",
- "View profile" : "Zobacz profil",
- "Clear status message after" : "Wyczyść komunikat statusu po",
+ "Clear status after" : "Wyczyść status po",
+ "Emoji for your status message" : "Emoji dla komunikatu o statusie",
"What is your status?" : "Jaki jest Twój status?",
- "Set status" : "Ustaw status",
+ "Predefined statuses" : "Predefiniowane statusy",
+ "Previously set" : "Ustawione wcześniej",
+ "Reset status" : "Zresetuj status",
+ "Reset status to \"{icon} {message}\"" : "Zresetuj status do \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Zresetuj status do \"{message}\"",
+ "Reset status to \"{icon}\"" : "Zresetuj status do \"{icon}\"",
+ "There was an error saving the status" : "Wystąpił błąd podczas zapisywania statusu",
+ "There was an error clearing the status" : "Wystąpił błąd podczas usuwania statusu",
+ "There was an error reverting the status" : "Podczas przywracania statusu wystąpił błąd",
"Online status" : "Status online",
"Status message" : "Komunikat statusu",
+ "Set absence period" : "Ustaw okres nieobecności",
+ "Set absence period and replacement" : "Ustaw okres nieobecności i zastępstwo",
+ "Your status was set automatically" : "Twój status został ustawiony automatycznie",
"Clear status message" : "Wyczyść komunikat statusu",
"Set status message" : "Ustaw komunikat statusu",
- "There was an error saving the status" : "Wystąpił błąd podczas zapisywania statusu",
- "There was an error clearing the status" : "Wystąpił błąd podczas usuwania statusu",
- "No recent status changes" : "Brak ostatnich zmian statusu",
- "Away" : "Bezczynny",
- "Do not disturb" : "Nie przeszkadzać",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Nie czyść",
"Today" : "Dzisiaj",
"This week" : "W tym tygodniu",
"Online" : "Online",
+ "Away" : "Bezczynny",
+ "Do not disturb" : "Nie przeszkadzać",
"Invisible" : "Niewidoczny",
"Offline" : "Offline",
+ "Set status" : "Ustaw status",
"There was an error saving the new status" : "Wystąpił błąd podczas zapisywania nowego statusu",
"30 minutes" : "30 minut",
"1 hour" : "1 godzina",
"4 hours" : "4 godziny",
+ "Busy" : "Brak dostępności",
"Mute all notifications" : "Wycisz wszystkie powiadomienia",
- "Appear offline" : "Widnieje jako offline",
- "What's your status?" : "Jaki jest Twój status?"
+ "Appear offline" : "Widnieje jako offline"
},
"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/user_status/l10n/pl.json b/apps/user_status/l10n/pl.json
index 528ff7d9f9c..48079696e54 100644
--- a/apps/user_status/l10n/pl.json
+++ b/apps/user_status/l10n/pl.json
@@ -1,38 +1,49 @@
{ "translations": {
"Recent statuses" : "Najnowsze statusy",
+ "No recent status changes" : "Brak ostatnich zmian statusu",
"In a meeting" : "Na spotkaniu",
"Commuting" : "W drodze",
"Out sick" : "Chory",
"Vacationing" : "Na wakacjach",
+ "Out of office" : "Biuro nie funkcjonuje",
"Working remotely" : "Praca zdalna",
"In a call" : "Rozmawia",
+ "Be right back" : "Zaraz wracam",
"User status" : "Status użytkownika",
- "View profile" : "Zobacz profil",
- "Clear status message after" : "Wyczyść komunikat statusu po",
+ "Clear status after" : "Wyczyść status po",
+ "Emoji for your status message" : "Emoji dla komunikatu o statusie",
"What is your status?" : "Jaki jest Twój status?",
- "Set status" : "Ustaw status",
+ "Predefined statuses" : "Predefiniowane statusy",
+ "Previously set" : "Ustawione wcześniej",
+ "Reset status" : "Zresetuj status",
+ "Reset status to \"{icon} {message}\"" : "Zresetuj status do \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Zresetuj status do \"{message}\"",
+ "Reset status to \"{icon}\"" : "Zresetuj status do \"{icon}\"",
+ "There was an error saving the status" : "Wystąpił błąd podczas zapisywania statusu",
+ "There was an error clearing the status" : "Wystąpił błąd podczas usuwania statusu",
+ "There was an error reverting the status" : "Podczas przywracania statusu wystąpił błąd",
"Online status" : "Status online",
"Status message" : "Komunikat statusu",
+ "Set absence period" : "Ustaw okres nieobecności",
+ "Set absence period and replacement" : "Ustaw okres nieobecności i zastępstwo",
+ "Your status was set automatically" : "Twój status został ustawiony automatycznie",
"Clear status message" : "Wyczyść komunikat statusu",
"Set status message" : "Ustaw komunikat statusu",
- "There was an error saving the status" : "Wystąpił błąd podczas zapisywania statusu",
- "There was an error clearing the status" : "Wystąpił błąd podczas usuwania statusu",
- "No recent status changes" : "Brak ostatnich zmian statusu",
- "Away" : "Bezczynny",
- "Do not disturb" : "Nie przeszkadzać",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Nie czyść",
"Today" : "Dzisiaj",
"This week" : "W tym tygodniu",
"Online" : "Online",
+ "Away" : "Bezczynny",
+ "Do not disturb" : "Nie przeszkadzać",
"Invisible" : "Niewidoczny",
"Offline" : "Offline",
+ "Set status" : "Ustaw status",
"There was an error saving the new status" : "Wystąpił błąd podczas zapisywania nowego statusu",
"30 minutes" : "30 minut",
"1 hour" : "1 godzina",
"4 hours" : "4 godziny",
+ "Busy" : "Brak dostępności",
"Mute all notifications" : "Wycisz wszystkie powiadomienia",
- "Appear offline" : "Widnieje jako offline",
- "What's your status?" : "Jaki jest Twój status?"
+ "Appear offline" : "Widnieje jako offline"
},"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/user_status/l10n/pt_BR.js b/apps/user_status/l10n/pt_BR.js
index a4b95c86569..3844bd746f7 100644
--- a/apps/user_status/l10n/pt_BR.js
+++ b/apps/user_status/l10n/pt_BR.js
@@ -2,39 +2,50 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Status recentes",
+ "No recent status changes" : "Sem alterações de status recentes",
"In a meeting" : "Em reunião",
"Commuting" : "Em trânsito",
"Out sick" : "Doente",
"Vacationing" : "Férias",
+ "Out of office" : "Fora do escritório",
"Working remotely" : "Em trabalho remoto",
- "In a call" : "Numa chamada",
+ "In a call" : "Em uma chamada",
+ "Be right back" : "Volto já",
"User status" : "Status do usuário",
- "View profile" : "Visualizar perfil",
- "Clear status message after" : "Limpar status do usuário após",
+ "Clear status after" : "Limpar status após",
+ "Emoji for your status message" : "Emoji para sua mensagem de status",
"What is your status?" : "Qual é o seu status?",
- "Set status" : "Definir status",
- "Online status" : "Status online",
+ "Predefined statuses" : "Status predefinidos",
+ "Previously set" : "Definido anteriormente",
+ "Reset status" : "Redefinir status",
+ "Reset status to \"{icon} {message}\"" : "Redefinir status para \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Redefinir status para \"{message}\"",
+ "Reset status to \"{icon}\"" : "Redefinir status para \"{icon}\"",
+ "There was an error saving the status" : "Ocorreu um erro ao salvar o status",
+ "There was an error clearing the status" : "Ocorreu um erro ao limpar o status",
+ "There was an error reverting the status" : "Ocorreu um erro ao reverter o status",
+ "Online status" : "Status on-line",
"Status message" : "Mensagem de status",
+ "Set absence period" : "Definir período de ausência",
+ "Set absence period and replacement" : "Definir período de ausência e substituição",
+ "Your status was set automatically" : "Seu status foi definido automaticamente",
"Clear status message" : "Limpar mensagem de status",
"Set status message" : "Definir mensagem de status",
- "There was an error saving the status" : "Ocorreu um erro ao salvar o status",
- "There was an error clearing the status" : "Ocorreu um erro ao limpar o status",
- "No recent status changes" : "Sem alterações de status recentes",
- "Away" : "Fora",
- "Do not disturb" : "Não perturbe",
- "{status}, {timestamp}" : "{status}, {timestamp}",
- "Don't clear" : "Não limpar",
+ "Don't clear" : "Não limpe",
"Today" : "Hoje",
"This week" : "Esta semana",
- "Online" : "Online",
+ "Online" : "On-line",
+ "Away" : "Fora",
+ "Do not disturb" : "Não perturbe",
"Invisible" : "Invisível",
- "Offline" : "Offline",
+ "Offline" : "Off-line",
+ "Set status" : "Definir status",
"There was an error saving the new status" : "Ocorreu um erro ao salvar o novo status",
"30 minutes" : "30 minutos",
"1 hour" : "1 hora",
"4 hours" : "4 horas",
+ "Busy" : "Ocupado",
"Mute all notifications" : "Silenciar todas as notificações",
- "Appear offline" : "Aparecer offline",
- "What's your status?" : "Qual é o seu status?"
+ "Appear offline" : "Aparecer off-line"
},
-"nplurals=2; plural=(n > 1);");
+"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/user_status/l10n/pt_BR.json b/apps/user_status/l10n/pt_BR.json
index 4c73045cfce..e596a39e2bf 100644
--- a/apps/user_status/l10n/pt_BR.json
+++ b/apps/user_status/l10n/pt_BR.json
@@ -1,38 +1,49 @@
{ "translations": {
"Recent statuses" : "Status recentes",
+ "No recent status changes" : "Sem alterações de status recentes",
"In a meeting" : "Em reunião",
"Commuting" : "Em trânsito",
"Out sick" : "Doente",
"Vacationing" : "Férias",
+ "Out of office" : "Fora do escritório",
"Working remotely" : "Em trabalho remoto",
- "In a call" : "Numa chamada",
+ "In a call" : "Em uma chamada",
+ "Be right back" : "Volto já",
"User status" : "Status do usuário",
- "View profile" : "Visualizar perfil",
- "Clear status message after" : "Limpar status do usuário após",
+ "Clear status after" : "Limpar status após",
+ "Emoji for your status message" : "Emoji para sua mensagem de status",
"What is your status?" : "Qual é o seu status?",
- "Set status" : "Definir status",
- "Online status" : "Status online",
+ "Predefined statuses" : "Status predefinidos",
+ "Previously set" : "Definido anteriormente",
+ "Reset status" : "Redefinir status",
+ "Reset status to \"{icon} {message}\"" : "Redefinir status para \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Redefinir status para \"{message}\"",
+ "Reset status to \"{icon}\"" : "Redefinir status para \"{icon}\"",
+ "There was an error saving the status" : "Ocorreu um erro ao salvar o status",
+ "There was an error clearing the status" : "Ocorreu um erro ao limpar o status",
+ "There was an error reverting the status" : "Ocorreu um erro ao reverter o status",
+ "Online status" : "Status on-line",
"Status message" : "Mensagem de status",
+ "Set absence period" : "Definir período de ausência",
+ "Set absence period and replacement" : "Definir período de ausência e substituição",
+ "Your status was set automatically" : "Seu status foi definido automaticamente",
"Clear status message" : "Limpar mensagem de status",
"Set status message" : "Definir mensagem de status",
- "There was an error saving the status" : "Ocorreu um erro ao salvar o status",
- "There was an error clearing the status" : "Ocorreu um erro ao limpar o status",
- "No recent status changes" : "Sem alterações de status recentes",
- "Away" : "Fora",
- "Do not disturb" : "Não perturbe",
- "{status}, {timestamp}" : "{status}, {timestamp}",
- "Don't clear" : "Não limpar",
+ "Don't clear" : "Não limpe",
"Today" : "Hoje",
"This week" : "Esta semana",
- "Online" : "Online",
+ "Online" : "On-line",
+ "Away" : "Fora",
+ "Do not disturb" : "Não perturbe",
"Invisible" : "Invisível",
- "Offline" : "Offline",
+ "Offline" : "Off-line",
+ "Set status" : "Definir status",
"There was an error saving the new status" : "Ocorreu um erro ao salvar o novo status",
"30 minutes" : "30 minutos",
"1 hour" : "1 hora",
"4 hours" : "4 horas",
+ "Busy" : "Ocupado",
"Mute all notifications" : "Silenciar todas as notificações",
- "Appear offline" : "Aparecer offline",
- "What's your status?" : "Qual é o seu status?"
-},"pluralForm" :"nplurals=2; plural=(n > 1);"
+ "Appear offline" : "Aparecer off-line"
+},"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/user_status/l10n/pt_PT.js b/apps/user_status/l10n/pt_PT.js
index 63bce5917ae..e6b64625619 100644
--- a/apps/user_status/l10n/pt_PT.js
+++ b/apps/user_status/l10n/pt_PT.js
@@ -2,39 +2,38 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Estados recentes",
+ "No recent status changes" : "Sem alterações de estado recentes",
"In a meeting" : "Numa reunião",
"Commuting" : "Em trânsito",
"Out sick" : "Doente",
"Vacationing" : "Férias",
+ "Out of office" : "Fora do escritório",
"Working remotely" : "A trabalhar à distância",
"In a call" : "Numa chamada",
"User status" : "Estado do utilizador",
- "View profile" : "Visualizar perfil",
- "Clear status message after" : "Limpar mensagem de estado após",
+ "Clear status after" : "Limpar mensagem de estado após",
"What is your status?" : "Qual é o seu estado?",
- "Set status" : "Definir estado",
+ "There was an error saving the status" : "Ocorreu um erro ao guardar o estado",
+ "There was an error clearing the status" : "Ocorreu um erro ao apagar o estado",
"Online status" : "Estado online",
"Status message" : "Mensagem de estado",
"Clear status message" : "Limpar mensagem de estado",
"Set status message" : "Definir mensagem de estado",
- "There was an error saving the status" : "Ocorreu um erro ao guardar o estado",
- "There was an error clearing the status" : "Ocorreu um erro ao apagar o estado",
- "No recent status changes" : "Sem alterações de estado recentes",
- "Away" : "Ausente",
- "Do not disturb" : "Não incomodar",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Não apagar",
"Today" : "Hoje",
"This week" : "Esta semana",
"Online" : "Online",
+ "Away" : "Ausente",
+ "Do not disturb" : "Não incomodar",
"Invisible" : "Invisível ",
"Offline" : "Offline",
+ "Set status" : "Definir estado",
"There was an error saving the new status" : "Ocorreu um erro ao guardar o novo estado",
"30 minutes" : "30 minutos",
"1 hour" : "1 hora",
"4 hours" : "4 horas",
+ "Busy" : "Ocupado",
"Mute all notifications" : "Desativar todas as notificações",
- "Appear offline" : "Aparecer offline",
- "What's your status?" : "Qual é o seu estado?"
+ "Appear offline" : "Aparecer offline"
},
-"nplurals=2; plural=(n != 1);");
+"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/user_status/l10n/pt_PT.json b/apps/user_status/l10n/pt_PT.json
index 243d1a4512b..17762a3db45 100644
--- a/apps/user_status/l10n/pt_PT.json
+++ b/apps/user_status/l10n/pt_PT.json
@@ -1,38 +1,37 @@
{ "translations": {
"Recent statuses" : "Estados recentes",
+ "No recent status changes" : "Sem alterações de estado recentes",
"In a meeting" : "Numa reunião",
"Commuting" : "Em trânsito",
"Out sick" : "Doente",
"Vacationing" : "Férias",
+ "Out of office" : "Fora do escritório",
"Working remotely" : "A trabalhar à distância",
"In a call" : "Numa chamada",
"User status" : "Estado do utilizador",
- "View profile" : "Visualizar perfil",
- "Clear status message after" : "Limpar mensagem de estado após",
+ "Clear status after" : "Limpar mensagem de estado após",
"What is your status?" : "Qual é o seu estado?",
- "Set status" : "Definir estado",
+ "There was an error saving the status" : "Ocorreu um erro ao guardar o estado",
+ "There was an error clearing the status" : "Ocorreu um erro ao apagar o estado",
"Online status" : "Estado online",
"Status message" : "Mensagem de estado",
"Clear status message" : "Limpar mensagem de estado",
"Set status message" : "Definir mensagem de estado",
- "There was an error saving the status" : "Ocorreu um erro ao guardar o estado",
- "There was an error clearing the status" : "Ocorreu um erro ao apagar o estado",
- "No recent status changes" : "Sem alterações de estado recentes",
- "Away" : "Ausente",
- "Do not disturb" : "Não incomodar",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Não apagar",
"Today" : "Hoje",
"This week" : "Esta semana",
"Online" : "Online",
+ "Away" : "Ausente",
+ "Do not disturb" : "Não incomodar",
"Invisible" : "Invisível ",
"Offline" : "Offline",
+ "Set status" : "Definir estado",
"There was an error saving the new status" : "Ocorreu um erro ao guardar o novo estado",
"30 minutes" : "30 minutos",
"1 hour" : "1 hora",
"4 hours" : "4 horas",
+ "Busy" : "Ocupado",
"Mute all notifications" : "Desativar todas as notificações",
- "Appear offline" : "Aparecer offline",
- "What's your status?" : "Qual é o seu estado?"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
+ "Appear offline" : "Aparecer offline"
+},"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/user_status/l10n/ro.js b/apps/user_status/l10n/ro.js
index 444a7badebc..3214bdf6d73 100644
--- a/apps/user_status/l10n/ro.js
+++ b/apps/user_status/l10n/ro.js
@@ -1,25 +1,48 @@
OC.L10N.register(
"user_status",
{
- "Clear status message after" : "Șterge mesajul de stare după",
+ "Recent statuses" : "Statusuri recente",
+ "No recent status changes" : "Nu există modificări recente ale statutului",
+ "In a meeting" : "În cadrul unei întâlniri",
+ "Commuting" : "În deplasare",
+ "Out sick" : "Bolnav",
+ "Vacationing" : "În vacanță",
+ "Out of office" : "În afara serviciului",
+ "Working remotely" : "Lucru la distanță",
+ "In a call" : "Într-un apel",
+ "User status" : "Statusul utilizatorului",
+ "Clear status after" : "Șterge statusul după",
+ "Emoji for your status message" : "Emoji pentru mesajul de status",
"What is your status?" : "Care este statusul dumneavoastră?",
- "Set status" : "Setează status",
+ "Predefined statuses" : "Stări predefinite",
+ "Previously set" : "Setat anterior",
+ "Reset status" : "Resetează starea",
+ "Reset status to \"{icon} {message}\"" : "Resetează statusul la \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Resetează statusul la \"{message}\"",
+ "Reset status to \"{icon}\"" : "Resetează statusul la \"{icon}\"",
+ "There was an error saving the status" : "S-a produs o eroare la salvarea stării",
+ "There was an error clearing the status" : "S-a produs o eroare de ștergere a statutului",
+ "There was an error reverting the status" : "Eroare la revenirea la statusul anterior",
"Online status" : "Status online",
"Status message" : "Mesaj de status",
+ "Your status was set automatically" : "Statusul a fost setat automat",
"Clear status message" : "Șterge mesajul de stare",
"Set status message" : "Setează mesajul de status",
- "Away" : "Plecat",
- "Do not disturb" : "Nu deranja",
"Don't clear" : "Nu curăța",
"Today" : "Azi",
"This week" : "Săptămâna asta",
"Online" : "Online",
+ "Away" : "Plecat",
+ "Do not disturb" : "Nu deranja",
"Invisible" : "Invizibil",
+ "Offline" : "Offline",
+ "Set status" : "Setează status",
+ "There was an error saving the new status" : "S-a produs o eroare de salvare a noului status",
"30 minutes" : "30 minute",
"1 hour" : "1 oră",
"4 hours" : "4 ore",
+ "Busy" : "Ocupat",
"Mute all notifications" : "Dezactivați toate notificările",
- "Appear offline" : "Apari deconectat",
- "What's your status?" : "Care este statusul tău?"
+ "Appear offline" : "Apari deconectat"
},
"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));");
diff --git a/apps/user_status/l10n/ro.json b/apps/user_status/l10n/ro.json
index 3b4c2630f74..292a2aaac70 100644
--- a/apps/user_status/l10n/ro.json
+++ b/apps/user_status/l10n/ro.json
@@ -1,23 +1,46 @@
{ "translations": {
- "Clear status message after" : "Șterge mesajul de stare după",
+ "Recent statuses" : "Statusuri recente",
+ "No recent status changes" : "Nu există modificări recente ale statutului",
+ "In a meeting" : "În cadrul unei întâlniri",
+ "Commuting" : "În deplasare",
+ "Out sick" : "Bolnav",
+ "Vacationing" : "În vacanță",
+ "Out of office" : "În afara serviciului",
+ "Working remotely" : "Lucru la distanță",
+ "In a call" : "Într-un apel",
+ "User status" : "Statusul utilizatorului",
+ "Clear status after" : "Șterge statusul după",
+ "Emoji for your status message" : "Emoji pentru mesajul de status",
"What is your status?" : "Care este statusul dumneavoastră?",
- "Set status" : "Setează status",
+ "Predefined statuses" : "Stări predefinite",
+ "Previously set" : "Setat anterior",
+ "Reset status" : "Resetează starea",
+ "Reset status to \"{icon} {message}\"" : "Resetează statusul la \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Resetează statusul la \"{message}\"",
+ "Reset status to \"{icon}\"" : "Resetează statusul la \"{icon}\"",
+ "There was an error saving the status" : "S-a produs o eroare la salvarea stării",
+ "There was an error clearing the status" : "S-a produs o eroare de ștergere a statutului",
+ "There was an error reverting the status" : "Eroare la revenirea la statusul anterior",
"Online status" : "Status online",
"Status message" : "Mesaj de status",
+ "Your status was set automatically" : "Statusul a fost setat automat",
"Clear status message" : "Șterge mesajul de stare",
"Set status message" : "Setează mesajul de status",
- "Away" : "Plecat",
- "Do not disturb" : "Nu deranja",
"Don't clear" : "Nu curăța",
"Today" : "Azi",
"This week" : "Săptămâna asta",
"Online" : "Online",
+ "Away" : "Plecat",
+ "Do not disturb" : "Nu deranja",
"Invisible" : "Invizibil",
+ "Offline" : "Offline",
+ "Set status" : "Setează status",
+ "There was an error saving the new status" : "S-a produs o eroare de salvare a noului status",
"30 minutes" : "30 minute",
"1 hour" : "1 oră",
"4 hours" : "4 ore",
+ "Busy" : "Ocupat",
"Mute all notifications" : "Dezactivați toate notificările",
- "Appear offline" : "Apari deconectat",
- "What's your status?" : "Care este statusul tău?"
+ "Appear offline" : "Apari deconectat"
},"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/user_status/l10n/ru.js b/apps/user_status/l10n/ru.js
index afe0ce63846..32b784b5e0c 100644
--- a/apps/user_status/l10n/ru.js
+++ b/apps/user_status/l10n/ru.js
@@ -2,39 +2,50 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Недавние статусы",
+ "No recent status changes" : "Нет недавних изменений статуса",
"In a meeting" : "На встрече",
"Commuting" : "В пути",
- "Out sick" : "Болею",
+ "Out sick" : "Болен",
"Vacationing" : "В отпуске",
- "Working remotely" : "Удалённая работа",
- "In a call" : "Вызывать",
+ "Out of office" : "Вне офиса",
+ "Working remotely" : "Удалённо",
+ "In a call" : "В вызове",
+ "Be right back" : "Скоро вернусь",
"User status" : "Статус пользователя",
- "View profile" : "Открыть профиль",
- "Clear status message after" : "Очистить сообщение о состоянии через",
- "What is your status?" : "Какой у вас статус?",
- "Set status" : "Установить статус",
- "Online status" : "Статус работы в сети",
+ "Clear status after" : "Очистить статус после",
+ "Emoji for your status message" : "Эмодзи для вашего сообщения к статусу",
+ "What is your status?" : "Какой у Вас статус?",
+ "Predefined statuses" : "Предопределенные статусы",
+ "Previously set" : "Установлено ранее",
+ "Reset status" : "Сбросить статус",
+ "Reset status to \"{icon} {message}\"" : "Сбросить статус на \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Сбросить статус на \"{message}\"",
+ "Reset status to \"{icon}\"" : "Сбросить статус на \"{icon}\"",
+ "There was an error saving the status" : "Произошла ошибка при сохранении статуса",
+ "There was an error clearing the status" : "Произошла ошибка при удалении статуса",
+ "There was an error reverting the status" : "Произошла ошибка при сбросе статуса",
+ "Online status" : "Онлайн статус",
"Status message" : "Описание статуса",
- "Clear status message" : "Удалить описание статуса",
- "Set status message" : "Установить описание статуса",
- "There was an error saving the status" : "Не удалось сохранить статус",
- "There was an error clearing the status" : "Не удалось убрать статус",
- "No recent status changes" : "Недавние изменения статуса отсуствуют ",
- "Away" : "Отошёл",
- "Do not disturb" : "Не беспокоить",
- "{status}, {timestamp}" : "{status}, {timestamp}",
+ "Set absence period" : "Задать период отсутствия",
+ "Set absence period and replacement" : "Задать период отсутствия и замену",
+ "Your status was set automatically" : "Ваш статус был установлен автоматически",
+ "Clear status message" : "Удалить сообщение к статусу",
+ "Set status message" : "Установить сообщение к статусу",
"Don't clear" : "Не очищать",
"Today" : "Сегодня",
"This week" : "Эта неделя",
- "Online" : "На связи",
- "Invisible" : "Невидимка",
- "Offline" : "Автономно",
- "There was an error saving the new status" : "Не удалось сохранить новый статус",
+ "Online" : "В сети",
+ "Away" : "Неактивен",
+ "Do not disturb" : "Не беспокоить",
+ "Invisible" : "Невидимый",
+ "Offline" : "Не в сети",
+ "Set status" : "Установить статус",
+ "There was an error saving the new status" : "Произошла ошибка при сохранении нового статуса",
"30 minutes" : "30 минут",
"1 hour" : "1 час",
"4 hours" : "4 часа",
+ "Busy" : "Занят",
"Mute all notifications" : "Отключить все уведомления",
- "Appear offline" : "Возможно, не в сети",
- "What's your status?" : "Укажите свой статус"
+ "Appear offline" : "\"Не в сети\" для остальных"
},
"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/user_status/l10n/ru.json b/apps/user_status/l10n/ru.json
index 0161434c967..f6b8d241ac4 100644
--- a/apps/user_status/l10n/ru.json
+++ b/apps/user_status/l10n/ru.json
@@ -1,38 +1,49 @@
{ "translations": {
"Recent statuses" : "Недавние статусы",
+ "No recent status changes" : "Нет недавних изменений статуса",
"In a meeting" : "На встрече",
"Commuting" : "В пути",
- "Out sick" : "Болею",
+ "Out sick" : "Болен",
"Vacationing" : "В отпуске",
- "Working remotely" : "Удалённая работа",
- "In a call" : "Вызывать",
+ "Out of office" : "Вне офиса",
+ "Working remotely" : "Удалённо",
+ "In a call" : "В вызове",
+ "Be right back" : "Скоро вернусь",
"User status" : "Статус пользователя",
- "View profile" : "Открыть профиль",
- "Clear status message after" : "Очистить сообщение о состоянии через",
- "What is your status?" : "Какой у вас статус?",
- "Set status" : "Установить статус",
- "Online status" : "Статус работы в сети",
+ "Clear status after" : "Очистить статус после",
+ "Emoji for your status message" : "Эмодзи для вашего сообщения к статусу",
+ "What is your status?" : "Какой у Вас статус?",
+ "Predefined statuses" : "Предопределенные статусы",
+ "Previously set" : "Установлено ранее",
+ "Reset status" : "Сбросить статус",
+ "Reset status to \"{icon} {message}\"" : "Сбросить статус на \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Сбросить статус на \"{message}\"",
+ "Reset status to \"{icon}\"" : "Сбросить статус на \"{icon}\"",
+ "There was an error saving the status" : "Произошла ошибка при сохранении статуса",
+ "There was an error clearing the status" : "Произошла ошибка при удалении статуса",
+ "There was an error reverting the status" : "Произошла ошибка при сбросе статуса",
+ "Online status" : "Онлайн статус",
"Status message" : "Описание статуса",
- "Clear status message" : "Удалить описание статуса",
- "Set status message" : "Установить описание статуса",
- "There was an error saving the status" : "Не удалось сохранить статус",
- "There was an error clearing the status" : "Не удалось убрать статус",
- "No recent status changes" : "Недавние изменения статуса отсуствуют ",
- "Away" : "Отошёл",
- "Do not disturb" : "Не беспокоить",
- "{status}, {timestamp}" : "{status}, {timestamp}",
+ "Set absence period" : "Задать период отсутствия",
+ "Set absence period and replacement" : "Задать период отсутствия и замену",
+ "Your status was set automatically" : "Ваш статус был установлен автоматически",
+ "Clear status message" : "Удалить сообщение к статусу",
+ "Set status message" : "Установить сообщение к статусу",
"Don't clear" : "Не очищать",
"Today" : "Сегодня",
"This week" : "Эта неделя",
- "Online" : "На связи",
- "Invisible" : "Невидимка",
- "Offline" : "Автономно",
- "There was an error saving the new status" : "Не удалось сохранить новый статус",
+ "Online" : "В сети",
+ "Away" : "Неактивен",
+ "Do not disturb" : "Не беспокоить",
+ "Invisible" : "Невидимый",
+ "Offline" : "Не в сети",
+ "Set status" : "Установить статус",
+ "There was an error saving the new status" : "Произошла ошибка при сохранении нового статуса",
"30 minutes" : "30 минут",
"1 hour" : "1 час",
"4 hours" : "4 часа",
+ "Busy" : "Занят",
"Mute all notifications" : "Отключить все уведомления",
- "Appear offline" : "Возможно, не в сети",
- "What's your status?" : "Укажите свой статус"
+ "Appear offline" : "\"Не в сети\" для остальных"
},"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/user_status/l10n/sc.js b/apps/user_status/l10n/sc.js
index 2586a7ca022..d4836447296 100644
--- a/apps/user_status/l10n/sc.js
+++ b/apps/user_status/l10n/sc.js
@@ -2,37 +2,37 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Istados reghentes",
+ "No recent status changes" : "Perunu càmbiu de istadu reghente",
"In a meeting" : "In riunione",
"Commuting" : "Biagende",
"Out sick" : "In maladia",
"Vacationing" : "In vacàntzia",
+ "Out of office" : "Foras de serbìtziu",
"Working remotely" : "Traballende in remotu",
"User status" : "Istadu de s'utente",
- "Clear status message after" : "Lìmpia su messàgiu de istadu a pustis",
+ "Clear status after" : "Lìmpia s'istadu a pustis",
"What is your status?" : "Cale est s'istadu tuo?",
- "Set status" : "Imposta istadu",
+ "There was an error saving the status" : "B'at àpidu un'errore sarvende s'istadu",
+ "There was an error clearing the status" : "B'at àpidu un'errore limpiende s'istadu",
"Online status" : "Istadu in lìnia",
"Status message" : "Messàgiu de istadu",
"Clear status message" : "Lìmpia su messàgiu de istadu",
- "Set status message" : "Imposta messàgiu de istadu",
- "There was an error saving the status" : "B'at àpidu un'errore sarvende s'istadu",
- "There was an error clearing the status" : "B'at àpidu un'errore limpiende s'istadu",
- "No recent status changes" : "Perunu càmbiu de istadu reghente",
- "Away" : "Ausente",
- "Do not disturb" : "No istorbes",
- "{status}, {timestamp}" : "{status}, {timestamp}",
+ "Set status message" : "Cunfigura su messàgiu de istadu",
"Don't clear" : "Non nche ddu lìmpies",
"Today" : "Oe",
"This week" : "Custa chida",
"Online" : "In lìnia",
+ "Away" : "Ausente",
+ "Do not disturb" : "No istorbes",
"Invisible" : "Invisìbile",
"Offline" : "Fora de lìnia",
+ "Set status" : "Cunfigura un'istadu",
"There was an error saving the new status" : "B'at àpidu un'errore sarvende s'istadu nou",
"30 minutes" : "30 minutos",
"1 hour" : "1 ora",
"4 hours" : "4 oras",
+ "Busy" : "Impinnadu",
"Mute all notifications" : "Istuda totu is notìficas",
- "Appear offline" : "Mustra•ti foras de lìnia",
- "What's your status?" : "Cale est s'istadu tuo?"
+ "Appear offline" : "Mustra•ti foras de lìnia"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/user_status/l10n/sc.json b/apps/user_status/l10n/sc.json
index 81e5320e537..9bec309186e 100644
--- a/apps/user_status/l10n/sc.json
+++ b/apps/user_status/l10n/sc.json
@@ -1,36 +1,36 @@
{ "translations": {
"Recent statuses" : "Istados reghentes",
+ "No recent status changes" : "Perunu càmbiu de istadu reghente",
"In a meeting" : "In riunione",
"Commuting" : "Biagende",
"Out sick" : "In maladia",
"Vacationing" : "In vacàntzia",
+ "Out of office" : "Foras de serbìtziu",
"Working remotely" : "Traballende in remotu",
"User status" : "Istadu de s'utente",
- "Clear status message after" : "Lìmpia su messàgiu de istadu a pustis",
+ "Clear status after" : "Lìmpia s'istadu a pustis",
"What is your status?" : "Cale est s'istadu tuo?",
- "Set status" : "Imposta istadu",
+ "There was an error saving the status" : "B'at àpidu un'errore sarvende s'istadu",
+ "There was an error clearing the status" : "B'at àpidu un'errore limpiende s'istadu",
"Online status" : "Istadu in lìnia",
"Status message" : "Messàgiu de istadu",
"Clear status message" : "Lìmpia su messàgiu de istadu",
- "Set status message" : "Imposta messàgiu de istadu",
- "There was an error saving the status" : "B'at àpidu un'errore sarvende s'istadu",
- "There was an error clearing the status" : "B'at àpidu un'errore limpiende s'istadu",
- "No recent status changes" : "Perunu càmbiu de istadu reghente",
- "Away" : "Ausente",
- "Do not disturb" : "No istorbes",
- "{status}, {timestamp}" : "{status}, {timestamp}",
+ "Set status message" : "Cunfigura su messàgiu de istadu",
"Don't clear" : "Non nche ddu lìmpies",
"Today" : "Oe",
"This week" : "Custa chida",
"Online" : "In lìnia",
+ "Away" : "Ausente",
+ "Do not disturb" : "No istorbes",
"Invisible" : "Invisìbile",
"Offline" : "Fora de lìnia",
+ "Set status" : "Cunfigura un'istadu",
"There was an error saving the new status" : "B'at àpidu un'errore sarvende s'istadu nou",
"30 minutes" : "30 minutos",
"1 hour" : "1 ora",
"4 hours" : "4 oras",
+ "Busy" : "Impinnadu",
"Mute all notifications" : "Istuda totu is notìficas",
- "Appear offline" : "Mustra•ti foras de lìnia",
- "What's your status?" : "Cale est s'istadu tuo?"
+ "Appear offline" : "Mustra•ti foras de lìnia"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/sk.js b/apps/user_status/l10n/sk.js
index d97a6ec4df2..9d91578b0f2 100644
--- a/apps/user_status/l10n/sk.js
+++ b/apps/user_status/l10n/sk.js
@@ -2,39 +2,49 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Nedávne stavy",
+ "No recent status changes" : "Žiadne nedávne zmeny stavu",
"In a meeting" : "Na schôdzke",
"Commuting" : "Na ceste",
"Out sick" : "Choroba",
"Vacationing" : "Na dovolenke",
- "Working remotely" : "Pracuje na diaľku",
+ "Out of office" : "Mimo kancelárie",
+ "Working remotely" : "Pracujem na diaľku",
"In a call" : "práve telefonuje",
"User status" : "Stav užívateľa",
- "View profile" : "Zobraziť profil",
- "Clear status message after" : "Vyčistiť správu o stave po",
+ "Clear status after" : "Vyčistiť správu o stave po",
+ "Emoji for your status message" : "Emoji pre vašu statusovú správu",
"What is your status?" : "Aký je váš stav?",
- "Set status" : "Nastaviť stav",
+ "Predefined statuses" : "Preddefinované statusy",
+ "Previously set" : "Predtým nastavené",
+ "Reset status" : "Obnoviť status",
+ "Reset status to \"{icon} {message}\"" : "Obnoviť stav na „{icon} {message}“",
+ "Reset status to \"{message}\"" : "Obnoviť stav na „{message}“",
+ "Reset status to \"{icon}\"" : "Obnoviť stav na „{icon}“",
+ "There was an error saving the status" : "Pri ukladaní stavu sa vyskytla chyba",
+ "There was an error clearing the status" : "Pri čistení stavu sa vyskytla chyba",
+ "There was an error reverting the status" : "Pri zmene statusu sa vyskytla chyba",
"Online status" : "Stav pripojenia",
"Status message" : "Správa o stave",
+ "Set absence period" : "Nastaviť dobu neprítomnosti",
+ "Set absence period and replacement" : "Nastaviť dobu neprítomnosti a svoju náhradu",
+ "Your status was set automatically" : "Váš status bol nastavený automaticky",
"Clear status message" : "Vyčistiť správu o stave",
"Set status message" : "Nastaviť správu o stave",
- "There was an error saving the status" : "Pri ukladaní stavu sa vyskytla chyba",
- "There was an error clearing the status" : "Pri čistení stavu sa vyskytla chyba",
- "No recent status changes" : "Žiadne nedávne zmeny stavu",
- "Away" : "Preč",
- "Do not disturb" : "Nerušiť",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Nemazať",
"Today" : "Dnes",
"This week" : "Tento týždeň",
"Online" : "Pripojené",
- "Invisible" : "Neviditeľné",
+ "Away" : "Preč",
+ "Do not disturb" : "Nerušiť",
+ "Invisible" : "Neviditeľnosť",
"Offline" : "Offline",
+ "Set status" : "Nastaviť stav",
"There was an error saving the new status" : "Pri ukladaní nového stavu sa vyskytla chyba",
"30 minutes" : "30 minút",
"1 hour" : "1 hodina",
"4 hours" : "4 hodiny",
+ "Busy" : "Zaneprázdnený",
"Mute all notifications" : "Stíšiť všetky upozornenia",
- "Appear offline" : "V odpojenom režime",
- "What's your status?" : "Aký je váš stav?"
+ "Appear offline" : "V odpojenom režime"
},
"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/user_status/l10n/sk.json b/apps/user_status/l10n/sk.json
index 7bb3f9c56a8..dffd39b9e8c 100644
--- a/apps/user_status/l10n/sk.json
+++ b/apps/user_status/l10n/sk.json
@@ -1,38 +1,48 @@
{ "translations": {
"Recent statuses" : "Nedávne stavy",
+ "No recent status changes" : "Žiadne nedávne zmeny stavu",
"In a meeting" : "Na schôdzke",
"Commuting" : "Na ceste",
"Out sick" : "Choroba",
"Vacationing" : "Na dovolenke",
- "Working remotely" : "Pracuje na diaľku",
+ "Out of office" : "Mimo kancelárie",
+ "Working remotely" : "Pracujem na diaľku",
"In a call" : "práve telefonuje",
"User status" : "Stav užívateľa",
- "View profile" : "Zobraziť profil",
- "Clear status message after" : "Vyčistiť správu o stave po",
+ "Clear status after" : "Vyčistiť správu o stave po",
+ "Emoji for your status message" : "Emoji pre vašu statusovú správu",
"What is your status?" : "Aký je váš stav?",
- "Set status" : "Nastaviť stav",
+ "Predefined statuses" : "Preddefinované statusy",
+ "Previously set" : "Predtým nastavené",
+ "Reset status" : "Obnoviť status",
+ "Reset status to \"{icon} {message}\"" : "Obnoviť stav na „{icon} {message}“",
+ "Reset status to \"{message}\"" : "Obnoviť stav na „{message}“",
+ "Reset status to \"{icon}\"" : "Obnoviť stav na „{icon}“",
+ "There was an error saving the status" : "Pri ukladaní stavu sa vyskytla chyba",
+ "There was an error clearing the status" : "Pri čistení stavu sa vyskytla chyba",
+ "There was an error reverting the status" : "Pri zmene statusu sa vyskytla chyba",
"Online status" : "Stav pripojenia",
"Status message" : "Správa o stave",
+ "Set absence period" : "Nastaviť dobu neprítomnosti",
+ "Set absence period and replacement" : "Nastaviť dobu neprítomnosti a svoju náhradu",
+ "Your status was set automatically" : "Váš status bol nastavený automaticky",
"Clear status message" : "Vyčistiť správu o stave",
"Set status message" : "Nastaviť správu o stave",
- "There was an error saving the status" : "Pri ukladaní stavu sa vyskytla chyba",
- "There was an error clearing the status" : "Pri čistení stavu sa vyskytla chyba",
- "No recent status changes" : "Žiadne nedávne zmeny stavu",
- "Away" : "Preč",
- "Do not disturb" : "Nerušiť",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Nemazať",
"Today" : "Dnes",
"This week" : "Tento týždeň",
"Online" : "Pripojené",
- "Invisible" : "Neviditeľné",
+ "Away" : "Preč",
+ "Do not disturb" : "Nerušiť",
+ "Invisible" : "Neviditeľnosť",
"Offline" : "Offline",
+ "Set status" : "Nastaviť stav",
"There was an error saving the new status" : "Pri ukladaní nového stavu sa vyskytla chyba",
"30 minutes" : "30 minút",
"1 hour" : "1 hodina",
"4 hours" : "4 hodiny",
+ "Busy" : "Zaneprázdnený",
"Mute all notifications" : "Stíšiť všetky upozornenia",
- "Appear offline" : "V odpojenom režime",
- "What's your status?" : "Aký je váš stav?"
+ "Appear offline" : "V odpojenom režime"
},"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/user_status/l10n/sl.js b/apps/user_status/l10n/sl.js
index 0909507c34d..0eb3b4a6d14 100644
--- a/apps/user_status/l10n/sl.js
+++ b/apps/user_status/l10n/sl.js
@@ -2,39 +2,47 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Nedavna stanja",
+ "No recent status changes" : "Ni nedavnih sprememb stanja",
"In a meeting" : "Na sestanku",
"Commuting" : "Med vožnjo",
"Out sick" : "Na bolniški",
"Vacationing" : "Na dopustu",
+ "Out of office" : "Službena odsotnost",
"Working remotely" : "Delam od doma",
"In a call" : "V klicu",
"User status" : "Stanje uporabnika",
- "View profile" : "Pokaži profil",
- "Clear status message after" : "Počisti sporočilo stanja po",
+ "Clear status after" : "Počisti stanje",
+ "Emoji for your status message" : "Izrazne ikone za stanje sporočila",
"What is your status?" : "Kako želite nastaviti stanje?",
- "Set status" : "Nastavi stanje",
+ "Predefined statuses" : "Pripravljena stanja",
+ "Previously set" : "Predhodno nastavljeno",
+ "Reset status" : "Ponastavi stanje",
+ "Reset status to \"{icon} {message}\"" : "Ponastavi stanje na »{icon} {message}«",
+ "Reset status to \"{message}\"" : "Ponastavi stanje na »{message}«",
+ "Reset status to \"{icon}\"" : "Ponastavi stanje na »{icon}«",
+ "There was an error saving the status" : "Prišlo je do napake med shranjevanjem stanja",
+ "There was an error clearing the status" : "Prišlo je do napake med odstranjevanjem stanja",
+ "There was an error reverting the status" : "Prišlo je do napake spreminjanja stanja",
"Online status" : "Povezano stanje",
"Status message" : "Sporočilo stanja",
+ "Your status was set automatically" : "Stanje je določeno samodejno",
"Clear status message" : "Počisti sporočilo stanja",
"Set status message" : "Nastavi sporočilo stanja",
- "There was an error saving the status" : "Prišlo je do napake med shranjevanjem stanja",
- "There was an error clearing the status" : "Prišlo je do napake med odstranjevanjem stanja",
- "No recent status changes" : "Ni nedavnih sprememb stanja",
- "Away" : "Trenutno ne spremljam",
- "Do not disturb" : "Ne pustim se motiti",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "ne počisti",
"Today" : "enkrat danes",
"This week" : "še ta teden",
"Online" : "Na spletu",
+ "Away" : "Trenutno ne spremljam",
+ "Do not disturb" : "Ne pustim se motiti",
"Invisible" : "Drugim neviden",
- "Offline" : "Začasno brez povezave",
+ "Offline" : "Brez povezave",
+ "Set status" : "Nastavi stanje",
"There was an error saving the new status" : "Prišlo je do napake med shranjevanjem novega stanja",
"30 minutes" : "po 30 minutah",
"1 hour" : "po 1 uri",
"4 hours" : "po 4 urah",
+ "Busy" : "Zasedeno",
"Mute all notifications" : "Utiša vsa obvestila",
- "Appear offline" : "Pokaže kot brez povezave",
- "What's your status?" : "Kako želite nastaviti stanje?"
+ "Appear offline" : "Pokaže kot brez povezave"
},
"nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);");
diff --git a/apps/user_status/l10n/sl.json b/apps/user_status/l10n/sl.json
index ab1638778c7..4e0c8582227 100644
--- a/apps/user_status/l10n/sl.json
+++ b/apps/user_status/l10n/sl.json
@@ -1,38 +1,46 @@
{ "translations": {
"Recent statuses" : "Nedavna stanja",
+ "No recent status changes" : "Ni nedavnih sprememb stanja",
"In a meeting" : "Na sestanku",
"Commuting" : "Med vožnjo",
"Out sick" : "Na bolniški",
"Vacationing" : "Na dopustu",
+ "Out of office" : "Službena odsotnost",
"Working remotely" : "Delam od doma",
"In a call" : "V klicu",
"User status" : "Stanje uporabnika",
- "View profile" : "Pokaži profil",
- "Clear status message after" : "Počisti sporočilo stanja po",
+ "Clear status after" : "Počisti stanje",
+ "Emoji for your status message" : "Izrazne ikone za stanje sporočila",
"What is your status?" : "Kako želite nastaviti stanje?",
- "Set status" : "Nastavi stanje",
+ "Predefined statuses" : "Pripravljena stanja",
+ "Previously set" : "Predhodno nastavljeno",
+ "Reset status" : "Ponastavi stanje",
+ "Reset status to \"{icon} {message}\"" : "Ponastavi stanje na »{icon} {message}«",
+ "Reset status to \"{message}\"" : "Ponastavi stanje na »{message}«",
+ "Reset status to \"{icon}\"" : "Ponastavi stanje na »{icon}«",
+ "There was an error saving the status" : "Prišlo je do napake med shranjevanjem stanja",
+ "There was an error clearing the status" : "Prišlo je do napake med odstranjevanjem stanja",
+ "There was an error reverting the status" : "Prišlo je do napake spreminjanja stanja",
"Online status" : "Povezano stanje",
"Status message" : "Sporočilo stanja",
+ "Your status was set automatically" : "Stanje je določeno samodejno",
"Clear status message" : "Počisti sporočilo stanja",
"Set status message" : "Nastavi sporočilo stanja",
- "There was an error saving the status" : "Prišlo je do napake med shranjevanjem stanja",
- "There was an error clearing the status" : "Prišlo je do napake med odstranjevanjem stanja",
- "No recent status changes" : "Ni nedavnih sprememb stanja",
- "Away" : "Trenutno ne spremljam",
- "Do not disturb" : "Ne pustim se motiti",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "ne počisti",
"Today" : "enkrat danes",
"This week" : "še ta teden",
"Online" : "Na spletu",
+ "Away" : "Trenutno ne spremljam",
+ "Do not disturb" : "Ne pustim se motiti",
"Invisible" : "Drugim neviden",
- "Offline" : "Začasno brez povezave",
+ "Offline" : "Brez povezave",
+ "Set status" : "Nastavi stanje",
"There was an error saving the new status" : "Prišlo je do napake med shranjevanjem novega stanja",
"30 minutes" : "po 30 minutah",
"1 hour" : "po 1 uri",
"4 hours" : "po 4 urah",
+ "Busy" : "Zasedeno",
"Mute all notifications" : "Utiša vsa obvestila",
- "Appear offline" : "Pokaže kot brez povezave",
- "What's your status?" : "Kako želite nastaviti stanje?"
+ "Appear offline" : "Pokaže kot brez povezave"
},"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/user_status/l10n/sr.js b/apps/user_status/l10n/sr.js
new file mode 100644
index 00000000000..8c94ab10e2e
--- /dev/null
+++ b/apps/user_status/l10n/sr.js
@@ -0,0 +1,50 @@
+OC.L10N.register(
+ "user_status",
+ {
+ "Recent statuses" : "Скорашњи статуси",
+ "No recent status changes" : "Нема скорашњих измена статуса",
+ "In a meeting" : "На састанку",
+ "Commuting" : "На путу до посла",
+ "Out sick" : "На боловању",
+ "Vacationing" : "На одмору",
+ "Out of office" : "Ван канцеларије",
+ "Working remotely" : "Радим од куће",
+ "In a call" : "У позиву",
+ "User status" : "Корисников статус",
+ "Clear status after" : "Обриши статус након",
+ "Emoji for your status message" : "Емођи за вашу статусну поруку",
+ "What is your status?" : "Који је ваш статус?",
+ "Predefined statuses" : "Предефинисани статуси",
+ "Previously set" : "Претходно постављено",
+ "Reset status" : "Ресетуј статус",
+ "Reset status to \"{icon} {message}\"" : "Ресетуј статус на „{icon} {message}”",
+ "Reset status to \"{message}\"" : "Ресетуј статус на „{message}”",
+ "Reset status to \"{icon}\"" : "Ресетуј статус на „{icon}”",
+ "There was an error saving the status" : "Дошло је до грешке приликом чувања статуса",
+ "There was an error clearing the status" : "Дошло је до грешке приликом брисања статуса",
+ "There was an error reverting the status" : "Дошло је до грешке приликом враћања претходног статуса",
+ "Online status" : "Мрежни статус",
+ "Status message" : "Порука стања",
+ "Set absence period" : "Постави период одсутности",
+ "Set absence period and replacement" : "Постави период одсутности и замену",
+ "Your status was set automatically" : "Ваш статус је аутоматски постављен",
+ "Clear status message" : "Обриши статусну поруку",
+ "Set status message" : "Постављање статусне поруке",
+ "Don't clear" : "Не бриши",
+ "Today" : "Данас",
+ "This week" : "Ове недеље",
+ "Online" : "На мрежи",
+ "Away" : "Одсутан",
+ "Do not disturb" : "Не узнемиравај",
+ "Invisible" : "Невидљива",
+ "Offline" : "Ван мреже",
+ "Set status" : "Постави статус",
+ "There was an error saving the new status" : "Дошло је до грешке приликом чувања новог статуса",
+ "30 minutes" : "30 минута",
+ "1 hour" : "1 сат",
+ "4 hours" : "4 сата",
+ "Busy" : "Заузет",
+ "Mute all notifications" : "Искључи сва обавештења",
+ "Appear offline" : "Прикажи као ван мреже"
+},
+"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/user_status/l10n/sr.json b/apps/user_status/l10n/sr.json
new file mode 100644
index 00000000000..a7953e5e0a3
--- /dev/null
+++ b/apps/user_status/l10n/sr.json
@@ -0,0 +1,48 @@
+{ "translations": {
+ "Recent statuses" : "Скорашњи статуси",
+ "No recent status changes" : "Нема скорашњих измена статуса",
+ "In a meeting" : "На састанку",
+ "Commuting" : "На путу до посла",
+ "Out sick" : "На боловању",
+ "Vacationing" : "На одмору",
+ "Out of office" : "Ван канцеларије",
+ "Working remotely" : "Радим од куће",
+ "In a call" : "У позиву",
+ "User status" : "Корисников статус",
+ "Clear status after" : "Обриши статус након",
+ "Emoji for your status message" : "Емођи за вашу статусну поруку",
+ "What is your status?" : "Који је ваш статус?",
+ "Predefined statuses" : "Предефинисани статуси",
+ "Previously set" : "Претходно постављено",
+ "Reset status" : "Ресетуј статус",
+ "Reset status to \"{icon} {message}\"" : "Ресетуј статус на „{icon} {message}”",
+ "Reset status to \"{message}\"" : "Ресетуј статус на „{message}”",
+ "Reset status to \"{icon}\"" : "Ресетуј статус на „{icon}”",
+ "There was an error saving the status" : "Дошло је до грешке приликом чувања статуса",
+ "There was an error clearing the status" : "Дошло је до грешке приликом брисања статуса",
+ "There was an error reverting the status" : "Дошло је до грешке приликом враћања претходног статуса",
+ "Online status" : "Мрежни статус",
+ "Status message" : "Порука стања",
+ "Set absence period" : "Постави период одсутности",
+ "Set absence period and replacement" : "Постави период одсутности и замену",
+ "Your status was set automatically" : "Ваш статус је аутоматски постављен",
+ "Clear status message" : "Обриши статусну поруку",
+ "Set status message" : "Постављање статусне поруке",
+ "Don't clear" : "Не бриши",
+ "Today" : "Данас",
+ "This week" : "Ове недеље",
+ "Online" : "На мрежи",
+ "Away" : "Одсутан",
+ "Do not disturb" : "Не узнемиравај",
+ "Invisible" : "Невидљива",
+ "Offline" : "Ван мреже",
+ "Set status" : "Постави статус",
+ "There was an error saving the new status" : "Дошло је до грешке приликом чувања новог статуса",
+ "30 minutes" : "30 минута",
+ "1 hour" : "1 сат",
+ "4 hours" : "4 сата",
+ "Busy" : "Заузет",
+ "Mute all notifications" : "Искључи сва обавештења",
+ "Appear offline" : "Прикажи као ван мреже"
+},"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/user_status/l10n/sr@latin.js b/apps/user_status/l10n/sr@latin.js
new file mode 100644
index 00000000000..532e6651761
--- /dev/null
+++ b/apps/user_status/l10n/sr@latin.js
@@ -0,0 +1,47 @@
+OC.L10N.register(
+ "user_status",
+ {
+ "Recent statuses" : "Poslednji statusi",
+ "No recent status changes" : "Nema skorašnjih promena statusa",
+ "In a meeting" : "Na sastanku",
+ "Commuting" : "Na putu do posla",
+ "Out sick" : "Na bolovanju",
+ "Vacationing" : "Na odmoru",
+ "Out of office" : "Van kancelarije",
+ "Working remotely" : "Radim od kuće",
+ "In a call" : "U pozivu",
+ "User status" : "Status korisnika",
+ "Clear status after" : "Obriši status nakon",
+ "Emoji for your status message" : "Emoji za vašu statusnu poruku",
+ "What is your status?" : "Koji je vaš status?",
+ "Predefined statuses" : "Predefinisani statusi",
+ "Previously set" : "Prethodno postavljeno",
+ "Reset status" : "Resetuj status",
+ "Reset status to \"{icon} {message}\"" : "Resetuj status na „{icon} {message}”",
+ "Reset status to \"{message}\"" : "Resertuj status na „{message}”",
+ "Reset status to \"{icon}\"" : "Resetuj status na „{icon}”",
+ "There was an error saving the status" : "Greška u snimanju statusa",
+ "There was an error clearing the status" : "Greška u brisanju statusa",
+ "There was an error reverting the status" : "Greška u vraćanju statusa",
+ "Online status" : "Mrežni status",
+ "Status message" : "Poruka stanja",
+ "Your status was set automatically" : "Vaš status je postavljen automatski",
+ "Clear status message" : "Obriši statusnu poruku",
+ "Set status message" : "Postavi statusnu poruku",
+ "Don't clear" : "Ne briši",
+ "Today" : "Danas",
+ "This week" : "Ove sedmice",
+ "Online" : "Na mreži",
+ "Away" : "Odsutan",
+ "Do not disturb" : "Ne uznemiravaj",
+ "Invisible" : "Nevidljiv",
+ "Offline" : "Van mreže",
+ "Set status" : "Postavi status",
+ "There was an error saving the new status" : "Greška u snimanju novog statusa",
+ "30 minutes" : "30 minuta",
+ "1 hour" : "1 sat",
+ "4 hours" : "4 sata",
+ "Mute all notifications" : "Isključi sva obaveštenja",
+ "Appear offline" : "Prikaži kao van mreže"
+},
+"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/user_status/l10n/sr@latin.json b/apps/user_status/l10n/sr@latin.json
new file mode 100644
index 00000000000..bb642d5708c
--- /dev/null
+++ b/apps/user_status/l10n/sr@latin.json
@@ -0,0 +1,45 @@
+{ "translations": {
+ "Recent statuses" : "Poslednji statusi",
+ "No recent status changes" : "Nema skorašnjih promena statusa",
+ "In a meeting" : "Na sastanku",
+ "Commuting" : "Na putu do posla",
+ "Out sick" : "Na bolovanju",
+ "Vacationing" : "Na odmoru",
+ "Out of office" : "Van kancelarije",
+ "Working remotely" : "Radim od kuće",
+ "In a call" : "U pozivu",
+ "User status" : "Status korisnika",
+ "Clear status after" : "Obriši status nakon",
+ "Emoji for your status message" : "Emoji za vašu statusnu poruku",
+ "What is your status?" : "Koji je vaš status?",
+ "Predefined statuses" : "Predefinisani statusi",
+ "Previously set" : "Prethodno postavljeno",
+ "Reset status" : "Resetuj status",
+ "Reset status to \"{icon} {message}\"" : "Resetuj status na „{icon} {message}”",
+ "Reset status to \"{message}\"" : "Resertuj status na „{message}”",
+ "Reset status to \"{icon}\"" : "Resetuj status na „{icon}”",
+ "There was an error saving the status" : "Greška u snimanju statusa",
+ "There was an error clearing the status" : "Greška u brisanju statusa",
+ "There was an error reverting the status" : "Greška u vraćanju statusa",
+ "Online status" : "Mrežni status",
+ "Status message" : "Poruka stanja",
+ "Your status was set automatically" : "Vaš status je postavljen automatski",
+ "Clear status message" : "Obriši statusnu poruku",
+ "Set status message" : "Postavi statusnu poruku",
+ "Don't clear" : "Ne briši",
+ "Today" : "Danas",
+ "This week" : "Ove sedmice",
+ "Online" : "Na mreži",
+ "Away" : "Odsutan",
+ "Do not disturb" : "Ne uznemiravaj",
+ "Invisible" : "Nevidljiv",
+ "Offline" : "Van mreže",
+ "Set status" : "Postavi status",
+ "There was an error saving the new status" : "Greška u snimanju novog statusa",
+ "30 minutes" : "30 minuta",
+ "1 hour" : "1 sat",
+ "4 hours" : "4 sata",
+ "Mute all notifications" : "Isključi sva obaveštenja",
+ "Appear offline" : "Prikaži kao van mreže"
+},"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/user_status/l10n/sv.js b/apps/user_status/l10n/sv.js
index 1ce860a949e..acd1b224d4b 100644
--- a/apps/user_status/l10n/sv.js
+++ b/apps/user_status/l10n/sv.js
@@ -2,39 +2,49 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "Senaste statusuppdateringar",
+ "No recent status changes" : "Inga statusuppdateringar den sista tiden",
"In a meeting" : "På ett möte",
"Commuting" : "Reser",
"Out sick" : "Sjuk",
"Vacationing" : "På semester",
+ "Out of office" : "Ej på plats",
"Working remotely" : "Arbetar hemifrån",
"In a call" : "I ett samtal",
"User status" : "Användarstatus",
- "View profile" : "Visa profil",
- "Clear status message after" : "Rensa statusmeddelande efter",
+ "Clear status after" : "Rensa status efter",
+ "Emoji for your status message" : "Emoji för ditt statusmeddelande",
"What is your status?" : "Vad är din status?",
- "Set status" : "Sätt status",
+ "Predefined statuses" : "Fördefinierade statusar",
+ "Previously set" : "Tidigare inställd",
+ "Reset status" : "Återställ status",
+ "Reset status to \"{icon} {message}\"" : "Återställ status till \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Återställ status till \"{message}\"",
+ "Reset status to \"{icon}\"" : "Återställ status till \"{icon}\"",
+ "There was an error saving the status" : "Ett fel inträffade när statusen skulle ändras",
+ "There was an error clearing the status" : "Ett fel inträffade när statusen skulle rensas",
+ "There was an error reverting the status" : "Det gick inte att återställa statusen",
"Online status" : "Online-status",
"Status message" : "Statusmeddelande",
+ "Set absence period" : "Ställ in frånvaroperiod",
+ "Set absence period and replacement" : "Ställ in frånvaroperiod och ersättare",
+ "Your status was set automatically" : "Din status ställdes in automatiskt",
"Clear status message" : "Rensa statusmeddelande",
"Set status message" : "Sätt statusmeddelande",
- "There was an error saving the status" : "Ett fel inträffade när statusen skulle ändras",
- "There was an error clearing the status" : "Ett fel inträffade när statusen skulle rensas",
- "No recent status changes" : "Inga statusuppdateringar den sista tiden",
- "Away" : "Iväg",
- "Do not disturb" : "Stör ej",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Rensa inte",
"Today" : "Idag",
"This week" : "Denna vecka",
"Online" : "Online",
+ "Away" : "Iväg",
+ "Do not disturb" : "Stör ej",
"Invisible" : "Osynlig",
"Offline" : "Frånkopplad",
+ "Set status" : "Sätt status",
"There was an error saving the new status" : "Ett fel inträffade när den nya statusen skulle sparas",
"30 minutes" : "30 minuter",
"1 hour" : "1 timme",
"4 hours" : "4 timmar",
+ "Busy" : "Upptagen",
"Mute all notifications" : "Dölj alla aviseringar",
- "Appear offline" : "Visa som frånkopplad",
- "What's your status?" : "Vad är din status?"
+ "Appear offline" : "Visa som frånkopplad"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/user_status/l10n/sv.json b/apps/user_status/l10n/sv.json
index 52ecbee3bed..502baef321b 100644
--- a/apps/user_status/l10n/sv.json
+++ b/apps/user_status/l10n/sv.json
@@ -1,38 +1,48 @@
{ "translations": {
"Recent statuses" : "Senaste statusuppdateringar",
+ "No recent status changes" : "Inga statusuppdateringar den sista tiden",
"In a meeting" : "På ett möte",
"Commuting" : "Reser",
"Out sick" : "Sjuk",
"Vacationing" : "På semester",
+ "Out of office" : "Ej på plats",
"Working remotely" : "Arbetar hemifrån",
"In a call" : "I ett samtal",
"User status" : "Användarstatus",
- "View profile" : "Visa profil",
- "Clear status message after" : "Rensa statusmeddelande efter",
+ "Clear status after" : "Rensa status efter",
+ "Emoji for your status message" : "Emoji för ditt statusmeddelande",
"What is your status?" : "Vad är din status?",
- "Set status" : "Sätt status",
+ "Predefined statuses" : "Fördefinierade statusar",
+ "Previously set" : "Tidigare inställd",
+ "Reset status" : "Återställ status",
+ "Reset status to \"{icon} {message}\"" : "Återställ status till \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Återställ status till \"{message}\"",
+ "Reset status to \"{icon}\"" : "Återställ status till \"{icon}\"",
+ "There was an error saving the status" : "Ett fel inträffade när statusen skulle ändras",
+ "There was an error clearing the status" : "Ett fel inträffade när statusen skulle rensas",
+ "There was an error reverting the status" : "Det gick inte att återställa statusen",
"Online status" : "Online-status",
"Status message" : "Statusmeddelande",
+ "Set absence period" : "Ställ in frånvaroperiod",
+ "Set absence period and replacement" : "Ställ in frånvaroperiod och ersättare",
+ "Your status was set automatically" : "Din status ställdes in automatiskt",
"Clear status message" : "Rensa statusmeddelande",
"Set status message" : "Sätt statusmeddelande",
- "There was an error saving the status" : "Ett fel inträffade när statusen skulle ändras",
- "There was an error clearing the status" : "Ett fel inträffade när statusen skulle rensas",
- "No recent status changes" : "Inga statusuppdateringar den sista tiden",
- "Away" : "Iväg",
- "Do not disturb" : "Stör ej",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Rensa inte",
"Today" : "Idag",
"This week" : "Denna vecka",
"Online" : "Online",
+ "Away" : "Iväg",
+ "Do not disturb" : "Stör ej",
"Invisible" : "Osynlig",
"Offline" : "Frånkopplad",
+ "Set status" : "Sätt status",
"There was an error saving the new status" : "Ett fel inträffade när den nya statusen skulle sparas",
"30 minutes" : "30 minuter",
"1 hour" : "1 timme",
"4 hours" : "4 timmar",
+ "Busy" : "Upptagen",
"Mute all notifications" : "Dölj alla aviseringar",
- "Appear offline" : "Visa som frånkopplad",
- "What's your status?" : "Vad är din status?"
+ "Appear offline" : "Visa som frånkopplad"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/sw.js b/apps/user_status/l10n/sw.js
new file mode 100644
index 00000000000..69e9430b920
--- /dev/null
+++ b/apps/user_status/l10n/sw.js
@@ -0,0 +1,51 @@
+OC.L10N.register(
+ "user_status",
+ {
+ "Recent statuses" : "Hali za hivi karibuni",
+ "No recent status changes" : "Hakuna mabadiliko ya hali ya hivi karibuni",
+ "In a meeting" : "Katika mkutano",
+ "Commuting" : "Kuelekea",
+ "Out sick" : "Nje mgonjwa",
+ "Vacationing" : "Likizo",
+ "Out of office" : "Nje ya ofisi",
+ "Working remotely" : "Kufanyia kazi mbali",
+ "In a call" : "Katika simu",
+ "Be right back" : "Rudi mara moja",
+ "User status" : "Hadhi ya mtumiaji",
+ "Clear status after" : "Futa hali baada ya",
+ "Emoji for your status message" : "Emoji kwa hali yako ya ujumbe",
+ "What is your status?" : "Hadhi yako ni nini?",
+ "Predefined statuses" : "Hali zilizoainishwa awali",
+ "Previously set" : "Imepangiliwa mwanzo",
+ "Reset status" : "Pangilia hali",
+ "Reset status to \"{icon} {message}\"" : " Weka upya hali kuwa \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Weka upya hali kuwa \"{message}\"",
+ "Reset status to \"{icon}\"" : "Weka upya hali kuwa \"{icon}\"",
+ "There was an error saving the status" : "Kulikuwa na hitilafu katika kuhifadhi hali",
+ "There was an error clearing the status" : "Kulikuwa na hitilafu katika kufuta hali",
+ "There was an error reverting the status" : "Kulikuwa na hitilafu katika kurejesha hali",
+ "Online status" : "Hali ya mtandaoni",
+ "Status message" : "Hali ya ujumbe",
+ "Set absence period" : "Weka kipindi cha kutokuwepo",
+ "Set absence period and replacement" : " Weka kipindi cha kutokuwepo na uingizwaji mbadala",
+ "Your status was set automatically" : "Hadhi yako ilipangiliwa moja kwa moja",
+ "Clear status message" : "Futa jumbe za wadhifa",
+ "Set status message" : "Pangilia hali ya ujumbe",
+ "Don't clear" : "Usifute",
+ "Today" : "Leo",
+ "This week" : "Wiki hii",
+ "Online" : "Mtandaoni",
+ "Away" : "Mbali",
+ "Do not disturb" : "Acha kusumbua",
+ "Invisible" : "Haionekani",
+ "Offline" : "Nje ya mtandao",
+ "Set status" : "Panglia hali",
+ "There was an error saving the new status" : "Kulikuwa na hitilafu katika kuhifadhi hali mpya",
+ "30 minutes" : "Dakika 30",
+ "1 hour" : "Saa 1",
+ "4 hours" : "Masaa 4",
+ "Busy" : "Bize",
+ "Mute all notifications" : "Zima arifu zote",
+ "Appear offline" : "Tokea nje ya mtandao"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/user_status/l10n/sw.json b/apps/user_status/l10n/sw.json
new file mode 100644
index 00000000000..a106159c6fb
--- /dev/null
+++ b/apps/user_status/l10n/sw.json
@@ -0,0 +1,49 @@
+{ "translations": {
+ "Recent statuses" : "Hali za hivi karibuni",
+ "No recent status changes" : "Hakuna mabadiliko ya hali ya hivi karibuni",
+ "In a meeting" : "Katika mkutano",
+ "Commuting" : "Kuelekea",
+ "Out sick" : "Nje mgonjwa",
+ "Vacationing" : "Likizo",
+ "Out of office" : "Nje ya ofisi",
+ "Working remotely" : "Kufanyia kazi mbali",
+ "In a call" : "Katika simu",
+ "Be right back" : "Rudi mara moja",
+ "User status" : "Hadhi ya mtumiaji",
+ "Clear status after" : "Futa hali baada ya",
+ "Emoji for your status message" : "Emoji kwa hali yako ya ujumbe",
+ "What is your status?" : "Hadhi yako ni nini?",
+ "Predefined statuses" : "Hali zilizoainishwa awali",
+ "Previously set" : "Imepangiliwa mwanzo",
+ "Reset status" : "Pangilia hali",
+ "Reset status to \"{icon} {message}\"" : " Weka upya hali kuwa \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Weka upya hali kuwa \"{message}\"",
+ "Reset status to \"{icon}\"" : "Weka upya hali kuwa \"{icon}\"",
+ "There was an error saving the status" : "Kulikuwa na hitilafu katika kuhifadhi hali",
+ "There was an error clearing the status" : "Kulikuwa na hitilafu katika kufuta hali",
+ "There was an error reverting the status" : "Kulikuwa na hitilafu katika kurejesha hali",
+ "Online status" : "Hali ya mtandaoni",
+ "Status message" : "Hali ya ujumbe",
+ "Set absence period" : "Weka kipindi cha kutokuwepo",
+ "Set absence period and replacement" : " Weka kipindi cha kutokuwepo na uingizwaji mbadala",
+ "Your status was set automatically" : "Hadhi yako ilipangiliwa moja kwa moja",
+ "Clear status message" : "Futa jumbe za wadhifa",
+ "Set status message" : "Pangilia hali ya ujumbe",
+ "Don't clear" : "Usifute",
+ "Today" : "Leo",
+ "This week" : "Wiki hii",
+ "Online" : "Mtandaoni",
+ "Away" : "Mbali",
+ "Do not disturb" : "Acha kusumbua",
+ "Invisible" : "Haionekani",
+ "Offline" : "Nje ya mtandao",
+ "Set status" : "Panglia hali",
+ "There was an error saving the new status" : "Kulikuwa na hitilafu katika kuhifadhi hali mpya",
+ "30 minutes" : "Dakika 30",
+ "1 hour" : "Saa 1",
+ "4 hours" : "Masaa 4",
+ "Busy" : "Bize",
+ "Mute all notifications" : "Zima arifu zote",
+ "Appear offline" : "Tokea nje ya mtandao"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/user_status/l10n/th.js b/apps/user_status/l10n/th.js
index e2d4a9b1e5c..00bdced011d 100644
--- a/apps/user_status/l10n/th.js
+++ b/apps/user_status/l10n/th.js
@@ -2,36 +2,35 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "สถานะล่าสุด",
+ "No recent status changes" : "ไม่มีการเปลี่ยนสถานะล่าสุด",
"In a meeting" : "กำลังประชุม",
"Commuting" : "กำลังเดินทาง",
"Out sick" : "ป่วย",
"Vacationing" : "วันหยุดพักผ่อน",
"Working remotely" : "ทำงานจากระยะไกล",
"User status" : "สถานะผู้ใช้",
- "Clear status message after" : "ลบข้อความสถานะหลังจาก",
- "Set status" : "กำหนดสถานะ",
+ "Clear status after" : "ล้างสถานะหลังจาก",
+ "What is your status?" : "สถานะของคุณ",
+ "There was an error saving the status" : "เกิดข้อผิดพลาดในการบันทึกสถานะ",
+ "There was an error clearing the status" : "เกิดข้อผิดพลาดในการลบสถานะ",
"Online status" : "สถานะออนไลน์",
"Status message" : "ข้อความสถานะ",
"Clear status message" : "ล้างข้อความสถานะ",
"Set status message" : "กำหนดข้อความสถานะ",
- "There was an error saving the status" : "เกิดข้อผิดพลาดในการบันทึกสถานะ",
- "There was an error clearing the status" : "เกิดข้อผิดพลาดในการลบสถานะ",
- "No recent status changes" : "ไม่มีการเปลี่ยนสถานะล่าสุด",
- "Away" : "ไม่อยู่",
- "Do not disturb" : "ห้ามรบกวน",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "ไม่ต้องล้าง",
"Today" : "วันนี้",
"This week" : "สัปดาห์นี้",
"Online" : "ออนไลน์",
+ "Away" : "ไม่อยู่",
+ "Do not disturb" : "ห้ามรบกวน",
"Invisible" : "ไม่แสดงสถานะ",
"Offline" : "ออฟไลน์",
+ "Set status" : "กำหนดสถานะ",
"There was an error saving the new status" : "เกิดข้อผิดพลาดในการบันทึกสถานะใหม่",
"30 minutes" : "30 นาที",
"1 hour" : "1 ชั่วโมง",
"4 hours" : "4 ชั่วโมง",
"Mute all notifications" : "ปิดการแจ้งเตือนทั้งหมด",
- "Appear offline" : "แสดงเป็นออฟไลน์",
- "What's your status?" : "สถานะของคุณคืออะไร"
+ "Appear offline" : "แสดงเป็นออฟไลน์"
},
"nplurals=1; plural=0;");
diff --git a/apps/user_status/l10n/th.json b/apps/user_status/l10n/th.json
index bb6364a7eb5..36ca7503b17 100644
--- a/apps/user_status/l10n/th.json
+++ b/apps/user_status/l10n/th.json
@@ -1,35 +1,34 @@
{ "translations": {
"Recent statuses" : "สถานะล่าสุด",
+ "No recent status changes" : "ไม่มีการเปลี่ยนสถานะล่าสุด",
"In a meeting" : "กำลังประชุม",
"Commuting" : "กำลังเดินทาง",
"Out sick" : "ป่วย",
"Vacationing" : "วันหยุดพักผ่อน",
"Working remotely" : "ทำงานจากระยะไกล",
"User status" : "สถานะผู้ใช้",
- "Clear status message after" : "ลบข้อความสถานะหลังจาก",
- "Set status" : "กำหนดสถานะ",
+ "Clear status after" : "ล้างสถานะหลังจาก",
+ "What is your status?" : "สถานะของคุณ",
+ "There was an error saving the status" : "เกิดข้อผิดพลาดในการบันทึกสถานะ",
+ "There was an error clearing the status" : "เกิดข้อผิดพลาดในการลบสถานะ",
"Online status" : "สถานะออนไลน์",
"Status message" : "ข้อความสถานะ",
"Clear status message" : "ล้างข้อความสถานะ",
"Set status message" : "กำหนดข้อความสถานะ",
- "There was an error saving the status" : "เกิดข้อผิดพลาดในการบันทึกสถานะ",
- "There was an error clearing the status" : "เกิดข้อผิดพลาดในการลบสถานะ",
- "No recent status changes" : "ไม่มีการเปลี่ยนสถานะล่าสุด",
- "Away" : "ไม่อยู่",
- "Do not disturb" : "ห้ามรบกวน",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "ไม่ต้องล้าง",
"Today" : "วันนี้",
"This week" : "สัปดาห์นี้",
"Online" : "ออนไลน์",
+ "Away" : "ไม่อยู่",
+ "Do not disturb" : "ห้ามรบกวน",
"Invisible" : "ไม่แสดงสถานะ",
"Offline" : "ออฟไลน์",
+ "Set status" : "กำหนดสถานะ",
"There was an error saving the new status" : "เกิดข้อผิดพลาดในการบันทึกสถานะใหม่",
"30 minutes" : "30 นาที",
"1 hour" : "1 ชั่วโมง",
"4 hours" : "4 ชั่วโมง",
"Mute all notifications" : "ปิดการแจ้งเตือนทั้งหมด",
- "Appear offline" : "แสดงเป็นออฟไลน์",
- "What's your status?" : "สถานะของคุณคืออะไร"
+ "Appear offline" : "แสดงเป็นออฟไลน์"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/tr.js b/apps/user_status/l10n/tr.js
index b9082b44da5..c63ff93c164 100644
--- a/apps/user_status/l10n/tr.js
+++ b/apps/user_status/l10n/tr.js
@@ -1,40 +1,50 @@
OC.L10N.register(
"user_status",
{
- "Recent statuses" : "Yakın zamandaki durumlar",
+ "Recent statuses" : "Son durumlar",
+ "No recent status changes" : "Son zamanlarda durum değiştirilmemiş",
"In a meeting" : "Toplantıda",
"Commuting" : "İşe gidiyor/geliyor",
"Out sick" : "Hasta",
"Vacationing" : "Tatilde",
+ "Out of office" : "İş yeri dışında",
"Working remotely" : "Uzaktan çalışıyor",
- "In a call" : "Bir görüşmede",
+ "In a call" : "Bir çağrıda",
"User status" : "Kullanıcı durumu",
- "View profile" : "Profili görüntüle",
- "Clear status message after" : "Durum iletisi şu süre sonunda kaldırılsın",
+ "Clear status after" : "Durum şu kadar sonra kaldırılsın",
+ "Emoji for your status message" : "Durum iletiniz için emoji",
"What is your status?" : "Durumunuz nedir?",
- "Set status" : "Durumu ayarla",
- "Online status" : "Çevrimiçi durumu",
+ "Predefined statuses" : "Hazır durumlar",
+ "Previously set" : "Önceden ayarlanmış",
+ "Reset status" : "Durumu sıfırla",
+ "Reset status to \"{icon} {message}\"" : "Durumu \"{icon} {message}\" olarak sıfırla",
+ "Reset status to \"{message}\"" : "Durumu \"{message}\" olarak sıfırla",
+ "Reset status to \"{icon}\"" : "Durumu \"{icon}\" olarak sıfırla",
+ "There was an error saving the status" : "Durum kaydedilirken bir sorun çıktı",
+ "There was an error clearing the status" : "Durum kaldırılırken bir sorun çıktı",
+ "There was an error reverting the status" : "Durum geri alınırken bir sorun çıktı",
+ "Online status" : "Çevrim içi durumu",
"Status message" : "Durum iletisi",
+ "Set absence period" : "Bulunmama aralığını ayarla",
+ "Set absence period and replacement" : "Bulunmama aralığını ve yedek kişiyi ayarla",
+ "Your status was set automatically" : "Durumunuz otomatik olarak ayarlanmış",
"Clear status message" : "Durum iletisini temizle",
"Set status message" : "Durum iletisini ayarla",
- "There was an error saving the status" : "Durum kaydedilirken bir sorun çıktı",
- "There was an error clearing the status" : "Durum kaldırılırken bir sorun çıktı",
- "No recent status changes" : "Yakın zamanda değiştirilmiş bir durum yok",
- "Away" : "Uzakta",
- "Do not disturb" : "Rahatsız etmeyin",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Kaldırılmasın",
"Today" : "Bugün",
"This week" : "Bu hafta",
- "Online" : "Çevrimiçi",
+ "Online" : "Çevrim içi",
+ "Away" : "Uzakta",
+ "Do not disturb" : "Rahatsız etmeyin",
"Invisible" : "Gizli",
- "Offline" : "Çevrimdışı",
+ "Offline" : "Çevrim dışı",
+ "Set status" : "Durumu ayarla",
"There was an error saving the new status" : "Yeni durum kaydedilirken bir sorun çıktı",
"30 minutes" : "30 dakika",
"1 hour" : "1 saat",
"4 hours" : "4 saat",
+ "Busy" : "Meşgul",
"Mute all notifications" : "Tüm bildirimleri kapat",
- "Appear offline" : "Çevrimdışı görün",
- "What's your status?" : "Durumunuz nedir?"
+ "Appear offline" : "Çevrim dışı görün"
},
"nplurals=2; plural=(n > 1);");
diff --git a/apps/user_status/l10n/tr.json b/apps/user_status/l10n/tr.json
index f0a52887536..c601fbbd635 100644
--- a/apps/user_status/l10n/tr.json
+++ b/apps/user_status/l10n/tr.json
@@ -1,38 +1,48 @@
{ "translations": {
- "Recent statuses" : "Yakın zamandaki durumlar",
+ "Recent statuses" : "Son durumlar",
+ "No recent status changes" : "Son zamanlarda durum değiştirilmemiş",
"In a meeting" : "Toplantıda",
"Commuting" : "İşe gidiyor/geliyor",
"Out sick" : "Hasta",
"Vacationing" : "Tatilde",
+ "Out of office" : "İş yeri dışında",
"Working remotely" : "Uzaktan çalışıyor",
- "In a call" : "Bir görüşmede",
+ "In a call" : "Bir çağrıda",
"User status" : "Kullanıcı durumu",
- "View profile" : "Profili görüntüle",
- "Clear status message after" : "Durum iletisi şu süre sonunda kaldırılsın",
+ "Clear status after" : "Durum şu kadar sonra kaldırılsın",
+ "Emoji for your status message" : "Durum iletiniz için emoji",
"What is your status?" : "Durumunuz nedir?",
- "Set status" : "Durumu ayarla",
- "Online status" : "Çevrimiçi durumu",
+ "Predefined statuses" : "Hazır durumlar",
+ "Previously set" : "Önceden ayarlanmış",
+ "Reset status" : "Durumu sıfırla",
+ "Reset status to \"{icon} {message}\"" : "Durumu \"{icon} {message}\" olarak sıfırla",
+ "Reset status to \"{message}\"" : "Durumu \"{message}\" olarak sıfırla",
+ "Reset status to \"{icon}\"" : "Durumu \"{icon}\" olarak sıfırla",
+ "There was an error saving the status" : "Durum kaydedilirken bir sorun çıktı",
+ "There was an error clearing the status" : "Durum kaldırılırken bir sorun çıktı",
+ "There was an error reverting the status" : "Durum geri alınırken bir sorun çıktı",
+ "Online status" : "Çevrim içi durumu",
"Status message" : "Durum iletisi",
+ "Set absence period" : "Bulunmama aralığını ayarla",
+ "Set absence period and replacement" : "Bulunmama aralığını ve yedek kişiyi ayarla",
+ "Your status was set automatically" : "Durumunuz otomatik olarak ayarlanmış",
"Clear status message" : "Durum iletisini temizle",
"Set status message" : "Durum iletisini ayarla",
- "There was an error saving the status" : "Durum kaydedilirken bir sorun çıktı",
- "There was an error clearing the status" : "Durum kaldırılırken bir sorun çıktı",
- "No recent status changes" : "Yakın zamanda değiştirilmiş bir durum yok",
- "Away" : "Uzakta",
- "Do not disturb" : "Rahatsız etmeyin",
- "{status}, {timestamp}" : "{status}, {timestamp}",
"Don't clear" : "Kaldırılmasın",
"Today" : "Bugün",
"This week" : "Bu hafta",
- "Online" : "Çevrimiçi",
+ "Online" : "Çevrim içi",
+ "Away" : "Uzakta",
+ "Do not disturb" : "Rahatsız etmeyin",
"Invisible" : "Gizli",
- "Offline" : "Çevrimdışı",
+ "Offline" : "Çevrim dışı",
+ "Set status" : "Durumu ayarla",
"There was an error saving the new status" : "Yeni durum kaydedilirken bir sorun çıktı",
"30 minutes" : "30 dakika",
"1 hour" : "1 saat",
"4 hours" : "4 saat",
+ "Busy" : "Meşgul",
"Mute all notifications" : "Tüm bildirimleri kapat",
- "Appear offline" : "Çevrimdışı görün",
- "What's your status?" : "Durumunuz nedir?"
+ "Appear offline" : "Çevrim dışı görün"
},"pluralForm" :"nplurals=2; plural=(n > 1);"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/ug.js b/apps/user_status/l10n/ug.js
new file mode 100644
index 00000000000..43c620037e3
--- /dev/null
+++ b/apps/user_status/l10n/ug.js
@@ -0,0 +1,50 @@
+OC.L10N.register(
+ "user_status",
+ {
+ "Recent statuses" : "يېقىنقى ھالەت",
+ "No recent status changes" : "يېقىنقى ھالەت ئۆزگەرمىدى",
+ "In a meeting" : "بىر يىغىندا",
+ "Commuting" : "سەپەرگە چىقىش",
+ "Out sick" : "كېسەل",
+ "Vacationing" : "دەم ئېلىش",
+ "Out of office" : "ئىشخانىدىن چىقتى",
+ "Working remotely" : "يىراقتىن ئىشلەش",
+ "In a call" : "تېلېفوندا",
+ "User status" : "ئىشلەتكۈچى ھالىتى",
+ "Clear status after" : "كېيىنكى ھالەتنى ئېنىقلاش",
+ "Emoji for your status message" : "ھالەت ئۇچۇرىڭىز ئۈچۈن Emoji",
+ "What is your status?" : "ئەھۋالىڭىز نېمە؟",
+ "Predefined statuses" : "ئالدىن بېكىتىلگەن ھالەت",
+ "Previously set" : "ئىلگىرى تەڭشەلگەن",
+ "Reset status" : "ھالىتىنى ئەسلىگە كەلتۈرۈش",
+ "Reset status to \"{icon} {message}\"" : "ھالەتنى \"{icon} {message}\" غا قايتۇرۇڭ",
+ "Reset status to \"{message}\"" : "ھالەتنى \"{message}\" غا قايتۇرۇڭ",
+ "Reset status to \"{icon}\"" : "ھالەتنى \"{icon}\" گە قايتۇرۇڭ",
+ "There was an error saving the status" : "ھالەتنى ساقلاشتا خاتالىق كۆرۈلدى",
+ "There was an error clearing the status" : "ھالەتنى تازىلاشتا خاتالىق كۆرۈلدى",
+ "There was an error reverting the status" : "ھالەتنى ئەسلىگە كەلتۈرۈشتە خاتالىق كۆرۈلدى",
+ "Online status" : "توردىكى ئورنى",
+ "Status message" : "ھالەت ئۇچۇرى",
+ "Set absence period" : "يوقلۇق ۋاقتىنى بەلگىلەڭ",
+ "Set absence period and replacement" : "يوقلۇق ۋاقتى ۋە ئورنىنى بەلگىلەڭ",
+ "Your status was set automatically" : "ھالىتىڭىز ئاپتوماتىك تەڭشەلدى",
+ "Clear status message" : "ھالەت ئۇچۇرىنى تازىلاش",
+ "Set status message" : "ھالەت ئۇچۇرىنى بەلگىلەڭ",
+ "Don't clear" : "ئېنىق ئەمەس",
+ "Today" : "بۈگۈن",
+ "This week" : "بۇ ھەپتە",
+ "Online" : "توردا",
+ "Away" : "يىراق",
+ "Do not disturb" : "ئاۋارە قىلماڭ",
+ "Invisible" : "كۆرۈنمەيدۇ",
+ "Offline" : "تورسىز",
+ "Set status" : "ھالەت بەلگىلەڭ",
+ "There was an error saving the new status" : "يېڭى ھالەتنى ساقلاشتا خاتالىق كۆرۈلدى",
+ "30 minutes" : "30 مىنۇت",
+ "1 hour" : "1 سائەت",
+ "4 hours" : "4 سائەت",
+ "Busy" : "ئالدىراش",
+ "Mute all notifications" : "بارلىق ئۇقتۇرۇشلارنى ئاۋازسىز قىلىڭ",
+ "Appear offline" : "تورسىز كۆرۈنۈش"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/user_status/l10n/ug.json b/apps/user_status/l10n/ug.json
new file mode 100644
index 00000000000..eb439948185
--- /dev/null
+++ b/apps/user_status/l10n/ug.json
@@ -0,0 +1,48 @@
+{ "translations": {
+ "Recent statuses" : "يېقىنقى ھالەت",
+ "No recent status changes" : "يېقىنقى ھالەت ئۆزگەرمىدى",
+ "In a meeting" : "بىر يىغىندا",
+ "Commuting" : "سەپەرگە چىقىش",
+ "Out sick" : "كېسەل",
+ "Vacationing" : "دەم ئېلىش",
+ "Out of office" : "ئىشخانىدىن چىقتى",
+ "Working remotely" : "يىراقتىن ئىشلەش",
+ "In a call" : "تېلېفوندا",
+ "User status" : "ئىشلەتكۈچى ھالىتى",
+ "Clear status after" : "كېيىنكى ھالەتنى ئېنىقلاش",
+ "Emoji for your status message" : "ھالەت ئۇچۇرىڭىز ئۈچۈن Emoji",
+ "What is your status?" : "ئەھۋالىڭىز نېمە؟",
+ "Predefined statuses" : "ئالدىن بېكىتىلگەن ھالەت",
+ "Previously set" : "ئىلگىرى تەڭشەلگەن",
+ "Reset status" : "ھالىتىنى ئەسلىگە كەلتۈرۈش",
+ "Reset status to \"{icon} {message}\"" : "ھالەتنى \"{icon} {message}\" غا قايتۇرۇڭ",
+ "Reset status to \"{message}\"" : "ھالەتنى \"{message}\" غا قايتۇرۇڭ",
+ "Reset status to \"{icon}\"" : "ھالەتنى \"{icon}\" گە قايتۇرۇڭ",
+ "There was an error saving the status" : "ھالەتنى ساقلاشتا خاتالىق كۆرۈلدى",
+ "There was an error clearing the status" : "ھالەتنى تازىلاشتا خاتالىق كۆرۈلدى",
+ "There was an error reverting the status" : "ھالەتنى ئەسلىگە كەلتۈرۈشتە خاتالىق كۆرۈلدى",
+ "Online status" : "توردىكى ئورنى",
+ "Status message" : "ھالەت ئۇچۇرى",
+ "Set absence period" : "يوقلۇق ۋاقتىنى بەلگىلەڭ",
+ "Set absence period and replacement" : "يوقلۇق ۋاقتى ۋە ئورنىنى بەلگىلەڭ",
+ "Your status was set automatically" : "ھالىتىڭىز ئاپتوماتىك تەڭشەلدى",
+ "Clear status message" : "ھالەت ئۇچۇرىنى تازىلاش",
+ "Set status message" : "ھالەت ئۇچۇرىنى بەلگىلەڭ",
+ "Don't clear" : "ئېنىق ئەمەس",
+ "Today" : "بۈگۈن",
+ "This week" : "بۇ ھەپتە",
+ "Online" : "توردا",
+ "Away" : "يىراق",
+ "Do not disturb" : "ئاۋارە قىلماڭ",
+ "Invisible" : "كۆرۈنمەيدۇ",
+ "Offline" : "تورسىز",
+ "Set status" : "ھالەت بەلگىلەڭ",
+ "There was an error saving the new status" : "يېڭى ھالەتنى ساقلاشتا خاتالىق كۆرۈلدى",
+ "30 minutes" : "30 مىنۇت",
+ "1 hour" : "1 سائەت",
+ "4 hours" : "4 سائەت",
+ "Busy" : "ئالدىراش",
+ "Mute all notifications" : "بارلىق ئۇقتۇرۇشلارنى ئاۋازسىز قىلىڭ",
+ "Appear offline" : "تورسىز كۆرۈنۈش"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/user_status/l10n/uk.js b/apps/user_status/l10n/uk.js
index 745ce96edb7..b73417b164b 100644
--- a/apps/user_status/l10n/uk.js
+++ b/apps/user_status/l10n/uk.js
@@ -1,23 +1,51 @@
OC.L10N.register(
"user_status",
{
- "View profile" : "Перегляд профілю",
- "Clear status message after" : "Очистити повідомлення про стан після",
- "Set status" : "Встановити статус",
- "Online status" : "Статус онлайну",
+ "Recent statuses" : "Останні статуси",
+ "No recent status changes" : "Статус не змінювався",
+ "In a meeting" : "На зустрічі",
+ "Commuting" : "В дорозі на роботу",
+ "Out sick" : "Хворію",
+ "Vacationing" : "У відпустці",
+ "Out of office" : "Недоступний(-а)",
+ "Working remotely" : "Працюю віддалено",
+ "In a call" : "На дзвінку",
+ "Be right back" : "Зараз повернуся",
+ "User status" : "Статус користувача",
+ "Clear status after" : "Очистити статус після",
+ "Emoji for your status message" : "Емоційки для повідомлення вашого статусу",
+ "What is your status?" : "Який твій статус?",
+ "Predefined statuses" : "Попередньо визначені статуси",
+ "Previously set" : "Раніше встановлений",
+ "Reset status" : "Скинути статус",
+ "Reset status to \"{icon} {message}\"" : "Скинути статус на \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Скинути статус на \"{message}\"",
+ "Reset status to \"{icon}\"" : "Скинути статус на \"{icon}\"",
+ "There was an error saving the status" : "Помилка під час збереження статусу",
+ "There was an error clearing the status" : "Помилка під час очищення статусу",
+ "There was an error reverting the status" : "Помилка при скиданні статусу",
+ "Online status" : "Мій статус доступності",
"Status message" : "Повідомлення про статус",
- "Clear status message" : "Очистити повідомлення про стан",
- "Set status message" : "Встановити повідомлення про стан",
- "Away" : "Піти",
- "Do not disturb" : "Не турбувати",
- "Don't clear" : "Не очистувати",
+ "Set absence period" : "Встановити період відсутности",
+ "Set absence period and replacement" : "Встановити період відсутности та тимчасово виконуючого обов'язки",
+ "Your status was set automatically" : "Ваш статус встановлено автоматично",
+ "Clear status message" : "Прибрати статус",
+ "Set status message" : "Оновити статус",
+ "Don't clear" : "Залишити поточний",
"Today" : "Сьогодні",
"This week" : "Цього тижня",
- "Online" : "Онлайн",
- "Invisible" : "Невидима",
+ "Online" : "Доступний(-а)",
+ "Away" : "Відсутній(-я)",
+ "Do not disturb" : "Не турбувати",
+ "Invisible" : "Невидимка",
+ "Offline" : "Поза мережею",
+ "Set status" : "Встановити статус",
+ "There was an error saving the new status" : "Помилка під час збереження статусу",
"30 minutes" : "30 хвилин",
"1 hour" : "1 година",
"4 hours" : "4 години",
- "What's your status?" : "Який ваш статус?"
+ "Busy" : "Зайнято",
+ "Mute all notifications" : "Вимкнути всі сповіщення",
+ "Appear offline" : "Перебуваю поза мережею"
},
"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/user_status/l10n/uk.json b/apps/user_status/l10n/uk.json
index 04593c06b97..e115bf09f5f 100644
--- a/apps/user_status/l10n/uk.json
+++ b/apps/user_status/l10n/uk.json
@@ -1,21 +1,49 @@
{ "translations": {
- "View profile" : "Перегляд профілю",
- "Clear status message after" : "Очистити повідомлення про стан після",
- "Set status" : "Встановити статус",
- "Online status" : "Статус онлайну",
+ "Recent statuses" : "Останні статуси",
+ "No recent status changes" : "Статус не змінювався",
+ "In a meeting" : "На зустрічі",
+ "Commuting" : "В дорозі на роботу",
+ "Out sick" : "Хворію",
+ "Vacationing" : "У відпустці",
+ "Out of office" : "Недоступний(-а)",
+ "Working remotely" : "Працюю віддалено",
+ "In a call" : "На дзвінку",
+ "Be right back" : "Зараз повернуся",
+ "User status" : "Статус користувача",
+ "Clear status after" : "Очистити статус після",
+ "Emoji for your status message" : "Емоційки для повідомлення вашого статусу",
+ "What is your status?" : "Який твій статус?",
+ "Predefined statuses" : "Попередньо визначені статуси",
+ "Previously set" : "Раніше встановлений",
+ "Reset status" : "Скинути статус",
+ "Reset status to \"{icon} {message}\"" : "Скинути статус на \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Скинути статус на \"{message}\"",
+ "Reset status to \"{icon}\"" : "Скинути статус на \"{icon}\"",
+ "There was an error saving the status" : "Помилка під час збереження статусу",
+ "There was an error clearing the status" : "Помилка під час очищення статусу",
+ "There was an error reverting the status" : "Помилка при скиданні статусу",
+ "Online status" : "Мій статус доступності",
"Status message" : "Повідомлення про статус",
- "Clear status message" : "Очистити повідомлення про стан",
- "Set status message" : "Встановити повідомлення про стан",
- "Away" : "Піти",
- "Do not disturb" : "Не турбувати",
- "Don't clear" : "Не очистувати",
+ "Set absence period" : "Встановити період відсутности",
+ "Set absence period and replacement" : "Встановити період відсутности та тимчасово виконуючого обов'язки",
+ "Your status was set automatically" : "Ваш статус встановлено автоматично",
+ "Clear status message" : "Прибрати статус",
+ "Set status message" : "Оновити статус",
+ "Don't clear" : "Залишити поточний",
"Today" : "Сьогодні",
"This week" : "Цього тижня",
- "Online" : "Онлайн",
- "Invisible" : "Невидима",
+ "Online" : "Доступний(-а)",
+ "Away" : "Відсутній(-я)",
+ "Do not disturb" : "Не турбувати",
+ "Invisible" : "Невидимка",
+ "Offline" : "Поза мережею",
+ "Set status" : "Встановити статус",
+ "There was an error saving the new status" : "Помилка під час збереження статусу",
"30 minutes" : "30 хвилин",
"1 hour" : "1 година",
"4 hours" : "4 години",
- "What's your status?" : "Який ваш статус?"
+ "Busy" : "Зайнято",
+ "Mute all notifications" : "Вимкнути всі сповіщення",
+ "Appear offline" : "Перебуваю поза мережею"
},"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/user_status/l10n/uz.js b/apps/user_status/l10n/uz.js
new file mode 100644
index 00000000000..c2ada8c65d0
--- /dev/null
+++ b/apps/user_status/l10n/uz.js
@@ -0,0 +1,50 @@
+OC.L10N.register(
+ "user_status",
+ {
+ "Recent statuses" : "Oxirgi holatlar",
+ "No recent status changes" : "Oxirgi holatda o'zgarish mavjud emas",
+ "In a meeting" : "Uchrashuvda",
+ "Commuting" : "Qatnov",
+ "Out sick" : "Kasal",
+ "Vacationing" : "Dam olish",
+ "Out of office" : "Ofisda emas",
+ "Working remotely" : "Masofadan ishlash",
+ "In a call" : "Qo'ng'iroqda",
+ "User status" : "Foydalanuvchi holati",
+ "Clear status after" : "Holatni tozalashdan keyin",
+ "Emoji for your status message" : "Xabar holati uchun emoji",
+ "What is your status?" : "Sizning holatingiz qanday?",
+ "Predefined statuses" : "Oldindan belgilangan holatlar",
+ "Previously set" : "Ilgari o'rnatilgan",
+ "Reset status" : "Holatni tiklash",
+ "Reset status to \"{icon} {message}\"" : " \"{icon} {message}\" uchun holatni tiklash",
+ "Reset status to \"{message}\"" : " \"{message}\" uchun holatni tiklash",
+ "Reset status to \"{icon}\"" : " \"{icon}\" uchun holatni tiklash",
+ "There was an error saving the status" : "Holatni saqlashda xatolik yuz berdi",
+ "There was an error clearing the status" : "Holatni tozalashda xatolik yuz berdi",
+ "There was an error reverting the status" : "Holatni qaytarishda xatolik yuz berdi",
+ "Online status" : "Onlayn holat",
+ "Status message" : "Holat xabari",
+ "Set absence period" : "Aloqadan o`chirilgan muddatini belgilang",
+ "Set absence period and replacement" : "Aloqadan o`chirilgan muddatini va almashtirish belgilang",
+ "Your status was set automatically" : "Sizning holatingiz avtomatik ravishda o'rnatildi",
+ "Clear status message" : "Holat xabarini tozalash",
+ "Set status message" : "Holat xabarini o'rnatish",
+ "Don't clear" : "Aniq emas",
+ "Today" : "Bugun",
+ "This week" : "Shu hafta",
+ "Online" : "Online",
+ "Away" : "Uzoqda",
+ "Do not disturb" : "Bezovta qilmang",
+ "Invisible" : "Ko'rinmas",
+ "Offline" : "Offline",
+ "Set status" : "Holatni belgilash",
+ "There was an error saving the new status" : "Yangi holatni saqlashda xatolik yuz berdi",
+ "30 minutes" : "30 minut",
+ "1 hour" : "1 soat",
+ "4 hours" : "4 soat",
+ "Busy" : "Band",
+ "Mute all notifications" : "Barcha bildirishnomalarni o'chirish",
+ "Appear offline" : "Oflayn ko'rinishda"
+},
+"nplurals=1; plural=0;");
diff --git a/apps/user_status/l10n/uz.json b/apps/user_status/l10n/uz.json
new file mode 100644
index 00000000000..8d4d073a89f
--- /dev/null
+++ b/apps/user_status/l10n/uz.json
@@ -0,0 +1,48 @@
+{ "translations": {
+ "Recent statuses" : "Oxirgi holatlar",
+ "No recent status changes" : "Oxirgi holatda o'zgarish mavjud emas",
+ "In a meeting" : "Uchrashuvda",
+ "Commuting" : "Qatnov",
+ "Out sick" : "Kasal",
+ "Vacationing" : "Dam olish",
+ "Out of office" : "Ofisda emas",
+ "Working remotely" : "Masofadan ishlash",
+ "In a call" : "Qo'ng'iroqda",
+ "User status" : "Foydalanuvchi holati",
+ "Clear status after" : "Holatni tozalashdan keyin",
+ "Emoji for your status message" : "Xabar holati uchun emoji",
+ "What is your status?" : "Sizning holatingiz qanday?",
+ "Predefined statuses" : "Oldindan belgilangan holatlar",
+ "Previously set" : "Ilgari o'rnatilgan",
+ "Reset status" : "Holatni tiklash",
+ "Reset status to \"{icon} {message}\"" : " \"{icon} {message}\" uchun holatni tiklash",
+ "Reset status to \"{message}\"" : " \"{message}\" uchun holatni tiklash",
+ "Reset status to \"{icon}\"" : " \"{icon}\" uchun holatni tiklash",
+ "There was an error saving the status" : "Holatni saqlashda xatolik yuz berdi",
+ "There was an error clearing the status" : "Holatni tozalashda xatolik yuz berdi",
+ "There was an error reverting the status" : "Holatni qaytarishda xatolik yuz berdi",
+ "Online status" : "Onlayn holat",
+ "Status message" : "Holat xabari",
+ "Set absence period" : "Aloqadan o`chirilgan muddatini belgilang",
+ "Set absence period and replacement" : "Aloqadan o`chirilgan muddatini va almashtirish belgilang",
+ "Your status was set automatically" : "Sizning holatingiz avtomatik ravishda o'rnatildi",
+ "Clear status message" : "Holat xabarini tozalash",
+ "Set status message" : "Holat xabarini o'rnatish",
+ "Don't clear" : "Aniq emas",
+ "Today" : "Bugun",
+ "This week" : "Shu hafta",
+ "Online" : "Online",
+ "Away" : "Uzoqda",
+ "Do not disturb" : "Bezovta qilmang",
+ "Invisible" : "Ko'rinmas",
+ "Offline" : "Offline",
+ "Set status" : "Holatni belgilash",
+ "There was an error saving the new status" : "Yangi holatni saqlashda xatolik yuz berdi",
+ "30 minutes" : "30 minut",
+ "1 hour" : "1 soat",
+ "4 hours" : "4 soat",
+ "Busy" : "Band",
+ "Mute all notifications" : "Barcha bildirishnomalarni o'chirish",
+ "Appear offline" : "Oflayn ko'rinishda"
+},"pluralForm" :"nplurals=1; plural=0;"
+} \ No newline at end of file
diff --git a/apps/user_status/l10n/vi.js b/apps/user_status/l10n/vi.js
index e10bbaf0f93..0c2e8081a8e 100644
--- a/apps/user_status/l10n/vi.js
+++ b/apps/user_status/l10n/vi.js
@@ -1,24 +1,47 @@
OC.L10N.register(
"user_status",
{
+ "Recent statuses" : "Trạng thái gần đây",
+ "No recent status changes" : "Không có thay đổi trạng thái gần đây",
+ "In a meeting" : "Trong một cuộc họp",
"Commuting" : "Đang di chuyển",
- "Clear status message after" : "Xoá thông báo trạng thái sau",
+ "Out sick" : "Bị ốm",
+ "Vacationing" : "Đi nghỉ",
+ "Out of office" : "Không ở văn phòng",
+ "Working remotely" : "Làm việc từ xa",
+ "User status" : "Trạng thái người dùng",
+ "Clear status after" : "Xóa trạng thái sau",
+ "Emoji for your status message" : "Biểu tượng cảm xúc cho thông báo trạng thái của bạn",
"What is your status?" : "Trạng thái của bạn là gì?",
- "Set status" : "Đặt trạng thái",
+ "Predefined statuses" : "Trạng thái được xác định trước",
+ "Previously set" : "Đã đặt trước đó",
+ "Reset status" : "Thiết lập trạng thái",
+ "Reset status to \"{icon} {message}\"" : "Đặt lại trạng thái thành \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Đặt lại trạng thái thành \"{message}\"",
+ "Reset status to \"{icon}\"" : "Đặt lại trạng thái thành \"{icon}\"",
+ "There was an error saving the status" : "Đã xảy ra lỗi khi lưu trạng thái",
+ "There was an error clearing the status" : "Đã xảy ra lỗi khi xóa trạng thái",
+ "There was an error reverting the status" : "Đã xảy ra lỗi khi hoàn nguyên trạng thái",
"Online status" : "Trạng thái trực tuyến",
"Status message" : "Thông báo trạng thái",
+ "Your status was set automatically" : "Trạng thái của bạn đã được đặt tự động",
"Clear status message" : "Xoá thông báo trạng thái",
"Set status message" : "Đặt thông báo trạng thái",
- "Away" : "Tạm vắng",
- "Do not disturb" : "Đừng làm phiền",
"Don't clear" : "Không xoá",
"Today" : "Hôm nay",
"This week" : "Tuần này",
"Online" : "Trực tuyến",
+ "Away" : "Tạm vắng",
+ "Do not disturb" : "Đừng làm phiền",
"Invisible" : "Vô hình",
+ "Offline" : "Ngoại tuyến",
+ "Set status" : "Đặt trạng thái",
+ "There was an error saving the new status" : "Đã xảy ra lỗi khi lưu trạng thái mới",
"30 minutes" : "30 phút",
"1 hour" : "1 tiếng",
"4 hours" : "4 tiếng",
- "What's your status?" : "Trạng thái của bạn là gì?"
+ "Busy" : "Bận",
+ "Mute all notifications" : "Tắt tiếng tất cả thông báo",
+ "Appear offline" : "Đang offline"
},
"nplurals=1; plural=0;");
diff --git a/apps/user_status/l10n/vi.json b/apps/user_status/l10n/vi.json
index eaef648d350..daf7d940656 100644
--- a/apps/user_status/l10n/vi.json
+++ b/apps/user_status/l10n/vi.json
@@ -1,22 +1,45 @@
{ "translations": {
+ "Recent statuses" : "Trạng thái gần đây",
+ "No recent status changes" : "Không có thay đổi trạng thái gần đây",
+ "In a meeting" : "Trong một cuộc họp",
"Commuting" : "Đang di chuyển",
- "Clear status message after" : "Xoá thông báo trạng thái sau",
+ "Out sick" : "Bị ốm",
+ "Vacationing" : "Đi nghỉ",
+ "Out of office" : "Không ở văn phòng",
+ "Working remotely" : "Làm việc từ xa",
+ "User status" : "Trạng thái người dùng",
+ "Clear status after" : "Xóa trạng thái sau",
+ "Emoji for your status message" : "Biểu tượng cảm xúc cho thông báo trạng thái của bạn",
"What is your status?" : "Trạng thái của bạn là gì?",
- "Set status" : "Đặt trạng thái",
+ "Predefined statuses" : "Trạng thái được xác định trước",
+ "Previously set" : "Đã đặt trước đó",
+ "Reset status" : "Thiết lập trạng thái",
+ "Reset status to \"{icon} {message}\"" : "Đặt lại trạng thái thành \"{icon} {message}\"",
+ "Reset status to \"{message}\"" : "Đặt lại trạng thái thành \"{message}\"",
+ "Reset status to \"{icon}\"" : "Đặt lại trạng thái thành \"{icon}\"",
+ "There was an error saving the status" : "Đã xảy ra lỗi khi lưu trạng thái",
+ "There was an error clearing the status" : "Đã xảy ra lỗi khi xóa trạng thái",
+ "There was an error reverting the status" : "Đã xảy ra lỗi khi hoàn nguyên trạng thái",
"Online status" : "Trạng thái trực tuyến",
"Status message" : "Thông báo trạng thái",
+ "Your status was set automatically" : "Trạng thái của bạn đã được đặt tự động",
"Clear status message" : "Xoá thông báo trạng thái",
"Set status message" : "Đặt thông báo trạng thái",
- "Away" : "Tạm vắng",
- "Do not disturb" : "Đừng làm phiền",
"Don't clear" : "Không xoá",
"Today" : "Hôm nay",
"This week" : "Tuần này",
"Online" : "Trực tuyến",
+ "Away" : "Tạm vắng",
+ "Do not disturb" : "Đừng làm phiền",
"Invisible" : "Vô hình",
+ "Offline" : "Ngoại tuyến",
+ "Set status" : "Đặt trạng thái",
+ "There was an error saving the new status" : "Đã xảy ra lỗi khi lưu trạng thái mới",
"30 minutes" : "30 phút",
"1 hour" : "1 tiếng",
"4 hours" : "4 tiếng",
- "What's your status?" : "Trạng thái của bạn là gì?"
+ "Busy" : "Bận",
+ "Mute all notifications" : "Tắt tiếng tất cả thông báo",
+ "Appear offline" : "Đang offline"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/zh_CN.js b/apps/user_status/l10n/zh_CN.js
index d37d0687b89..c36ad38c713 100644
--- a/apps/user_status/l10n/zh_CN.js
+++ b/apps/user_status/l10n/zh_CN.js
@@ -2,39 +2,50 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "最近状态",
+ "No recent status changes" : "最近状态没有改变",
"In a meeting" : "开会中",
"Commuting" : "通勤中",
"Out sick" : "生病了",
"Vacationing" : "度假中",
+ "Out of office" : "不在办公室",
"Working remotely" : "远程办公中",
"In a call" : "通话中",
+ "Be right back" : "马上回来",
"User status" : "用户状态",
- "View profile" : "查看个人资料",
- "Clear status message after" : "清除状态信息",
- "What is your status?" : "你什么状态?",
- "Set status" : "设定状态",
- "Online status" : "在线状态",
- "Status message" : "状态信息",
- "Clear status message" : "清除状态信息",
- "Set status message" : "设定状态信息",
+ "Clear status after" : "清除状态于",
+ "Emoji for your status message" : "状态消息的表情符号",
+ "What is your status?" : "您的状态如何?",
+ "Predefined statuses" : "预定义状态",
+ "Previously set" : "先前设置",
+ "Reset status" : "重置状态",
+ "Reset status to \"{icon} {message}\"" : "将状态重置为“{icon} {message}”",
+ "Reset status to \"{message}\"" : "将状态重置为“{message}”",
+ "Reset status to \"{icon}\"" : "将状态重置为“{icon}”",
"There was an error saving the status" : "保存状态时出错",
"There was an error clearing the status" : "清除状态时出错",
- "No recent status changes" : "最近状态没有改变",
- "Away" : "离开",
- "Do not disturb" : "请勿打扰",
- "{status}, {timestamp}" : "{status}, {timestamp}",
+ "There was an error reverting the status" : "恢复状态时出错",
+ "Online status" : "在线状态",
+ "Status message" : "状态消息",
+ "Set absence period" : "设置缺勤时段",
+ "Set absence period and replacement" : "设置缺勤时段和接替者",
+ "Your status was set automatically" : "您的状态已自动设置",
+ "Clear status message" : "清除状态消息",
+ "Set status message" : "设置状态消息",
"Don't clear" : "不要清除",
"Today" : "今天",
"This week" : "本周",
"Online" : "在线",
- "Invisible" : "不可见",
+ "Away" : "离开",
+ "Do not disturb" : "勿扰",
+ "Invisible" : "隐身",
"Offline" : "离线",
+ "Set status" : "设置状态",
"There was an error saving the new status" : "保存新状态时出错",
"30 minutes" : "30 分钟",
"1 hour" : "1 小时",
"4 hours" : "4 小时",
+ "Busy" : "忙碌",
"Mute all notifications" : "静音所有通知",
- "Appear offline" : "显示为离线",
- "What's your status?" : "您现在是什么状态?"
+ "Appear offline" : "显示为离线"
},
"nplurals=1; plural=0;");
diff --git a/apps/user_status/l10n/zh_CN.json b/apps/user_status/l10n/zh_CN.json
index 1eb70482ecc..8546482d238 100644
--- a/apps/user_status/l10n/zh_CN.json
+++ b/apps/user_status/l10n/zh_CN.json
@@ -1,38 +1,49 @@
{ "translations": {
"Recent statuses" : "最近状态",
+ "No recent status changes" : "最近状态没有改变",
"In a meeting" : "开会中",
"Commuting" : "通勤中",
"Out sick" : "生病了",
"Vacationing" : "度假中",
+ "Out of office" : "不在办公室",
"Working remotely" : "远程办公中",
"In a call" : "通话中",
+ "Be right back" : "马上回来",
"User status" : "用户状态",
- "View profile" : "查看个人资料",
- "Clear status message after" : "清除状态信息",
- "What is your status?" : "你什么状态?",
- "Set status" : "设定状态",
- "Online status" : "在线状态",
- "Status message" : "状态信息",
- "Clear status message" : "清除状态信息",
- "Set status message" : "设定状态信息",
+ "Clear status after" : "清除状态于",
+ "Emoji for your status message" : "状态消息的表情符号",
+ "What is your status?" : "您的状态如何?",
+ "Predefined statuses" : "预定义状态",
+ "Previously set" : "先前设置",
+ "Reset status" : "重置状态",
+ "Reset status to \"{icon} {message}\"" : "将状态重置为“{icon} {message}”",
+ "Reset status to \"{message}\"" : "将状态重置为“{message}”",
+ "Reset status to \"{icon}\"" : "将状态重置为“{icon}”",
"There was an error saving the status" : "保存状态时出错",
"There was an error clearing the status" : "清除状态时出错",
- "No recent status changes" : "最近状态没有改变",
- "Away" : "离开",
- "Do not disturb" : "请勿打扰",
- "{status}, {timestamp}" : "{status}, {timestamp}",
+ "There was an error reverting the status" : "恢复状态时出错",
+ "Online status" : "在线状态",
+ "Status message" : "状态消息",
+ "Set absence period" : "设置缺勤时段",
+ "Set absence period and replacement" : "设置缺勤时段和接替者",
+ "Your status was set automatically" : "您的状态已自动设置",
+ "Clear status message" : "清除状态消息",
+ "Set status message" : "设置状态消息",
"Don't clear" : "不要清除",
"Today" : "今天",
"This week" : "本周",
"Online" : "在线",
- "Invisible" : "不可见",
+ "Away" : "离开",
+ "Do not disturb" : "勿扰",
+ "Invisible" : "隐身",
"Offline" : "离线",
+ "Set status" : "设置状态",
"There was an error saving the new status" : "保存新状态时出错",
"30 minutes" : "30 分钟",
"1 hour" : "1 小时",
"4 hours" : "4 小时",
+ "Busy" : "忙碌",
"Mute all notifications" : "静音所有通知",
- "Appear offline" : "显示为离线",
- "What's your status?" : "您现在是什么状态?"
+ "Appear offline" : "显示为离线"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/zh_HK.js b/apps/user_status/l10n/zh_HK.js
index c6c385c93d3..66fcd087abe 100644
--- a/apps/user_status/l10n/zh_HK.js
+++ b/apps/user_status/l10n/zh_HK.js
@@ -2,39 +2,50 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "最近的狀態",
+ "No recent status changes" : "最近沒有狀態變更",
"In a meeting" : "會議中",
"Commuting" : "通勤中",
"Out sick" : "生病了 ",
"Vacationing" : "休假中",
+ "Out of office" : "不在辦公室",
"Working remotely" : "遠程工作中",
"In a call" : "通話中",
+ "Be right back" : "馬上回來",
"User status" : "用戶狀態",
- "View profile" : "查看個人資料",
- "Clear status message after" : "繼此之後清空狀態訊息",
+ "Clear status after" : "繼此之後清空狀態",
+ "Emoji for your status message" : "狀態訊息的表情符號",
"What is your status?" : "您目前的狀態是什麼呢?",
- "Set status" : "設定狀態",
+ "Predefined statuses" : "預先定義的狀態",
+ "Previously set" : "先前設定",
+ "Reset status" : "重設狀態",
+ "Reset status to \"{icon} {message}\"" : "將狀態重置為 “{icon} {message}”",
+ "Reset status to \"{message}\"" : "將狀態重置為“{message}”",
+ "Reset status to \"{icon}\"" : "將狀態重置為“{icon}”",
+ "There was an error saving the status" : "儲存狀態時發生錯誤",
+ "There was an error clearing the status" : "變更狀態時發生錯誤",
+ "There was an error reverting the status" : "恢復狀態時出錯",
"Online status" : "線上狀態",
"Status message" : "狀態訊息",
+ "Set absence period" : "設定缺席時間",
+ "Set absence period and replacement" : "設定缺席時間與職務代理人",
+ "Your status was set automatically" : "您的狀態是自動設置的",
"Clear status message" : "清空狀態訊息",
"Set status message" : "設定狀態訊息",
- "There was an error saving the status" : "儲存狀態時發生錯誤",
- "There was an error clearing the status" : "變更狀態時發生錯誤",
- "No recent status changes" : "最近沒有狀態變更",
- "Away" : "離開",
- "Do not disturb" : "請勿打擾",
- "{status}, {timestamp}" : "{status},{timestamp}",
"Don't clear" : "不要清空",
"Today" : "今日",
"This week" : "本星期",
"Online" : "在線",
+ "Away" : "離開",
+ "Do not disturb" : "請勿打擾",
"Invisible" : "隱藏",
"Offline" : "離線",
+ "Set status" : "設定狀態",
"There was an error saving the new status" : "儲存新狀態時發生錯誤",
"30 minutes" : "30分鐘",
"1 hour" : "1 小時",
"4 hours" : "4 小時",
+ "Busy" : "忙碌",
"Mute all notifications" : "靜音所有通知",
- "Appear offline" : "顯示為離線",
- "What's your status?" : "你目前的狀態?"
+ "Appear offline" : "顯示為離線"
},
"nplurals=1; plural=0;");
diff --git a/apps/user_status/l10n/zh_HK.json b/apps/user_status/l10n/zh_HK.json
index f9aaaa1f6ea..a95da1fa45c 100644
--- a/apps/user_status/l10n/zh_HK.json
+++ b/apps/user_status/l10n/zh_HK.json
@@ -1,38 +1,49 @@
{ "translations": {
"Recent statuses" : "最近的狀態",
+ "No recent status changes" : "最近沒有狀態變更",
"In a meeting" : "會議中",
"Commuting" : "通勤中",
"Out sick" : "生病了 ",
"Vacationing" : "休假中",
+ "Out of office" : "不在辦公室",
"Working remotely" : "遠程工作中",
"In a call" : "通話中",
+ "Be right back" : "馬上回來",
"User status" : "用戶狀態",
- "View profile" : "查看個人資料",
- "Clear status message after" : "繼此之後清空狀態訊息",
+ "Clear status after" : "繼此之後清空狀態",
+ "Emoji for your status message" : "狀態訊息的表情符號",
"What is your status?" : "您目前的狀態是什麼呢?",
- "Set status" : "設定狀態",
+ "Predefined statuses" : "預先定義的狀態",
+ "Previously set" : "先前設定",
+ "Reset status" : "重設狀態",
+ "Reset status to \"{icon} {message}\"" : "將狀態重置為 “{icon} {message}”",
+ "Reset status to \"{message}\"" : "將狀態重置為“{message}”",
+ "Reset status to \"{icon}\"" : "將狀態重置為“{icon}”",
+ "There was an error saving the status" : "儲存狀態時發生錯誤",
+ "There was an error clearing the status" : "變更狀態時發生錯誤",
+ "There was an error reverting the status" : "恢復狀態時出錯",
"Online status" : "線上狀態",
"Status message" : "狀態訊息",
+ "Set absence period" : "設定缺席時間",
+ "Set absence period and replacement" : "設定缺席時間與職務代理人",
+ "Your status was set automatically" : "您的狀態是自動設置的",
"Clear status message" : "清空狀態訊息",
"Set status message" : "設定狀態訊息",
- "There was an error saving the status" : "儲存狀態時發生錯誤",
- "There was an error clearing the status" : "變更狀態時發生錯誤",
- "No recent status changes" : "最近沒有狀態變更",
- "Away" : "離開",
- "Do not disturb" : "請勿打擾",
- "{status}, {timestamp}" : "{status},{timestamp}",
"Don't clear" : "不要清空",
"Today" : "今日",
"This week" : "本星期",
"Online" : "在線",
+ "Away" : "離開",
+ "Do not disturb" : "請勿打擾",
"Invisible" : "隱藏",
"Offline" : "離線",
+ "Set status" : "設定狀態",
"There was an error saving the new status" : "儲存新狀態時發生錯誤",
"30 minutes" : "30分鐘",
"1 hour" : "1 小時",
"4 hours" : "4 小時",
+ "Busy" : "忙碌",
"Mute all notifications" : "靜音所有通知",
- "Appear offline" : "顯示為離線",
- "What's your status?" : "你目前的狀態?"
+ "Appear offline" : "顯示為離線"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/apps/user_status/l10n/zh_TW.js b/apps/user_status/l10n/zh_TW.js
index 2b8bb4b6c15..c4cd18345a5 100644
--- a/apps/user_status/l10n/zh_TW.js
+++ b/apps/user_status/l10n/zh_TW.js
@@ -2,39 +2,50 @@ OC.L10N.register(
"user_status",
{
"Recent statuses" : "最近的狀態",
+ "No recent status changes" : "最近沒有狀態變更",
"In a meeting" : "會議中",
"Commuting" : "通勤中",
- "Out sick" : "生病",
- "Vacationing" : "休假",
- "Working remotely" : "遠地工作",
+ "Out sick" : "病假",
+ "Vacationing" : "休假中",
+ "Out of office" : "不在辦公室",
+ "Working remotely" : "遠端工作",
"In a call" : "通話中",
+ "Be right back" : "馬上回來",
"User status" : "使用者狀態",
- "View profile" : "檢視個人檔案",
- "Clear status message after" : "清空狀態訊息於……之後",
+ "Clear status after" : "多久後清除狀態",
+ "Emoji for your status message" : "狀態訊息的表情符號",
"What is your status?" : "您目前的狀態是什麼呢?",
- "Set status" : "設定狀態",
+ "Predefined statuses" : "預先定義的狀態",
+ "Previously set" : "先前設定",
+ "Reset status" : "重設狀態",
+ "Reset status to \"{icon} {message}\"" : "重設狀態為「{icon} {message}」",
+ "Reset status to \"{message}\"" : "重設狀態為「{message}」",
+ "Reset status to \"{icon}\"" : "重設狀態為「{icon}」",
+ "There was an error saving the status" : "儲存狀態時發生錯誤",
+ "There was an error clearing the status" : "變更狀態時發生錯誤",
+ "There was an error reverting the status" : "還原狀態時發生錯誤",
"Online status" : "線上狀態",
"Status message" : "狀態訊息",
- "Clear status message" : "清空狀態訊息",
+ "Set absence period" : "設定缺席時間",
+ "Set absence period and replacement" : "設定缺席時間與職務代理人",
+ "Your status was set automatically" : "您的狀態為自動設定",
+ "Clear status message" : "清除狀態訊息",
"Set status message" : "設定狀態訊息",
- "There was an error saving the status" : "儲存狀態時發生錯誤",
- "There was an error clearing the status" : "變更狀態時發生錯誤",
- "No recent status changes" : "最近沒有狀態變更",
- "Away" : "外出",
- "Do not disturb" : "請勿打擾",
- "{status}, {timestamp}" : "{status},{timestamp}",
- "Don't clear" : "不要清空",
+ "Don't clear" : "不要清除",
"Today" : "今天",
"This week" : "本週",
"Online" : "上線",
+ "Away" : "離開",
+ "Do not disturb" : "請勿打擾",
"Invisible" : "隱藏",
"Offline" : "離線",
+ "Set status" : "設定狀態",
"There was an error saving the new status" : "儲存新狀態時發生錯誤",
- "30 minutes" : "30分鐘",
- "1 hour" : "1小時",
- "4 hours" : "4小時",
- "Mute all notifications" : "所有通知靜音",
- "Appear offline" : "顯示為離線",
- "What's your status?" : "您現在的狀態?"
+ "30 minutes" : "30 分鐘",
+ "1 hour" : "1 小時",
+ "4 hours" : "4 小時",
+ "Busy" : "忙碌",
+ "Mute all notifications" : "靜音所有通知",
+ "Appear offline" : "顯示為離線"
},
"nplurals=1; plural=0;");
diff --git a/apps/user_status/l10n/zh_TW.json b/apps/user_status/l10n/zh_TW.json
index 7990e9b54e3..9e99204b682 100644
--- a/apps/user_status/l10n/zh_TW.json
+++ b/apps/user_status/l10n/zh_TW.json
@@ -1,38 +1,49 @@
{ "translations": {
"Recent statuses" : "最近的狀態",
+ "No recent status changes" : "最近沒有狀態變更",
"In a meeting" : "會議中",
"Commuting" : "通勤中",
- "Out sick" : "生病",
- "Vacationing" : "休假",
- "Working remotely" : "遠地工作",
+ "Out sick" : "病假",
+ "Vacationing" : "休假中",
+ "Out of office" : "不在辦公室",
+ "Working remotely" : "遠端工作",
"In a call" : "通話中",
+ "Be right back" : "馬上回來",
"User status" : "使用者狀態",
- "View profile" : "檢視個人檔案",
- "Clear status message after" : "清空狀態訊息於……之後",
+ "Clear status after" : "多久後清除狀態",
+ "Emoji for your status message" : "狀態訊息的表情符號",
"What is your status?" : "您目前的狀態是什麼呢?",
- "Set status" : "設定狀態",
+ "Predefined statuses" : "預先定義的狀態",
+ "Previously set" : "先前設定",
+ "Reset status" : "重設狀態",
+ "Reset status to \"{icon} {message}\"" : "重設狀態為「{icon} {message}」",
+ "Reset status to \"{message}\"" : "重設狀態為「{message}」",
+ "Reset status to \"{icon}\"" : "重設狀態為「{icon}」",
+ "There was an error saving the status" : "儲存狀態時發生錯誤",
+ "There was an error clearing the status" : "變更狀態時發生錯誤",
+ "There was an error reverting the status" : "還原狀態時發生錯誤",
"Online status" : "線上狀態",
"Status message" : "狀態訊息",
- "Clear status message" : "清空狀態訊息",
+ "Set absence period" : "設定缺席時間",
+ "Set absence period and replacement" : "設定缺席時間與職務代理人",
+ "Your status was set automatically" : "您的狀態為自動設定",
+ "Clear status message" : "清除狀態訊息",
"Set status message" : "設定狀態訊息",
- "There was an error saving the status" : "儲存狀態時發生錯誤",
- "There was an error clearing the status" : "變更狀態時發生錯誤",
- "No recent status changes" : "最近沒有狀態變更",
- "Away" : "外出",
- "Do not disturb" : "請勿打擾",
- "{status}, {timestamp}" : "{status},{timestamp}",
- "Don't clear" : "不要清空",
+ "Don't clear" : "不要清除",
"Today" : "今天",
"This week" : "本週",
"Online" : "上線",
+ "Away" : "離開",
+ "Do not disturb" : "請勿打擾",
"Invisible" : "隱藏",
"Offline" : "離線",
+ "Set status" : "設定狀態",
"There was an error saving the new status" : "儲存新狀態時發生錯誤",
- "30 minutes" : "30分鐘",
- "1 hour" : "1小時",
- "4 hours" : "4小時",
- "Mute all notifications" : "所有通知靜音",
- "Appear offline" : "顯示為離線",
- "What's your status?" : "您現在的狀態?"
+ "30 minutes" : "30 分鐘",
+ "1 hour" : "1 小時",
+ "4 hours" : "4 小時",
+ "Busy" : "忙碌",
+ "Mute all notifications" : "靜音所有通知",
+ "Appear offline" : "顯示為離線"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/apps/user_status/lib/AppInfo/Application.php b/apps/user_status/lib/AppInfo/Application.php
index 7a47fc45c95..5199c3fdbf0 100644
--- a/apps/user_status/lib/AppInfo/Application.php
+++ b/apps/user_status/lib/AppInfo/Application.php
@@ -3,40 +3,29 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\AppInfo;
use OCA\UserStatus\Capabilities;
use OCA\UserStatus\Connector\UserStatusProvider;
+use OCA\UserStatus\Dashboard\UserStatusWidget;
use OCA\UserStatus\Listener\BeforeTemplateRenderedListener;
+use OCA\UserStatus\Listener\OutOfOfficeStatusListener;
use OCA\UserStatus\Listener\UserDeletedListener;
use OCA\UserStatus\Listener\UserLiveStatusListener;
-use OCA\UserStatus\Dashboard\UserStatusWidget;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent;
use OCP\IConfig;
+use OCP\User\Events\OutOfOfficeChangedEvent;
+use OCP\User\Events\OutOfOfficeClearedEvent;
+use OCP\User\Events\OutOfOfficeEndedEvent;
+use OCP\User\Events\OutOfOfficeScheduledEvent;
+use OCP\User\Events\OutOfOfficeStartedEvent;
use OCP\User\Events\UserDeletedEvent;
use OCP\User\Events\UserLiveStatusEvent;
use OCP\UserStatus\IManager;
@@ -71,6 +60,11 @@ class Application extends App implements IBootstrap {
$context->registerEventListener(UserDeletedEvent::class, UserDeletedListener::class);
$context->registerEventListener(UserLiveStatusEvent::class, UserLiveStatusListener::class);
$context->registerEventListener(BeforeTemplateRenderedEvent::class, BeforeTemplateRenderedListener::class);
+ $context->registerEventListener(OutOfOfficeChangedEvent::class, OutOfOfficeStatusListener::class);
+ $context->registerEventListener(OutOfOfficeScheduledEvent::class, OutOfOfficeStatusListener::class);
+ $context->registerEventListener(OutOfOfficeClearedEvent::class, OutOfOfficeStatusListener::class);
+ $context->registerEventListener(OutOfOfficeStartedEvent::class, OutOfOfficeStatusListener::class);
+ $context->registerEventListener(OutOfOfficeEndedEvent::class, OutOfOfficeStatusListener::class);
$config = $this->getContainer()->query(IConfig::class);
$shareeEnumeration = $config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
diff --git a/apps/user_status/lib/BackgroundJob/ClearOldStatusesBackgroundJob.php b/apps/user_status/lib/BackgroundJob/ClearOldStatusesBackgroundJob.php
index 0d8f5ac431b..51a9c623a03 100644
--- a/apps/user_status/lib/BackgroundJob/ClearOldStatusesBackgroundJob.php
+++ b/apps/user_status/lib/BackgroundJob/ClearOldStatusesBackgroundJob.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\BackgroundJob;
@@ -37,21 +20,18 @@ use OCP\BackgroundJob\TimedJob;
*/
class ClearOldStatusesBackgroundJob extends TimedJob {
- /** @var UserStatusMapper */
- private $mapper;
-
/**
* ClearOldStatusesBackgroundJob constructor.
*
* @param ITimeFactory $time
* @param UserStatusMapper $mapper
*/
- public function __construct(ITimeFactory $time,
- UserStatusMapper $mapper) {
+ public function __construct(
+ ITimeFactory $time,
+ private UserStatusMapper $mapper,
+ ) {
parent::__construct($time);
- $this->mapper = $mapper;
- // Run every time the cron is run
$this->setInterval(60);
}
@@ -61,7 +41,7 @@ class ClearOldStatusesBackgroundJob extends TimedJob {
protected function run($argument) {
$now = $this->time->getTime();
- $this->mapper->clearMessagesOlderThan($now);
+ $this->mapper->clearOlderThanClearAt($now);
$this->mapper->clearStatusesOlderThan($now - StatusService::INVALIDATE_STATUS_THRESHOLD, $now);
}
}
diff --git a/apps/user_status/lib/Capabilities.php b/apps/user_status/lib/Capabilities.php
index f5b35896a56..c3edbc032d6 100644
--- a/apps/user_status/lib/Capabilities.php
+++ b/apps/user_status/lib/Capabilities.php
@@ -3,30 +3,13 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus;
-use OCA\UserStatus\Service\EmojiService;
use OCP\Capabilities\ICapability;
+use OCP\IEmojiHelper;
/**
* Class Capabilities
@@ -34,27 +17,21 @@ use OCP\Capabilities\ICapability;
* @package OCA\UserStatus
*/
class Capabilities implements ICapability {
-
- /** @var EmojiService */
- private $emojiService;
-
- /**
- * Capabilities constructor.
- *
- * @param EmojiService $emojiService
- */
- public function __construct(EmojiService $emojiService) {
- $this->emojiService = $emojiService;
+ public function __construct(
+ private IEmojiHelper $emojiHelper,
+ ) {
}
/**
- * @inheritDoc
+ * @return array{user_status: array{enabled: bool, restore: bool, supports_emoji: bool, supports_busy: bool}}
*/
public function getCapabilities() {
return [
'user_status' => [
'enabled' => true,
- 'supports_emoji' => $this->emojiService->doesPlatformSupportEmoji(),
+ 'restore' => true,
+ 'supports_emoji' => $this->emojiHelper->doesPlatformSupportEmoji(),
+ 'supports_busy' => true,
],
];
}
diff --git a/apps/user_status/lib/Connector/UserStatus.php b/apps/user_status/lib/Connector/UserStatus.php
index ff05ded9e2b..04467a99e5e 100644
--- a/apps/user_status/lib/Connector/UserStatus.php
+++ b/apps/user_status/lib/Connector/UserStatus.php
@@ -3,31 +3,14 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Connector;
use DateTimeImmutable;
-use OCP\UserStatus\IUserStatus;
use OCA\UserStatus\Db;
+use OCP\UserStatus\IUserStatus;
class UserStatus implements IUserStatus {
@@ -46,21 +29,19 @@ class UserStatus implements IUserStatus {
/** @var DateTimeImmutable|null */
private $clearAt;
- /** @var Db\UserStatus */
- private $internalStatus;
-
- public function __construct(Db\UserStatus $status) {
- $this->internalStatus = $status;
- $this->userId = $status->getUserId();
- $this->status = $status->getStatus();
- $this->message = $status->getCustomMessage();
- $this->icon = $status->getCustomIcon();
+ public function __construct(
+ private Db\UserStatus $internalStatus,
+ ) {
+ $this->userId = $this->internalStatus->getUserId();
+ $this->status = $this->internalStatus->getStatus();
+ $this->message = $this->internalStatus->getCustomMessage();
+ $this->icon = $this->internalStatus->getCustomIcon();
- if ($status->getStatus() === IUserStatus::INVISIBLE) {
+ if ($this->internalStatus->getStatus() === IUserStatus::INVISIBLE) {
$this->status = IUserStatus::OFFLINE;
}
- if ($status->getClearAt() !== null) {
- $this->clearAt = DateTimeImmutable::createFromFormat('U', (string)$status->getClearAt());
+ if ($this->internalStatus->getClearAt() !== null) {
+ $this->clearAt = DateTimeImmutable::createFromFormat('U', (string)$this->internalStatus->getClearAt());
}
}
diff --git a/apps/user_status/lib/Connector/UserStatusProvider.php b/apps/user_status/lib/Connector/UserStatusProvider.php
index 46b89739f7c..e84d69d1eb2 100644
--- a/apps/user_status/lib/Connector/UserStatusProvider.php
+++ b/apps/user_status/lib/Connector/UserStatusProvider.php
@@ -3,44 +3,25 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Connector;
+use OC\UserStatus\ISettableProvider;
use OCA\UserStatus\Service\StatusService;
use OCP\UserStatus\IProvider;
-use OC\UserStatus\ISettableProvider;
class UserStatusProvider implements IProvider, ISettableProvider {
- /** @var StatusService */
- private $service;
-
/**
* UserStatusProvider constructor.
*
* @param StatusService $service
*/
- public function __construct(StatusService $service) {
- $this->service = $service;
+ public function __construct(
+ private StatusService $service,
+ ) {
}
/**
@@ -57,15 +38,15 @@ class UserStatusProvider implements IProvider, ISettableProvider {
return $userStatuses;
}
- public function setUserStatus(string $userId, string $messageId, string $status, bool $createBackup): void {
- $this->service->setUserStatus($userId, $status, $messageId, $createBackup);
+ public function setUserStatus(string $userId, string $messageId, string $status, bool $createBackup, ?string $customMessage = null): void {
+ $this->service->setUserStatus($userId, $status, $messageId, $createBackup, $customMessage);
}
public function revertUserStatus(string $userId, string $messageId, string $status): void {
- $this->service->revertUserStatus($userId, $messageId, $status);
+ $this->service->revertUserStatus($userId, $messageId);
}
public function revertMultipleUserStatus(array $userIds, string $messageId, string $status): void {
- $this->service->revertMultipleUserStatus($userIds, $messageId, $status);
+ $this->service->revertMultipleUserStatus($userIds, $messageId);
}
}
diff --git a/apps/user_status/lib/ContactsMenu/StatusProvider.php b/apps/user_status/lib/ContactsMenu/StatusProvider.php
new file mode 100644
index 00000000000..6a6949b46ba
--- /dev/null
+++ b/apps/user_status/lib/ContactsMenu/StatusProvider.php
@@ -0,0 +1,53 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCA\UserStatus\ContactsMenu;
+
+use OCA\UserStatus\Db\UserStatus;
+use OCA\UserStatus\Service\StatusService;
+use OCP\Contacts\ContactsMenu\IBulkProvider;
+use OCP\Contacts\ContactsMenu\IEntry;
+use function array_combine;
+use function array_filter;
+use function array_map;
+
+class StatusProvider implements IBulkProvider {
+
+ public function __construct(
+ private StatusService $statusService,
+ ) {
+ }
+
+ public function process(array $entries): void {
+ $uids = array_filter(
+ array_map(fn (IEntry $entry): ?string => $entry->getProperty('UID'), $entries)
+ );
+
+ $statuses = $this->statusService->findByUserIds($uids);
+ /** @var array<string, UserStatus> $indexed */
+ $indexed = array_combine(
+ array_map(fn (UserStatus $status) => $status->getUserId(), $statuses),
+ $statuses
+ );
+
+ foreach ($entries as $entry) {
+ $uid = $entry->getProperty('UID');
+ if ($uid !== null && isset($indexed[$uid])) {
+ $status = $indexed[$uid];
+ $entry->setStatus(
+ $status->getStatus(),
+ $status->getCustomMessage(),
+ $status->getStatusMessageTimestamp(),
+ $status->getCustomIcon(),
+ );
+ }
+ }
+ }
+
+}
diff --git a/apps/user_status/lib/Controller/HeartbeatController.php b/apps/user_status/lib/Controller/HeartbeatController.php
index c11a63b4420..30f4af6572a 100644
--- a/apps/user_status/lib/Controller/HeartbeatController.php
+++ b/apps/user_status/lib/Controller/HeartbeatController.php
@@ -3,34 +3,19 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Controller;
use OCA\UserStatus\Db\UserStatus;
+use OCA\UserStatus\ResponseDefinitions;
use OCA\UserStatus\Service\StatusService;
-use OCP\AppFramework\Controller;
-use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Http;
-use OCP\AppFramework\Http\JSONResponse;
+use OCP\AppFramework\Http\Attribute\ApiRoute;
+use OCP\AppFramework\Http\Attribute\NoAdminRequired;
+use OCP\AppFramework\Http\DataResponse;
+use OCP\AppFramework\OCSController;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\IRequest;
@@ -38,47 +23,43 @@ use OCP\IUserSession;
use OCP\User\Events\UserLiveStatusEvent;
use OCP\UserStatus\IUserStatus;
-class HeartbeatController extends Controller {
-
- /** @var IEventDispatcher */
- private $eventDispatcher;
-
- /** @var IUserSession */
- private $userSession;
-
- /** @var ITimeFactory */
- private $timeFactory;
-
- /** @var StatusService */
- private $service;
-
- public function __construct(string $appName,
- IRequest $request,
- IEventDispatcher $eventDispatcher,
- IUserSession $userSession,
- ITimeFactory $timeFactory,
- StatusService $service) {
+/**
+ * @psalm-import-type UserStatusPrivate from ResponseDefinitions
+ */
+class HeartbeatController extends OCSController {
+
+ public function __construct(
+ string $appName,
+ IRequest $request,
+ private IEventDispatcher $eventDispatcher,
+ private IUserSession $userSession,
+ private ITimeFactory $timeFactory,
+ private StatusService $service,
+ ) {
parent::__construct($appName, $request);
- $this->eventDispatcher = $eventDispatcher;
- $this->userSession = $userSession;
- $this->timeFactory = $timeFactory;
- $this->service = $service;
}
/**
- * @NoAdminRequired
+ * Keep the status alive
+ *
+ * @param string $status Only online, away
+ *
+ * @return DataResponse<Http::STATUS_OK, UserStatusPrivate, array{}>|DataResponse<Http::STATUS_BAD_REQUEST|Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_NO_CONTENT, list<empty>, array{}>
*
- * @param string $status
- * @return JSONResponse
+ * 200: Status successfully updated
+ * 204: User has no status to keep alive
+ * 400: Invalid status to update
*/
- public function heartbeat(string $status): JSONResponse {
+ #[NoAdminRequired]
+ #[ApiRoute(verb: 'PUT', url: '/api/v1/heartbeat')]
+ public function heartbeat(string $status): DataResponse {
if (!\in_array($status, [IUserStatus::ONLINE, IUserStatus::AWAY], true)) {
- return new JSONResponse([], Http::STATUS_BAD_REQUEST);
+ return new DataResponse([], Http::STATUS_BAD_REQUEST);
}
$user = $this->userSession->getUser();
if ($user === null) {
- return new JSONResponse([], Http::STATUS_INTERNAL_SERVER_ERROR);
+ return new DataResponse([], Http::STATUS_INTERNAL_SERVER_ERROR);
}
$event = new UserLiveStatusEvent(
@@ -91,11 +72,11 @@ class HeartbeatController extends Controller {
$userStatus = $event->getUserStatus();
if (!$userStatus) {
- return new JSONResponse([], Http::STATUS_NO_CONTENT);
+ return new DataResponse([], Http::STATUS_NO_CONTENT);
}
/** @psalm-suppress UndefinedInterfaceMethod */
- return new JSONResponse($this->formatStatus($userStatus->getInternal()));
+ return new DataResponse($this->formatStatus($userStatus->getInternal()));
}
private function formatStatus(UserStatus $status): array {
diff --git a/apps/user_status/lib/Controller/PredefinedStatusController.php b/apps/user_status/lib/Controller/PredefinedStatusController.php
index ea1ff5209b8..70262d1108a 100644
--- a/apps/user_status/lib/Controller/PredefinedStatusController.php
+++ b/apps/user_status/lib/Controller/PredefinedStatusController.php
@@ -3,43 +3,27 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Controller;
+use OCA\UserStatus\ResponseDefinitions;
use OCA\UserStatus\Service\PredefinedStatusService;
+use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\Attribute\ApiRoute;
+use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCSController;
use OCP\IRequest;
/**
- * Class DefaultStatusController
- *
* @package OCA\UserStatus\Controller
+ *
+ * @psalm-import-type UserStatusPredefined from ResponseDefinitions
*/
class PredefinedStatusController extends OCSController {
- /** @var PredefinedStatusService */
- private $predefinedStatusService;
-
/**
* AStatusController constructor.
*
@@ -47,22 +31,27 @@ class PredefinedStatusController extends OCSController {
* @param IRequest $request
* @param PredefinedStatusService $predefinedStatusService
*/
- public function __construct(string $appName,
- IRequest $request,
- PredefinedStatusService $predefinedStatusService) {
+ public function __construct(
+ string $appName,
+ IRequest $request,
+ private PredefinedStatusService $predefinedStatusService,
+ ) {
parent::__construct($appName, $request);
- $this->predefinedStatusService = $predefinedStatusService;
}
/**
- * @NoAdminRequired
+ * Get all predefined messages
+ *
+ * @return DataResponse<Http::STATUS_OK, list<UserStatusPredefined>, array{}>
*
- * @return DataResponse
+ * 200: Predefined statuses returned
*/
+ #[NoAdminRequired]
+ #[ApiRoute(verb: 'GET', url: '/api/v1/predefined_statuses/')]
public function findAll():DataResponse {
// Filtering out the invisible one, that should only be set by API
- return new DataResponse(array_filter($this->predefinedStatusService->getDefaultStatuses(), function (array $status) {
+ return new DataResponse(array_values(array_filter($this->predefinedStatusService->getDefaultStatuses(), function (array $status) {
return !array_key_exists('visible', $status) || $status['visible'] === true;
- }));
+ })));
}
}
diff --git a/apps/user_status/lib/Controller/StatusesController.php b/apps/user_status/lib/Controller/StatusesController.php
index d30389e1716..44688c39023 100644
--- a/apps/user_status/lib/Controller/StatusesController.php
+++ b/apps/user_status/lib/Controller/StatusesController.php
@@ -3,43 +3,30 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Controller;
use OCA\UserStatus\Db\UserStatus;
+use OCA\UserStatus\ResponseDefinitions;
use OCA\UserStatus\Service\StatusService;
use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\Attribute\ApiRoute;
+use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCS\OCSNotFoundException;
use OCP\AppFramework\OCSController;
use OCP\IRequest;
use OCP\UserStatus\IUserStatus;
+/**
+ * @psalm-import-type UserStatusType from ResponseDefinitions
+ * @psalm-import-type UserStatusPublic from ResponseDefinitions
+ */
class StatusesController extends OCSController {
- /** @var StatusService */
- private $service;
-
/**
* StatusesController constructor.
*
@@ -47,35 +34,44 @@ class StatusesController extends OCSController {
* @param IRequest $request
* @param StatusService $service
*/
- public function __construct(string $appName,
- IRequest $request,
- StatusService $service) {
+ public function __construct(
+ string $appName,
+ IRequest $request,
+ private StatusService $service,
+ ) {
parent::__construct($appName, $request);
- $this->service = $service;
}
/**
- * @NoAdminRequired
+ * Find statuses of users
*
- * @param int|null $limit
- * @param int|null $offset
- * @return DataResponse
+ * @param int|null $limit Maximum number of statuses to find
+ * @param non-negative-int|null $offset Offset for finding statuses
+ * @return DataResponse<Http::STATUS_OK, list<UserStatusPublic>, array{}>
+ *
+ * 200: Statuses returned
*/
+ #[NoAdminRequired]
+ #[ApiRoute(verb: 'GET', url: '/api/v1/statuses')]
public function findAll(?int $limit = null, ?int $offset = null): DataResponse {
$allStatuses = $this->service->findAll($limit, $offset);
- return new DataResponse(array_map(function ($userStatus) {
+ return new DataResponse(array_values(array_map(function ($userStatus) {
return $this->formatStatus($userStatus);
- }, $allStatuses));
+ }, $allStatuses)));
}
/**
- * @NoAdminRequired
+ * Find the status of a user
+ *
+ * @param string $userId ID of the user
+ * @return DataResponse<Http::STATUS_OK, UserStatusPublic, array{}>
+ * @throws OCSNotFoundException The user was not found
*
- * @param string $userId
- * @return DataResponse
- * @throws OCSNotFoundException
+ * 200: Status returned
*/
+ #[NoAdminRequired]
+ #[ApiRoute(verb: 'GET', url: '/api/v1/statuses/{userId}')]
public function find(string $userId): DataResponse {
try {
$userStatus = $this->service->findByUserId($userId);
@@ -88,9 +84,10 @@ class StatusesController extends OCSController {
/**
* @param UserStatus $status
- * @return array{userId: string, message: string, icon: string, clearAt: int, status: string}
+ * @return UserStatusPublic
*/
private function formatStatus(UserStatus $status): array {
+ /** @var UserStatusType $visibleStatus */
$visibleStatus = $status->getStatus();
if ($visibleStatus === IUserStatus::INVISIBLE) {
$visibleStatus = IUserStatus::OFFLINE;
diff --git a/apps/user_status/lib/Controller/UserStatusController.php b/apps/user_status/lib/Controller/UserStatusController.php
index 8708a7c2aac..9b3807ce86e 100644
--- a/apps/user_status/lib/Controller/UserStatusController.php
+++ b/apps/user_status/lib/Controller/UserStatusController.php
@@ -3,84 +3,60 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Simon Spannagel <simonspa@kth.se>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Controller;
+use OCA\DAV\CalDAV\Status\StatusService as CalendarStatusService;
use OCA\UserStatus\Db\UserStatus;
use OCA\UserStatus\Exception\InvalidClearAtException;
use OCA\UserStatus\Exception\InvalidMessageIdException;
use OCA\UserStatus\Exception\InvalidStatusIconException;
use OCA\UserStatus\Exception\InvalidStatusTypeException;
use OCA\UserStatus\Exception\StatusMessageTooLongException;
+use OCA\UserStatus\ResponseDefinitions;
use OCA\UserStatus\Service\StatusService;
use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\Attribute\ApiRoute;
+use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCS\OCSBadRequestException;
use OCP\AppFramework\OCS\OCSNotFoundException;
use OCP\AppFramework\OCSController;
-use OCP\ILogger;
use OCP\IRequest;
+use Psr\Log\LoggerInterface;
+/**
+ * @psalm-import-type UserStatusType from ResponseDefinitions
+ * @psalm-import-type UserStatusPrivate from ResponseDefinitions
+ */
class UserStatusController extends OCSController {
-
- /** @var string */
- private $userId;
-
- /** @var ILogger */
- private $logger;
-
- /** @var StatusService */
- private $service;
-
- /**
- * StatusesController constructor.
- *
- * @param string $appName
- * @param IRequest $request
- * @param string $userId
- * @param ILogger $logger;
- * @param StatusService $service
- */
- public function __construct(string $appName,
- IRequest $request,
- string $userId,
- ILogger $logger,
- StatusService $service) {
+ public function __construct(
+ string $appName,
+ IRequest $request,
+ private ?string $userId,
+ private LoggerInterface $logger,
+ private StatusService $service,
+ private CalendarStatusService $calendarStatusService,
+ ) {
parent::__construct($appName, $request);
- $this->userId = $userId;
- $this->logger = $logger;
- $this->service = $service;
}
/**
- * @NoAdminRequired
+ * Get the status of the current user
*
- * @return DataResponse
- * @throws OCSNotFoundException
+ * @return DataResponse<Http::STATUS_OK, UserStatusPrivate, array{}>
+ * @throws OCSNotFoundException The user was not found
+ *
+ * 200: The status was found successfully
*/
+ #[NoAdminRequired]
+ #[ApiRoute(verb: 'GET', url: '/api/v1/user_status')]
public function getStatus(): DataResponse {
try {
+ $this->calendarStatusService->processCalendarStatus($this->userId);
$userStatus = $this->service->findByUserId($this->userId);
} catch (DoesNotExistException $ex) {
throw new OCSNotFoundException('No status for the current user');
@@ -90,12 +66,16 @@ class UserStatusController extends OCSController {
}
/**
- * @NoAdminRequired
+ * Update the status type of the current user
+ *
+ * @param string $statusType The new status type
+ * @return DataResponse<Http::STATUS_OK, UserStatusPrivate, array{}>
+ * @throws OCSBadRequestException The status type is invalid
*
- * @param string $statusType
- * @return DataResponse
- * @throws OCSBadRequestException
+ * 200: The status was updated successfully
*/
+ #[NoAdminRequired]
+ #[ApiRoute(verb: 'PUT', url: '/api/v1/user_status/status')]
public function setStatus(string $statusType): DataResponse {
try {
$status = $this->service->setStatus($this->userId, $statusType, null, true);
@@ -109,15 +89,19 @@ class UserStatusController extends OCSController {
}
/**
- * @NoAdminRequired
+ * Set the message to a predefined message for the current user
+ *
+ * @param string $messageId ID of the predefined message
+ * @param int|null $clearAt When the message should be cleared
+ * @return DataResponse<Http::STATUS_OK, UserStatusPrivate, array{}>
+ * @throws OCSBadRequestException The clearAt or message-id is invalid
*
- * @param string $messageId
- * @param int|null $clearAt
- * @return DataResponse
- * @throws OCSBadRequestException
+ * 200: The message was updated successfully
*/
+ #[NoAdminRequired]
+ #[ApiRoute(verb: 'PUT', url: '/api/v1/user_status/message/predefined')]
public function setPredefinedMessage(string $messageId,
- ?int $clearAt): DataResponse {
+ ?int $clearAt): DataResponse {
try {
$status = $this->service->setPredefinedMessage($this->userId, $messageId, $clearAt);
$this->service->removeBackupUserStatus($this->userId);
@@ -132,19 +116,24 @@ class UserStatusController extends OCSController {
}
/**
- * @NoAdminRequired
+ * Set the message to a custom message for the current user
*
- * @param string|null $statusIcon
- * @param string $message
- * @param int|null $clearAt
- * @return DataResponse
- * @throws OCSBadRequestException
+ * @param string|null $statusIcon Icon of the status
+ * @param string|null $message Message of the status
+ * @param int|null $clearAt When the message should be cleared
+ * @return DataResponse<Http::STATUS_OK, UserStatusPrivate, array{}>
+ * @throws OCSBadRequestException The clearAt or icon is invalid or the message is too long
+ * @throws OCSNotFoundException No status for the current user
+ *
+ * 200: The message was updated successfully
*/
+ #[NoAdminRequired]
+ #[ApiRoute(verb: 'PUT', url: '/api/v1/user_status/message/custom')]
public function setCustomMessage(?string $statusIcon,
- ?string $message,
- ?int $clearAt): DataResponse {
+ ?string $message,
+ ?int $clearAt): DataResponse {
try {
- if ($message !== null && $message !== '') {
+ if (($statusIcon !== null && $statusIcon !== '') || ($message !== null && $message !== '') || ($clearAt !== null && $clearAt !== 0)) {
$status = $this->service->setCustomMessage($this->userId, $statusIcon, $message, $clearAt);
} else {
$this->service->clearMessage($this->userId);
@@ -161,34 +150,51 @@ class UserStatusController extends OCSController {
} catch (StatusMessageTooLongException $ex) {
$this->logger->debug('New user-status for "' . $this->userId . '" was rejected due to a too long status message.');
throw new OCSBadRequestException($ex->getMessage(), $ex);
+ } catch (DoesNotExistException $ex) {
+ throw new OCSNotFoundException('No status for the current user');
}
}
/**
- * @NoAdminRequired
+ * Clear the message of the current user
*
- * @return DataResponse
+ * @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
+ *
+ * 200: Message cleared successfully
*/
- public function clearStatus(): DataResponse {
- $this->service->clearStatus($this->userId);
+ #[NoAdminRequired]
+ #[ApiRoute(verb: 'DELETE', url: '/api/v1/user_status/message')]
+ public function clearMessage(): DataResponse {
+ $this->service->clearMessage($this->userId);
return new DataResponse([]);
}
/**
- * @NoAdminRequired
+ * Revert the status to the previous status
*
- * @return DataResponse
+ * @param string $messageId ID of the message to delete
+ *
+ * @return DataResponse<Http::STATUS_OK, UserStatusPrivate|list<empty>, array{}>
+ *
+ * 200: Status reverted
*/
- public function clearMessage(): DataResponse {
- $this->service->clearMessage($this->userId);
+ #[NoAdminRequired]
+ #[ApiRoute(verb: 'DELETE', url: '/api/v1/user_status/revert/{messageId}')]
+ public function revertStatus(string $messageId): DataResponse {
+ $backupStatus = $this->service->revertUserStatus($this->userId, $messageId, true);
+ if ($backupStatus) {
+ return new DataResponse($this->formatStatus($backupStatus));
+ }
return new DataResponse([]);
}
/**
* @param UserStatus $status
- * @return array
+ * @return UserStatusPrivate
*/
private function formatStatus(UserStatus $status): array {
+ /** @var UserStatusType $visibleStatus */
+ $visibleStatus = $status->getStatus();
return [
'userId' => $status->getUserId(),
'message' => $status->getCustomMessage(),
@@ -196,7 +202,7 @@ class UserStatusController extends OCSController {
'messageIsPredefined' => $status->getMessageId() !== null,
'icon' => $status->getCustomIcon(),
'clearAt' => $status->getClearAt(),
- 'status' => $status->getStatus(),
+ 'status' => $visibleStatus,
'statusIsUserDefined' => $status->getIsUserDefined(),
];
}
diff --git a/apps/user_status/lib/Dashboard/UserStatusWidget.php b/apps/user_status/lib/Dashboard/UserStatusWidget.php
index 10411dc7f9d..2870a2c1907 100644
--- a/apps/user_status/lib/Dashboard/UserStatusWidget.php
+++ b/apps/user_status/lib/Dashboard/UserStatusWidget.php
@@ -3,34 +3,25 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Dashboard;
use OCA\UserStatus\AppInfo\Application;
use OCA\UserStatus\Db\UserStatus;
use OCA\UserStatus\Service\StatusService;
-use OCP\Dashboard\IWidget;
-use OCP\IInitialStateService;
+use OCP\AppFramework\Services\IInitialState;
+use OCP\Dashboard\IAPIWidget;
+use OCP\Dashboard\IAPIWidgetV2;
+use OCP\Dashboard\IIconWidget;
+use OCP\Dashboard\IOptionWidget;
+use OCP\Dashboard\Model\WidgetItem;
+use OCP\Dashboard\Model\WidgetItems;
+use OCP\Dashboard\Model\WidgetOptions;
+use OCP\IDateTimeFormatter;
use OCP\IL10N;
+use OCP\IURLGenerator;
use OCP\IUserManager;
use OCP\IUserSession;
use OCP\UserStatus\IUserStatus;
@@ -40,42 +31,27 @@ use OCP\UserStatus\IUserStatus;
*
* @package OCA\UserStatus
*/
-class UserStatusWidget implements IWidget {
-
- /** @var IL10N */
- private $l10n;
-
- /** @var IInitialStateService */
- private $initialStateService;
-
- /** @var IUserManager */
- private $userManager;
-
- /** @var IUserSession */
- private $userSession;
-
- /** @var StatusService */
- private $service;
-
+class UserStatusWidget implements IAPIWidget, IAPIWidgetV2, IIconWidget, IOptionWidget {
/**
* UserStatusWidget constructor
*
* @param IL10N $l10n
- * @param IInitialStateService $initialStateService
+ * @param IDateTimeFormatter $dateTimeFormatter
+ * @param IURLGenerator $urlGenerator
+ * @param IInitialState $initialStateService
* @param IUserManager $userManager
* @param IUserSession $userSession
* @param StatusService $service
*/
- public function __construct(IL10N $l10n,
- IInitialStateService $initialStateService,
- IUserManager $userManager,
- IUserSession $userSession,
- StatusService $service) {
- $this->l10n = $l10n;
- $this->initialStateService = $initialStateService;
- $this->userManager = $userManager;
- $this->userSession = $userSession;
- $this->service = $service;
+ public function __construct(
+ private IL10N $l10n,
+ private IDateTimeFormatter $dateTimeFormatter,
+ private IURLGenerator $urlGenerator,
+ private IInitialState $initialStateService,
+ private IUserManager $userManager,
+ private IUserSession $userSession,
+ private StatusService $service,
+ ) {
}
/**
@@ -103,7 +79,16 @@ class UserStatusWidget implements IWidget {
* @inheritDoc
*/
public function getIconClass(): string {
- return 'icon-user-status';
+ return 'icon-user-status-dark';
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getIconUrl(): string {
+ return $this->urlGenerator->getAbsoluteURL(
+ $this->urlGenerator->imagePath(Application::APP_ID, 'app-dark.svg')
+ );
}
/**
@@ -117,28 +102,22 @@ class UserStatusWidget implements IWidget {
* @inheritDoc
*/
public function load(): void {
- \OCP\Util::addScript(Application::APP_ID, 'dashboard');
-
- $currentUser = $this->userSession->getUser();
- if ($currentUser === null) {
- $this->initialStateService->provideInitialState(Application::APP_ID, 'dashboard_data', []);
- return;
- }
- $currentUserId = $currentUser->getUID();
+ }
+ private function getWidgetData(string $userId, ?string $since = null, int $limit = 7): array {
// Fetch status updates and filter current user
$recentStatusUpdates = array_slice(
array_filter(
- $this->service->findAllRecentStatusChanges(8, 0),
- static function (UserStatus $status) use ($currentUserId): bool {
- return $status->getUserId() !== $currentUserId;
+ $this->service->findAllRecentStatusChanges($limit + 1, 0),
+ static function (UserStatus $status) use ($userId, $since): bool {
+ return $status->getUserId() !== $userId
+ && ($since === null || $status->getStatusTimestamp() > (int)$since);
}
),
0,
- 7
+ $limit
);
-
- $this->initialStateService->provideInitialState(Application::APP_ID, 'dashboard_data', array_map(function (UserStatus $status): array {
+ return array_map(function (UserStatus $status): array {
$user = $this->userManager->get($status->getUserId());
$displayName = $status->getUserId();
if ($user !== null) {
@@ -153,8 +132,46 @@ class UserStatusWidget implements IWidget {
: $status->getStatus(),
'icon' => $status->getCustomIcon(),
'message' => $status->getCustomMessage(),
- 'timestamp' => $status->getStatusTimestamp(),
+ 'timestamp' => $status->getStatusMessageTimestamp(),
];
- }, $recentStatusUpdates));
+ }, $recentStatusUpdates);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getItems(string $userId, ?string $since = null, int $limit = 7): array {
+ $widgetItemsData = $this->getWidgetData($userId, $since, $limit);
+
+ return array_values(array_map(function (array $widgetData) {
+ $formattedDate = $this->dateTimeFormatter->formatTimeSpan($widgetData['timestamp']);
+ return new WidgetItem(
+ $widgetData['displayName'],
+ $widgetData['icon'] . ($widgetData['icon'] ? ' ' : '') . $widgetData['message'] . ', ' . $formattedDate,
+ // https://nextcloud.local/index.php/u/julien
+ $this->urlGenerator->getAbsoluteURL(
+ $this->urlGenerator->linkToRoute('profile.ProfilePage.index', ['targetUserId' => $widgetData['userId']])
+ ),
+ $this->urlGenerator->getAbsoluteURL(
+ $this->urlGenerator->linkToRoute('core.avatar.getAvatar', ['userId' => $widgetData['userId'], 'size' => 44])
+ ),
+ (string)$widgetData['timestamp']
+ );
+ }, $widgetItemsData));
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getItemsV2(string $userId, ?string $since = null, int $limit = 7): WidgetItems {
+ $items = $this->getItems($userId, $since, $limit);
+ return new WidgetItems(
+ $items,
+ count($items) === 0 ? $this->l10n->t('No recent status changes') : '',
+ );
+ }
+
+ public function getWidgetOptions(): WidgetOptions {
+ return new WidgetOptions(true);
}
}
diff --git a/apps/user_status/lib/Db/UserStatus.php b/apps/user_status/lib/Db/UserStatus.php
index 8907c4a2c1b..b2da4a9e07a 100644
--- a/apps/user_status/lib/Db/UserStatus.php
+++ b/apps/user_status/lib/Db/UserStatus.php
@@ -3,29 +3,13 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Db;
use OCP\AppFramework\Db\Entity;
+use OCP\DB\Types;
/**
* Class UserStatus
@@ -42,16 +26,18 @@ use OCP\AppFramework\Db\Entity;
* @method void setStatusTimestamp(int $statusTimestamp)
* @method bool getIsUserDefined()
* @method void setIsUserDefined(bool $isUserDefined)
- * @method string getMessageId()
+ * @method string|null getMessageId()
* @method void setMessageId(string|null $messageId)
- * @method string getCustomIcon()
+ * @method string|null getCustomIcon()
* @method void setCustomIcon(string|null $customIcon)
- * @method string getCustomMessage()
+ * @method string|null getCustomMessage()
* @method void setCustomMessage(string|null $customMessage)
- * @method int getClearAt()
+ * @method int|null getClearAt()
* @method void setClearAt(int|null $clearAt)
- * @method setIsBackup(bool $true): void
+ * @method setIsBackup(bool $isBackup): void
* @method getIsBackup(): bool
+ * @method int getStatusMessageTimestamp()
+ * @method void setStatusMessageTimestamp(int $statusTimestamp)
*/
class UserStatus extends Entity {
@@ -82,15 +68,19 @@ class UserStatus extends Entity {
/** @var bool $isBackup */
public $isBackup;
+ /** @var int */
+ protected $statusMessageTimestamp = 0;
+
public function __construct() {
$this->addType('userId', 'string');
$this->addType('status', 'string');
- $this->addType('statusTimestamp', 'int');
+ $this->addType('statusTimestamp', Types::INTEGER);
$this->addType('isUserDefined', 'boolean');
$this->addType('messageId', 'string');
$this->addType('customIcon', 'string');
$this->addType('customMessage', 'string');
- $this->addType('clearAt', 'int');
+ $this->addType('clearAt', Types::INTEGER);
$this->addType('isBackup', 'boolean');
+ $this->addType('statusMessageTimestamp', Types::INTEGER);
}
}
diff --git a/apps/user_status/lib/Db/UserStatusMapper.php b/apps/user_status/lib/Db/UserStatusMapper.php
index f67cfcd472d..15982d44fd8 100644
--- a/apps/user_status/lib/Db/UserStatusMapper.php
+++ b/apps/user_status/lib/Db/UserStatusMapper.php
@@ -3,29 +3,13 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Db;
+use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Db\QBMapper;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
@@ -75,11 +59,17 @@ class UserStatusMapper extends QBMapper {
$qb
->select('*')
->from($this->tableName)
- ->orderBy('status_timestamp', 'DESC')
- ->where($qb->expr()->notIn('status', $qb->createNamedParameter([IUserStatus::ONLINE, IUserStatus::AWAY, IUserStatus::OFFLINE], IQueryBuilder::PARAM_STR_ARRAY)))
- ->orWhere($qb->expr()->isNotNull('message_id'))
- ->orWhere($qb->expr()->isNotNull('custom_icon'))
- ->orWhere($qb->expr()->isNotNull('custom_message'));
+ ->orderBy('status_message_timestamp', 'DESC')
+ ->where($qb->expr()->andX(
+ $qb->expr()->neq('status_message_timestamp', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT), IQueryBuilder::PARAM_INT),
+ $qb->expr()->orX(
+ $qb->expr()->notIn('status', $qb->createNamedParameter([IUserStatus::ONLINE, IUserStatus::AWAY, IUserStatus::OFFLINE], IQueryBuilder::PARAM_STR_ARRAY)),
+ $qb->expr()->isNotNull('message_id'),
+ $qb->expr()->isNotNull('custom_icon'),
+ $qb->expr()->isNotNull('custom_message'),
+ ),
+ $qb->expr()->notLike('user_id', $qb->createNamedParameter($this->db->escapeLikeParameter('_') . '%'))
+ ));
if ($limit !== null) {
$qb->setMaxResults($limit);
@@ -94,9 +84,9 @@ class UserStatusMapper extends QBMapper {
/**
* @param string $userId
* @return UserStatus
- * @throws \OCP\AppFramework\Db\DoesNotExistException
+ * @throws DoesNotExistException
*/
- public function findByUserId(string $userId, bool $isBackup = false):UserStatus {
+ public function findByUserId(string $userId, bool $isBackup = false): UserStatus {
$qb = $this->db->getQueryBuilder();
$qb
->select('*')
@@ -137,7 +127,7 @@ class UserStatusMapper extends QBMapper {
$qb->expr()->eq('status', $qb->createNamedParameter(IUserStatus::ONLINE))
));
- $qb->execute();
+ $qb->executeStatement();
}
/**
@@ -145,17 +135,13 @@ class UserStatusMapper extends QBMapper {
*
* @param int $timestamp
*/
- public function clearMessagesOlderThan(int $timestamp): void {
+ public function clearOlderThanClearAt(int $timestamp): void {
$qb = $this->db->getQueryBuilder();
- $qb->update($this->tableName)
- ->set('message_id', $qb->createNamedParameter(null))
- ->set('custom_icon', $qb->createNamedParameter(null))
- ->set('custom_message', $qb->createNamedParameter(null))
- ->set('clear_at', $qb->createNamedParameter(null))
+ $qb->delete($this->tableName)
->where($qb->expr()->isNotNull('clear_at'))
->andWhere($qb->expr()->lte('clear_at', $qb->createNamedParameter($timestamp, IQueryBuilder::PARAM_INT)));
- $qb->execute();
+ $qb->executeStatement();
}
@@ -164,15 +150,13 @@ class UserStatusMapper extends QBMapper {
*
* @param string $userId
* @param string $messageId
- * @param string $status
* @return bool True if an entry was deleted
*/
- public function deleteCurrentStatusToRestoreBackup(string $userId, string $messageId, string $status): bool {
+ public function deleteCurrentStatusToRestoreBackup(string $userId, string $messageId): bool {
$qb = $this->db->getQueryBuilder();
$qb->delete($this->tableName)
->where($qb->expr()->eq('user_id', $qb->createNamedParameter($userId)))
->andWhere($qb->expr()->eq('message_id', $qb->createNamedParameter($messageId)))
- ->andWhere($qb->expr()->eq('status', $qb->createNamedParameter($status)))
->andWhere($qb->expr()->eq('is_backup', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL)));
return $qb->executeStatement() > 0;
}
diff --git a/apps/user_status/lib/Exception/InvalidClearAtException.php b/apps/user_status/lib/Exception/InvalidClearAtException.php
index a0ca08ade76..a3bd4dfa0d0 100644
--- a/apps/user_status/lib/Exception/InvalidClearAtException.php
+++ b/apps/user_status/lib/Exception/InvalidClearAtException.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Exception;
diff --git a/apps/user_status/lib/Exception/InvalidMessageIdException.php b/apps/user_status/lib/Exception/InvalidMessageIdException.php
index dbf8d83d970..1feb36a916a 100644
--- a/apps/user_status/lib/Exception/InvalidMessageIdException.php
+++ b/apps/user_status/lib/Exception/InvalidMessageIdException.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Exception;
diff --git a/apps/user_status/lib/Exception/InvalidStatusIconException.php b/apps/user_status/lib/Exception/InvalidStatusIconException.php
index 7a7c7947d5b..80dff2a7666 100644
--- a/apps/user_status/lib/Exception/InvalidStatusIconException.php
+++ b/apps/user_status/lib/Exception/InvalidStatusIconException.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Exception;
diff --git a/apps/user_status/lib/Exception/InvalidStatusTypeException.php b/apps/user_status/lib/Exception/InvalidStatusTypeException.php
index 12115054b2c..a09284be40e 100644
--- a/apps/user_status/lib/Exception/InvalidStatusTypeException.php
+++ b/apps/user_status/lib/Exception/InvalidStatusTypeException.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Exception;
diff --git a/apps/user_status/lib/Exception/StatusMessageTooLongException.php b/apps/user_status/lib/Exception/StatusMessageTooLongException.php
index c52f6079874..03d578abf46 100644
--- a/apps/user_status/lib/Exception/StatusMessageTooLongException.php
+++ b/apps/user_status/lib/Exception/StatusMessageTooLongException.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Exception;
diff --git a/apps/user_status/lib/Listener/BeforeTemplateRenderedListener.php b/apps/user_status/lib/Listener/BeforeTemplateRenderedListener.php
index daf7265d988..ab3a1e62beb 100644
--- a/apps/user_status/lib/Listener/BeforeTemplateRenderedListener.php
+++ b/apps/user_status/lib/Listener/BeforeTemplateRenderedListener.php
@@ -3,26 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- * @author Julius Härtl <jus@bitgrid.net>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Listener;
@@ -36,21 +18,14 @@ use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\IInitialStateService;
use OCP\IUserSession;
+use OCP\Util;
+/** @template-implements IEventListener<BeforeTemplateRenderedEvent> */
class BeforeTemplateRenderedListener implements IEventListener {
/** @var ProfileManager */
private $profileManager;
- /** @var IUserSession */
- private $userSession;
-
- /** @var IInitialStateService */
- private $initialState;
-
- /** @var JSDataService */
- private $jsDataService;
-
/**
* BeforeTemplateRenderedListener constructor.
*
@@ -61,14 +36,11 @@ class BeforeTemplateRenderedListener implements IEventListener {
*/
public function __construct(
ProfileManager $profileManager,
- IUserSession $userSession,
- IInitialStateService $initialState,
- JSDataService $jsDataService
+ private IUserSession $userSession,
+ private IInitialStateService $initialState,
+ private JSDataService $jsDataService,
) {
$this->profileManager = $profileManager;
- $this->userSession = $userSession;
- $this->initialState = $initialState;
- $this->jsDataService = $jsDataService;
}
/**
@@ -97,7 +69,7 @@ class BeforeTemplateRenderedListener implements IEventListener {
return ['profileEnabled' => $this->profileManager->isProfileEnabled($user)];
});
- \OCP\Util::addScript('user_status', 'menu');
- \OCP\Util::addStyle('user_status', 'user-status-menu');
+ Util::addScript('user_status', 'menu');
+ Util::addStyle('user_status', 'user-status-menu');
}
}
diff --git a/apps/user_status/lib/Listener/OutOfOfficeStatusListener.php b/apps/user_status/lib/Listener/OutOfOfficeStatusListener.php
new file mode 100644
index 00000000000..6337d637896
--- /dev/null
+++ b/apps/user_status/lib/Listener/OutOfOfficeStatusListener.php
@@ -0,0 +1,57 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\UserStatus\Listener;
+
+use OCA\DAV\BackgroundJob\UserStatusAutomation;
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\BackgroundJob\IJobList;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\User\Events\OutOfOfficeChangedEvent;
+use OCP\User\Events\OutOfOfficeClearedEvent;
+use OCP\User\Events\OutOfOfficeEndedEvent;
+use OCP\User\Events\OutOfOfficeScheduledEvent;
+use OCP\User\Events\OutOfOfficeStartedEvent;
+use OCP\UserStatus\IManager;
+use OCP\UserStatus\IUserStatus;
+
+/**
+ * Class UserDeletedListener
+ *
+ * @template-implements IEventListener<OutOfOfficeScheduledEvent|OutOfOfficeChangedEvent|OutOfOfficeClearedEvent|OutOfOfficeStartedEvent|OutOfOfficeEndedEvent>
+ *
+ */
+class OutOfOfficeStatusListener implements IEventListener {
+ public function __construct(
+ private IJobList $jobsList,
+ private ITimeFactory $time,
+ private IManager $manager,
+ ) {
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function handle(Event $event): void {
+ if ($event instanceof OutOfOfficeClearedEvent) {
+ $this->manager->revertUserStatus($event->getData()->getUser()->getUID(), IUserStatus::MESSAGE_OUT_OF_OFFICE, IUserStatus::DND);
+ $this->jobsList->scheduleAfter(UserStatusAutomation::class, $this->time->getTime(), ['userId' => $event->getData()->getUser()->getUID()]);
+ return;
+ }
+
+ if ($event instanceof OutOfOfficeScheduledEvent
+ || $event instanceof OutOfOfficeChangedEvent
+ || $event instanceof OutOfOfficeStartedEvent
+ || $event instanceof OutOfOfficeEndedEvent
+ ) {
+ // This might be overwritten by the office hours automation, but that is ok. This is just in case no office hours are set
+ $this->jobsList->scheduleAfter(UserStatusAutomation::class, $this->time->getTime(), ['userId' => $event->getData()->getUser()->getUID()]);
+ }
+ }
+}
diff --git a/apps/user_status/lib/Listener/UserDeletedListener.php b/apps/user_status/lib/Listener/UserDeletedListener.php
index 0cacc89971a..bf021635156 100644
--- a/apps/user_status/lib/Listener/UserDeletedListener.php
+++ b/apps/user_status/lib/Listener/UserDeletedListener.php
@@ -3,50 +3,32 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Listener;
use OCA\UserStatus\Service\StatusService;
-use OCP\EventDispatcher\IEventListener;
use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
use OCP\User\Events\UserDeletedEvent;
/**
* Class UserDeletedListener
*
* @package OCA\UserStatus\Listener
+ * @template-implements IEventListener<UserDeletedEvent>
*/
class UserDeletedListener implements IEventListener {
- /** @var StatusService */
- private $service;
-
/**
* UserDeletedListener constructor.
*
* @param StatusService $service
*/
- public function __construct(StatusService $service) {
- $this->service = $service;
+ public function __construct(
+ private StatusService $service,
+ ) {
}
diff --git a/apps/user_status/lib/Listener/UserLiveStatusListener.php b/apps/user_status/lib/Listener/UserLiveStatusListener.php
index c015e684142..2db999d3712 100644
--- a/apps/user_status/lib/Listener/UserLiveStatusListener.php
+++ b/apps/user_status/lib/Listener/UserLiveStatusListener.php
@@ -3,52 +3,39 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Listener;
-use OCA\UserStatus\Db\UserStatus;
+use OCA\DAV\CalDAV\Status\StatusService as CalendarStatusService;
use OCA\UserStatus\Connector\UserStatus as ConnectorUserStatus;
+use OCA\UserStatus\Db\UserStatus;
use OCA\UserStatus\Db\UserStatusMapper;
use OCA\UserStatus\Service\StatusService;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Utility\ITimeFactory;
-use OCP\EventDispatcher\IEventListener;
+use OCP\DB\Exception;
use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
use OCP\User\Events\UserLiveStatusEvent;
use OCP\UserStatus\IUserStatus;
+use Psr\Log\LoggerInterface;
/**
* Class UserDeletedListener
*
* @package OCA\UserStatus\Listener
+ * @template-implements IEventListener<UserLiveStatusEvent>
*/
class UserLiveStatusListener implements IEventListener {
- private UserStatusMapper $mapper;
- private ITimeFactory $timeFactory;
-
- public function __construct(UserStatusMapper $mapper,
- ITimeFactory $timeFactory) {
- $this->mapper = $mapper;
- $this->timeFactory = $timeFactory;
+ public function __construct(
+ private UserStatusMapper $mapper,
+ private StatusService $statusService,
+ private ITimeFactory $timeFactory,
+ private CalendarStatusService $calendarStatusService,
+ private LoggerInterface $logger,
+ ) {
}
/**
@@ -62,7 +49,8 @@ class UserLiveStatusListener implements IEventListener {
$user = $event->getUser();
try {
- $userStatus = $this->mapper->findByUserId($user->getUID());
+ $this->calendarStatusService->processCalendarStatus($user->getUID());
+ $userStatus = $this->statusService->findByUserId($user->getUID());
} catch (DoesNotExistException $ex) {
$userStatus = new UserStatus();
$userStatus->setUserId($user->getUID());
@@ -71,10 +59,16 @@ class UserLiveStatusListener implements IEventListener {
$userStatus->setIsUserDefined(false);
}
- // If the status is user-defined and one of the persistent statuses, we
+ // If the status is user-defined and one of the persistent status, we
// will not override it.
- if ($userStatus->getIsUserDefined() &&
- \in_array($userStatus->getStatus(), StatusService::PERSISTENT_STATUSES, true)) {
+ if ($userStatus->getIsUserDefined()
+ && \in_array($userStatus->getStatus(), StatusService::PERSISTENT_STATUSES, true)) {
+ return;
+ }
+
+ // Don't overwrite the "away" calendar status if it's set
+ if ($userStatus->getMessageId() === IUserStatus::MESSAGE_CALENDAR_BUSY) {
+ $event->setUserStatus(new ConnectorUserStatus($userStatus));
return;
}
@@ -98,7 +92,19 @@ class UserLiveStatusListener implements IEventListener {
$userStatus->setIsUserDefined(false);
if ($userStatus->getId() === null) {
- $this->mapper->insert($userStatus);
+ try {
+ $this->mapper->insert($userStatus);
+ } catch (Exception $e) {
+ if ($e->getReason() === Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION) {
+ // A different process might have written another status
+ // update to the DB while we're processing our stuff.
+ // We can safely ignore it as we're only changing between AWAY and ONLINE
+ // and not doing anything with the message or icon.
+ $this->logger->debug('Unique constraint violation for live user status', ['exception' => $e]);
+ return;
+ }
+ throw $e;
+ }
} else {
$this->mapper->update($userStatus);
}
diff --git a/apps/user_status/lib/Migration/Version0001Date20200602134824.php b/apps/user_status/lib/Migration/Version0001Date20200602134824.php
index 64490cc4207..678c2ec245a 100644
--- a/apps/user_status/lib/Migration/Version0001Date20200602134824.php
+++ b/apps/user_status/lib/Migration/Version0001Date20200602134824.php
@@ -3,32 +3,13 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Georg Ehrke <oc.list@georgehrke.com>
- * @author Joas Schilling <coding@schilljs.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Migration;
-use OCP\DB\Types;
use OCP\DB\ISchemaWrapper;
+use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
diff --git a/apps/user_status/lib/Migration/Version0002Date20200902144824.php b/apps/user_status/lib/Migration/Version0002Date20200902144824.php
index 0c222eff8cd..199d2a4cc6b 100644
--- a/apps/user_status/lib/Migration/Version0002Date20200902144824.php
+++ b/apps/user_status/lib/Migration/Version0002Date20200902144824.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Migration;
diff --git a/apps/user_status/lib/Migration/Version1000Date20201111130204.php b/apps/user_status/lib/Migration/Version1000Date20201111130204.php
index 8b20ed8306f..b0789684da0 100644
--- a/apps/user_status/lib/Migration/Version1000Date20201111130204.php
+++ b/apps/user_status/lib/Migration/Version1000Date20201111130204.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020 Joas Schilling <coding@schilljs.com>
- *
- * @author Joas Schilling <coding@schilljs.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Migration;
diff --git a/apps/user_status/lib/Migration/Version1003Date20210809144824.php b/apps/user_status/lib/Migration/Version1003Date20210809144824.php
new file mode 100644
index 00000000000..7c6cf76adbe
--- /dev/null
+++ b/apps/user_status/lib/Migration/Version1003Date20210809144824.php
@@ -0,0 +1,43 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\UserStatus\Migration;
+
+use OCP\DB\ISchemaWrapper;
+use OCP\DB\Types;
+use OCP\Migration\IOutput;
+use OCP\Migration\SimpleMigrationStep;
+
+/**
+ * @package OCA\UserStatus\Migration
+ */
+class Version1003Date20210809144824 extends SimpleMigrationStep {
+
+ /**
+ * @param IOutput $output
+ * @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
+ * @param array $options
+ * @return null|ISchemaWrapper
+ * @since 23.0.0
+ */
+ public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) {
+ /** @var ISchemaWrapper $schema */
+ $schema = $schemaClosure();
+
+ $statusTable = $schema->getTable('user_status');
+
+ if (!$statusTable->hasColumn('is_backup')) {
+ $statusTable->addColumn('is_backup', Types::BOOLEAN, [
+ 'notnull' => false,
+ 'default' => false,
+ ]);
+ }
+
+ return $schema;
+ }
+}
diff --git a/apps/user_status/lib/Migration/Version1008Date20230921144701.php b/apps/user_status/lib/Migration/Version1008Date20230921144701.php
new file mode 100644
index 00000000000..30ebbf37b0e
--- /dev/null
+++ b/apps/user_status/lib/Migration/Version1008Date20230921144701.php
@@ -0,0 +1,54 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCA\UserStatus\Migration;
+
+use Closure;
+use OCP\DB\ISchemaWrapper;
+use OCP\DB\Types;
+use OCP\IDBConnection;
+use OCP\Migration\IOutput;
+use OCP\Migration\SimpleMigrationStep;
+
+class Version1008Date20230921144701 extends SimpleMigrationStep {
+
+ public function __construct(
+ private IDBConnection $connection,
+ ) {
+ }
+
+ public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
+ /** @var ISchemaWrapper $schema */
+ $schema = $schemaClosure();
+
+ $statusTable = $schema->getTable('user_status');
+ if (!($statusTable->hasColumn('status_message_timestamp'))) {
+ $statusTable->addColumn('status_message_timestamp', Types::INTEGER, [
+ 'notnull' => true,
+ 'length' => 11,
+ 'unsigned' => true,
+ 'default' => 0,
+ ]);
+ }
+ if (!$statusTable->hasIndex('user_status_mtstmp_ix')) {
+ $statusTable->addIndex(['status_message_timestamp'], 'user_status_mtstmp_ix');
+ }
+
+ return $schema;
+ }
+
+ public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
+ $qb = $this->connection->getQueryBuilder();
+
+ $update = $qb->update('user_status')
+ ->set('status_message_timestamp', 'status_timestamp');
+
+ $update->executeStatement();
+ }
+}
diff --git a/apps/user_status/lib/Migration/Version2301Date20210809144824.php b/apps/user_status/lib/Migration/Version2301Date20210809144824.php
deleted file mode 100644
index 947378484c6..00000000000
--- a/apps/user_status/lib/Migration/Version2301Date20210809144824.php
+++ /dev/null
@@ -1,58 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-/**
- * @copyright Copyright (c) 2021 Carl Schwan <carl@carlschwan.eu>
- *
- * @author Carl Schwan <carl@carlschwan.eu>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-namespace OCA\UserStatus\Migration;
-
-use OCP\DB\ISchemaWrapper;
-use OCP\DB\Types;
-use OCP\Migration\IOutput;
-use OCP\Migration\SimpleMigrationStep;
-
-/**
- * @package OCA\UserStatus\Migration
- */
-class Version2301Date20210809144824 extends SimpleMigrationStep {
-
- /**
- * @param IOutput $output
- * @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
- * @param array $options
- * @return null|ISchemaWrapper
- * @since 23.0.0
- */
- public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) {
- /** @var ISchemaWrapper $schema */
- $schema = $schemaClosure();
-
- $statusTable = $schema->getTable('user_status');
-
- $statusTable->addColumn('is_backup', Types::BOOLEAN, [
- 'notnull' => false,
- 'default' => false,
- ]);
-
- return $schema;
- }
-}
diff --git a/apps/user_status/lib/ResponseDefinitions.php b/apps/user_status/lib/ResponseDefinitions.php
new file mode 100644
index 00000000000..82f606dd301
--- /dev/null
+++ b/apps/user_status/lib/ResponseDefinitions.php
@@ -0,0 +1,44 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCA\UserStatus;
+
+/**
+ * @psalm-type UserStatusClearAtTimeType = "day"|"week"
+ *
+ * @psalm-type UserStatusClearAt = array{
+ * type: "period"|"end-of",
+ * time: int|UserStatusClearAtTimeType,
+ * }
+ *
+ * @psalm-type UserStatusPredefined = array{
+ * id: string,
+ * icon: string,
+ * message: string,
+ * clearAt: ?UserStatusClearAt,
+ * }
+ *
+ * @psalm-type UserStatusType = "online"|"away"|"dnd"|"busy"|"offline"|"invisible"
+ *
+ * @psalm-type UserStatusPublic = array{
+ * userId: string,
+ * message: ?string,
+ * icon: ?string,
+ * clearAt: ?int,
+ * status: UserStatusType,
+ * }
+ *
+ * @psalm-type UserStatusPrivate = UserStatusPublic&array{
+ * messageId: ?string,
+ * messageIsPredefined: bool,
+ * statusIsUserDefined: bool,
+ * }
+ */
+class ResponseDefinitions {
+}
diff --git a/apps/user_status/lib/Service/EmojiService.php b/apps/user_status/lib/Service/EmojiService.php
deleted file mode 100644
index 0f197933872..00000000000
--- a/apps/user_status/lib/Service/EmojiService.php
+++ /dev/null
@@ -1,102 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- * @author Joas Schilling <coding@schilljs.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-namespace OCA\UserStatus\Service;
-
-use OCP\IDBConnection;
-
-/**
- * Class EmojiService
- *
- * @package OCA\UserStatus\Service
- */
-class EmojiService {
-
- /** @var IDBConnection */
- private $db;
-
- /**
- * EmojiService constructor.
- *
- * @param IDBConnection $db
- */
- public function __construct(IDBConnection $db) {
- $this->db = $db;
- }
-
- /**
- * @return bool
- */
- public function doesPlatformSupportEmoji(): bool {
- return $this->db->supports4ByteText() &&
- \class_exists(\IntlBreakIterator::class);
- }
-
- /**
- * @param string $emoji
- * @return bool
- */
- public function isValidEmoji(string $emoji): bool {
- $intlBreakIterator = \IntlBreakIterator::createCharacterInstance();
- $intlBreakIterator->setText($emoji);
-
- $characterCount = 0;
- while ($intlBreakIterator->next() !== \IntlBreakIterator::DONE) {
- $characterCount++;
- }
-
- if ($characterCount !== 1) {
- return false;
- }
-
- $codePointIterator = \IntlBreakIterator::createCodePointInstance();
- $codePointIterator->setText($emoji);
-
- foreach ($codePointIterator->getPartsIterator() as $codePoint) {
- $codePointType = \IntlChar::charType($codePoint);
-
- // If the current code-point is an emoji or a modifier (like a skin-tone)
- // just continue and check the next character
- if ($codePointType === \IntlChar::CHAR_CATEGORY_MODIFIER_SYMBOL ||
- $codePointType === \IntlChar::CHAR_CATEGORY_MODIFIER_LETTER ||
- $codePointType === \IntlChar::CHAR_CATEGORY_OTHER_SYMBOL ||
- $codePointType === \IntlChar::CHAR_CATEGORY_GENERAL_OTHER_TYPES) {
- continue;
- }
-
- // If it's neither a modifier nor an emoji, we only allow
- // a zero-width-joiner or a variation selector 16
- $codePointValue = \IntlChar::ord($codePoint);
- if ($codePointValue === 8205 || $codePointValue === 65039) {
- continue;
- }
-
- return false;
- }
-
- return true;
- }
-}
diff --git a/apps/user_status/lib/Service/JSDataService.php b/apps/user_status/lib/Service/JSDataService.php
index c08643ec64f..a777e97fe57 100644
--- a/apps/user_status/lib/Service/JSDataService.php
+++ b/apps/user_status/lib/Service/JSDataService.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Service;
@@ -31,22 +14,16 @@ use OCP\UserStatus\IUserStatus;
class JSDataService implements \JsonSerializable {
- /** @var IUserSession */
- private $userSession;
-
- /** @var StatusService */
- private $statusService;
-
/**
* JSDataService constructor.
*
* @param IUserSession $userSession
* @param StatusService $statusService
*/
- public function __construct(IUserSession $userSession,
- StatusService $statusService) {
- $this->userSession = $userSession;
- $this->statusService = $statusService;
+ public function __construct(
+ private IUserSession $userSession,
+ private StatusService $statusService,
+ ) {
}
public function jsonSerialize(): array {
diff --git a/apps/user_status/lib/Service/PredefinedStatusService.php b/apps/user_status/lib/Service/PredefinedStatusService.php
index 354e0f16b32..599d5b8b52f 100644
--- a/apps/user_status/lib/Service/PredefinedStatusService.php
+++ b/apps/user_status/lib/Service/PredefinedStatusService.php
@@ -3,29 +3,13 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Service;
use OCP\IL10N;
+use OCP\UserStatus\IUserStatus;
/**
* Class DefaultStatusService
@@ -36,23 +20,26 @@ use OCP\IL10N;
* @package OCA\UserStatus\Service
*/
class PredefinedStatusService {
+ private const BE_RIGHT_BACK = 'be-right-back';
private const MEETING = 'meeting';
private const COMMUTING = 'commuting';
private const SICK_LEAVE = 'sick-leave';
private const VACATIONING = 'vacationing';
private const REMOTE_WORK = 'remote-work';
+ /**
+ * @deprecated See \OCP\UserStatus\IUserStatus::MESSAGE_CALL
+ */
public const CALL = 'call';
-
- /** @var IL10N */
- private $l10n;
+ public const OUT_OF_OFFICE = 'out-of-office';
/**
* DefaultStatusService constructor.
*
* @param IL10N $l10n
*/
- public function __construct(IL10N $l10n) {
- $this->l10n = $l10n;
+ public function __construct(
+ private IL10N $l10n,
+ ) {
}
/**
@@ -79,6 +66,15 @@ class PredefinedStatusService {
],
],
[
+ 'id' => self::BE_RIGHT_BACK,
+ 'icon' => '⏳',
+ 'message' => $this->getTranslatedStatusForId(self::BE_RIGHT_BACK),
+ 'clearAt' => [
+ 'type' => 'period',
+ 'time' => 900,
+ ],
+ ],
+ [
'id' => self::REMOTE_WORK,
'icon' => '🏡',
'message' => $this->getTranslatedStatusForId(self::REMOTE_WORK),
@@ -109,6 +105,13 @@ class PredefinedStatusService {
'clearAt' => null,
'visible' => false,
],
+ [
+ 'id' => self::OUT_OF_OFFICE,
+ 'icon' => '🛑',
+ 'message' => $this->getTranslatedStatusForId(self::OUT_OF_OFFICE),
+ 'clearAt' => null,
+ 'visible' => false,
+ ],
];
}
@@ -144,9 +147,15 @@ class PredefinedStatusService {
case self::VACATIONING:
return '🌴';
+ case self::OUT_OF_OFFICE:
+ return '🛑';
+
case self::REMOTE_WORK:
return '🏡';
+ case self::BE_RIGHT_BACK:
+ return '⏳';
+
case self::CALL:
return '💬';
@@ -174,12 +183,18 @@ class PredefinedStatusService {
case self::VACATIONING:
return $this->l10n->t('Vacationing');
+ case self::OUT_OF_OFFICE:
+ return $this->l10n->t('Out of office');
+
case self::REMOTE_WORK:
return $this->l10n->t('Working remotely');
case self::CALL:
return $this->l10n->t('In a call');
+ case self::BE_RIGHT_BACK:
+ return $this->l10n->t('Be right back');
+
default:
return null;
}
@@ -195,8 +210,14 @@ class PredefinedStatusService {
self::COMMUTING,
self::SICK_LEAVE,
self::VACATIONING,
+ self::OUT_OF_OFFICE,
+ self::BE_RIGHT_BACK,
self::REMOTE_WORK,
- self::CALL,
+ IUserStatus::MESSAGE_CALL,
+ IUserStatus::MESSAGE_AVAILABILITY,
+ IUserStatus::MESSAGE_VACATION,
+ IUserStatus::MESSAGE_CALENDAR_BUSY,
+ IUserStatus::MESSAGE_CALENDAR_BUSY_TENTATIVE,
], true);
}
}
diff --git a/apps/user_status/lib/Service/StatusService.php b/apps/user_status/lib/Service/StatusService.php
index 5dd70e4ea5e..188eb26d1d7 100644
--- a/apps/user_status/lib/Service/StatusService.php
+++ b/apps/user_status/lib/Service/StatusService.php
@@ -3,26 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- * @author Joas Schilling <coding@schilljs.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Service;
@@ -37,8 +19,11 @@ use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\DB\Exception;
use OCP\IConfig;
-use OCP\IUser;
+use OCP\IEmojiHelper;
+use OCP\IUserManager;
use OCP\UserStatus\IUserStatus;
+use Psr\Log\LoggerInterface;
+use function in_array;
/**
* Class StatusService
@@ -46,27 +31,9 @@ use OCP\UserStatus\IUserStatus;
* @package OCA\UserStatus\Service
*/
class StatusService {
-
- /** @var UserStatusMapper */
- private $mapper;
-
- /** @var ITimeFactory */
- private $timeFactory;
-
- /** @var PredefinedStatusService */
- private $predefinedStatusService;
-
- /** @var EmojiService */
- private $emojiService;
-
- /** @var bool */
- private $shareeEnumeration;
-
- /** @var bool */
- private $shareeEnumerationInGroupOnly;
-
- /** @var bool */
- private $shareeEnumerationPhone;
+ private bool $shareeEnumeration;
+ private bool $shareeEnumerationInGroupOnly;
+ private bool $shareeEnumerationPhone;
/**
* List of priorities ordered by their priority
@@ -75,6 +42,7 @@ class StatusService {
IUserStatus::ONLINE,
IUserStatus::AWAY,
IUserStatus::DND,
+ IUserStatus::BUSY,
IUserStatus::INVISIBLE,
IUserStatus::OFFLINE,
];
@@ -85,6 +53,7 @@ class StatusService {
*/
public const PERSISTENT_STATUSES = [
IUserStatus::AWAY,
+ IUserStatus::BUSY,
IUserStatus::DND,
IUserStatus::INVISIBLE,
];
@@ -95,27 +64,18 @@ class StatusService {
/** @var int */
public const MAXIMUM_MESSAGE_LENGTH = 80;
- /**
- * StatusService constructor.
- *
- * @param UserStatusMapper $mapper
- * @param ITimeFactory $timeFactory
- * @param PredefinedStatusService $defaultStatusService
- * @param EmojiService $emojiService
- * @param IConfig $config
- */
- public function __construct(UserStatusMapper $mapper,
- ITimeFactory $timeFactory,
- PredefinedStatusService $defaultStatusService,
- EmojiService $emojiService,
- IConfig $config) {
- $this->mapper = $mapper;
- $this->timeFactory = $timeFactory;
- $this->predefinedStatusService = $defaultStatusService;
- $this->emojiService = $emojiService;
- $this->shareeEnumeration = $config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
- $this->shareeEnumerationInGroupOnly = $this->shareeEnumeration && $config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes';
- $this->shareeEnumerationPhone = $this->shareeEnumeration && $config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_phone', 'no') === 'yes';
+ public function __construct(
+ private UserStatusMapper $mapper,
+ private ITimeFactory $timeFactory,
+ private PredefinedStatusService $predefinedStatusService,
+ private IEmojiHelper $emojiHelper,
+ private IConfig $config,
+ private IUserManager $userManager,
+ private LoggerInterface $logger,
+ ) {
+ $this->shareeEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
+ $this->shareeEnumerationInGroupOnly = $this->shareeEnumeration && $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes';
+ $this->shareeEnumerationPhone = $this->shareeEnumeration && $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_phone', 'no') === 'yes';
}
/**
@@ -159,7 +119,7 @@ class StatusService {
* @return UserStatus
* @throws DoesNotExistException
*/
- public function findByUserId(string $userId):UserStatus {
+ public function findByUserId(string $userId): UserStatus {
return $this->processStatus($this->mapper->findByUserId($userId));
}
@@ -182,9 +142,9 @@ class StatusService {
* @throws InvalidStatusTypeException
*/
public function setStatus(string $userId,
- string $status,
- ?int $statusTimestamp,
- bool $isUserDefined): UserStatus {
+ string $status,
+ ?int $statusTimestamp,
+ bool $isUserDefined): UserStatus {
try {
$userStatus = $this->mapper->findByUserId($userId);
} catch (DoesNotExistException $ex) {
@@ -193,9 +153,10 @@ class StatusService {
}
// Check if status-type is valid
- if (!\in_array($status, self::PRIORITY_ORDERED_STATUSES, true)) {
+ if (!in_array($status, self::PRIORITY_ORDERED_STATUSES, true)) {
throw new InvalidStatusTypeException('Status-type "' . $status . '" is not supported');
}
+
if ($statusTimestamp === null) {
$statusTimestamp = $this->timeFactory->getTime();
}
@@ -206,7 +167,7 @@ class StatusService {
$userStatus->setIsBackup(false);
if ($userStatus->getId() === null) {
- return $this->mapper->insert($userStatus);
+ return $this->insertWithoutThrowingUniqueConstrain($userStatus);
}
return $this->mapper->update($userStatus);
@@ -221,8 +182,8 @@ class StatusService {
* @throws InvalidClearAtException
*/
public function setPredefinedMessage(string $userId,
- string $messageId,
- ?int $clearAt): UserStatus {
+ string $messageId,
+ ?int $clearAt): UserStatus {
try {
$userStatus = $this->mapper->findByUserId($userId);
} catch (DoesNotExistException $ex) {
@@ -247,9 +208,10 @@ class StatusService {
$userStatus->setCustomIcon(null);
$userStatus->setCustomMessage(null);
$userStatus->setClearAt($clearAt);
+ $userStatus->setStatusMessageTimestamp($this->timeFactory->now()->getTimestamp());
if ($userStatus->getId() === null) {
- return $this->mapper->insert($userStatus);
+ return $this->insertWithoutThrowingUniqueConstrain($userStatus);
}
return $this->mapper->update($userStatus);
@@ -260,15 +222,17 @@ class StatusService {
* @param string $status
* @param string $messageId
* @param bool $createBackup
+ * @param string|null $customMessage
* @throws InvalidStatusTypeException
* @throws InvalidMessageIdException
*/
public function setUserStatus(string $userId,
- string $status,
- string $messageId,
- bool $createBackup): void {
+ string $status,
+ string $messageId,
+ bool $createBackup,
+ ?string $customMessage = null): ?UserStatus {
// Check if status-type is valid
- if (!\in_array($status, self::PRIORITY_ORDERED_STATUSES, true)) {
+ if (!in_array($status, self::PRIORITY_ORDERED_STATUSES, true)) {
throw new InvalidStatusTypeException('Status-type "' . $status . '" is not supported');
}
@@ -276,21 +240,58 @@ class StatusService {
throw new InvalidMessageIdException('Message-Id "' . $messageId . '" is not supported');
}
+ try {
+ $userStatus = $this->mapper->findByUserId($userId);
+ } catch (DoesNotExistException $e) {
+ // We don't need to do anything
+ $userStatus = new UserStatus();
+ $userStatus->setUserId($userId);
+ }
+
+ $updateStatus = false;
+ if ($messageId === IUserStatus::MESSAGE_OUT_OF_OFFICE) {
+ // OUT_OF_OFFICE trumps AVAILABILITY, CALL and CALENDAR status
+ $updateStatus = $userStatus->getMessageId() === IUserStatus::MESSAGE_AVAILABILITY || $userStatus->getMessageId() === IUserStatus::MESSAGE_CALL || $userStatus->getMessageId() === IUserStatus::MESSAGE_CALENDAR_BUSY;
+ } elseif ($messageId === IUserStatus::MESSAGE_AVAILABILITY) {
+ // AVAILABILITY trumps CALL and CALENDAR status
+ $updateStatus = $userStatus->getMessageId() === IUserStatus::MESSAGE_CALL || $userStatus->getMessageId() === IUserStatus::MESSAGE_CALENDAR_BUSY;
+ } elseif ($messageId === IUserStatus::MESSAGE_CALL) {
+ // CALL trumps CALENDAR status
+ $updateStatus = $userStatus->getMessageId() === IUserStatus::MESSAGE_CALENDAR_BUSY;
+ }
+
+ if ($messageId === IUserStatus::MESSAGE_OUT_OF_OFFICE || $messageId === IUserStatus::MESSAGE_AVAILABILITY || $messageId === IUserStatus::MESSAGE_CALL || $messageId === IUserStatus::MESSAGE_CALENDAR_BUSY) {
+ if ($updateStatus) {
+ $this->logger->debug('User ' . $userId . ' is currently NOT available, overwriting status [status: ' . $userStatus->getStatus() . ', messageId: ' . json_encode($userStatus->getMessageId()) . ']', ['app' => 'dav']);
+ } else {
+ $this->logger->debug('User ' . $userId . ' is currently NOT available, but we are NOT overwriting status [status: ' . $userStatus->getStatus() . ', messageId: ' . json_encode($userStatus->getMessageId()) . ']', ['app' => 'dav']);
+ }
+ }
+
+ // There should be a backup already or none is needed. So we take a shortcut.
+ if ($updateStatus) {
+ $userStatus->setStatus($status);
+ $userStatus->setStatusTimestamp($this->timeFactory->getTime());
+ $userStatus->setIsUserDefined(true);
+ $userStatus->setIsBackup(false);
+ $userStatus->setMessageId($messageId);
+ $userStatus->setCustomIcon(null);
+ $userStatus->setCustomMessage($customMessage);
+ $userStatus->setClearAt(null);
+ $userStatus->setStatusMessageTimestamp($this->timeFactory->now()->getTimestamp());
+ return $this->mapper->update($userStatus);
+ }
+
if ($createBackup) {
if ($this->backupCurrentStatus($userId) === false) {
- return; // Already a status set automatically => abort.
+ return null; // Already a status set automatically => abort.
}
// If we just created the backup
+ // we need to create a new status to insert
+ // Unfortunately there's no way to unset the DB ID on an Entity
$userStatus = new UserStatus();
$userStatus->setUserId($userId);
- } else {
- try {
- $userStatus = $this->mapper->findByUserId($userId);
- } catch (DoesNotExistException $ex) {
- $userStatus = new UserStatus();
- $userStatus->setUserId($userId);
- }
}
$userStatus->setStatus($status);
@@ -299,20 +300,26 @@ class StatusService {
$userStatus->setIsBackup(false);
$userStatus->setMessageId($messageId);
$userStatus->setCustomIcon(null);
- $userStatus->setCustomMessage(null);
+ $userStatus->setCustomMessage($customMessage);
$userStatus->setClearAt(null);
+ if ($this->predefinedStatusService->getTranslatedStatusForId($messageId) !== null
+ || ($customMessage !== null && $customMessage !== '')) {
+ // Only track status message ID if there is one
+ $userStatus->setStatusMessageTimestamp($this->timeFactory->now()->getTimestamp());
+ } else {
+ $userStatus->setStatusMessageTimestamp(0);
+ }
if ($userStatus->getId() !== null) {
- $this->mapper->update($userStatus);
- return;
+ return $this->mapper->update($userStatus);
}
- $this->mapper->insert($userStatus);
+ return $this->insertWithoutThrowingUniqueConstrain($userStatus);
}
/**
* @param string $userId
* @param string|null $statusIcon
- * @param string $message
+ * @param string|null $message
* @param int|null $clearAt
* @return UserStatus
* @throws InvalidClearAtException
@@ -320,9 +327,9 @@ class StatusService {
* @throws StatusMessageTooLongException
*/
public function setCustomMessage(string $userId,
- ?string $statusIcon,
- string $message,
- ?int $clearAt): UserStatus {
+ ?string $statusIcon,
+ ?string $message,
+ ?int $clearAt): UserStatus {
try {
$userStatus = $this->mapper->findByUserId($userId);
} catch (DoesNotExistException $ex) {
@@ -334,11 +341,11 @@ class StatusService {
}
// Check if statusIcon contains only one character
- if ($statusIcon !== null && !$this->emojiService->isValidEmoji($statusIcon)) {
+ if ($statusIcon !== null && !$this->emojiHelper->isValidSingleEmoji($statusIcon)) {
throw new InvalidStatusIconException('Status-Icon is longer than one character');
}
// Check for maximum length of custom message
- if (\mb_strlen($message) > self::MAXIMUM_MESSAGE_LENGTH) {
+ if ($message !== null && \mb_strlen($message) > self::MAXIMUM_MESSAGE_LENGTH) {
throw new StatusMessageTooLongException('Message is longer than supported length of ' . self::MAXIMUM_MESSAGE_LENGTH . ' characters');
}
// Check that clearAt is in the future
@@ -350,9 +357,10 @@ class StatusService {
$userStatus->setCustomIcon($statusIcon);
$userStatus->setCustomMessage($message);
$userStatus->setClearAt($clearAt);
+ $userStatus->setStatusMessageTimestamp($this->timeFactory->now()->getTimestamp());
if ($userStatus->getId() === null) {
- return $this->mapper->insert($userStatus);
+ return $this->insertWithoutThrowingUniqueConstrain($userStatus);
}
return $this->mapper->update($userStatus);
@@ -394,6 +402,7 @@ class StatusService {
$userStatus->setCustomMessage(null);
$userStatus->setCustomIcon(null);
$userStatus->setClearAt(null);
+ $userStatus->setStatusMessageTimestamp(0);
$this->mapper->update($userStatus);
return true;
@@ -442,6 +451,7 @@ class StatusService {
$this->cleanStatus($status);
}
if ($clearAt !== null && $clearAt < $this->timeFactory->getTime()) {
+ $this->cleanStatus($status);
$this->cleanStatusMessage($status);
}
if ($status->getMessageId() !== null) {
@@ -474,6 +484,7 @@ class StatusService {
$status->setCustomIcon(null);
$status->setCustomMessage(null);
$status->setClearAt(null);
+ $status->setStatusMessageTimestamp(0);
$this->mapper->update($status);
}
@@ -484,8 +495,14 @@ class StatusService {
private function addDefaultMessage(UserStatus $status): void {
// If the message is predefined, insert the translated message and icon
$predefinedMessage = $this->predefinedStatusService->getDefaultStatusById($status->getMessageId());
- if ($predefinedMessage !== null) {
+ if ($predefinedMessage === null) {
+ return;
+ }
+ // If there is a custom message, don't overwrite it
+ if (empty($status->getCustomMessage())) {
$status->setCustomMessage($predefinedMessage['message']);
+ }
+ if (empty($status->getCustomIcon())) {
$status->setCustomIcon($predefinedMessage['icon']);
}
}
@@ -505,28 +522,38 @@ class StatusService {
}
}
- public function revertUserStatus(string $userId, string $messageId, string $status): void {
+ public function revertUserStatus(string $userId, string $messageId, bool $revertedManually = false): ?UserStatus {
try {
/** @var UserStatus $userStatus */
$backupUserStatus = $this->mapper->findByUserId($userId, true);
} catch (DoesNotExistException $ex) {
// No user status to revert, do nothing
- return;
+ return null;
}
- $deleted = $this->mapper->deleteCurrentStatusToRestoreBackup($userId, $messageId, $status);
+ $deleted = $this->mapper->deleteCurrentStatusToRestoreBackup($userId, $messageId);
if (!$deleted) {
// Another status is set automatically or no status, do nothing
- return;
+ return null;
+ }
+
+ if ($revertedManually) {
+ if ($backupUserStatus->getStatus() === IUserStatus::OFFLINE) {
+ // When the user reverts the status manually they are online
+ $backupUserStatus->setStatus(IUserStatus::ONLINE);
+ }
+ $backupUserStatus->setStatusTimestamp($this->timeFactory->getTime());
}
$backupUserStatus->setIsBackup(false);
// Remove the underscore prefix added when creating the backup
$backupUserStatus->setUserId(substr($backupUserStatus->getUserId(), 1));
$this->mapper->update($backupUserStatus);
+
+ return $backupUserStatus;
}
- public function revertMultipleUserStatus(array $userIds, string $messageId, string $status): void {
+ public function revertMultipleUserStatus(array $userIds, string $messageId): void {
// Get all user statuses and the backups
$findById = $userIds;
foreach ($userIds as $userId) {
@@ -537,10 +564,9 @@ class StatusService {
$backups = $restoreIds = $statuesToDelete = [];
foreach ($userStatuses as $userStatus) {
if (!$userStatus->getIsBackup()
- && $userStatus->getMessageId() === $messageId
- && $userStatus->getStatus() === $status) {
+ && $userStatus->getMessageId() === $messageId) {
$statuesToDelete[$userStatus->getUserId()] = $userStatus->getId();
- } else if ($userStatus->getIsBackup()) {
+ } elseif ($userStatus->getIsBackup()) {
$backups[$userStatus->getUserId()] = $userStatus->getId();
}
}
@@ -558,4 +584,16 @@ class StatusService {
// For users that matched restore the previous status
$this->mapper->restoreBackupStatuses($restoreIds);
}
+
+ protected function insertWithoutThrowingUniqueConstrain(UserStatus $userStatus): UserStatus {
+ try {
+ return $this->mapper->insert($userStatus);
+ } catch (Exception $e) {
+ // Ignore if a parallel request already set the status
+ if ($e->getReason() !== Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION) {
+ throw $e;
+ }
+ }
+ return $userStatus;
+ }
}
diff --git a/apps/user_status/openapi.json b/apps/user_status/openapi.json
new file mode 100644
index 00000000000..e48d4970b96
--- /dev/null
+++ b/apps/user_status/openapi.json
@@ -0,0 +1,1195 @@
+{
+ "openapi": "3.0.3",
+ "info": {
+ "title": "user_status",
+ "version": "0.0.1",
+ "description": "User status",
+ "license": {
+ "name": "agpl"
+ }
+ },
+ "components": {
+ "securitySchemes": {
+ "basic_auth": {
+ "type": "http",
+ "scheme": "basic"
+ },
+ "bearer_auth": {
+ "type": "http",
+ "scheme": "bearer"
+ }
+ },
+ "schemas": {
+ "Capabilities": {
+ "type": "object",
+ "required": [
+ "user_status"
+ ],
+ "properties": {
+ "user_status": {
+ "type": "object",
+ "required": [
+ "enabled",
+ "restore",
+ "supports_emoji",
+ "supports_busy"
+ ],
+ "properties": {
+ "enabled": {
+ "type": "boolean"
+ },
+ "restore": {
+ "type": "boolean"
+ },
+ "supports_emoji": {
+ "type": "boolean"
+ },
+ "supports_busy": {
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "ClearAt": {
+ "type": "object",
+ "required": [
+ "type",
+ "time"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "period",
+ "end-of"
+ ]
+ },
+ "time": {
+ "anyOf": [
+ {
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "$ref": "#/components/schemas/ClearAtTimeType"
+ }
+ ]
+ }
+ }
+ },
+ "ClearAtTimeType": {
+ "type": "string",
+ "enum": [
+ "day",
+ "week"
+ ]
+ },
+ "OCSMeta": {
+ "type": "object",
+ "required": [
+ "status",
+ "statuscode"
+ ],
+ "properties": {
+ "status": {
+ "type": "string"
+ },
+ "statuscode": {
+ "type": "integer"
+ },
+ "message": {
+ "type": "string"
+ },
+ "totalitems": {
+ "type": "string"
+ },
+ "itemsperpage": {
+ "type": "string"
+ }
+ }
+ },
+ "Predefined": {
+ "type": "object",
+ "required": [
+ "id",
+ "icon",
+ "message",
+ "clearAt"
+ ],
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "icon": {
+ "type": "string"
+ },
+ "message": {
+ "type": "string"
+ },
+ "clearAt": {
+ "nullable": true,
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/ClearAt"
+ }
+ ]
+ }
+ }
+ },
+ "Private": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/Public"
+ },
+ {
+ "type": "object",
+ "required": [
+ "messageId",
+ "messageIsPredefined",
+ "statusIsUserDefined"
+ ],
+ "properties": {
+ "messageId": {
+ "type": "string",
+ "nullable": true
+ },
+ "messageIsPredefined": {
+ "type": "boolean"
+ },
+ "statusIsUserDefined": {
+ "type": "boolean"
+ }
+ }
+ }
+ ]
+ },
+ "Public": {
+ "type": "object",
+ "required": [
+ "userId",
+ "message",
+ "icon",
+ "clearAt",
+ "status"
+ ],
+ "properties": {
+ "userId": {
+ "type": "string"
+ },
+ "message": {
+ "type": "string",
+ "nullable": true
+ },
+ "icon": {
+ "type": "string",
+ "nullable": true
+ },
+ "clearAt": {
+ "type": "integer",
+ "format": "int64",
+ "nullable": true
+ },
+ "status": {
+ "$ref": "#/components/schemas/Type"
+ }
+ }
+ },
+ "Type": {
+ "type": "string",
+ "enum": [
+ "online",
+ "away",
+ "dnd",
+ "busy",
+ "offline",
+ "invisible"
+ ]
+ }
+ }
+ },
+ "paths": {
+ "/ocs/v2.php/apps/user_status/api/v1/heartbeat": {
+ "put": {
+ "operationId": "heartbeat-heartbeat",
+ "summary": "Keep the status alive",
+ "tags": [
+ "heartbeat"
+ ],
+ "security": [
+ {
+ "bearer_auth": []
+ },
+ {
+ "basic_auth": []
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "status"
+ ],
+ "properties": {
+ "status": {
+ "type": "string",
+ "description": "Only online, away"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "OCS-APIRequest",
+ "in": "header",
+ "description": "Required to be true for the API request to pass",
+ "required": true,
+ "schema": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Status successfully updated",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "ocs"
+ ],
+ "properties": {
+ "ocs": {
+ "type": "object",
+ "required": [
+ "meta",
+ "data"
+ ],
+ "properties": {
+ "meta": {
+ "$ref": "#/components/schemas/OCSMeta"
+ },
+ "data": {
+ "$ref": "#/components/schemas/Private"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Invalid status to update",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "ocs"
+ ],
+ "properties": {
+ "ocs": {
+ "type": "object",
+ "required": [
+ "meta",
+ "data"
+ ],
+ "properties": {
+ "meta": {
+ "$ref": "#/components/schemas/OCSMeta"
+ },
+ "data": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "ocs"
+ ],
+ "properties": {
+ "ocs": {
+ "type": "object",
+ "required": [
+ "meta",
+ "data"
+ ],
+ "properties": {
+ "meta": {
+ "$ref": "#/components/schemas/OCSMeta"
+ },
+ "data": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "204": {
+ "description": "User has no status to keep alive"
+ }
+ }
+ }
+ },
+ "/ocs/v2.php/apps/user_status/api/v1/predefined_statuses": {
+ "get": {
+ "operationId": "predefined_status-find-all",
+ "summary": "Get all predefined messages",
+ "tags": [
+ "predefined_status"
+ ],
+ "security": [
+ {
+ "bearer_auth": []
+ },
+ {
+ "basic_auth": []
+ }
+ ],
+ "parameters": [
+ {
+ "name": "OCS-APIRequest",
+ "in": "header",
+ "description": "Required to be true for the API request to pass",
+ "required": true,
+ "schema": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Predefined statuses returned",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "ocs"
+ ],
+ "properties": {
+ "ocs": {
+ "type": "object",
+ "required": [
+ "meta",
+ "data"
+ ],
+ "properties": {
+ "meta": {
+ "$ref": "#/components/schemas/OCSMeta"
+ },
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Predefined"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/ocs/v2.php/apps/user_status/api/v1/statuses": {
+ "get": {
+ "operationId": "statuses-find-all",
+ "summary": "Find statuses of users",
+ "tags": [
+ "statuses"
+ ],
+ "security": [
+ {
+ "bearer_auth": []
+ },
+ {
+ "basic_auth": []
+ }
+ ],
+ "parameters": [
+ {
+ "name": "limit",
+ "in": "query",
+ "description": "Maximum number of statuses to find",
+ "schema": {
+ "type": "integer",
+ "format": "int64",
+ "nullable": true,
+ "default": null
+ }
+ },
+ {
+ "name": "offset",
+ "in": "query",
+ "description": "Offset for finding statuses",
+ "schema": {
+ "type": "integer",
+ "format": "int64",
+ "nullable": true,
+ "default": null,
+ "minimum": 0
+ }
+ },
+ {
+ "name": "OCS-APIRequest",
+ "in": "header",
+ "description": "Required to be true for the API request to pass",
+ "required": true,
+ "schema": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Statuses returned",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "ocs"
+ ],
+ "properties": {
+ "ocs": {
+ "type": "object",
+ "required": [
+ "meta",
+ "data"
+ ],
+ "properties": {
+ "meta": {
+ "$ref": "#/components/schemas/OCSMeta"
+ },
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Public"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/ocs/v2.php/apps/user_status/api/v1/statuses/{userId}": {
+ "get": {
+ "operationId": "statuses-find",
+ "summary": "Find the status of a user",
+ "tags": [
+ "statuses"
+ ],
+ "security": [
+ {
+ "bearer_auth": []
+ },
+ {
+ "basic_auth": []
+ }
+ ],
+ "parameters": [
+ {
+ "name": "userId",
+ "in": "path",
+ "description": "ID of the user",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "OCS-APIRequest",
+ "in": "header",
+ "description": "Required to be true for the API request to pass",
+ "required": true,
+ "schema": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Status returned",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "ocs"
+ ],
+ "properties": {
+ "ocs": {
+ "type": "object",
+ "required": [
+ "meta",
+ "data"
+ ],
+ "properties": {
+ "meta": {
+ "$ref": "#/components/schemas/OCSMeta"
+ },
+ "data": {
+ "$ref": "#/components/schemas/Public"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The user was not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "ocs"
+ ],
+ "properties": {
+ "ocs": {
+ "type": "object",
+ "required": [
+ "meta",
+ "data"
+ ],
+ "properties": {
+ "meta": {
+ "$ref": "#/components/schemas/OCSMeta"
+ },
+ "data": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/ocs/v2.php/apps/user_status/api/v1/user_status": {
+ "get": {
+ "operationId": "user_status-get-status",
+ "summary": "Get the status of the current user",
+ "tags": [
+ "user_status"
+ ],
+ "security": [
+ {
+ "bearer_auth": []
+ },
+ {
+ "basic_auth": []
+ }
+ ],
+ "parameters": [
+ {
+ "name": "OCS-APIRequest",
+ "in": "header",
+ "description": "Required to be true for the API request to pass",
+ "required": true,
+ "schema": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "The status was found successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "ocs"
+ ],
+ "properties": {
+ "ocs": {
+ "type": "object",
+ "required": [
+ "meta",
+ "data"
+ ],
+ "properties": {
+ "meta": {
+ "$ref": "#/components/schemas/OCSMeta"
+ },
+ "data": {
+ "$ref": "#/components/schemas/Private"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The user was not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "ocs"
+ ],
+ "properties": {
+ "ocs": {
+ "type": "object",
+ "required": [
+ "meta",
+ "data"
+ ],
+ "properties": {
+ "meta": {
+ "$ref": "#/components/schemas/OCSMeta"
+ },
+ "data": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/ocs/v2.php/apps/user_status/api/v1/user_status/status": {
+ "put": {
+ "operationId": "user_status-set-status",
+ "summary": "Update the status type of the current user",
+ "tags": [
+ "user_status"
+ ],
+ "security": [
+ {
+ "bearer_auth": []
+ },
+ {
+ "basic_auth": []
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "statusType"
+ ],
+ "properties": {
+ "statusType": {
+ "type": "string",
+ "description": "The new status type"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "OCS-APIRequest",
+ "in": "header",
+ "description": "Required to be true for the API request to pass",
+ "required": true,
+ "schema": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "The status was updated successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "ocs"
+ ],
+ "properties": {
+ "ocs": {
+ "type": "object",
+ "required": [
+ "meta",
+ "data"
+ ],
+ "properties": {
+ "meta": {
+ "$ref": "#/components/schemas/OCSMeta"
+ },
+ "data": {
+ "$ref": "#/components/schemas/Private"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "The status type is invalid",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "ocs"
+ ],
+ "properties": {
+ "ocs": {
+ "type": "object",
+ "required": [
+ "meta",
+ "data"
+ ],
+ "properties": {
+ "meta": {
+ "$ref": "#/components/schemas/OCSMeta"
+ },
+ "data": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/ocs/v2.php/apps/user_status/api/v1/user_status/message/predefined": {
+ "put": {
+ "operationId": "user_status-set-predefined-message",
+ "summary": "Set the message to a predefined message for the current user",
+ "tags": [
+ "user_status"
+ ],
+ "security": [
+ {
+ "bearer_auth": []
+ },
+ {
+ "basic_auth": []
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "messageId"
+ ],
+ "properties": {
+ "messageId": {
+ "type": "string",
+ "description": "ID of the predefined message"
+ },
+ "clearAt": {
+ "type": "integer",
+ "format": "int64",
+ "nullable": true,
+ "description": "When the message should be cleared"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "OCS-APIRequest",
+ "in": "header",
+ "description": "Required to be true for the API request to pass",
+ "required": true,
+ "schema": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "The message was updated successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "ocs"
+ ],
+ "properties": {
+ "ocs": {
+ "type": "object",
+ "required": [
+ "meta",
+ "data"
+ ],
+ "properties": {
+ "meta": {
+ "$ref": "#/components/schemas/OCSMeta"
+ },
+ "data": {
+ "$ref": "#/components/schemas/Private"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "The clearAt or message-id is invalid",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "ocs"
+ ],
+ "properties": {
+ "ocs": {
+ "type": "object",
+ "required": [
+ "meta",
+ "data"
+ ],
+ "properties": {
+ "meta": {
+ "$ref": "#/components/schemas/OCSMeta"
+ },
+ "data": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/ocs/v2.php/apps/user_status/api/v1/user_status/message/custom": {
+ "put": {
+ "operationId": "user_status-set-custom-message",
+ "summary": "Set the message to a custom message for the current user",
+ "tags": [
+ "user_status"
+ ],
+ "security": [
+ {
+ "bearer_auth": []
+ },
+ {
+ "basic_auth": []
+ }
+ ],
+ "requestBody": {
+ "required": false,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "statusIcon": {
+ "type": "string",
+ "nullable": true,
+ "description": "Icon of the status"
+ },
+ "message": {
+ "type": "string",
+ "nullable": true,
+ "description": "Message of the status"
+ },
+ "clearAt": {
+ "type": "integer",
+ "format": "int64",
+ "nullable": true,
+ "description": "When the message should be cleared"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "OCS-APIRequest",
+ "in": "header",
+ "description": "Required to be true for the API request to pass",
+ "required": true,
+ "schema": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "The message was updated successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "ocs"
+ ],
+ "properties": {
+ "ocs": {
+ "type": "object",
+ "required": [
+ "meta",
+ "data"
+ ],
+ "properties": {
+ "meta": {
+ "$ref": "#/components/schemas/OCSMeta"
+ },
+ "data": {
+ "$ref": "#/components/schemas/Private"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "The clearAt or icon is invalid or the message is too long",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "ocs"
+ ],
+ "properties": {
+ "ocs": {
+ "type": "object",
+ "required": [
+ "meta",
+ "data"
+ ],
+ "properties": {
+ "meta": {
+ "$ref": "#/components/schemas/OCSMeta"
+ },
+ "data": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "No status for the current user",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "ocs"
+ ],
+ "properties": {
+ "ocs": {
+ "type": "object",
+ "required": [
+ "meta",
+ "data"
+ ],
+ "properties": {
+ "meta": {
+ "$ref": "#/components/schemas/OCSMeta"
+ },
+ "data": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/ocs/v2.php/apps/user_status/api/v1/user_status/message": {
+ "delete": {
+ "operationId": "user_status-clear-message",
+ "summary": "Clear the message of the current user",
+ "tags": [
+ "user_status"
+ ],
+ "security": [
+ {
+ "bearer_auth": []
+ },
+ {
+ "basic_auth": []
+ }
+ ],
+ "parameters": [
+ {
+ "name": "OCS-APIRequest",
+ "in": "header",
+ "description": "Required to be true for the API request to pass",
+ "required": true,
+ "schema": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Message cleared successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "ocs"
+ ],
+ "properties": {
+ "ocs": {
+ "type": "object",
+ "required": [
+ "meta",
+ "data"
+ ],
+ "properties": {
+ "meta": {
+ "$ref": "#/components/schemas/OCSMeta"
+ },
+ "data": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/ocs/v2.php/apps/user_status/api/v1/user_status/revert/{messageId}": {
+ "delete": {
+ "operationId": "user_status-revert-status",
+ "summary": "Revert the status to the previous status",
+ "tags": [
+ "user_status"
+ ],
+ "security": [
+ {
+ "bearer_auth": []
+ },
+ {
+ "basic_auth": []
+ }
+ ],
+ "parameters": [
+ {
+ "name": "messageId",
+ "in": "path",
+ "description": "ID of the message to delete",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "OCS-APIRequest",
+ "in": "header",
+ "description": "Required to be true for the API request to pass",
+ "required": true,
+ "schema": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Status reverted",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "ocs"
+ ],
+ "properties": {
+ "ocs": {
+ "type": "object",
+ "required": [
+ "meta",
+ "data"
+ ],
+ "properties": {
+ "meta": {
+ "$ref": "#/components/schemas/OCSMeta"
+ },
+ "data": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/Private"
+ },
+ {
+ "type": "array",
+ "maxItems": 0
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": []
+}
diff --git a/apps/user_status/openapi.json.license b/apps/user_status/openapi.json.license
new file mode 100644
index 00000000000..83559daa9dc
--- /dev/null
+++ b/apps/user_status/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/user_status/src/UserStatus.vue b/apps/user_status/src/UserStatus.vue
index 8baf31de1b7..07d81aad95c 100644
--- a/apps/user_status/src/UserStatus.vue
+++ b/apps/user_status/src/UserStatus.vue
@@ -1,80 +1,70 @@
<!--
- - @copyright Copyright (c) 2020 Georg Ehrke <oc.list@georgehrke.com>
- - @author Georg Ehrke <oc.list@georgehrke.com>
- -
- - @license GNU AGPL version 3 or any later version
- -
- - This program is free software: you can redistribute it and/or modify
- - it under the terms of the GNU Affero General Public License as
- - published by the Free Software Foundation, either version 3 of the
- - License, or (at your option) any later version.
- -
- - 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
- - along with this program. If not, see <http://www.gnu.org/licenses/>.
- -
- -->
+ - SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
+-->
<template>
- <li>
- <div class="user-status-menu-item">
- <!-- Username display -->
- <a v-if="!inline"
- class="user-status-menu-item__header"
- :href="profilePageLink"
- @click="loadProfilePage">
- <div class="user-status-menu-item__header-content">
- <div class="user-status-menu-item__header-content-displayname">{{ displayName }}</div>
- <div v-if="!loadingProfilePage" class="user-status-menu-item__header-content-placeholder" />
- <div v-else class="icon-loading-small" />
- </div>
- <div v-if="profileEnabled">
- {{ t('user_status', 'View profile') }}
- </div>
- </a>
-
- <!-- Status modal toggle -->
- <toggle :is="inline ? 'button' : 'a'"
- :class="{'user-status-menu-item__toggle--inline': inline}"
- class="user-status-menu-item__toggle"
- href="#"
- @click.prevent.stop="openModal">
- <span :class="statusIcon" class="user-status-menu-item__toggle-icon" />
+ <Fragment>
+ <NcListItem v-if="!inline"
+ class="user-status-menu-item"
+ compact
+ :name="visibleMessage"
+ @click.stop="openModal">
+ <template #icon>
+ <NcUserStatusIcon class="user-status-icon"
+ :status="statusType"
+ aria-hidden="true" />
+ </template>
+ </NcListItem>
+
+ <div v-else>
+ <!-- Dashboard Status -->
+ <NcButton @click.stop="openModal">
+ <template #icon>
+ <NcUserStatusIcon class="user-status-icon"
+ :status="statusType"
+ aria-hidden="true" />
+ </template>
{{ visibleMessage }}
- </toggle>
+ </NcButton>
</div>
-
<!-- Status management modal -->
<SetStatusModal v-if="isModalOpen"
+ :inline="inline"
@close="closeModal" />
- </li>
+ </Fragment>
</template>
<script>
-import { generateUrl } from '@nextcloud/router'
import { getCurrentUser } from '@nextcloud/auth'
-import { loadState } from '@nextcloud/initial-state'
import { subscribe, unsubscribe } from '@nextcloud/event-bus'
+import { Fragment } from 'vue-frag'
+import NcButton from '@nextcloud/vue/components/NcButton'
+import NcListItem from '@nextcloud/vue/components/NcListItem'
+import NcUserStatusIcon from '@nextcloud/vue/components/NcUserStatusIcon'
import debounce from 'debounce'
-import { sendHeartbeat } from './services/heartbeatService'
-import OnlineStatusMixin from './mixins/OnlineStatusMixin'
-
-const { profileEnabled } = loadState('user_status', 'profileEnabled', false)
+import { sendHeartbeat } from './services/heartbeatService.js'
+import OnlineStatusMixin from './mixins/OnlineStatusMixin.js'
export default {
name: 'UserStatus',
components: {
- SetStatusModal: () => import(/* webpackChunkName: 'user-status-modal' */'./components/SetStatusModal'),
+ Fragment,
+ NcButton,
+ NcListItem,
+ NcUserStatusIcon,
+ SetStatusModal: () => import(/* webpackChunkName: 'user-status-modal' */'./components/SetStatusModal.vue'),
},
mixins: [OnlineStatusMixin],
props: {
+ /**
+ * Whether the component should be rendered as a Dashboard Status or a User Menu Entries
+ * true = Dashboard Status
+ * false = User Menu Entries
+ */
inline: {
type: Boolean,
default: false,
@@ -83,41 +73,19 @@ export default {
data() {
return {
- displayName: getCurrentUser().displayName,
heartbeatInterval: null,
isAway: false,
isModalOpen: false,
- loadingProfilePage: false,
mouseMoveListener: null,
- profileEnabled,
setAwayTimeout: null,
}
},
- computed: {
- /**
- * The profile page link
- *
- * @return {string | null}
- */
- profilePageLink() {
- if (this.profileEnabled) {
- return generateUrl('/u/{userId}', { userId: getCurrentUser().uid })
- }
- // Since an anchor element is used rather than a button,
- // this hack removes href if the profile is disabled so that disabling pointer-events is not needed to prevent a click from opening a page
- // and to allow the hover event for styling
- return null
- },
- },
/**
* Loads the current user's status from initial state
* and stores it in Vuex
*/
mounted() {
- subscribe('settings:display-name:updated', this.handleDisplayNameUpdate)
- subscribe('settings:profile-enabled:updated', this.handleProfileEnabledUpdate)
-
this.$store.dispatch('loadStatusFromInitialState')
if (OC.config.session_keepalive) {
@@ -154,28 +122,12 @@ export default {
* Some housekeeping before destroying the component
*/
beforeDestroy() {
- unsubscribe('settings:display-name:updated', this.handleDisplayNameUpdate)
- unsubscribe('settings:profile-enabled:updated', this.handleProfileEnabledUpdate)
window.removeEventListener('mouseMove', this.mouseMoveListener)
clearInterval(this.heartbeatInterval)
unsubscribe('user_status:status.updated', this.handleUserStatusUpdated)
},
methods: {
- handleDisplayNameUpdate(displayName) {
- this.displayName = displayName
- },
-
- handleProfileEnabledUpdate(profileEnabled) {
- this.profileEnabled = profileEnabled
- },
-
- loadProfilePage() {
- if (this.profileEnabled) {
- this.loadingProfilePage = true
- }
- },
-
/**
* Opens the modal to set a custom status
*/
@@ -208,7 +160,7 @@ export default {
}
},
handleUserStatusUpdated(state) {
- if (OC.getCurrentUser().uid === state.userId) {
+ if (getCurrentUser()?.uid === state.userId) {
this.$store.dispatch('setStatusFromObject', {
status: state.status,
icon: state.icon,
@@ -221,91 +173,12 @@ export default {
</script>
<style lang="scss" scoped>
-.user-status-menu-item {
- &__header {
- display: flex !important;
- flex-direction: column !important;
- width: auto !important;
- height: 44px * 1.5 !important;
- padding: 10px 12px 5px 12px !important;
- align-items: flex-start !important;
- color: var(--color-main-text) !important;
-
- &:not([href]) {
- height: var(--header-menu-item-height) !important;
- color: var(--color-text-maxcontrast) !important;
- cursor: default !important;
-
- & * {
- cursor: default !important;
- }
-
- &:hover {
- background-color: transparent !important;
- }
- }
-
- &-content {
- display: inline-flex !important;
- font-weight: bold !important;
- gap: 0 10px !important;
- width: auto;
-
- &-displayname {
- width: auto;
- }
-
- &-placeholder {
- width: 16px !important;
- height: 24px !important;
- margin-right: 10px !important;
- visibility: hidden !important;
- }
- }
-
- span {
- color: var(--color-text-maxcontrast) !important;
- }
- }
-
- &__toggle {
- &-icon {
- width: 16px;
- height: 16px;
- margin-right: 10px;
- opacity: 1 !important;
- background-size: 16px;
- }
-
- // In dashboard
- &--inline {
- width: auto;
- min-width: 44px;
- height: 44px;
- margin: 0;
- border: 0;
- border-radius: var(--border-radius-pill);
- background-color: var(--color-background-translucent);
- font-size: inherit;
- font-weight: normal;
-
- -webkit-backdrop-filter: var(--background-blur);
- backdrop-filter: var(--background-blur);
-
- &:active,
- &:hover,
- &:focus {
- background-color: var(--color-background-hover);
- }
- &:focus {
- border: 2px solid var(--color-main-text)!important;
- }
- }
- }
+.user-status-icon {
+ width: 20px;
+ height: 20px;
+ margin: calc((var(--default-clickable-area) - 20px) / 2); // 20px icon size
+ opacity: 1 !important;
+ background-size: 20px;
+ vertical-align: middle !important;
}
-
-li {
- list-style-type: none;
-}
-
</style>
diff --git a/apps/user_status/src/components/ClearAtSelect.vue b/apps/user_status/src/components/ClearAtSelect.vue
index 09e0068f87f..91b816dc04a 100644
--- a/apps/user_status/src/components/ClearAtSelect.vue
+++ b/apps/user_status/src/components/ClearAtSelect.vue
@@ -1,46 +1,33 @@
<!--
- - @copyright Copyright (c) 2020 Georg Ehrke <oc.list@georgehrke.com>
- - @author Georg Ehrke <oc.list@georgehrke.com>
- -
- - @license GNU AGPL version 3 or any later version
- -
- - This program is free software: you can redistribute it and/or modify
- - it under the terms of the GNU Affero General Public License as
- - published by the Free Software Foundation, either version 3 of the
- - License, or (at your option) any later version.
- -
- - 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
- - along with this program. If not, see <http://www.gnu.org/licenses/>.
- -
- -->
+ - SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
+-->
<template>
<div class="clear-at-select">
- <span class="clear-at-select__label">
- {{ $t('user_status', 'Clear status message after') }}
- </span>
- <Multiselect label="label"
- :value="option"
+ <label class="clear-at-select__label" for="clearStatus">
+ {{ $t('user_status', 'Clear status after') }}
+ </label>
+ <NcSelect input-id="clearStatus"
+ class="clear-at-select__select"
:options="options"
- open-direction="top"
- @select="select" />
+ :value="option"
+ :clearable="false"
+ placement="top"
+ label-outside
+ @option:selected="select" />
</div>
</template>
<script>
-import Multiselect from '@nextcloud/vue/dist/Components/Multiselect'
-import { getAllClearAtOptions } from '../services/clearAtOptionsService'
-import { clearAtFilter } from '../filters/clearAtFilter'
+import NcSelect from '@nextcloud/vue/components/NcSelect'
+import { getAllClearAtOptions } from '../services/clearAtOptionsService.js'
+import { clearAtFilter } from '../filters/clearAtFilter.js'
export default {
name: 'ClearAtSelect',
components: {
- Multiselect,
+ NcSelect,
},
props: {
clearAt: {
@@ -86,16 +73,13 @@ export default {
<style lang="scss" scoped>
.clear-at-select {
display: flex;
- margin-bottom: 10px;
+ gap: calc(2 * var(--default-grid-baseline));
align-items: center;
+ margin-block: 0 calc(2 * var(--default-grid-baseline));
- &__label {
- margin-right: 10px;
- }
-
- .multiselect {
+ &__select {
flex-grow: 1;
- min-width: 130px;
+ min-width: 215px;
}
}
</style>
diff --git a/apps/user_status/src/components/CustomMessageInput.vue b/apps/user_status/src/components/CustomMessageInput.vue
index 88956e6871b..fb129281430 100644
--- a/apps/user_status/src/components/CustomMessageInput.vue
+++ b/apps/user_status/src/components/CustomMessageInput.vue
@@ -1,43 +1,49 @@
<!--
- - @copyright Copyright (c) 2020 Georg Ehrke <oc.list@georgehrke.com>
- - @author Georg Ehrke <oc.list@georgehrke.com>
- -
- - @license GNU AGPL version 3 or any later version
- -
- - This program is free software: you can redistribute it and/or modify
- - it under the terms of the GNU Affero General Public License as
- - published by the Free Software Foundation, either version 3 of the
- - License, or (at your option) any later version.
- -
- - 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
- - along with this program. If not, see <http://www.gnu.org/licenses/>.
- -
- -->
+ - SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
+-->
<template>
- <form class="custom-input__form"
- @submit.prevent>
- <input ref="input"
- maxlength="80"
- :disabled="disabled"
- :placeholder="$t('user_status', 'What is your status?')"
- type="text"
- :value="message"
- @change="change"
- @keyup="change"
- @paste="change"
- @keyup.enter="submit">
- </form>
+ <div class="custom-input" role="group">
+ <NcEmojiPicker container=".custom-input" @select="setIcon">
+ <NcButton type="tertiary"
+ :aria-label="t('user_status', 'Emoji for your status message')">
+ <template #icon>
+ {{ visibleIcon }}
+ </template>
+ </NcButton>
+ </NcEmojiPicker>
+ <div class="custom-input__container">
+ <NcTextField ref="input"
+ maxlength="80"
+ :disabled="disabled"
+ :placeholder="t('user_status', 'What is your status?')"
+ :value="message"
+ type="text"
+ :label="t('user_status', 'What is your status?')"
+ @input="onChange" />
+ </div>
+ </div>
</template>
<script>
+import NcButton from '@nextcloud/vue/components/NcButton'
+import NcEmojiPicker from '@nextcloud/vue/components/NcEmojiPicker'
+import NcTextField from '@nextcloud/vue/components/NcTextField'
+
export default {
name: 'CustomMessageInput',
+
+ components: {
+ NcTextField,
+ NcButton,
+ NcEmojiPicker,
+ },
+
props: {
+ icon: {
+ type: String,
+ default: '😀',
+ },
message: {
type: String,
required: true,
@@ -48,6 +54,23 @@ export default {
default: false,
},
},
+
+ emits: [
+ 'change',
+ 'select-icon',
+ ],
+
+ computed: {
+ /**
+ * Returns the user-set icon or a smiley in case no icon is set
+ *
+ * @return {string}
+ */
+ visibleIcon() {
+ return this.icon || '😀'
+ },
+ },
+
methods: {
focus() {
this.$refs.input.focus()
@@ -58,24 +81,26 @@ export default {
*
* @param {Event} event The Change Event
*/
- change(event) {
+ onChange(event) {
this.$emit('change', event.target.value)
},
- submit(event) {
- this.$emit('submit', event.target.value)
+ setIcon(icon) {
+ this.$emit('select-icon', icon)
},
},
}
</script>
<style lang="scss" scoped>
-.custom-input__form {
- flex-grow: 1;
+.custom-input {
+ display: flex;
+ align-items: flex-end;
+ gap: var(--default-grid-baseline);
+ width: 100%;
- input {
+ &__container {
width: 100%;
- border-radius: 0 var(--border-radius) var(--border-radius) 0;
}
}
</style>
diff --git a/apps/user_status/src/components/OnlineStatusSelect.vue b/apps/user_status/src/components/OnlineStatusSelect.vue
index d9ce249ad13..0abcc8d68e6 100644
--- a/apps/user_status/src/components/OnlineStatusSelect.vue
+++ b/apps/user_status/src/components/OnlineStatusSelect.vue
@@ -1,33 +1,19 @@
<!--
- - @copyright Copyright (c) 2020 John Molakvoæ <skjnldsv@protonmail.com>
- -
- - @author John Molakvoæ <skjnldsv@protonmail.com>
- -
- - @license GNU AGPL version 3 or any later version
- -
- - This program is free software: you can redistribute it and/or modify
- - it under the terms of the GNU Affero General Public License as
- - published by the Free Software Foundation, either version 3 of the
- - License, or (at your option) any later version.
- -
- - 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
- - along with this program. If not, see <http://www.gnu.org/licenses/>.
- -
- -->
+ - SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
+-->
<template>
<div class="user-status-online-select">
<input :id="id"
:checked="checked"
- class="user-status-online-select__input"
+ class="hidden-visually user-status-online-select__input"
type="radio"
name="user-status-online"
@change="onChange">
- <label :for="id" :class="icon" class="user-status-online-select__label">
+ <label :for="id" class="user-status-online-select__label">
+ <NcUserStatusIcon :status="type"
+ class="user-status-online-select__icon"
+ aria-hidden="true" />
{{ label }}
<em class="user-status-online-select__subline">{{ subline }}</em>
</label>
@@ -35,18 +21,20 @@
</template>
<script>
+import NcUserStatusIcon from '@nextcloud/vue/components/NcUserStatusIcon'
+
export default {
name: 'OnlineStatusSelect',
+ components: {
+ NcUserStatusIcon,
+ },
+
props: {
checked: {
type: Boolean,
default: false,
},
- icon: {
- type: String,
- required: true,
- },
type: {
type: String,
required: true,
@@ -76,41 +64,42 @@ export default {
</script>
<style lang="scss" scoped>
-$icon-size: 24px;
-$label-padding: 8px;
-
.user-status-online-select {
- // Inputs are here for keyboard navigation, they are not visually visible
- &__input {
- position: absolute;
- top: auto;
- left: -10000px;
- overflow: hidden;
- width: 1px;
- height: 1px;
- }
-
&__label {
- display: block;
- margin: $label-padding;
- padding: $label-padding;
- padding-left: $icon-size + $label-padding * 2;
- border: 2px solid var(--color-main-background);
+ box-sizing: inherit;
+ display: grid;
+ grid-template-columns: var(--default-clickable-area) 1fr 2fr;
+ align-items: center;
+ gap: var(--default-grid-baseline);
+ min-height: var(--default-clickable-area);
+ padding: var(--default-grid-baseline);
border-radius: var(--border-radius-large);
background-color: var(--color-background-hover);
- background-position: $label-padding center;
- background-size: $icon-size;
- span,
- & {
+ &, & * {
cursor: pointer;
}
+
+ &:hover {
+ background-color: var(--color-background-dark);
+ }
+ }
+
+ &__icon {
+ flex-shrink: 0;
+ max-width: 34px;
+ max-height: 100%;
+ }
+
+ &__input:checked + &__label {
+ outline: 2px solid var(--color-main-text);
+ background-color: var(--color-background-dark);
+ box-shadow: 0 0 0 4px var(--color-main-background);
}
- &__input:checked + &__label,
- &__input:focus + &__label,
- &__label:hover {
- border-color: var(--color-primary);
+ &__input:focus-visible + &__label {
+ outline: 2px solid var(--color-primary-element) !important;
+ background-color: var(--color-background-dark);
}
&__subline {
@@ -118,5 +107,4 @@ $label-padding: 8px;
color: var(--color-text-lighter);
}
}
-
</style>
diff --git a/apps/user_status/src/components/PredefinedStatus.vue b/apps/user_status/src/components/PredefinedStatus.vue
index f8d5fe26be4..b12892d4add 100644
--- a/apps/user_status/src/components/PredefinedStatus.vue
+++ b/apps/user_status/src/components/PredefinedStatus.vue
@@ -1,43 +1,31 @@
<!--
- - @copyright Copyright (c) 2020 Georg Ehrke <oc.list@georgehrke.com>
- - @author Georg Ehrke <oc.list@georgehrke.com>
- -
- - @license GNU AGPL version 3 or any later version
- -
- - This program is free software: you can redistribute it and/or modify
- - it under the terms of the GNU Affero General Public License as
- - published by the Free Software Foundation, either version 3 of the
- - License, or (at your option) any later version.
- -
- - 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
- - along with this program. If not, see <http://www.gnu.org/licenses/>.
- -
- -->
+ - SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
+-->
<template>
- <div class="predefined-status"
- tabindex="0"
- @keyup.enter="select"
- @keyup.space="select"
- @click="select">
- <span class="predefined-status__icon">
- {{ icon }}
- </span>
- <span class="predefined-status__message">
- {{ message }}
- </span>
- <span class="predefined-status__clear-at">
- {{ clearAt | clearAtFilter }}
- </span>
- </div>
+ <li class="predefined-status">
+ <input :id="id"
+ class="hidden-visually predefined-status__input"
+ type="radio"
+ name="predefined-status"
+ :checked="selected"
+ @change="select">
+ <label class="predefined-status__label" :for="id">
+ <span aria-hidden="true" class="predefined-status__label--icon">
+ {{ icon }}
+ </span>
+ <span class="predefined-status__label--message">
+ {{ message }}
+ </span>
+ <span class="predefined-status__label--clear-at">
+ {{ clearAt | clearAtFilter }}
+ </span>
+ </label>
+ </li>
</template>
<script>
-import { clearAtFilter } from '../filters/clearAtFilter'
+import { clearAtFilter } from '../filters/clearAtFilter.js'
export default {
name: 'PredefinedStatus',
@@ -62,6 +50,16 @@ export default {
required: false,
default: null,
},
+ selected: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
+ computed: {
+ id() {
+ return `user-status-predefined-status-${this.messageId}`
+ },
},
methods: {
/**
@@ -76,35 +74,55 @@ export default {
<style lang="scss" scoped>
.predefined-status {
- display: flex;
- flex-wrap: nowrap;
- justify-content: flex-start;
- flex-basis: 100%;
- border-radius: var(--border-radius);
- align-items: center;
- min-height: 44px;
+ &__label {
+ display: flex;
+ flex-wrap: nowrap;
+ justify-content: flex-start;
+ flex-basis: 100%;
+ border-radius: var(--border-radius);
+ align-items: center;
+ min-height: var(--default-clickable-area);
+ padding-inline: var(--default-grid-baseline);
- &:hover,
- &:focus {
- background-color: var(--color-background-hover);
- }
+ &, & * {
+ cursor: pointer;
+ }
- &__icon {
- flex-basis: 40px;
- text-align: center;
- }
+ &:hover {
+ background-color: var(--color-background-dark);
+ }
- &__message {
- font-weight: bold;
- padding: 0 6px;
- }
+ &--icon {
+ flex-basis: var(--default-clickable-area);
+ text-align: center;
+ }
+
+ &--message {
+ font-weight: bold;
+ padding: 0 6px;
+ }
- &__clear-at {
- opacity: .7;
+ &--clear-at {
+ color: var(--color-text-maxcontrast);
- &::before {
- content: ' - ';
+ &::before {
+ content: ' – ';
+ }
}
}
+
+ &__input:checked + &__label,
+ &__label:active {
+ outline: 2px solid var(--color-main-text);
+ box-shadow: 0 0 0 4px var(--color-main-background);
+ background-color: var(--color-background-dark);
+ border-radius: var(--border-radius-large);
+ }
+
+ &__input:focus-visible + &__label {
+ outline: 2px solid var(--color-primary-element) !important;
+ background-color: var(--color-background-dark);
+ border-radius: var(--border-radius-large);
+ }
}
</style>
diff --git a/apps/user_status/src/components/PredefinedStatusesList.vue b/apps/user_status/src/components/PredefinedStatusesList.vue
index cff03289715..cdf359dce76 100644
--- a/apps/user_status/src/components/PredefinedStatusesList.vue
+++ b/apps/user_status/src/components/PredefinedStatusesList.vue
@@ -1,35 +1,21 @@
<!--
- - @copyright Copyright (c) 2020 Georg Ehrke <oc.list@georgehrke.com>
- - @author Georg Ehrke <oc.list@georgehrke.com>
- -
- - @license GNU AGPL version 3 or any later version
- -
- - This program is free software: you can redistribute it and/or modify
- - it under the terms of the GNU Affero General Public License as
- - published by the Free Software Foundation, either version 3 of the
- - License, or (at your option) any later version.
- -
- - 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
- - along with this program. If not, see <http://www.gnu.org/licenses/>.
- -
- -->
+ - SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
+-->
<template>
- <div v-if="hasLoaded"
- class="predefined-statuses-list">
+ <ul v-if="statusesHaveLoaded"
+ class="predefined-statuses-list"
+ :aria-label="t('user_status', 'Predefined statuses')">
<PredefinedStatus v-for="status in predefinedStatuses"
:key="status.id"
:message-id="status.id"
:icon="status.icon"
:message="status.message"
:clear-at="status.clearAt"
+ :selected="lastSelected === status.id"
@select="selectStatus(status)" />
- </div>
+ </ul>
<div v-else
class="predefined-statuses-list">
<div class="icon icon-loading-small" />
@@ -37,32 +23,41 @@
</template>
<script>
-import PredefinedStatus from './PredefinedStatus'
-import { mapState } from 'vuex'
+import PredefinedStatus from './PredefinedStatus.vue'
+import { mapGetters, mapState } from 'vuex'
export default {
name: 'PredefinedStatusesList',
components: {
PredefinedStatus,
},
+ data() {
+ return {
+ lastSelected: null,
+ }
+ },
computed: {
...mapState({
predefinedStatuses: state => state.predefinedStatuses.predefinedStatuses,
+ messageId: state => state.userStatus.messageId,
}),
- /**
- * Indicator whether the predefined statuses have already been loaded
- *
- * @return {boolean}
- */
- hasLoaded() {
- return this.predefinedStatuses.length > 0
- },
+ ...mapGetters(['statusesHaveLoaded']),
},
+
+ watch: {
+ messageId: {
+ immediate: true,
+ handler() {
+ this.lastSelected = this.messageId
+ },
+ },
+ },
+
/**
* Loads all predefined statuses from the server
* when this component is mounted
*/
- mounted() {
+ created() {
this.$store.dispatch('loadAllPredefinedStatuses')
},
methods: {
@@ -72,6 +67,7 @@ export default {
* @param {object} status The selected status
*/
selectStatus(status) {
+ this.lastSelected = status.id
this.$emit('select-status', status)
},
},
@@ -82,6 +78,7 @@ export default {
.predefined-statuses-list {
display: flex;
flex-direction: column;
- margin-bottom: 10px;
+ gap: var(--default-grid-baseline);
+ margin-block: 0 calc(2 * var(--default-grid-baseline));
}
</style>
diff --git a/apps/user_status/src/components/PreviousStatus.vue b/apps/user_status/src/components/PreviousStatus.vue
new file mode 100644
index 00000000000..58d6ebd294b
--- /dev/null
+++ b/apps/user_status/src/components/PreviousStatus.vue
@@ -0,0 +1,106 @@
+<!--
+ - SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
+-->
+<template>
+ <div class="predefined-status backup-status"
+ tabindex="0"
+ @keyup.enter="select"
+ @keyup.space="select"
+ @click="select">
+ <span class="predefined-status__icon">
+ {{ icon }}
+ </span>
+ <span class="predefined-status__message">
+ {{ message }}
+ </span>
+ <span class="predefined-status__clear-at">
+ {{ $t('user_status', 'Previously set') }}
+ </span>
+
+ <div class="backup-status__reset-button">
+ <NcButton @click="select">
+ {{ $t('user_status', 'Reset status') }}
+ </NcButton>
+ </div>
+ </div>
+</template>
+
+<script>
+import NcButton from '@nextcloud/vue/components/NcButton'
+
+export default {
+ name: 'PreviousStatus',
+
+ components: {
+ NcButton,
+ },
+
+ props: {
+ icon: {
+ type: [String, null],
+ required: true,
+ },
+ message: {
+ type: String,
+ required: true,
+ },
+ },
+ methods: {
+ /**
+ * Emits an event when the user clicks the row
+ */
+ select() {
+ this.$emit('select')
+ },
+ },
+}
+</script>
+
+<style lang="scss" scoped>
+.predefined-status {
+ display: flex;
+ flex-wrap: nowrap;
+ justify-content: flex-start;
+ flex-basis: 100%;
+ border-radius: var(--border-radius);
+ align-items: center;
+ min-height: var(--default-clickable-area);
+ padding-inline: var(--default-grid-baseline);
+
+ &:hover,
+ &:focus {
+ background-color: var(--color-background-hover);
+ }
+
+ &:active{
+ background-color: var(--color-background-dark);
+ }
+
+ &__icon {
+ flex-basis: var(--default-clickable-area);
+ text-align: center;
+ }
+
+ &__message {
+ font-weight: bold;
+ padding: 0 6px;
+ }
+
+ &__clear-at {
+ color: var(--color-text-maxcontrast);
+
+ &::before {
+ content: ' – ';
+ }
+ }
+}
+
+.backup-status {
+ &__reset-button {
+ justify-content: flex-end;
+ display: flex;
+ flex-grow: 1;
+ }
+}
+</style>
diff --git a/apps/user_status/src/components/SetStatusModal.vue b/apps/user_status/src/components/SetStatusModal.vue
index df6858ca6ff..8624ed19e94 100644
--- a/apps/user_status/src/components/SetStatusModal.vue
+++ b/apps/user_status/src/components/SetStatusModal.vue
@@ -1,34 +1,22 @@
<!--
- - @copyright Copyright (c) 2020 Georg Ehrke <oc.list@georgehrke.com>
- - @author Georg Ehrke <oc.list@georgehrke.com>
- -
- - @license GNU AGPL version 3 or any later version
- -
- - This program is free software: you can redistribute it and/or modify
- - it under the terms of the GNU Affero General Public License as
- - published by the Free Software Foundation, either version 3 of the
- - License, or (at your option) any later version.
- -
- - 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
- - along with this program. If not, see <http://www.gnu.org/licenses/>.
- -
- -->
+ - SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
+-->
<template>
- <Modal size="normal"
- :title="$t('user_status', 'Set status')"
+ <NcModal size="normal"
+ label-id="user_status-set-dialog"
+ dark
+ :set-return-focus="setReturnFocus"
@close="closeModal">
<div class="set-status-modal">
<!-- Status selector -->
- <div class="set-status-modal__header">
- <h3>{{ $t('user_status', 'Online status') }}</h3>
- </div>
- <div class="set-status-modal__online-status">
+ <h2 id="user_status-set-dialog" class="set-status-modal__header">
+ {{ $t('user_status', 'Online status') }}
+ </h2>
+ <div class="set-status-modal__online-status"
+ role="radiogroup"
+ :aria-label="$t('user_status', 'Online status')">
<OnlineStatusSelect v-for="status in statuses"
:key="status.type"
v-bind="status"
@@ -36,55 +24,69 @@
@select="changeStatus" />
</div>
- <!-- Status message -->
- <div class="set-status-modal__header">
- <h3>{{ $t('user_status', 'Status message') }}</h3>
- </div>
- <div class="set-status-modal__custom-input">
- <EmojiPicker @select="setIcon">
- <button class="custom-input__emoji-button">
- {{ visibleIcon }}
- </button>
- </EmojiPicker>
- <CustomMessageInput ref="customMessageInput"
- :message="message"
- @change="setMessage"
- @submit="saveStatus" />
- </div>
- <PredefinedStatusesList @select-status="selectPredefinedMessage" />
- <ClearAtSelect :clear-at="clearAt"
- @select-clear-at="setClearAt" />
- <div class="status-buttons">
- <ButtonVue wide="true"
- type="tertiary"
- :text="$t('user_status', 'Clear status message')"
- :disabled="isSavingStatus"
- @click="clearStatus">
- {{ $t('user_status', 'Clear status message') }}
- </ButtonVue>
- <ButtonVue wide="true"
- type="primary"
- :text="$t('user_status', 'Set status message')"
- :disabled="isSavingStatus"
- @click="saveStatus">
- {{ $t('user_status', 'Set status message') }}
- </ButtonVue>
- </div>
+ <!-- Status message form -->
+ <form @submit.prevent="saveStatus" @reset="clearStatus">
+ <h3 class="set-status-modal__header">
+ {{ $t('user_status', 'Status message') }}
+ </h3>
+ <div class="set-status-modal__custom-input">
+ <CustomMessageInput ref="customMessageInput"
+ :icon="icon"
+ :message="editedMessage"
+ @change="setMessage"
+ @select-icon="setIcon" />
+ <NcButton v-if="messageId === 'vacationing'"
+ :href="absencePageUrl"
+ target="_blank"
+ type="secondary"
+ :aria-label="$t('user_status', 'Set absence period')">
+ {{ $t('user_status', 'Set absence period and replacement') + ' ↗' }}
+ </NcButton>
+ </div>
+ <div v-if="hasBackupStatus"
+ class="set-status-modal__automation-hint">
+ {{ $t('user_status', 'Your status was set automatically') }}
+ </div>
+ <PreviousStatus v-if="hasBackupStatus"
+ :icon="backupIcon"
+ :message="backupMessage"
+ @select="revertBackupFromServer" />
+ <PredefinedStatusesList @select-status="selectPredefinedMessage" />
+ <ClearAtSelect :clear-at="clearAt"
+ @select-clear-at="setClearAt" />
+ <div class="status-buttons">
+ <NcButton :wide="true"
+ type="tertiary"
+ native-type="reset"
+ :aria-label="$t('user_status', 'Clear status message')"
+ :disabled="isSavingStatus">
+ {{ $t('user_status', 'Clear status message') }}
+ </NcButton>
+ <NcButton :wide="true"
+ type="primary"
+ native-type="submit"
+ :aria-label="$t('user_status', 'Set status message')"
+ :disabled="isSavingStatus">
+ {{ $t('user_status', 'Set status message') }}
+ </NcButton>
+ </div>
+ </form>
</div>
- </Modal>
+ </NcModal>
</template>
<script>
import { showError } from '@nextcloud/dialogs'
-import EmojiPicker from '@nextcloud/vue/dist/Components/EmojiPicker'
-import Modal from '@nextcloud/vue/dist/Components/Modal'
-import ButtonVue from '@nextcloud/vue/dist/Components/Button'
-import { getAllStatusOptions } from '../services/statusOptionsService'
-import OnlineStatusMixin from '../mixins/OnlineStatusMixin'
-import PredefinedStatusesList from './PredefinedStatusesList'
-import CustomMessageInput from './CustomMessageInput'
-import ClearAtSelect from './ClearAtSelect'
-import OnlineStatusSelect from './OnlineStatusSelect'
+import { generateUrl } from '@nextcloud/router'
+import NcModal from '@nextcloud/vue/components/NcModal'
+import NcButton from '@nextcloud/vue/components/NcButton'
+import { getAllStatusOptions } from '../services/statusOptionsService.js'
+import OnlineStatusMixin from '../mixins/OnlineStatusMixin.js'
+import PredefinedStatusesList from './PredefinedStatusesList.vue'
+import PreviousStatus from './PreviousStatus.vue'
+import CustomMessageInput from './CustomMessageInput.vue'
+import ClearAtSelect from './ClearAtSelect.vue'
+import OnlineStatusSelect from './OnlineStatusSelect.vue'
export default {
name: 'SetStatusModal',
@@ -92,32 +94,93 @@ export default {
components: {
ClearAtSelect,
CustomMessageInput,
- EmojiPicker,
- Modal,
+ NcModal,
OnlineStatusSelect,
PredefinedStatusesList,
- ButtonVue,
+ PreviousStatus,
+ NcButton,
},
mixins: [OnlineStatusMixin],
+ props: {
+ /**
+ * Whether the component should be rendered as a Dashboard Status or a User Menu Entries
+ * true = Dashboard Status
+ * false = User Menu Entries
+ */
+ inline: {
+ type: Boolean,
+ default: false,
+ },
+ },
+
data() {
return {
clearAt: null,
- icon: null,
- message: '',
- messageId: '',
+ editedMessage: '',
+ predefinedMessageId: null,
isSavingStatus: false,
statuses: getAllStatusOptions(),
}
},
+
computed: {
- /**
- * Returns the user-set icon or a smiley in case no icon is set
- *
- * @return {string}
- */
- visibleIcon() {
- return this.icon || '😀'
+ messageId() {
+ return this.$store.state.userStatus.messageId
+ },
+ icon() {
+ return this.$store.state.userStatus.icon
+ },
+ message() {
+ return this.$store.state.userStatus.message || ''
+ },
+ hasBackupStatus() {
+ return this.messageId && (this.backupIcon || this.backupMessage)
+ },
+ backupIcon() {
+ return this.$store.state.userBackupStatus.icon || ''
+ },
+ backupMessage() {
+ return this.$store.state.userBackupStatus.message || ''
+ },
+
+ absencePageUrl() {
+ return generateUrl('settings/user/availability#absence')
+ },
+
+ resetButtonText() {
+ if (this.backupIcon && this.backupMessage) {
+ return this.$t('user_status', 'Reset status to "{icon} {message}"', {
+ icon: this.backupIcon,
+ message: this.backupMessage,
+ })
+ } else if (this.backupMessage) {
+ return this.$t('user_status', 'Reset status to "{message}"', {
+ message: this.backupMessage,
+ })
+ } else if (this.backupIcon) {
+ return this.$t('user_status', 'Reset status to "{icon}"', {
+ icon: this.backupIcon,
+ })
+ }
+
+ return this.$t('user_status', 'Reset status')
+ },
+
+ setReturnFocus() {
+ if (this.inline) {
+ return undefined
+ }
+ return document.querySelector('[aria-controls="header-menu-user-menu"]') ?? undefined
+ },
+ },
+
+ watch: {
+ message: {
+ immediate: true,
+ handler(newValue) {
+ this.editedMessage = newValue
+ },
},
},
@@ -125,10 +188,9 @@ export default {
* Loads the current status when a user opens dialog
*/
mounted() {
- this.messageId = this.$store.state.userStatus.messageId
- this.icon = this.$store.state.userStatus.icon
- this.message = this.$store.state.userStatus.message || ''
+ this.$store.dispatch('fetchBackupFromServer')
+ this.predefinedMessageId = this.$store.state.userStatus.messageId
if (this.$store.state.userStatus.clearAt !== null) {
this.clearAt = {
type: '_time',
@@ -149,8 +211,12 @@ export default {
* @param {string} icon The new icon
*/
setIcon(icon) {
- this.messageId = null
- this.icon = icon
+ this.predefinedMessageId = null
+ this.$store.dispatch('setCustomMessage', {
+ message: this.message,
+ icon,
+ clearAt: this.clearAt,
+ })
this.$nextTick(() => {
this.$refs.customMessageInput.focus()
})
@@ -161,8 +227,8 @@ export default {
* @param {string} message The new message
*/
setMessage(message) {
- this.messageId = null
- this.message = message
+ this.predefinedMessageId = null
+ this.editedMessage = message
},
/**
* Sets a new clearAt value
@@ -178,10 +244,12 @@ export default {
* @param {object} status The predefined status object
*/
selectPredefinedMessage(status) {
- this.messageId = status.id
+ this.predefinedMessageId = status.id
this.clearAt = status.clearAt
- this.icon = status.icon
- this.message = status.message
+ this.$store.dispatch('setPredefinedMessage', {
+ messageId: status.id,
+ clearAt: status.clearAt,
+ })
},
/**
* Saves the status and closes the
@@ -196,15 +264,15 @@ export default {
try {
this.isSavingStatus = true
- if (this.messageId !== undefined && this.messageId !== null) {
- await this.$store.dispatch('setPredefinedMessage', {
- messageId: this.messageId,
+ if (this.predefinedMessageId === null) {
+ await this.$store.dispatch('setCustomMessage', {
+ message: this.editedMessage,
+ icon: this.icon,
clearAt: this.clearAt,
})
} else {
- await this.$store.dispatch('setCustomMessage', {
- message: this.message,
- icon: this.icon,
+ this.$store.dispatch('setPredefinedMessage', {
+ messageId: this.predefinedMessageId,
clearAt: this.clearAt,
})
}
@@ -235,8 +303,30 @@ export default {
}
this.isSavingStatus = false
+ this.predefinedMessageId = null
this.closeModal()
},
+ /**
+ *
+ * @return {Promise<void>}
+ */
+ async revertBackupFromServer() {
+ try {
+ this.isSavingStatus = true
+
+ await this.$store.dispatch('revertBackupFromServer', {
+ messageId: this.messageId,
+ })
+ } catch (err) {
+ showError(this.$t('user_status', 'There was an error reverting the status'))
+ console.debug(err)
+ this.isSavingStatus = false
+ return
+ }
+
+ this.isSavingStatus = false
+ this.predefinedMessageId = this.$store.state.userStatus?.messageId
+ },
},
}
</script>
@@ -246,38 +336,48 @@ export default {
.set-status-modal {
padding: 8px 20px 20px 20px;
+ &, & * {
+ box-sizing: border-box;
+ }
+
&__header {
+ font-size: 21px;
text-align: center;
- font-weight: bold;
+ height: fit-content;
+ min-height: var(--default-clickable-area);
+ line-height: var(--default-clickable-area);
+ overflow-wrap: break-word;
+ margin-block: 0 calc(2 * var(--default-grid-baseline));
}
&__online-status {
- display: grid;
- // Space between the two sections
- margin-bottom: 40px;
- grid-template-columns: 1fr 1fr;
+ display: flex;
+ flex-direction: column;
+ gap: calc(2 * var(--default-grid-baseline));
+ margin-block: 0 calc(2 * var(--default-grid-baseline));
}
&__custom-input {
display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: var(--default-grid-baseline);
width: 100%;
- margin-bottom: 10px;
-
- .custom-input__emoji-button {
- flex-basis: 40px;
- flex-grow: 0;
- width: 40px;
- height: 34px;
- margin-right: 0;
- border-right: none;
- border-radius: var(--border-radius) 0 0 var(--border-radius);
- }
+ padding-inline-start: var(--default-grid-baseline);
+ margin-block: 0 calc(2 * var(--default-grid-baseline));
+ }
+
+ &__automation-hint {
+ display: flex;
+ width: 100%;
+ margin-block: 0 calc(2 * var(--default-grid-baseline));
+ color: var(--color-text-maxcontrast);
}
.status-buttons {
display: flex;
padding: 3px;
- padding-left:0;
+ padding-inline-start:0;
gap: 3px;
}
}
diff --git a/apps/user_status/src/dashboard.js b/apps/user_status/src/dashboard.js
deleted file mode 100644
index 9c3d94151d0..00000000000
--- a/apps/user_status/src/dashboard.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * @copyright Copyright (c) 2020 Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license AGPL-3.0-or-later
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-import Vue from 'vue'
-import { getRequestToken } from '@nextcloud/auth'
-import { translate, translatePlural } from '@nextcloud/l10n'
-import Dashboard from './views/Dashboard'
-
-// eslint-disable-next-line camelcase
-__webpack_nonce__ = btoa(getRequestToken())
-
-Vue.prototype.t = translate
-Vue.prototype.n = translatePlural
-Vue.prototype.OC = OC
-Vue.prototype.OCA = OCA
-
-document.addEventListener('DOMContentLoaded', function() {
- OCA.Dashboard.register('user_status', (el) => {
- const View = Vue.extend(Dashboard)
- new View({
- propsData: {},
- }).$mount(el)
- })
-
-})
diff --git a/apps/user_status/src/filters/clearAtFilter.js b/apps/user_status/src/filters/clearAtFilter.js
index 9a99b9ec69f..5f62385a978 100644
--- a/apps/user_status/src/filters/clearAtFilter.js
+++ b/apps/user_status/src/filters/clearAtFilter.js
@@ -1,28 +1,11 @@
/**
- * @copyright Copyright (c) 2020 Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license AGPL-3.0-or-later
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { translate as t } from '@nextcloud/l10n'
import moment from '@nextcloud/moment'
-import { dateFactory } from '../services/dateService'
+import { dateFactory } from '../services/dateService.js'
/**
* Formats a clearAt object to be human readable
diff --git a/apps/user_status/src/menu.js b/apps/user_status/src/menu.js
index c8d007d98a0..34e5e6eabb1 100644
--- a/apps/user_status/src/menu.js
+++ b/apps/user_status/src/menu.js
@@ -1,66 +1,38 @@
/**
- * @copyright Copyright (c) 2020 Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- * @author John Molakvoæ <skjnldsv@protonmail.com>
- * @author Julius Härtl <jus@bitgrid.net>
- *
- * @license AGPL-3.0-or-later
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
+import { getCSPNonce } from '@nextcloud/auth'
+import { subscribe } from '@nextcloud/event-bus'
import Vue from 'vue'
-import { getRequestToken } from '@nextcloud/auth'
-import UserStatus from './UserStatus'
-import store from './store'
-import Avatar from '@nextcloud/vue/dist/Components/Avatar'
-import { loadState } from '@nextcloud/initial-state'
+
+import UserStatus from './UserStatus.vue'
+import store from './store/index.js'
// eslint-disable-next-line camelcase
-__webpack_nonce__ = btoa(getRequestToken())
+__webpack_nonce__ = getCSPNonce()
Vue.prototype.t = t
Vue.prototype.$t = t
-const avatarDiv = document.getElementById('avatardiv-menu')
-const userStatusData = loadState('user_status', 'status')
-const propsData = {
- preloadedUserStatus: {
- message: userStatusData.message,
- icon: userStatusData.icon,
- status: userStatusData.status
- },
- user: avatarDiv.dataset.user,
- displayName: avatarDiv.dataset.displayname,
- url: avatarDiv.dataset.avatar,
- disableMenu: true,
- disableTooltip: true,
-}
+const mountPoint = document.getElementById('user_status-menu-entry')
-const AvatarInMenu = Vue.extend(Avatar)
-new AvatarInMenu({ propsData }).$mount('#avatardiv-menu')
+const mountMenuEntry = () => {
+ const mountPoint = document.getElementById('user_status-menu-entry')
+ // eslint-disable-next-line no-new
+ new Vue({
+ el: mountPoint,
+ render: h => h(UserStatus),
+ store,
+ })
+}
-// Register settings menu entry
-export default new Vue({
- el: 'li[data-id="user_status-menuitem"]',
- // eslint-disable-next-line vue/match-component-file-name
- name: 'UserStatusRoot',
- render: h => h(UserStatus),
- store,
-})
+if (mountPoint) {
+ mountMenuEntry()
+} else {
+ subscribe('core:user-menu:mounted', mountMenuEntry)
+}
// Register dashboard status
document.addEventListener('DOMContentLoaded', function() {
diff --git a/apps/user_status/src/mixins/OnlineStatusMixin.js b/apps/user_status/src/mixins/OnlineStatusMixin.js
index d1e3a9111fa..5670eb4dc06 100644
--- a/apps/user_status/src/mixins/OnlineStatusMixin.js
+++ b/apps/user_status/src/mixins/OnlineStatusMixin.js
@@ -1,23 +1,6 @@
/**
- * @copyright Copyright (c) 2020 John Molakvoæ <skjnldsv@protonmail.com>
- *
- * @author John Molakvoæ <skjnldsv@protonmail.com>
- *
- * @license AGPL-3.0-or-later
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { mapState } from 'vuex'
@@ -52,6 +35,7 @@ export default {
return this.$t('user_status', 'Online')
case 'away':
+ case 'busy':
return this.$t('user_status', 'Away')
case 'dnd':
@@ -67,30 +51,6 @@ export default {
return this.$t('user_status', 'Set status')
},
-
- /**
- * The status indicator icon
- *
- * @return {string | null}
- */
- statusIcon() {
- switch (this.statusType) {
- case 'online':
- return 'icon-user-status-online'
-
- case 'away':
- return 'icon-user-status-away'
-
- case 'dnd':
- return 'icon-user-status-dnd'
-
- case 'invisible':
- case 'offline':
- return 'icon-user-status-invisible'
- }
-
- return ''
- },
},
methods: {
diff --git a/apps/user_status/src/services/clearAtOptionsService.js b/apps/user_status/src/services/clearAtOptionsService.js
index 2849e6170f2..af0059bfb7f 100644
--- a/apps/user_status/src/services/clearAtOptionsService.js
+++ b/apps/user_status/src/services/clearAtOptionsService.js
@@ -1,23 +1,6 @@
/**
- * @copyright Copyright (c) 2020 Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license AGPL-3.0-or-later
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { translate as t } from '@nextcloud/l10n'
diff --git a/apps/user_status/src/services/clearAtService.js b/apps/user_status/src/services/clearAtService.js
index a02905b90c9..f23d267ad02 100644
--- a/apps/user_status/src/services/clearAtService.js
+++ b/apps/user_status/src/services/clearAtService.js
@@ -1,28 +1,11 @@
/**
- * @copyright Copyright (c) 2020 Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license AGPL-3.0-or-later
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
import {
dateFactory,
-} from './dateService'
+} from './dateService.js'
import moment from '@nextcloud/moment'
/**
diff --git a/apps/user_status/src/services/dateService.js b/apps/user_status/src/services/dateService.js
index 2d110db5998..26a61d4a3e2 100644
--- a/apps/user_status/src/services/dateService.js
+++ b/apps/user_status/src/services/dateService.js
@@ -1,23 +1,6 @@
/**
- * @copyright Copyright (c) 2020 Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license AGPL-3.0-or-later
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
const dateFactory = () => {
diff --git a/apps/user_status/src/services/heartbeatService.js b/apps/user_status/src/services/heartbeatService.js
index 2065cb6836a..fda1a1ffc9f 100644
--- a/apps/user_status/src/services/heartbeatService.js
+++ b/apps/user_status/src/services/heartbeatService.js
@@ -1,27 +1,10 @@
/**
- * @copyright Copyright (c) 2020 Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license AGPL-3.0-or-later
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
import HttpClient from '@nextcloud/axios'
-import { generateUrl } from '@nextcloud/router'
+import { generateOcsUrl } from '@nextcloud/router'
/**
* Sends a heartbeat
@@ -30,11 +13,11 @@ import { generateUrl } from '@nextcloud/router'
* @return {Promise<void>}
*/
const sendHeartbeat = async (isAway) => {
- const url = generateUrl('/apps/user_status/heartbeat')
+ const url = generateOcsUrl('apps/user_status/api/v1/heartbeat?format=json')
const response = await HttpClient.put(url, {
status: isAway ? 'away' : 'online',
})
- return response.data
+ return response.data.ocs.data
}
export {
diff --git a/apps/user_status/src/services/predefinedStatusService.js b/apps/user_status/src/services/predefinedStatusService.js
index 0a4cb55b573..b423c6e0cc4 100644
--- a/apps/user_status/src/services/predefinedStatusService.js
+++ b/apps/user_status/src/services/predefinedStatusService.js
@@ -1,23 +1,6 @@
/**
- * @copyright Copyright (c) 2020 Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license AGPL-3.0-or-later
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
import HttpClient from '@nextcloud/axios'
diff --git a/apps/user_status/src/services/statusOptionsService.js b/apps/user_status/src/services/statusOptionsService.js
index 7bd50bf7aff..6c23645e5be 100644
--- a/apps/user_status/src/services/statusOptionsService.js
+++ b/apps/user_status/src/services/statusOptionsService.js
@@ -1,24 +1,6 @@
/**
- * @copyright Copyright (c) 2020 Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- * @author Jan C. Borchardt <hey@jancborchardt.net>
- *
- * @license AGPL-3.0-or-later
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { translate as t } from '@nextcloud/l10n'
@@ -32,22 +14,20 @@ const getAllStatusOptions = () => {
return [{
type: 'online',
label: t('user_status', 'Online'),
- icon: 'icon-user-status-online',
}, {
type: 'away',
label: t('user_status', 'Away'),
- icon: 'icon-user-status-away',
+ }, {
+ type: 'busy',
+ label: t('user_status', 'Busy'),
}, {
type: 'dnd',
label: t('user_status', 'Do not disturb'),
subline: t('user_status', 'Mute all notifications'),
- icon: 'icon-user-status-dnd',
-
}, {
type: 'invisible',
label: t('user_status', 'Invisible'),
subline: t('user_status', 'Appear offline'),
- icon: 'icon-user-status-invisible',
}]
}
diff --git a/apps/user_status/src/services/statusService.js b/apps/user_status/src/services/statusService.js
index f4bda930303..6504411c996 100644
--- a/apps/user_status/src/services/statusService.js
+++ b/apps/user_status/src/services/statusService.js
@@ -1,23 +1,6 @@
/**
- * @copyright Copyright (c) 2020 Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license AGPL-3.0-or-later
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
import HttpClient from '@nextcloud/axios'
@@ -36,6 +19,19 @@ const fetchCurrentStatus = async () => {
}
/**
+ * Fetches the current user-status
+ *
+ * @param {string} userId Id of the user to fetch the status
+ * @return {Promise<object>}
+ */
+const fetchBackupStatus = async (userId) => {
+ const url = generateOcsUrl('apps/user_status/api/v1/statuses/{userId}', { userId: '_' + userId })
+ const response = await HttpClient.get(url)
+
+ return response.data.ocs.data
+}
+
+/**
* Sets the status
*
* @param {string} statusType The status (online / away / dnd / invisible)
@@ -90,10 +86,25 @@ const clearMessage = async () => {
await HttpClient.delete(url)
}
+/**
+ * Revert the automated status
+ *
+ * @param {string} messageId ID of the message to revert
+ * @return {Promise<object>}
+ */
+const revertToBackupStatus = async (messageId) => {
+ const url = generateOcsUrl('apps/user_status/api/v1/user_status/revert/{messageId}', { messageId })
+ const response = await HttpClient.delete(url)
+
+ return response.data.ocs.data
+}
+
export {
fetchCurrentStatus,
+ fetchBackupStatus,
setStatus,
setCustomMessage,
setPredefinedMessage,
clearMessage,
+ revertToBackupStatus,
}
diff --git a/apps/user_status/src/store/index.js b/apps/user_status/src/store/index.js
index c2c270d14d8..d9cfe674165 100644
--- a/apps/user_status/src/store/index.js
+++ b/apps/user_status/src/store/index.js
@@ -1,29 +1,13 @@
/**
- * @copyright Copyright (c) 2020 Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license AGPL-3.0-or-later
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
import Vue from 'vue'
import Vuex, { Store } from 'vuex'
-import predefinedStatuses from './predefinedStatuses'
-import userStatus from './userStatus'
+import predefinedStatuses from './predefinedStatuses.js'
+import userStatus from './userStatus.js'
+import userBackupStatus from './userBackupStatus.js'
Vue.use(Vuex)
@@ -31,6 +15,7 @@ export default new Store({
modules: {
predefinedStatuses,
userStatus,
+ userBackupStatus,
},
strict: true,
})
diff --git a/apps/user_status/src/store/predefinedStatuses.js b/apps/user_status/src/store/predefinedStatuses.js
index e41ba24f7dd..6d592ca627e 100644
--- a/apps/user_status/src/store/predefinedStatuses.js
+++ b/apps/user_status/src/store/predefinedStatuses.js
@@ -1,26 +1,9 @@
/**
- * @copyright Copyright (c) 2020 Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license AGPL-3.0-or-later
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
-import { fetchAllPredefinedStatuses } from '../services/predefinedStatusService'
+import { fetchAllPredefinedStatuses } from '../services/predefinedStatusService.js'
const state = {
predefinedStatuses: [],
@@ -35,11 +18,15 @@ const mutations = {
* @param {object} status The status to add
*/
addPredefinedStatus(state, status) {
- state.predefinedStatuses.push(status)
+ state.predefinedStatuses = [...state.predefinedStatuses, status]
},
}
-const getters = {}
+const getters = {
+ statusesHaveLoaded(state) {
+ return state.predefinedStatuses.length > 0
+ },
+}
const actions = {
diff --git a/apps/user_status/src/store/userBackupStatus.js b/apps/user_status/src/store/userBackupStatus.js
new file mode 100644
index 00000000000..78e5318de9d
--- /dev/null
+++ b/apps/user_status/src/store/userBackupStatus.js
@@ -0,0 +1,102 @@
+/**
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import {
+ fetchBackupStatus,
+ revertToBackupStatus,
+} from '../services/statusService.js'
+import { getCurrentUser } from '@nextcloud/auth'
+import { emit } from '@nextcloud/event-bus'
+
+const state = {
+ // Status (online / away / dnd / invisible / offline)
+ status: null,
+ // Whether the status is user-defined
+ statusIsUserDefined: null,
+ // A custom message set by the user
+ message: null,
+ // The icon selected by the user
+ icon: null,
+ // When to automatically clean the status
+ clearAt: null,
+ // Whether the message is predefined
+ // (and can automatically be translated by Nextcloud)
+ messageIsPredefined: null,
+ // The id of the message in case it's predefined
+ messageId: null,
+}
+
+const mutations = {
+ /**
+ * Loads the status from initial state
+ *
+ * @param {object} state The Vuex state
+ * @param {object} data The destructuring object
+ * @param {string} data.status The status type
+ * @param {boolean} data.statusIsUserDefined Whether or not this status is user-defined
+ * @param {string} data.message The message
+ * @param {string} data.icon The icon
+ * @param {number} data.clearAt When to automatically clear the status
+ * @param {boolean} data.messageIsPredefined Whether or not the message is predefined
+ * @param {string} data.messageId The id of the predefined message
+ */
+ loadBackupStatusFromServer(state, { status, statusIsUserDefined, message, icon, clearAt, messageIsPredefined, messageId }) {
+ state.status = status
+ state.message = message
+ state.icon = icon
+
+ // Don't overwrite certain values if the refreshing comes in via short updates
+ // E.g. from talk participant list which only has the status, message and icon
+ if (typeof statusIsUserDefined !== 'undefined') {
+ state.statusIsUserDefined = statusIsUserDefined
+ }
+ if (typeof clearAt !== 'undefined') {
+ state.clearAt = clearAt
+ }
+ if (typeof messageIsPredefined !== 'undefined') {
+ state.messageIsPredefined = messageIsPredefined
+ }
+ if (typeof messageId !== 'undefined') {
+ state.messageId = messageId
+ }
+ },
+}
+
+const getters = {}
+
+const actions = {
+ /**
+ * Re-fetches the status from the server
+ *
+ * @param {object} vuex The Vuex destructuring object
+ * @param {Function} vuex.commit The Vuex commit function
+ * @return {Promise<void>}
+ */
+ async fetchBackupFromServer({ commit }) {
+ try {
+ const status = await fetchBackupStatus(getCurrentUser()?.uid)
+ commit('loadBackupStatusFromServer', status)
+ } catch (e) {
+ // Ignore missing user backup status
+ }
+ },
+
+ async revertBackupFromServer({ commit }, { messageId }) {
+ const status = await revertToBackupStatus(messageId)
+ if (status) {
+ commit('loadBackupStatusFromServer', {})
+ commit('loadStatusFromServer', status)
+ emit('user_status:status.updated', {
+ status: status.status,
+ message: status.message,
+ icon: status.icon,
+ clearAt: status.clearAt,
+ userId: getCurrentUser()?.uid,
+ })
+ }
+ },
+}
+
+export default { state, mutations, getters, actions }
diff --git a/apps/user_status/src/store/userStatus.js b/apps/user_status/src/store/userStatus.js
index c54fbe5040b..9bc86ab5062 100644
--- a/apps/user_status/src/store/userStatus.js
+++ b/apps/user_status/src/store/userStatus.js
@@ -1,23 +1,6 @@
/**
- * @copyright Copyright (c) 2020 Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license AGPL-3.0-or-later
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
import {
@@ -26,16 +9,16 @@ import {
setPredefinedMessage,
setCustomMessage,
clearMessage,
-} from '../services/statusService'
+} from '../services/statusService.js'
import { loadState } from '@nextcloud/initial-state'
import { getCurrentUser } from '@nextcloud/auth'
-import { getTimestampForClearAt } from '../services/clearAtService'
+import { getTimestampForClearAt } from '../services/clearAtService.js'
import { emit } from '@nextcloud/event-bus'
const state = {
// Status (online / away / dnd / invisible / offline)
status: null,
- // Whether or not the status is user-defined
+ // Whether the status is user-defined
statusIsUserDefined: null,
// A custom message set by the user
message: null,
@@ -43,7 +26,7 @@ const state = {
icon: null,
// When to automatically clean the status
clearAt: null,
- // Whether or not the message is predefined
+ // Whether the message is predefined
// (and can automatically be translated by Nextcloud)
messageIsPredefined: null,
// The id of the message in case it's predefined
@@ -130,12 +113,23 @@ const mutations = {
*/
loadStatusFromServer(state, { status, statusIsUserDefined, message, icon, clearAt, messageIsPredefined, messageId }) {
state.status = status
- state.statusIsUserDefined = statusIsUserDefined
state.message = message
state.icon = icon
- state.clearAt = clearAt
- state.messageIsPredefined = messageIsPredefined
- state.messageId = messageId
+
+ // Don't overwrite certain values if the refreshing comes in via short updates
+ // E.g. from talk participant list which only has the status, message and icon
+ if (typeof statusIsUserDefined !== 'undefined') {
+ state.statusIsUserDefined = statusIsUserDefined
+ }
+ if (typeof clearAt !== 'undefined') {
+ state.clearAt = clearAt
+ }
+ if (typeof messageIsPredefined !== 'undefined') {
+ state.messageIsPredefined = messageIsPredefined
+ }
+ if (typeof messageId !== 'undefined') {
+ state.messageId = messageId
+ }
},
}
diff --git a/apps/user_status/src/views/Dashboard.vue b/apps/user_status/src/views/Dashboard.vue
deleted file mode 100644
index 629a28abeb5..00000000000
--- a/apps/user_status/src/views/Dashboard.vue
+++ /dev/null
@@ -1,122 +0,0 @@
-<!--
- - @copyright Copyright (c) 2020 Georg Ehrke <oc.list@georgehrke.com>
- - @author Georg Ehrke <oc.list@georgehrke.com>
- -
- - @license GNU AGPL version 3 or any later version
- -
- - This program is free software: you can redistribute it and/or modify
- - it under the terms of the GNU Affero General Public License as
- - published by the Free Software Foundation, either version 3 of the
- - License, or (at your option) any later version.
- -
- - 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
- - along with this program. If not, see <http://www.gnu.org/licenses/>.
- -
- -->
-
-<template>
- <DashboardWidget id="user-status_panel"
- :items="items"
- :loading="loading">
- <template #default="{ item }">
- <DashboardWidgetItem :main-text="item.mainText"
- :sub-text="item.subText">
- <template #avatar>
- <Avatar class="item-avatar"
- :size="44"
- :user="item.avatarUsername"
- :display-name="item.mainText"
- :show-user-status="false"
- :show-user-status-compact="false" />
- </template>
- </DashboardWidgetItem>
- </template>
- <template #empty-content>
- <EmptyContent id="user_status-widget-empty-content"
- icon="icon-user-status">
- {{ t('user_status', 'No recent status changes') }}
- </EmptyContent>
- </template>
- </DashboardWidget>
-</template>
-
-<script>
-import { DashboardWidget, DashboardWidgetItem } from '@nextcloud/vue-dashboard'
-import Avatar from '@nextcloud/vue/dist/Components/Avatar'
-import EmptyContent from '@nextcloud/vue/dist/Components/EmptyContent'
-import { loadState } from '@nextcloud/initial-state'
-import moment from '@nextcloud/moment'
-
-export default {
- name: 'Dashboard',
- components: {
- Avatar,
- DashboardWidget,
- DashboardWidgetItem,
- EmptyContent,
- },
- data() {
- return {
- statuses: [],
- loading: true,
- }
- },
- computed: {
- items() {
- return this.statuses.map((item) => {
- const icon = item.icon || ''
- let message = item.message || ''
- if (message === '') {
- if (item.status === 'away') {
- message = t('user_status', 'Away')
- }
- if (item.status === 'dnd') {
- message = t('user_status', 'Do not disturb')
- }
- }
- const status = item.icon !== '' ? `${icon} ${message}` : message
-
- let subText
- if (item.icon === null && message === '' && item.timestamp === null) {
- subText = ''
- } else if (item.icon === null && message === '' && item.timestamp !== null) {
- subText = moment(item.timestamp, 'X').fromNow()
- } else if (item.timestamp !== null) {
- subText = this.t('user_status', '{status}, {timestamp}', {
- status,
- timestamp: moment(item.timestamp, 'X').fromNow(),
- }, null, { escape: false, sanitize: false })
- } else {
- subText = status
- }
-
- return {
- mainText: item.displayName,
- subText,
- avatarUsername: item.userId,
- }
- })
- },
- },
- mounted() {
- try {
- this.statuses = loadState('user_status', 'dashboard_data')
- this.loading = false
- } catch (e) {
- console.error(e)
- }
- },
-}
-</script>
-
-<style lang="scss">
-#user_status-widget-empty-content {
- text-align: center;
- margin-top: 5vh;
-}
-</style>
diff --git a/apps/user_status/tests/Integration/Service/StatusServiceIntegrationTest.php b/apps/user_status/tests/Integration/Service/StatusServiceIntegrationTest.php
new file mode 100644
index 00000000000..8a21052b09f
--- /dev/null
+++ b/apps/user_status/tests/Integration/Service/StatusServiceIntegrationTest.php
@@ -0,0 +1,196 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCA\UserStatus\Tests\Integration\Service;
+
+use OCA\UserStatus\Service\StatusService;
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\IDBConnection;
+use OCP\Server;
+use OCP\UserStatus\IUserStatus;
+use Test\TestCase;
+use function sleep;
+use function time;
+
+/**
+ * @group DB
+ */
+class StatusServiceIntegrationTest extends TestCase {
+
+ private StatusService $service;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->service = Server::get(StatusService::class);
+
+ $db = Server::get(IDBConnection::class);
+ $qb = $db->getQueryBuilder();
+ $qb->delete('user_status')->executeStatement();
+ }
+
+ public function testNoStatusYet(): void {
+ $this->expectException(DoesNotExistException::class);
+
+ $this->service->findByUserId('test123');
+ }
+
+ public function testCustomStatusMessageTimestamp(): void {
+ $before = time();
+ $this->service->setCustomMessage(
+ 'test123',
+ '🍕',
+ 'Lunch',
+ null,
+ );
+ $after = time();
+
+ $status = $this->service->findByUserId('test123');
+
+ self::assertSame('Lunch', $status->getCustomMessage());
+ self::assertGreaterThanOrEqual($before, $status->getStatusMessageTimestamp());
+ self::assertLessThanOrEqual($after, $status->getStatusMessageTimestamp());
+ }
+
+ public function testOnlineStatusKeepsMessageTimestamp(): void {
+ $this->service->setStatus(
+ 'test123',
+ IUserStatus::OFFLINE,
+ time() + 1000,
+ false,
+ );
+ $this->service->setCustomMessage(
+ 'test123',
+ '🍕',
+ 'Lunch',
+ null,
+ );
+ $timeAfterInsert = time();
+ sleep(1);
+ $this->service->setStatus(
+ 'test123',
+ IUserStatus::ONLINE,
+ time() + 2000,
+ false,
+ );
+ $status = $this->service->findByUserId('test123');
+
+ self::assertSame('Lunch', $status->getCustomMessage());
+ self::assertLessThanOrEqual($timeAfterInsert, $status->getStatusMessageTimestamp());
+ }
+
+ public function testCreateRestoreBackupAutomatically(): void {
+ $this->service->setStatus(
+ 'test123',
+ IUserStatus::ONLINE,
+ null,
+ false,
+ );
+ $this->service->setUserStatus(
+ 'test123',
+ IUserStatus::DND,
+ 'meeting',
+ true,
+ );
+
+ self::assertSame(
+ 'meeting',
+ $this->service->findByUserId('test123')->getMessageId(),
+ );
+ self::assertSame(
+ IUserStatus::ONLINE,
+ $this->service->findByUserId('_test123')->getStatus(),
+ );
+
+ $revertedStatus = $this->service->revertUserStatus(
+ 'test123',
+ 'meeting',
+ );
+
+ self::assertNotNull($revertedStatus, 'Status should have been reverted');
+
+ try {
+ $this->service->findByUserId('_test123');
+ $this->fail('Expected DoesNotExistException() to be thrown when finding backup status after reverting');
+ } catch (DoesNotExistException) {
+ }
+
+ self::assertSame(
+ IUserStatus::ONLINE,
+ $this->service->findByUserId('test123')->getStatus(),
+ );
+ }
+
+ public function testCallOverwritesMeetingStatus(): void {
+ $this->service->setStatus(
+ 'test123',
+ IUserStatus::ONLINE,
+ null,
+ false,
+ );
+ $this->service->setUserStatus(
+ 'test123',
+ IUserStatus::BUSY,
+ IUserStatus::MESSAGE_CALENDAR_BUSY,
+ true,
+ );
+ self::assertSame(
+ 'meeting',
+ $this->service->findByUserId('test123')->getMessageId(),
+ );
+
+ $this->service->setUserStatus(
+ 'test123',
+ IUserStatus::BUSY,
+ IUserStatus::MESSAGE_CALL,
+ true,
+ );
+ self::assertSame(
+ IUserStatus::BUSY,
+ $this->service->findByUserId('test123')->getStatus(),
+ );
+
+ self::assertSame(
+ IUserStatus::MESSAGE_CALL,
+ $this->service->findByUserId('test123')->getMessageId(),
+ );
+ }
+
+ public function testOtherAutomationsDoNotOverwriteEachOther(): void {
+ $this->service->setStatus(
+ 'test123',
+ IUserStatus::ONLINE,
+ null,
+ false,
+ );
+ $this->service->setUserStatus(
+ 'test123',
+ IUserStatus::DND,
+ IUserStatus::MESSAGE_AVAILABILITY,
+ true,
+ );
+ self::assertSame(
+ 'availability',
+ $this->service->findByUserId('test123')->getMessageId(),
+ );
+
+ $nostatus = $this->service->setUserStatus(
+ 'test123',
+ IUserStatus::BUSY,
+ IUserStatus::MESSAGE_CALENDAR_BUSY,
+ true,
+ );
+
+ self::assertNull($nostatus);
+ self::assertSame(
+ IUserStatus::MESSAGE_AVAILABILITY,
+ $this->service->findByUserId('test123')->getMessageId(),
+ );
+ }
+}
diff --git a/apps/user_status/tests/Unit/BackgroundJob/ClearOldStatusesBackgroundJobTest.php b/apps/user_status/tests/Unit/BackgroundJob/ClearOldStatusesBackgroundJobTest.php
index 2cf9b7d1bd4..66142082343 100644
--- a/apps/user_status/tests/Unit/BackgroundJob/ClearOldStatusesBackgroundJobTest.php
+++ b/apps/user_status/tests/Unit/BackgroundJob/ClearOldStatusesBackgroundJobTest.php
@@ -3,44 +3,21 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- * @author Joas Schilling <coding@schilljs.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Tests\BackgroundJob;
use OCA\UserStatus\BackgroundJob\ClearOldStatusesBackgroundJob;
use OCA\UserStatus\Db\UserStatusMapper;
use OCP\AppFramework\Utility\ITimeFactory;
+use PHPUnit\Framework\MockObject\MockObject;
use Test\TestCase;
class ClearOldStatusesBackgroundJobTest extends TestCase {
-
- /** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */
- private $time;
-
- /** @var UserStatusMapper|\PHPUnit\Framework\MockObject\MockObject */
- private $mapper;
-
- /** @var ClearOldStatusesBackgroundJob */
- private $job;
+ private ITimeFactory&MockObject $time;
+ private UserStatusMapper&MockObject $mapper;
+ private ClearOldStatusesBackgroundJob $job;
protected function setUp(): void {
parent::setUp();
@@ -51,9 +28,9 @@ class ClearOldStatusesBackgroundJobTest extends TestCase {
$this->job = new ClearOldStatusesBackgroundJob($this->time, $this->mapper);
}
- public function testRun() {
+ public function testRun(): void {
$this->mapper->expects($this->once())
- ->method('clearMessagesOlderThan')
+ ->method('clearOlderThanClearAt')
->with(1337);
$this->mapper->expects($this->once())
->method('clearStatusesOlderThan')
diff --git a/apps/user_status/tests/Unit/CapabilitiesTest.php b/apps/user_status/tests/Unit/CapabilitiesTest.php
index af36900d3bc..601fb207df4 100644
--- a/apps/user_status/tests/Unit/CapabilitiesTest.php
+++ b/apps/user_status/tests/Unit/CapabilitiesTest.php
@@ -3,66 +3,44 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Tests;
use OCA\UserStatus\Capabilities;
-use OCA\UserStatus\Service\EmojiService;
+use OCP\IEmojiHelper;
+use PHPUnit\Framework\MockObject\MockObject;
use Test\TestCase;
class CapabilitiesTest extends TestCase {
-
- /** @var EmojiService|\PHPUnit\Framework\MockObject\MockObject */
- private $emojiService;
-
- /** @var Capabilities */
- private $capabilities;
+ private IEmojiHelper&MockObject $emojiHelper;
+ private Capabilities $capabilities;
protected function setUp(): void {
parent::setUp();
- $this->emojiService = $this->createMock(EmojiService::class);
- $this->capabilities = new Capabilities($this->emojiService);
+ $this->emojiHelper = $this->createMock(IEmojiHelper::class);
+ $this->capabilities = new Capabilities($this->emojiHelper);
}
- /**
- * @param bool $supportsEmojis
- *
- * @dataProvider getCapabilitiesDataProvider
- */
+ #[\PHPUnit\Framework\Attributes\DataProvider('getCapabilitiesDataProvider')]
public function testGetCapabilities(bool $supportsEmojis): void {
- $this->emojiService->expects($this->once())
+ $this->emojiHelper->expects($this->once())
->method('doesPlatformSupportEmoji')
->willReturn($supportsEmojis);
$this->assertEquals([
'user_status' => [
'enabled' => true,
+ 'restore' => true,
'supports_emoji' => $supportsEmojis,
+ 'supports_busy' => true,
]
], $this->capabilities->getCapabilities());
}
- public function getCapabilitiesDataProvider(): array {
+ public static function getCapabilitiesDataProvider(): array {
return [
[true],
[false],
diff --git a/apps/user_status/tests/Unit/Connector/UserStatusProviderTest.php b/apps/user_status/tests/Unit/Connector/UserStatusProviderTest.php
index 2b126a7a5ea..df6c55488d5 100644
--- a/apps/user_status/tests/Unit/Connector/UserStatusProviderTest.php
+++ b/apps/user_status/tests/Unit/Connector/UserStatusProviderTest.php
@@ -3,40 +3,20 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Tests\Connector;
use OCA\UserStatus\Connector\UserStatusProvider;
use OCA\UserStatus\Db\UserStatus;
use OCA\UserStatus\Service\StatusService;
+use PHPUnit\Framework\MockObject\MockObject;
use Test\TestCase;
class UserStatusProviderTest extends TestCase {
-
- /** @var \PHPUnit\Framework\MockObject\MockObject */
- private $service;
-
- /** @var UserStatusProvider */
- private $provider;
+ private StatusService&MockObject $service;
+ private UserStatusProvider $provider;
protected function setUp(): void {
parent::setUp();
diff --git a/apps/user_status/tests/Unit/Connector/UserStatusTest.php b/apps/user_status/tests/Unit/Connector/UserStatusTest.php
index 61b5d326287..fee9b4e4b89 100644
--- a/apps/user_status/tests/Unit/Connector/UserStatusTest.php
+++ b/apps/user_status/tests/Unit/Connector/UserStatusTest.php
@@ -3,34 +3,17 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Tests\Connector;
use OCA\UserStatus\Connector\UserStatus;
-use Test\TestCase;
use OCA\UserStatus\Db;
+use Test\TestCase;
class UserStatusTest extends TestCase {
- public function testUserStatus() {
+ public function testUserStatus(): void {
$status = new Db\UserStatus();
$status->setUserId('user2');
$status->setStatus('away');
@@ -51,7 +34,7 @@ class UserStatusTest extends TestCase {
$this->assertEquals('60000', $dateTime->format('U'));
}
- public function testUserStatusInvisible() {
+ public function testUserStatusInvisible(): void {
$status = new Db\UserStatus();
$status->setUserId('user2');
$status->setStatus('invisible');
diff --git a/apps/user_status/tests/Unit/Controller/PredefinedStatusControllerTest.php b/apps/user_status/tests/Unit/Controller/PredefinedStatusControllerTest.php
index 81ad3b8e390..0f96f41a524 100644
--- a/apps/user_status/tests/Unit/Controller/PredefinedStatusControllerTest.php
+++ b/apps/user_status/tests/Unit/Controller/PredefinedStatusControllerTest.php
@@ -3,40 +3,20 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Tests\Controller;
use OCA\UserStatus\Controller\PredefinedStatusController;
use OCA\UserStatus\Service\PredefinedStatusService;
use OCP\IRequest;
+use PHPUnit\Framework\MockObject\MockObject;
use Test\TestCase;
class PredefinedStatusControllerTest extends TestCase {
-
- /** @var PredefinedStatusService|\PHPUnit\Framework\MockObject\MockObject */
- private $service;
-
- /** @var PredefinedStatusController */
- private $controller;
+ private PredefinedStatusService&MockObject $service;
+ private PredefinedStatusController $controller;
protected function setUp(): void {
parent::setUp();
@@ -44,11 +24,10 @@ class PredefinedStatusControllerTest extends TestCase {
$request = $this->createMock(IRequest::class);
$this->service = $this->createMock(PredefinedStatusService::class);
- $this->controller = new PredefinedStatusController('user_status', $request,
- $this->service);
+ $this->controller = new PredefinedStatusController('user_status', $request, $this->service);
}
- public function testFindAll() {
+ public function testFindAll(): void {
$this->service->expects($this->once())
->method('getDefaultStatuses')
->with()
diff --git a/apps/user_status/tests/Unit/Controller/StatusesControllerTest.php b/apps/user_status/tests/Unit/Controller/StatusesControllerTest.php
index 19c4bee076e..76d337879c3 100644
--- a/apps/user_status/tests/Unit/Controller/StatusesControllerTest.php
+++ b/apps/user_status/tests/Unit/Controller/StatusesControllerTest.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Tests\Controller;
@@ -31,15 +14,12 @@ use OCA\UserStatus\Service\StatusService;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\OCS\OCSNotFoundException;
use OCP\IRequest;
+use PHPUnit\Framework\MockObject\MockObject;
use Test\TestCase;
class StatusesControllerTest extends TestCase {
-
- /** @var StatusService|\PHPUnit\Framework\MockObject\MockObject */
- private $service;
-
- /** @var StatusesController */
- private $controller;
+ private StatusService&MockObject $service;
+ private StatusesController $controller;
protected function setUp(): void {
parent::setUp();
diff --git a/apps/user_status/tests/Unit/Controller/UserStatusControllerTest.php b/apps/user_status/tests/Unit/Controller/UserStatusControllerTest.php
index 916f5447ea4..e99290319ed 100644
--- a/apps/user_status/tests/Unit/Controller/UserStatusControllerTest.php
+++ b/apps/user_status/tests/Unit/Controller/UserStatusControllerTest.php
@@ -3,29 +3,12 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- * @author Joas Schilling <coding@schilljs.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Tests\Controller;
+use OCA\DAV\CalDAV\Status\StatusService as CalendarStatusService;
use OCA\UserStatus\Controller\UserStatusController;
use OCA\UserStatus\Db\UserStatus;
use OCA\UserStatus\Exception\InvalidClearAtException;
@@ -37,37 +20,41 @@ use OCA\UserStatus\Service\StatusService;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\OCS\OCSBadRequestException;
use OCP\AppFramework\OCS\OCSNotFoundException;
-use OCP\ILogger;
use OCP\IRequest;
+use PHPUnit\Framework\MockObject\MockObject;
+use Psr\Log\LoggerInterface;
use Test\TestCase;
use Throwable;
class UserStatusControllerTest extends TestCase {
-
- /** @var ILogger|\PHPUnit\Framework\MockObject\MockObject */
- private $logger;
-
- /** @var StatusService|\PHPUnit\Framework\MockObject\MockObject */
- private $service;
-
- /** @var UserStatusController */
- private $controller;
+ private LoggerInterface&MockObject $logger;
+ private StatusService&MockObject $statusService;
+ private CalendarStatusService&MockObject $calendarStatusService;
+ private UserStatusController $controller;
protected function setUp(): void {
parent::setUp();
$request = $this->createMock(IRequest::class);
$userId = 'john.doe';
- $this->logger = $this->createMock(ILogger::class);
- $this->service = $this->createMock(StatusService::class);
-
- $this->controller = new UserStatusController('user_status', $request, $userId, $this->logger, $this->service);
+ $this->logger = $this->createMock(LoggerInterface::class);
+ $this->statusService = $this->createMock(StatusService::class);
+ $this->calendarStatusService = $this->createMock(CalendarStatusService::class);
+
+ $this->controller = new UserStatusController(
+ 'user_status',
+ $request,
+ $userId,
+ $this->logger,
+ $this->statusService,
+ $this->calendarStatusService,
+ );
}
public function testGetStatus(): void {
$userStatus = $this->getUserStatus();
- $this->service->expects($this->once())
+ $this->statusService->expects($this->once())
->method('findByUserId')
->with('john.doe')
->willReturn($userStatus);
@@ -86,7 +73,10 @@ class UserStatusControllerTest extends TestCase {
}
public function testGetStatusDoesNotExist(): void {
- $this->service->expects($this->once())
+ $this->calendarStatusService->expects(self::once())
+ ->method('processCalendarStatus')
+ ->with('john.doe');
+ $this->statusService->expects($this->once())
->method('findByUserId')
->with('john.doe')
->willThrowException(new DoesNotExistException(''));
@@ -97,37 +87,27 @@ class UserStatusControllerTest extends TestCase {
$this->controller->getStatus();
}
- /**
- * @param string $statusType
- * @param string|null $statusIcon
- * @param string|null $message
- * @param int|null $clearAt
- * @param bool $expectSuccess
- * @param bool $expectException
- * @param Throwable|null $exception
- * @param bool $expectLogger
- * @param string|null $expectedLogMessage
- *
- * @dataProvider setStatusDataProvider
- */
- public function testSetStatus(string $statusType,
- ?string $statusIcon,
- ?string $message,
- ?int $clearAt,
- bool $expectSuccess,
- bool $expectException,
- ?Throwable $exception,
- bool $expectLogger,
- ?string $expectedLogMessage): void {
+ #[\PHPUnit\Framework\Attributes\DataProvider('setStatusDataProvider')]
+ public function testSetStatus(
+ string $statusType,
+ ?string $statusIcon,
+ ?string $message,
+ ?int $clearAt,
+ bool $expectSuccess,
+ bool $expectException,
+ ?Throwable $exception,
+ bool $expectLogger,
+ ?string $expectedLogMessage,
+ ): void {
$userStatus = $this->getUserStatus();
if ($expectException) {
- $this->service->expects($this->once())
+ $this->statusService->expects($this->once())
->method('setStatus')
->with('john.doe', $statusType, null, true)
->willThrowException($exception);
} else {
- $this->service->expects($this->once())
+ $this->statusService->expects($this->once())
->method('setStatus')
->with('john.doe', $statusType, null, true)
->willReturn($userStatus);
@@ -159,7 +139,7 @@ class UserStatusControllerTest extends TestCase {
}
}
- public function setStatusDataProvider(): array {
+ public static function setStatusDataProvider(): array {
return [
['busy', '👨🏽‍💻', 'Busy developing the status feature', 500, true, false, null, false, null],
['busy', '👨🏽‍💻', 'Busy developing the status feature', 500, false, true, new InvalidStatusTypeException('Original exception message'), true,
@@ -167,33 +147,25 @@ class UserStatusControllerTest extends TestCase {
];
}
- /**
- * @param string $messageId
- * @param int|null $clearAt
- * @param bool $expectSuccess
- * @param bool $expectException
- * @param Throwable|null $exception
- * @param bool $expectLogger
- * @param string|null $expectedLogMessage
- *
- * @dataProvider setPredefinedMessageDataProvider
- */
- public function testSetPredefinedMessage(string $messageId,
- ?int $clearAt,
- bool $expectSuccess,
- bool $expectException,
- ?Throwable $exception,
- bool $expectLogger,
- ?string $expectedLogMessage): void {
+ #[\PHPUnit\Framework\Attributes\DataProvider('setPredefinedMessageDataProvider')]
+ public function testSetPredefinedMessage(
+ string $messageId,
+ ?int $clearAt,
+ bool $expectSuccess,
+ bool $expectException,
+ ?Throwable $exception,
+ bool $expectLogger,
+ ?string $expectedLogMessage,
+ ): void {
$userStatus = $this->getUserStatus();
if ($expectException) {
- $this->service->expects($this->once())
+ $this->statusService->expects($this->once())
->method('setPredefinedMessage')
->with('john.doe', $messageId, $clearAt)
->willThrowException($exception);
} else {
- $this->service->expects($this->once())
+ $this->statusService->expects($this->once())
->method('setPredefinedMessage')
->with('john.doe', $messageId, $clearAt)
->willReturn($userStatus);
@@ -225,7 +197,7 @@ class UserStatusControllerTest extends TestCase {
}
}
- public function setPredefinedMessageDataProvider(): array {
+ public static function setPredefinedMessageDataProvider(): array {
return [
['messageId-42', 500, true, false, null, false, null],
['messageId-42', 500, false, true, new InvalidClearAtException('Original exception message'), true,
@@ -235,53 +207,43 @@ class UserStatusControllerTest extends TestCase {
];
}
- /**
- * @param string|null $statusIcon
- * @param string $message
- * @param int|null $clearAt
- * @param bool $expectSuccess
- * @param bool $expectException
- * @param Throwable|null $exception
- * @param bool $expectLogger
- * @param string|null $expectedLogMessage
- * @param bool $expectSuccessAsReset
- *
- * @dataProvider setCustomMessageDataProvider
- */
- public function testSetCustomMessage(?string $statusIcon,
- string $message,
- ?int $clearAt,
- bool $expectSuccess,
- bool $expectException,
- ?Throwable $exception,
- bool $expectLogger,
- ?string $expectedLogMessage,
- bool $expectSuccessAsReset = false): void {
+ #[\PHPUnit\Framework\Attributes\DataProvider('setCustomMessageDataProvider')]
+ public function testSetCustomMessage(
+ ?string $statusIcon,
+ string $message,
+ ?int $clearAt,
+ bool $expectSuccess,
+ bool $expectException,
+ ?Throwable $exception,
+ bool $expectLogger,
+ ?string $expectedLogMessage,
+ bool $expectSuccessAsReset = false,
+ ): void {
$userStatus = $this->getUserStatus();
if ($expectException) {
- $this->service->expects($this->once())
+ $this->statusService->expects($this->once())
->method('setCustomMessage')
->with('john.doe', $statusIcon, $message, $clearAt)
->willThrowException($exception);
} else {
if ($expectSuccessAsReset) {
- $this->service->expects($this->never())
+ $this->statusService->expects($this->never())
->method('setCustomMessage');
- $this->service->expects($this->once())
+ $this->statusService->expects($this->once())
->method('clearMessage')
->with('john.doe');
- $this->service->expects($this->once())
+ $this->statusService->expects($this->once())
->method('findByUserId')
->with('john.doe')
->willReturn($userStatus);
} else {
- $this->service->expects($this->once())
+ $this->statusService->expects($this->once())
->method('setCustomMessage')
->with('john.doe', $statusIcon, $message, $clearAt)
->willReturn($userStatus);
- $this->service->expects($this->never())
+ $this->statusService->expects($this->never())
->method('clearMessage');
}
}
@@ -312,10 +274,11 @@ class UserStatusControllerTest extends TestCase {
}
}
- public function setCustomMessageDataProvider(): array {
+ public static function setCustomMessageDataProvider(): array {
return [
['👨🏽‍💻', 'Busy developing the status feature', 500, true, false, null, false, null],
- ['👨🏽‍💻', '', 500, true, false, null, false, null, true],
+ ['👨🏽‍💻', '', 500, true, false, null, false, null, false],
+ ['👨🏽‍💻', '', 0, true, false, null, false, null, false],
['👨🏽‍💻', 'Busy developing the status feature', 500, false, true, new InvalidClearAtException('Original exception message'), true,
'New user-status for "john.doe" was rejected due to an invalid clearAt value "500"'],
['👨🏽‍💻', 'Busy developing the status feature', 500, false, true, new InvalidStatusIconException('Original exception message'), true,
@@ -325,17 +288,8 @@ class UserStatusControllerTest extends TestCase {
];
}
- public function testClearStatus(): void {
- $this->service->expects($this->once())
- ->method('clearStatus')
- ->with('john.doe');
-
- $response = $this->controller->clearStatus();
- $this->assertEquals([], $response->getData());
- }
-
public function testClearMessage(): void {
- $this->service->expects($this->once())
+ $this->statusService->expects($this->once())
->method('clearMessage')
->with('john.doe');
diff --git a/apps/user_status/tests/Unit/Dashboard/UserStatusWidgetTest.php b/apps/user_status/tests/Unit/Dashboard/UserStatusWidgetTest.php
index d23b2bc02ff..8773b04c95f 100644
--- a/apps/user_status/tests/Unit/Dashboard/UserStatusWidgetTest.php
+++ b/apps/user_status/tests/Unit/Dashboard/UserStatusWidgetTest.php
@@ -3,69 +3,44 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Tests\Dashboard;
use OCA\UserStatus\Dashboard\UserStatusWidget;
-use OCA\UserStatus\Db\UserStatus;
use OCA\UserStatus\Service\StatusService;
-use OCP\IInitialStateService;
+use OCP\AppFramework\Services\IInitialState;
+use OCP\IDateTimeFormatter;
use OCP\IL10N;
-use OCP\IUser;
+use OCP\IURLGenerator;
use OCP\IUserManager;
use OCP\IUserSession;
+use PHPUnit\Framework\MockObject\MockObject;
use Test\TestCase;
class UserStatusWidgetTest extends TestCase {
-
- /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */
- private $l10n;
-
- /** @var IInitialStateService|\PHPUnit\Framework\MockObject\MockObject */
- private $initialState;
-
- /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */
- private $userManager;
-
- /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */
- private $userSession;
-
- /** @var StatusService|\PHPUnit\Framework\MockObject\MockObject */
- private $service;
-
- /** @var UserStatusWidget */
- private $widget;
+ private IL10N&MockObject $l10n;
+ private IDateTimeFormatter&MockObject $dateTimeFormatter;
+ private IURLGenerator&MockObject $urlGenerator;
+ private IInitialState&MockObject $initialState;
+ private IUserManager&MockObject $userManager;
+ private IUserSession&MockObject $userSession;
+ private StatusService&MockObject $service;
+ private UserStatusWidget $widget;
protected function setUp(): void {
parent::setUp();
$this->l10n = $this->createMock(IL10N::class);
- $this->initialState = $this->createMock(IInitialStateService::class);
+ $this->dateTimeFormatter = $this->createMock(IDateTimeFormatter::class);
+ $this->urlGenerator = $this->createMock(IURLGenerator::class);
+ $this->initialState = $this->createMock(IInitialState::class);
$this->userManager = $this->createMock(IUserManager::class);
$this->userSession = $this->createMock(IUserSession::class);
$this->service = $this->createMock(StatusService::class);
- $this->widget = new UserStatusWidget($this->l10n, $this->initialState, $this->userManager, $this->userSession, $this->service);
+ $this->widget = new UserStatusWidget($this->l10n, $this->dateTimeFormatter, $this->urlGenerator, $this->initialState, $this->userManager, $this->userSession, $this->service);
}
public function testGetId(): void {
@@ -85,178 +60,10 @@ class UserStatusWidgetTest extends TestCase {
}
public function testGetIconClass(): void {
- $this->assertEquals('icon-user-status', $this->widget->getIconClass());
+ $this->assertEquals('icon-user-status-dark', $this->widget->getIconClass());
}
public function testGetUrl(): void {
$this->assertNull($this->widget->getUrl());
}
-
- public function testLoadNoUserSession(): void {
- $this->userSession->expects($this->once())
- ->method('getUser')
- ->willReturn(null);
-
- $this->initialState->expects($this->once())
- ->method('provideInitialState')
- ->with('user_status', 'dashboard_data', []);
-
- $this->service->expects($this->never())
- ->method('findAllRecentStatusChanges');
-
- $this->widget->load();
- }
-
- public function testLoadWithCurrentUser(): void {
- $user = $this->createMock(IUser::class);
- $user->method('getUid')->willReturn('john.doe');
- $this->userSession->expects($this->once())
- ->method('getUser')
- ->willReturn($user);
-
- $user1 = $this->createMock(IUser::class);
- $user1->method('getDisplayName')->willReturn('User No. 1');
-
- $this->userManager
- ->method('get')
- ->willReturnMap([
- ['user_1', $user1],
- ['user_2', null],
- ['user_3', null],
- ['user_4', null],
- ['user_5', null],
- ['user_6', null],
- ['user_7', null],
- ]);
-
- $userStatuses = [
- UserStatus::fromParams([
- 'userId' => 'user_1',
- 'status' => 'online',
- 'customIcon' => '💻',
- 'customMessage' => 'Working',
- 'statusTimestamp' => 5000,
- ]),
- UserStatus::fromParams([
- 'userId' => 'user_2',
- 'status' => 'away',
- 'customIcon' => '☕️',
- 'customMessage' => 'Office Hangout',
- 'statusTimestamp' => 6000,
- ]),
- UserStatus::fromParams([
- 'userId' => 'user_3',
- 'status' => 'dnd',
- 'customIcon' => null,
- 'customMessage' => null,
- 'statusTimestamp' => 7000,
- ]),
- UserStatus::fromParams([
- 'userId' => 'john.doe',
- 'status' => 'away',
- 'customIcon' => '☕️',
- 'customMessage' => 'Office Hangout',
- 'statusTimestamp' => 90000,
- ]),
- UserStatus::fromParams([
- 'userId' => 'user_4',
- 'status' => 'dnd',
- 'customIcon' => null,
- 'customMessage' => null,
- 'statusTimestamp' => 7000,
- ]),
- UserStatus::fromParams([
- 'userId' => 'user_5',
- 'status' => 'invisible',
- 'customIcon' => '🏝',
- 'customMessage' => 'On vacation',
- 'statusTimestamp' => 7000,
- ]),
- UserStatus::fromParams([
- 'userId' => 'user_6',
- 'status' => 'offline',
- 'customIcon' => null,
- 'customMessage' => null,
- 'statusTimestamp' => 7000,
- ]),
- UserStatus::fromParams([
- 'userId' => 'user_7',
- 'status' => 'invisible',
- 'customIcon' => null,
- 'customMessage' => null,
- 'statusTimestamp' => 7000,
- ]),
- ];
-
- $this->service->expects($this->once())
- ->method('findAllRecentStatusChanges')
- ->with(8, 0)
- ->willReturn($userStatuses);
-
- $this->initialState->expects($this->once())
- ->method('provideInitialState')
- ->with('user_status', 'dashboard_data', $this->callback(function ($data): bool {
- $this->assertEquals([
- [
- 'userId' => 'user_1',
- 'displayName' => 'User No. 1',
- 'status' => 'online',
- 'icon' => '💻',
- 'message' => 'Working',
- 'timestamp' => 5000,
- ],
- [
- 'userId' => 'user_2',
- 'displayName' => 'user_2',
- 'status' => 'away',
- 'icon' => '☕️',
- 'message' => 'Office Hangout',
- 'timestamp' => 6000,
- ],
- [
- 'userId' => 'user_3',
- 'displayName' => 'user_3',
- 'status' => 'dnd',
- 'icon' => null,
- 'message' => null,
- 'timestamp' => 7000,
- ],
- [
- 'userId' => 'user_4',
- 'displayName' => 'user_4',
- 'status' => 'dnd',
- 'icon' => null,
- 'message' => null,
- 'timestamp' => 7000,
- ],
- [
- 'userId' => 'user_5',
- 'displayName' => 'user_5',
- 'status' => 'offline',
- 'icon' => '🏝',
- 'message' => 'On vacation',
- 'timestamp' => 7000,
- ],
- [
- 'userId' => 'user_6',
- 'displayName' => 'user_6',
- 'status' => 'offline',
- 'icon' => null,
- 'message' => null,
- 'timestamp' => 7000,
- ],
- [
- 'userId' => 'user_7',
- 'displayName' => 'user_7',
- 'status' => 'offline',
- 'icon' => null,
- 'message' => null,
- 'timestamp' => 7000,
- ],
- ], $data);
- return true;
- }));
-
- $this->widget->load();
- }
}
diff --git a/apps/user_status/tests/Unit/Db/UserStatusMapperTest.php b/apps/user_status/tests/Unit/Db/UserStatusMapperTest.php
index 0d9f1c1f718..ea4480489c7 100644
--- a/apps/user_status/tests/Unit/Db/UserStatusMapperTest.php
+++ b/apps/user_status/tests/Unit/Db/UserStatusMapperTest.php
@@ -3,38 +3,19 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Tests\Db;
use OCA\UserStatus\Db\UserStatus;
use OCA\UserStatus\Db\UserStatusMapper;
+use OCP\AppFramework\Db\DoesNotExistException;
use OCP\DB\Exception;
use Test\TestCase;
class UserStatusMapperTest extends TestCase {
-
- /** @var UserStatusMapper */
- private $mapper;
+ private UserStatusMapper $mapper;
protected function setUp(): void {
parent::setUp();
@@ -153,14 +134,7 @@ class UserStatusMapperTest extends TestCase {
$this->mapper->insert($userStatus2);
}
- /**
- * @param string $status
- * @param bool $isUserDefined
- * @param int $timestamp
- * @param bool $expectsClean
- *
- * @dataProvider clearStatusesOlderThanDataProvider
- */
+ #[\PHPUnit\Framework\Attributes\DataProvider('clearStatusesOlderThanDataProvider')]
public function testClearStatusesOlderThan(string $status, bool $isUserDefined, int $timestamp, bool $expectsClean): void {
$oldStatus = UserStatus::fromParams([
'userId' => 'john.doe',
@@ -186,7 +160,7 @@ class UserStatusMapperTest extends TestCase {
}
}
- public function clearStatusesOlderThanDataProvider(): array {
+ public static function clearStatusesOlderThanDataProvider(): array {
return [
['offline', false, 6000, false],
['online', true, 6000, false],
@@ -204,22 +178,16 @@ class UserStatusMapperTest extends TestCase {
];
}
- public function testClearMessagesOlderThan(): void {
+ public function testClearOlderThanClearAt(): void {
$this->insertSampleStatuses();
- $this->mapper->clearMessagesOlderThan(55000);
+ $this->mapper->clearOlderThanClearAt(55000);
$allStatuses = $this->mapper->findAll();
- $this->assertCount(3, $allStatuses);
+ $this->assertCount(2, $allStatuses);
- $user1Status = $this->mapper->findByUserId('user1');
- $this->assertEquals('user1', $user1Status->getUserId());
- $this->assertEquals('dnd', $user1Status->getStatus());
- $this->assertEquals(5000, $user1Status->getStatusTimestamp());
- $this->assertEquals(true, $user1Status->getIsUserDefined());
- $this->assertEquals(null, $user1Status->getCustomIcon());
- $this->assertEquals(null, $user1Status->getCustomMessage());
- $this->assertEquals(null, $user1Status->getClearAt());
+ $this->expectException(DoesNotExistException::class);
+ $this->mapper->findByUserId('user1');
}
private function insertSampleStatuses(): void {
@@ -233,6 +201,7 @@ class UserStatusMapperTest extends TestCase {
$userStatus2->setUserId('user1');
$userStatus2->setStatus('dnd');
$userStatus2->setStatusTimestamp(5000);
+ $userStatus2->setStatusMessageTimestamp(5000);
$userStatus2->setIsUserDefined(true);
$userStatus2->setCustomIcon('💩');
$userStatus2->setCustomMessage('Do not disturb');
@@ -242,6 +211,7 @@ class UserStatusMapperTest extends TestCase {
$userStatus3->setUserId('user2');
$userStatus3->setStatus('away');
$userStatus3->setStatusTimestamp(6000);
+ $userStatus3->setStatusMessageTimestamp(6000);
$userStatus3->setIsUserDefined(false);
$userStatus3->setCustomIcon('🏝');
$userStatus3->setCustomMessage('On vacation');
@@ -252,7 +222,7 @@ class UserStatusMapperTest extends TestCase {
$this->mapper->insert($userStatus3);
}
- public function dataCreateBackupStatus(): array {
+ public static function dataCreateBackupStatus(): array {
return [
[false, false, false],
[true, false, true],
@@ -261,12 +231,7 @@ class UserStatusMapperTest extends TestCase {
];
}
- /**
- * @dataProvider dataCreateBackupStatus
- * @param bool $hasStatus
- * @param bool $hasBackup
- * @param bool $backupCreated
- */
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataCreateBackupStatus')]
public function testCreateBackupStatus(bool $hasStatus, bool $hasBackup, bool $backupCreated): void {
if ($hasStatus) {
$userStatus1 = new UserStatus();
@@ -305,7 +270,7 @@ class UserStatusMapperTest extends TestCase {
$this->assertEquals('_user1', $user1Status->getUserId());
$this->assertEquals(true, $user1Status->getIsBackup());
$this->assertEquals('Current', $user1Status->getCustomMessage());
- } else if ($hasBackup) {
+ } elseif ($hasBackup) {
$user1Status = $this->mapper->findByUserId('user1', true);
$this->assertEquals('_user1', $user1Status->getUserId());
$this->assertEquals(true, $user1Status->getIsBackup());
diff --git a/apps/user_status/tests/Unit/Listener/UserDeletedListenerTest.php b/apps/user_status/tests/Unit/Listener/UserDeletedListenerTest.php
index 883a06059f7..fbcea23338d 100644
--- a/apps/user_status/tests/Unit/Listener/UserDeletedListenerTest.php
+++ b/apps/user_status/tests/Unit/Listener/UserDeletedListenerTest.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Tests\Listener;
@@ -30,15 +13,12 @@ use OCA\UserStatus\Service\StatusService;
use OCP\EventDispatcher\GenericEvent;
use OCP\IUser;
use OCP\User\Events\UserDeletedEvent;
+use PHPUnit\Framework\MockObject\MockObject;
use Test\TestCase;
class UserDeletedListenerTest extends TestCase {
-
- /** @var StatusService|\PHPUnit\Framework\MockObject\MockObject */
- private $service;
-
- /** @var UserDeletedListener */
- private $listener;
+ private StatusService&MockObject $service;
+ private UserDeletedListener $listener;
protected function setUp(): void {
parent::setUp();
diff --git a/apps/user_status/tests/Unit/Listener/UserLiveStatusListenerTest.php b/apps/user_status/tests/Unit/Listener/UserLiveStatusListenerTest.php
index 2e815073b5a..c03eed0089e 100644
--- a/apps/user_status/tests/Unit/Listener/UserLiveStatusListenerTest.php
+++ b/apps/user_status/tests/Unit/Listener/UserLiveStatusListenerTest.php
@@ -3,79 +3,63 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Daniel Kesselberg <mail@danielkesselberg.de>
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Tests\Listener;
+use OCA\DAV\CalDAV\Status\StatusService as CalendarStatusService;
use OCA\UserStatus\Db\UserStatus;
use OCA\UserStatus\Db\UserStatusMapper;
-use OCA\UserStatus\Listener\UserDeletedListener;
use OCA\UserStatus\Listener\UserLiveStatusListener;
+use OCA\UserStatus\Service\StatusService;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\EventDispatcher\GenericEvent;
use OCP\IUser;
use OCP\User\Events\UserLiveStatusEvent;
+use PHPUnit\Framework\MockObject\MockObject;
+use Psr\Log\LoggerInterface;
use Test\TestCase;
class UserLiveStatusListenerTest extends TestCase {
+ private UserStatusMapper&MockObject $mapper;
+ private StatusService&MockObject $statusService;
+ private ITimeFactory&MockObject $timeFactory;
+ private CalendarStatusService&MockObject $calendarStatusService;
- /** @var UserStatusMapper|\PHPUnit\Framework\MockObject\MockObject */
- private $mapper;
-
- /** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */
- private $timeFactory;
-
- /** @var UserDeletedListener */
- private $listener;
+ private LoggerInterface&MockObject $logger;
+ private UserLiveStatusListener $listener;
protected function setUp(): void {
parent::setUp();
$this->mapper = $this->createMock(UserStatusMapper::class);
+ $this->statusService = $this->createMock(StatusService::class);
$this->timeFactory = $this->createMock(ITimeFactory::class);
- $this->listener = new UserLiveStatusListener($this->mapper, $this->timeFactory);
+ $this->calendarStatusService = $this->createMock(CalendarStatusService::class);
+ $this->logger = $this->createMock(LoggerInterface::class);
+
+ $this->listener = new UserLiveStatusListener(
+ $this->mapper,
+ $this->statusService,
+ $this->timeFactory,
+ $this->calendarStatusService,
+ $this->logger,
+ );
}
- /**
- * @param string $userId
- * @param string $previousStatus
- * @param int $previousTimestamp
- * @param bool $previousIsUserDefined
- * @param string $eventStatus
- * @param int $eventTimestamp
- * @param bool $expectExisting
- * @param bool $expectUpdate
- *
- * @dataProvider handleEventWithCorrectEventDataProvider
- */
- public function testHandleWithCorrectEvent(string $userId,
- string $previousStatus,
- int $previousTimestamp,
- bool $previousIsUserDefined,
- string $eventStatus,
- int $eventTimestamp,
- bool $expectExisting,
- bool $expectUpdate): void {
+ #[\PHPUnit\Framework\Attributes\DataProvider('handleEventWithCorrectEventDataProvider')]
+ public function testHandleWithCorrectEvent(
+ string $userId,
+ string $previousStatus,
+ int $previousTimestamp,
+ bool $previousIsUserDefined,
+ string $eventStatus,
+ int $eventTimestamp,
+ bool $expectExisting,
+ bool $expectUpdate,
+ ): void {
$userStatus = new UserStatus();
if ($expectExisting) {
@@ -85,12 +69,12 @@ class UserLiveStatusListenerTest extends TestCase {
$userStatus->setStatusTimestamp($previousTimestamp);
$userStatus->setIsUserDefined($previousIsUserDefined);
- $this->mapper->expects($this->once())
+ $this->statusService->expects($this->once())
->method('findByUserId')
->with($userId)
->willReturn($userStatus);
} else {
- $this->mapper->expects($this->once())
+ $this->statusService->expects($this->once())
->method('findByUserId')
->with($userId)
->willThrowException(new DoesNotExistException(''));
@@ -142,7 +126,7 @@ class UserLiveStatusListenerTest extends TestCase {
}
}
- public function handleEventWithCorrectEventDataProvider(): array {
+ public static function handleEventWithCorrectEventDataProvider(): array {
return [
['john.doe', 'offline', 0, false, 'online', 5000, true, true],
['john.doe', 'offline', 0, false, 'online', 5000, false, true],
diff --git a/apps/user_status/tests/Unit/Service/EmojiServiceTest.php b/apps/user_status/tests/Unit/Service/EmojiServiceTest.php
deleted file mode 100644
index 454f1d75a0d..00000000000
--- a/apps/user_status/tests/Unit/Service/EmojiServiceTest.php
+++ /dev/null
@@ -1,100 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-namespace OCA\UserStatus\Tests\Service;
-
-use OCA\UserStatus\Service\EmojiService;
-use OCP\IDBConnection;
-use Test\TestCase;
-
-class EmojiServiceTest extends TestCase {
-
- /** @var IDBConnection|\PHPUnit\Framework\MockObject\MockObject */
- private $db;
-
- /** @var EmojiService */
- private $service;
-
- protected function setUp(): void {
- parent::setUp();
-
- $this->db = $this->createMock(IDBConnection::class);
- $this->service = new EmojiService($this->db);
- }
-
- /**
- * @param bool $supports4ByteText
- * @param bool $expected
- *
- * @dataProvider doesPlatformSupportEmojiDataProvider
- */
- public function testDoesPlatformSupportEmoji(bool $supports4ByteText, bool $expected): void {
- $this->db->expects($this->once())
- ->method('supports4ByteText')
- ->willReturn($supports4ByteText);
-
- $this->assertEquals($expected, $this->service->doesPlatformSupportEmoji());
- }
-
- /**
- * @return array
- */
- public function doesPlatformSupportEmojiDataProvider(): array {
- return [
- [true, true],
- [false, false],
- ];
- }
-
- /**
- * @param string $emoji
- * @param bool $expected
- *
- * @dataProvider isValidEmojiDataProvider
- */
- public function testIsValidEmoji(string $emoji, bool $expected): void {
- $actual = $this->service->isValidEmoji($emoji);
-
- $this->assertEquals($expected, $actual);
- }
-
- public function isValidEmojiDataProvider(): array {
- return [
- ['🏝', true],
- ['📱', true],
- ['🏢', true],
- ['📱📠', false],
- ['a', false],
- ['0', false],
- ['$', false],
- // Test some more complex emojis with modifiers and zero-width-joiner
- ['👩🏿‍💻', true],
- ['🤷🏼‍♀️', true],
- ['🏳️‍🌈', true],
- ['👨‍👨‍👦‍👦', true],
- ['👩‍❤️‍👩', true]
- ];
- }
-}
diff --git a/apps/user_status/tests/Unit/Service/PredefinedStatusServiceTest.php b/apps/user_status/tests/Unit/Service/PredefinedStatusServiceTest.php
index 0a65256bfac..78e4a18d9f1 100644
--- a/apps/user_status/tests/Unit/Service/PredefinedStatusServiceTest.php
+++ b/apps/user_status/tests/Unit/Service/PredefinedStatusServiceTest.php
@@ -3,40 +3,19 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Daniel Kesselberg <mail@danielkesselberg.de>
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Tests\Service;
use OCA\UserStatus\Service\PredefinedStatusService;
use OCP\IL10N;
+use PHPUnit\Framework\MockObject\MockObject;
use Test\TestCase;
class PredefinedStatusServiceTest extends TestCase {
-
- /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */
- protected $l10n;
-
- /** @var PredefinedStatusService */
- protected $service;
+ protected IL10N&MockObject $l10n;
+ protected PredefinedStatusService $service;
protected function setUp(): void {
parent::setUp();
@@ -47,17 +26,11 @@ class PredefinedStatusServiceTest extends TestCase {
}
public function testGetDefaultStatuses(): void {
- $this->l10n->expects($this->exactly(6))
+ $this->l10n->expects($this->exactly(8))
->method('t')
- ->withConsecutive(
- ['In a meeting'],
- ['Commuting'],
- ['Working remotely'],
- ['Out sick'],
- ['Vacationing'],
- ['In a call'],
- )
- ->willReturnArgument(0);
+ ->willReturnCallback(function ($text, $parameters = []) {
+ return vsprintf($text, $parameters);
+ });
$actual = $this->service->getDefaultStatuses();
$this->assertEquals([
@@ -80,6 +53,15 @@ class PredefinedStatusServiceTest extends TestCase {
],
],
[
+ 'id' => 'be-right-back',
+ 'icon' => '⏳',
+ 'message' => 'Be right back',
+ 'clearAt' => [
+ 'type' => 'period',
+ 'time' => 900,
+ ],
+ ],
+ [
'id' => 'remote-work',
'icon' => '🏡',
'message' => 'Working remotely',
@@ -110,41 +92,36 @@ class PredefinedStatusServiceTest extends TestCase {
'clearAt' => null,
'visible' => false,
],
+ [
+ 'id' => 'out-of-office',
+ 'icon' => '🛑',
+ 'message' => 'Out of office',
+ 'clearAt' => null,
+ 'visible' => false,
+ ],
], $actual);
}
- /**
- * @param string $id
- * @param string|null $expectedIcon
- *
- * @dataProvider getIconForIdDataProvider
- */
+ #[\PHPUnit\Framework\Attributes\DataProvider('getIconForIdDataProvider')]
public function testGetIconForId(string $id, ?string $expectedIcon): void {
$actual = $this->service->getIconForId($id);
$this->assertEquals($expectedIcon, $actual);
}
- /**
- * @return array
- */
- public function getIconForIdDataProvider(): array {
+ public static function getIconForIdDataProvider(): array {
return [
['meeting', '📅'],
['commuting', '🚌'],
['sick-leave', '🤒'],
['vacationing', '🌴'],
['remote-work', '🏡'],
+ ['be-right-back', '⏳'],
['call', '💬'],
['unknown-id', null],
];
}
- /**
- * @param string $id
- * @param string|null $expected
- *
- * @dataProvider getTranslatedStatusForIdDataProvider
- */
+ #[\PHPUnit\Framework\Attributes\DataProvider('getTranslatedStatusForIdDataProvider')]
public function testGetTranslatedStatusForId(string $id, ?string $expected): void {
$this->l10n->method('t')
->willReturnArgument(0);
@@ -153,59 +130,44 @@ class PredefinedStatusServiceTest extends TestCase {
$this->assertEquals($expected, $actual);
}
- /**
- * @return array
- */
- public function getTranslatedStatusForIdDataProvider(): array {
+ public static function getTranslatedStatusForIdDataProvider(): array {
return [
['meeting', 'In a meeting'],
['commuting', 'Commuting'],
['sick-leave', 'Out sick'],
['vacationing', 'Vacationing'],
['remote-work', 'Working remotely'],
+ ['be-right-back', 'Be right back'],
['call', 'In a call'],
['unknown-id', null],
];
}
- /**
- * @param string $id
- * @param bool $expected
- *
- * @dataProvider isValidIdDataProvider
- */
+ #[\PHPUnit\Framework\Attributes\DataProvider('isValidIdDataProvider')]
public function testIsValidId(string $id, bool $expected): void {
$actual = $this->service->isValidId($id);
$this->assertEquals($expected, $actual);
}
- /**
- * @return array
- */
- public function isValidIdDataProvider(): array {
+ public static function isValidIdDataProvider(): array {
return [
['meeting', true],
['commuting', true],
['sick-leave', true],
['vacationing', true],
['remote-work', true],
+ ['be-right-back', true],
['call', true],
['unknown-id', false],
];
}
public function testGetDefaultStatusById(): void {
- $this->l10n->expects($this->exactly(6))
+ $this->l10n->expects($this->exactly(8))
->method('t')
- ->withConsecutive(
- ['In a meeting'],
- ['Commuting'],
- ['Working remotely'],
- ['Out sick'],
- ['Vacationing'],
- ['In a call'],
- )
- ->willReturnArgument(0);
+ ->willReturnCallback(function ($text, $parameters = []) {
+ return vsprintf($text, $parameters);
+ });
$this->assertEquals([
'id' => 'call',
diff --git a/apps/user_status/tests/Unit/Service/StatusServiceTest.php b/apps/user_status/tests/Unit/Service/StatusServiceTest.php
index 3dd397e1d36..7dfa5b0d064 100644
--- a/apps/user_status/tests/Unit/Service/StatusServiceTest.php
+++ b/apps/user_status/tests/Unit/Service/StatusServiceTest.php
@@ -3,26 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- * @author Joas Schilling <coding@schilljs.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\UserStatus\Tests\Service;
@@ -35,35 +17,29 @@ use OCA\UserStatus\Exception\InvalidMessageIdException;
use OCA\UserStatus\Exception\InvalidStatusIconException;
use OCA\UserStatus\Exception\InvalidStatusTypeException;
use OCA\UserStatus\Exception\StatusMessageTooLongException;
-use OCA\UserStatus\Service\EmojiService;
use OCA\UserStatus\Service\PredefinedStatusService;
use OCA\UserStatus\Service\StatusService;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\DB\Exception;
use OCP\IConfig;
+use OCP\IEmojiHelper;
+use OCP\IUserManager;
use OCP\UserStatus\IUserStatus;
+use PHPUnit\Framework\MockObject\MockObject;
+use Psr\Log\LoggerInterface;
use Test\TestCase;
class StatusServiceTest extends TestCase {
+ private UserStatusMapper&MockObject $mapper;
+ private ITimeFactory&MockObject $timeFactory;
+ private PredefinedStatusService&MockObject $predefinedStatusService;
+ private IEmojiHelper&MockObject $emojiHelper;
+ private IConfig&MockObject $config;
+ private IUserManager&MockObject $userManager;
+ private LoggerInterface&MockObject $logger;
- /** @var UserStatusMapper|\PHPUnit\Framework\MockObject\MockObject */
- private $mapper;
-
- /** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */
- private $timeFactory;
-
- /** @var PredefinedStatusService|\PHPUnit\Framework\MockObject\MockObject */
- private $predefinedStatusService;
-
- /** @var EmojiService|\PHPUnit\Framework\MockObject\MockObject */
- private $emojiService;
-
- /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
- private $config;
-
- /** @var StatusService */
- private $service;
+ private StatusService $service;
protected function setUp(): void {
parent::setUp();
@@ -71,9 +47,10 @@ class StatusServiceTest extends TestCase {
$this->mapper = $this->createMock(UserStatusMapper::class);
$this->timeFactory = $this->createMock(ITimeFactory::class);
$this->predefinedStatusService = $this->createMock(PredefinedStatusService::class);
- $this->emojiService = $this->createMock(EmojiService::class);
-
+ $this->emojiHelper = $this->createMock(IEmojiHelper::class);
+ $this->userManager = $this->createMock(IUserManager::class);
$this->config = $this->createMock(IConfig::class);
+ $this->logger = $this->createMock(LoggerInterface::class);
$this->config->method('getAppValue')
->willReturnMap([
@@ -84,8 +61,11 @@ class StatusServiceTest extends TestCase {
$this->service = new StatusService($this->mapper,
$this->timeFactory,
$this->predefinedStatusService,
- $this->emojiService,
- $this->config);
+ $this->emojiHelper,
+ $this->config,
+ $this->userManager,
+ $this->logger,
+ );
}
public function testFindAll(): void {
@@ -138,8 +118,11 @@ class StatusServiceTest extends TestCase {
$this->service = new StatusService($this->mapper,
$this->timeFactory,
$this->predefinedStatusService,
- $this->emojiService,
- $this->config);
+ $this->emojiHelper,
+ $this->config,
+ $this->userManager,
+ $this->logger,
+ );
$this->assertEquals([], $this->service->findAllRecentStatusChanges(20, 50));
@@ -155,22 +138,15 @@ class StatusServiceTest extends TestCase {
$this->service = new StatusService($this->mapper,
$this->timeFactory,
$this->predefinedStatusService,
- $this->emojiService,
- $this->config);
+ $this->emojiHelper,
+ $this->config,
+ $this->userManager,
+ $this->logger,
+ );
$this->assertEquals([], $this->service->findAllRecentStatusChanges(20, 50));
}
- public function testFindByUserId(): void {
- $status = $this->createMock(UserStatus::class);
- $this->mapper->expects($this->once())
- ->method('findByUserId')
- ->with('john.doe')
- ->willReturn($status);
-
- $this->assertEquals($status, $this->service->findByUserId('john.doe'));
- }
-
public function testFindByUserIdDoesNotExist(): void {
$this->mapper->expects($this->once())
->method('findByUserId')
@@ -245,30 +221,19 @@ class StatusServiceTest extends TestCase {
$this->assertNull($status->getMessageId());
}
- /**
- * @param string $userId
- * @param string $status
- * @param int|null $statusTimestamp
- * @param bool $isUserDefined
- * @param bool $expectExisting
- * @param bool $expectSuccess
- * @param bool $expectTimeFactory
- * @param bool $expectException
- * @param string|null $expectedExceptionClass
- * @param string|null $expectedExceptionMessage
- *
- * @dataProvider setStatusDataProvider
- */
- public function testSetStatus(string $userId,
- string $status,
- ?int $statusTimestamp,
- bool $isUserDefined,
- bool $expectExisting,
- bool $expectSuccess,
- bool $expectTimeFactory,
- bool $expectException,
- ?string $expectedExceptionClass,
- ?string $expectedExceptionMessage): void {
+ #[\PHPUnit\Framework\Attributes\DataProvider('setStatusDataProvider')]
+ public function testSetStatus(
+ string $userId,
+ string $status,
+ ?int $statusTimestamp,
+ bool $isUserDefined,
+ bool $expectExisting,
+ bool $expectSuccess,
+ bool $expectTimeFactory,
+ bool $expectException,
+ ?string $expectedExceptionClass,
+ ?string $expectedExceptionMessage,
+ ): void {
$userStatus = new UserStatus();
if ($expectExisting) {
@@ -319,7 +284,7 @@ class StatusServiceTest extends TestCase {
}
}
- public function setStatusDataProvider(): array {
+ public static function setStatusDataProvider(): array {
return [
['john.doe', 'online', 50, true, true, true, false, false, null, null],
['john.doe', 'online', 50, true, false, true, false, false, null, null],
@@ -377,28 +342,18 @@ class StatusServiceTest extends TestCase {
];
}
- /**
- * @param string $userId
- * @param string $messageId
- * @param bool $isValidMessageId
- * @param int|null $clearAt
- * @param bool $expectExisting
- * @param bool $expectSuccess
- * @param bool $expectException
- * @param string|null $expectedExceptionClass
- * @param string|null $expectedExceptionMessage
- *
- * @dataProvider setPredefinedMessageDataProvider
- */
- public function testSetPredefinedMessage(string $userId,
- string $messageId,
- bool $isValidMessageId,
- ?int $clearAt,
- bool $expectExisting,
- bool $expectSuccess,
- bool $expectException,
- ?string $expectedExceptionClass,
- ?string $expectedExceptionMessage): void {
+ #[\PHPUnit\Framework\Attributes\DataProvider('setPredefinedMessageDataProvider')]
+ public function testSetPredefinedMessage(
+ string $userId,
+ string $messageId,
+ bool $isValidMessageId,
+ ?int $clearAt,
+ bool $expectExisting,
+ bool $expectSuccess,
+ bool $expectException,
+ ?string $expectedExceptionClass,
+ ?string $expectedExceptionMessage,
+ ): void {
$userStatus = new UserStatus();
if ($expectExisting) {
@@ -461,7 +416,7 @@ class StatusServiceTest extends TestCase {
}
}
- public function setPredefinedMessageDataProvider(): array {
+ public static function setPredefinedMessageDataProvider(): array {
return [
['john.doe', 'sick-leave', true, null, true, true, false, null, null],
['john.doe', 'sick-leave', true, null, false, true, false, null, null],
@@ -474,30 +429,19 @@ class StatusServiceTest extends TestCase {
];
}
- /**
- * @param string $userId
- * @param string|null $statusIcon
- * @param bool $supportsEmoji
- * @param string $message
- * @param int|null $clearAt
- * @param bool $expectExisting
- * @param bool $expectSuccess
- * @param bool $expectException
- * @param string|null $expectedExceptionClass
- * @param string|null $expectedExceptionMessage
- *
- * @dataProvider setCustomMessageDataProvider
- */
- public function testSetCustomMessage(string $userId,
- ?string $statusIcon,
- bool $supportsEmoji,
- string $message,
- ?int $clearAt,
- bool $expectExisting,
- bool $expectSuccess,
- bool $expectException,
- ?string $expectedExceptionClass,
- ?string $expectedExceptionMessage): void {
+ #[\PHPUnit\Framework\Attributes\DataProvider('setCustomMessageDataProvider')]
+ public function testSetCustomMessage(
+ string $userId,
+ ?string $statusIcon,
+ bool $supportsEmoji,
+ string $message,
+ ?int $clearAt,
+ bool $expectExisting,
+ bool $expectSuccess,
+ bool $expectException,
+ ?string $expectedExceptionClass,
+ ?string $expectedExceptionMessage,
+ ): void {
$userStatus = new UserStatus();
if ($expectExisting) {
@@ -519,7 +463,7 @@ class StatusServiceTest extends TestCase {
->willThrowException(new DoesNotExistException(''));
}
- $this->emojiService->method('isValidEmoji')
+ $this->emojiHelper->method('isValidSingleEmoji')
->with($statusIcon)
->willReturn($supportsEmoji);
@@ -558,7 +502,7 @@ class StatusServiceTest extends TestCase {
}
}
- public function setCustomMessageDataProvider(): array {
+ public static function setCustomMessageDataProvider(): array {
return [
['john.doe', '😁', true, 'Custom message', null, true, true, false, null, null],
['john.doe', '😁', true, 'Custom message', null, false, true, false, null, null],
@@ -749,7 +693,6 @@ class StatusServiceTest extends TestCase {
}
public function testBackup(): void {
- $e = new Exception('', Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION);
$this->mapper->expects($this->once())
->method('createBackupStatus')
->with('john')
@@ -795,24 +738,91 @@ class StatusServiceTest extends TestCase {
$backupOnly->setUserId('_backuponly');
$backupOnly->setIsBackup(true);
+ $noBackupDND = new UserStatus();
+ $noBackupDND->setId(5);
+ $noBackupDND->setStatus(IUserStatus::DND);
+ $noBackupDND->setStatusTimestamp(1337);
+ $noBackupDND->setIsUserDefined(false);
+ $noBackupDND->setMessageId('call');
+ $noBackupDND->setUserId('nobackupanddnd');
+ $noBackupDND->setIsBackup(false);
+
$this->mapper->expects($this->once())
->method('findByUserIds')
- ->with(['john', 'nobackup', 'backuponly', '_john', '_nobackup', '_backuponly'])
+ ->with(['john', 'nobackup', 'backuponly', 'nobackupanddnd', '_john', '_nobackup', '_backuponly', '_nobackupanddnd'])
->willReturn([
$john,
$johnBackup,
$noBackup,
$backupOnly,
+ $noBackupDND,
]);
$this->mapper->expects($this->once())
->method('deleteByIds')
- ->with([1, 3]);
+ ->with([1, 3, 5]);
$this->mapper->expects($this->once())
->method('restoreBackupStatuses')
->with([2]);
- $this->service->revertMultipleUserStatus(['john', 'nobackup', 'backuponly'], 'call', IUserStatus::AWAY);
+ $this->service->revertMultipleUserStatus(['john', 'nobackup', 'backuponly', 'nobackupanddnd'], 'call');
+ }
+
+ public static function dataSetUserStatus(): array {
+ return [
+ [IUserStatus::MESSAGE_CALENDAR_BUSY, '', false],
+
+ // Call > Meeting
+ [IUserStatus::MESSAGE_CALENDAR_BUSY, IUserStatus::MESSAGE_CALL, false],
+ [IUserStatus::MESSAGE_CALL, IUserStatus::MESSAGE_CALENDAR_BUSY, true],
+
+ // Availability > Call&Meeting
+ [IUserStatus::MESSAGE_CALENDAR_BUSY, IUserStatus::MESSAGE_AVAILABILITY, false],
+ [IUserStatus::MESSAGE_CALL, IUserStatus::MESSAGE_AVAILABILITY, false],
+ [IUserStatus::MESSAGE_AVAILABILITY, IUserStatus::MESSAGE_CALENDAR_BUSY, true],
+ [IUserStatus::MESSAGE_AVAILABILITY, IUserStatus::MESSAGE_CALL, true],
+
+ // Out-of-office > Availability&Call&Meeting
+ [IUserStatus::MESSAGE_AVAILABILITY, IUserStatus::MESSAGE_OUT_OF_OFFICE, false],
+ [IUserStatus::MESSAGE_CALENDAR_BUSY, IUserStatus::MESSAGE_OUT_OF_OFFICE, false],
+ [IUserStatus::MESSAGE_CALL, IUserStatus::MESSAGE_OUT_OF_OFFICE, false],
+ [IUserStatus::MESSAGE_OUT_OF_OFFICE, IUserStatus::MESSAGE_AVAILABILITY, true],
+ [IUserStatus::MESSAGE_OUT_OF_OFFICE, IUserStatus::MESSAGE_CALENDAR_BUSY, true],
+ [IUserStatus::MESSAGE_OUT_OF_OFFICE, IUserStatus::MESSAGE_CALL, true],
+ ];
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataSetUserStatus')]
+ public function testSetUserStatus(string $messageId, string $oldMessageId, bool $expectedUpdateShortcut): void {
+ $previous = new UserStatus();
+ $previous->setId(1);
+ $previous->setStatus(IUserStatus::AWAY);
+ $previous->setStatusTimestamp(1337);
+ $previous->setIsUserDefined(false);
+ $previous->setMessageId($oldMessageId);
+ $previous->setUserId('john');
+ $previous->setIsBackup(false);
+
+ $this->mapper->expects($this->once())
+ ->method('findByUserId')
+ ->with('john')
+ ->willReturn($previous);
+
+ $e = DbalException::wrap($this->createMock(UniqueConstraintViolationException::class));
+ $this->mapper->expects($expectedUpdateShortcut ? $this->never() : $this->once())
+ ->method('createBackupStatus')
+ ->willThrowException($e);
+
+ $this->mapper->expects($this->any())
+ ->method('update')
+ ->willReturnArgument(0);
+
+ $this->predefinedStatusService->expects($this->once())
+ ->method('isValidId')
+ ->with($messageId)
+ ->willReturn(true);
+
+ $this->service->setUserStatus('john', IUserStatus::DND, $messageId, true);
}
}
diff --git a/apps/user_status/tests/bootstrap.php b/apps/user_status/tests/bootstrap.php
index b6d8fc06417..c98daca1dfc 100644
--- a/apps/user_status/tests/bootstrap.php
+++ b/apps/user_status/tests/bootstrap.php
@@ -3,34 +3,18 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
+
+use OCP\App\IAppManager;
+use OCP\Server;
+
if (!defined('PHPUNIT_RUN')) {
define('PHPUNIT_RUN', 1);
}
-require_once __DIR__.'/../../../lib/base.php';
-
-\OC::$composerAutoloader->addPsr4('Test\\', OC::$SERVERROOT . '/tests/lib/', true);
-
-\OC_App::loadApp('user_status');
+require_once __DIR__ . '/../../../lib/base.php';
+require_once __DIR__ . '/../../../tests/autoload.php';
-OC_Hook::clear();
+Server::get(IAppManager::class)->loadApp('user_status');