mirror of
https://github.com/nextcloud/server.git
synced 2026-04-15 22:11:17 -04:00
Merge branch 'master' into auth-token-commands
This commit is contained in:
commit
79bc6ba06c
529 changed files with 4625 additions and 5149 deletions
5
.github/CODEOWNERS
vendored
5
.github/CODEOWNERS
vendored
|
|
@ -18,6 +18,7 @@
|
|||
/apps/oauth2/appinfo/info.xml @julien-nc @ChristophWurst
|
||||
/apps/provisioning_api/appinfo/info.xml @provokateurin @nickvergessen
|
||||
/apps/settings/appinfo/info.xml @Pytal @JuliaKirschenheuter
|
||||
/apps/sharebymail/appinfo/info.xml @Altahrim
|
||||
/apps/systemtags/appinfo/info.xml @Antreesy @marcelklehr
|
||||
/apps/theming/appinfo/info.xml @skjnldsv @juliushaertl
|
||||
/apps/twofactor_backupcodes/appinfo/info.xml @st3iny @miaulalala @ChristophWurst
|
||||
|
|
@ -36,6 +37,10 @@
|
|||
/apps/twofactor_backupcodes @ChristophWurst @miaulalala @nickvergessen @st3iny
|
||||
/core/templates/twofactor* @ChristophWurst @miaulalala @nickvergessen @st3iny
|
||||
|
||||
# Limit login to IP
|
||||
# Watch login routes for https://github.com/nextcloud/limit_login_to_ip
|
||||
/core/routes.php @Altahrim
|
||||
|
||||
# OpenAPI
|
||||
openapi.json @provokateurin
|
||||
ResponseDefinitions.php @provokateurin
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ OC.L10N.register(
|
|||
"You deleted to-do {todo} from list {calendar}" : "Ви вилучили завдання {todo} зі списку {calendar}",
|
||||
"{actor} updated to-do {todo} in list {calendar}" : "{actor} оновив(-ла) завдання {todo} у списку {calendar}",
|
||||
"You updated to-do {todo} in list {calendar}" : "Ви оновили завдання {todo} у списку {calendar}",
|
||||
"{actor} solved to-do {todo} in list {calendar}" : "{actor} вирішив(-ла) завдання {todo} у списку {calendar}",
|
||||
"You solved to-do {todo} in list {calendar}" : "Ви вирішили завдання {todo} у списку {calendar}",
|
||||
"{actor} solved to-do {todo} in list {calendar}" : "{actor} виконав(-ла) завдання {todo} зі списку {calendar}",
|
||||
"You solved to-do {todo} in list {calendar}" : "Ви виконали завдання {todo} зі списку {calendar}",
|
||||
"{actor} reopened to-do {todo} in list {calendar}" : "{actor} знову відкрив(-ла) завдання у списку {calendar}",
|
||||
"You reopened to-do {todo} in list {calendar}" : "Ви знову відкрили завдання {todo} зі списку {calendar}",
|
||||
"{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} перемістив(-ла) завдання {todo} зі списку {sourceCalendar} до списку {targetCalendar}",
|
||||
|
|
@ -154,7 +154,7 @@ OC.L10N.register(
|
|||
"WebDAV" : "WebDAV",
|
||||
"WebDAV endpoint" : "Точка доступу WebDAV",
|
||||
"Availability" : "Доступність",
|
||||
"If you configure your working hours, other users will see when you are out of office when they book a meeting." : "Якщо ви налаштуєте свій робочий час, інші користувачі побачать, коли вас немає на місці, коли вони бронюють зустріч.",
|
||||
"If you configure your working hours, other users will see when you are out of office when they book a meeting." : "Будь ласка, налаштуйте ваш робочий час, щоби інші користувачі могли бачити, коли ви відсутні під час бронювання зустрічей.",
|
||||
"Time zone:" : "Часовий пояс:",
|
||||
"to" : "до",
|
||||
"Delete slot" : "Вилучити діапазон",
|
||||
|
|
@ -167,17 +167,17 @@ OC.L10N.register(
|
|||
"Friday" : "П'ятниця",
|
||||
"Saturday" : "Субота",
|
||||
"Sunday" : "Неділя",
|
||||
"Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "Автоматично встановлюйте статус користувача на \"Не турбувати\", коли ви не доступні, щоб вимкнути усі сповіщення.",
|
||||
"Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "Автоматично встановлювати статус користувача у \"Не турбувати\", коли ви не доступні. В цей проміжок часу ви не отримуватимете сповіщення.",
|
||||
"Save" : "Зберегти",
|
||||
"Failed to load availability" : "Не вдалося завантажити доступність",
|
||||
"Saved availability" : "Збережена наявність",
|
||||
"Failed to save availability" : "Не вдалося зберегти наявність",
|
||||
"Calendar server" : "Календар",
|
||||
"Send invitations to attendees" : "Надіслати запрошення учасникам",
|
||||
"Automatically generate a birthday calendar" : "Автоматично згенерувати календар днів народження",
|
||||
"Send invitations to attendees" : "Надсилати запрошення учасникам",
|
||||
"Automatically generate a birthday calendar" : "Автоматично створити календар днів народження",
|
||||
"Birthday calendars will be generated by a background job." : "Календар днів народження буде згенеровано у фоновому завданні.",
|
||||
"Hence they will not be available immediately after enabling but will show up after some time." : "Отже вони не будуть доступні одразу після увімкнення, але з'являться згодом.",
|
||||
"Send notifications for events" : "Відправити сповіщення для подій",
|
||||
"Send notifications for events" : "Надсилати сповіщення про події",
|
||||
"Notifications are sent via background jobs, so these must occur often enough." : "Сповіщення надсилаються у фонових завданнях, тож вони мають запускатися достатньо часто.",
|
||||
"Send reminder notifications to calendar sharees as well" : "Також надсилайте нагадування користувачам вашого спільного календаря",
|
||||
"Reminders are always sent to organizers and attendees." : "Нагадування завжди надсилаються організаторам і учасникам.",
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@
|
|||
"You deleted to-do {todo} from list {calendar}" : "Ви вилучили завдання {todo} зі списку {calendar}",
|
||||
"{actor} updated to-do {todo} in list {calendar}" : "{actor} оновив(-ла) завдання {todo} у списку {calendar}",
|
||||
"You updated to-do {todo} in list {calendar}" : "Ви оновили завдання {todo} у списку {calendar}",
|
||||
"{actor} solved to-do {todo} in list {calendar}" : "{actor} вирішив(-ла) завдання {todo} у списку {calendar}",
|
||||
"You solved to-do {todo} in list {calendar}" : "Ви вирішили завдання {todo} у списку {calendar}",
|
||||
"{actor} solved to-do {todo} in list {calendar}" : "{actor} виконав(-ла) завдання {todo} зі списку {calendar}",
|
||||
"You solved to-do {todo} in list {calendar}" : "Ви виконали завдання {todo} зі списку {calendar}",
|
||||
"{actor} reopened to-do {todo} in list {calendar}" : "{actor} знову відкрив(-ла) завдання у списку {calendar}",
|
||||
"You reopened to-do {todo} in list {calendar}" : "Ви знову відкрили завдання {todo} зі списку {calendar}",
|
||||
"{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} перемістив(-ла) завдання {todo} зі списку {sourceCalendar} до списку {targetCalendar}",
|
||||
|
|
@ -152,7 +152,7 @@
|
|||
"WebDAV" : "WebDAV",
|
||||
"WebDAV endpoint" : "Точка доступу WebDAV",
|
||||
"Availability" : "Доступність",
|
||||
"If you configure your working hours, other users will see when you are out of office when they book a meeting." : "Якщо ви налаштуєте свій робочий час, інші користувачі побачать, коли вас немає на місці, коли вони бронюють зустріч.",
|
||||
"If you configure your working hours, other users will see when you are out of office when they book a meeting." : "Будь ласка, налаштуйте ваш робочий час, щоби інші користувачі могли бачити, коли ви відсутні під час бронювання зустрічей.",
|
||||
"Time zone:" : "Часовий пояс:",
|
||||
"to" : "до",
|
||||
"Delete slot" : "Вилучити діапазон",
|
||||
|
|
@ -165,17 +165,17 @@
|
|||
"Friday" : "П'ятниця",
|
||||
"Saturday" : "Субота",
|
||||
"Sunday" : "Неділя",
|
||||
"Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "Автоматично встановлюйте статус користувача на \"Не турбувати\", коли ви не доступні, щоб вимкнути усі сповіщення.",
|
||||
"Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "Автоматично встановлювати статус користувача у \"Не турбувати\", коли ви не доступні. В цей проміжок часу ви не отримуватимете сповіщення.",
|
||||
"Save" : "Зберегти",
|
||||
"Failed to load availability" : "Не вдалося завантажити доступність",
|
||||
"Saved availability" : "Збережена наявність",
|
||||
"Failed to save availability" : "Не вдалося зберегти наявність",
|
||||
"Calendar server" : "Календар",
|
||||
"Send invitations to attendees" : "Надіслати запрошення учасникам",
|
||||
"Automatically generate a birthday calendar" : "Автоматично згенерувати календар днів народження",
|
||||
"Send invitations to attendees" : "Надсилати запрошення учасникам",
|
||||
"Automatically generate a birthday calendar" : "Автоматично створити календар днів народження",
|
||||
"Birthday calendars will be generated by a background job." : "Календар днів народження буде згенеровано у фоновому завданні.",
|
||||
"Hence they will not be available immediately after enabling but will show up after some time." : "Отже вони не будуть доступні одразу після увімкнення, але з'являться згодом.",
|
||||
"Send notifications for events" : "Відправити сповіщення для подій",
|
||||
"Send notifications for events" : "Надсилати сповіщення про події",
|
||||
"Notifications are sent via background jobs, so these must occur often enough." : "Сповіщення надсилаються у фонових завданнях, тож вони мають запускатися достатньо часто.",
|
||||
"Send reminder notifications to calendar sharees as well" : "Також надсилайте нагадування користувачам вашого спільного календаря",
|
||||
"Reminders are always sent to organizers and attendees." : "Нагадування завжди надсилаються організаторам і учасникам.",
|
||||
|
|
|
|||
|
|
@ -24,22 +24,18 @@
|
|||
namespace OCA\DAV\Command;
|
||||
|
||||
use OCA\DAV\CardDAV\SyncService;
|
||||
use OCP\IConfig;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Helper\ProgressBar;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class SyncSystemAddressBook extends Command {
|
||||
|
||||
/** @var SyncService */
|
||||
private $syncService;
|
||||
|
||||
/**
|
||||
* @param SyncService $syncService
|
||||
*/
|
||||
public function __construct(SyncService $syncService) {
|
||||
public function __construct(private SyncService $syncService, private IConfig $config) {
|
||||
parent::__construct();
|
||||
$this->syncService = $syncService;
|
||||
}
|
||||
|
||||
protected function configure() {
|
||||
|
|
@ -62,6 +58,7 @@ class SyncSystemAddressBook extends Command {
|
|||
|
||||
$progress->finish();
|
||||
$output->writeln('');
|
||||
$this->config->setAppValue('dav', 'needs_system_address_book_sync', 'no');
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ namespace OCA\DAV\Migration;
|
|||
use Closure;
|
||||
use OCA\DAV\CardDAV\SyncService;
|
||||
use OCP\DB\ISchemaWrapper;
|
||||
use OCP\IConfig;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Migration\IOutput;
|
||||
use OCP\Migration\SimpleMigrationStep;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
|
|
@ -37,22 +39,27 @@ use Psr\Log\LoggerInterface;
|
|||
use Throwable;
|
||||
|
||||
class Version1027Date20230504122946 extends SimpleMigrationStep {
|
||||
private SyncService $syncService;
|
||||
private LoggerInterface $logger;
|
||||
|
||||
public function __construct(SyncService $syncService, LoggerInterface $logger) {
|
||||
$this->syncService = $syncService;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
public function __construct(private SyncService $syncService,
|
||||
private LoggerInterface $logger,
|
||||
private IUserManager $userManager,
|
||||
private IConfig $config) {}
|
||||
/**
|
||||
* @param IOutput $output
|
||||
* @param Closure(): ISchemaWrapper $schemaClosure
|
||||
* @param array $options
|
||||
*/
|
||||
public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
|
||||
if($this->userManager->countUsers() > 1000) {
|
||||
$this->config->setAppValue('dav', 'needs_system_address_book_sync', 'yes');
|
||||
$output->info('Could not sync system address books during update - too many user records have been found. Please call occ dav:sync-system-addressbook manually.');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->syncService->syncInstance();
|
||||
$this->config->setAppValue('dav', 'needs_system_address_book_sync', 'no');
|
||||
} catch (Throwable $e) {
|
||||
$this->config->setAppValue('dav', 'needs_system_address_book_sync', 'yes');
|
||||
$this->logger->error('Could not sync system address books during update', [
|
||||
'exception' => $e,
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ OC.L10N.register(
|
|||
"Cancel" : "Скасувати",
|
||||
"Add remote share" : "Додати віддалений каталог",
|
||||
"Invalid Federated Cloud ID" : "Неправильний Об'єднаний Хмарний Ідентіфікатор ",
|
||||
"Server to server sharing is not enabled on this server" : "На даному сервері вимкнута можливість передачі даних між серверами",
|
||||
"Server to server sharing is not enabled on this server" : "На цьому сервері вимкнута можливість передавання даних між серверами",
|
||||
"Couldn't establish a federated share." : "Не вдалося встановити об’єднаний спільний доступ.",
|
||||
"Couldn't establish a federated share, maybe the password was wrong." : "Не вдалося встановити спільний доступ до об'єднаної хмари, можливо, пароль неправильний.",
|
||||
"Federated Share request sent, you will receive an invitation. Check your notifications." : "Запит на Federated Share надіслано, ви отримаєте запрошення. Перевірте сповіщення.",
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
"Cancel" : "Скасувати",
|
||||
"Add remote share" : "Додати віддалений каталог",
|
||||
"Invalid Federated Cloud ID" : "Неправильний Об'єднаний Хмарний Ідентіфікатор ",
|
||||
"Server to server sharing is not enabled on this server" : "На даному сервері вимкнута можливість передачі даних між серверами",
|
||||
"Server to server sharing is not enabled on this server" : "На цьому сервері вимкнута можливість передавання даних між серверами",
|
||||
"Couldn't establish a federated share." : "Не вдалося встановити об’єднаний спільний доступ.",
|
||||
"Couldn't establish a federated share, maybe the password was wrong." : "Не вдалося встановити спільний доступ до об'єднаної хмари, можливо, пароль неправильний.",
|
||||
"Federated Share request sent, you will receive an invitation. Check your notifications." : "Запит на Federated Share надіслано, ви отримаєте запрошення. Перевірте сповіщення.",
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ OC.L10N.register(
|
|||
"An unknown error has occurred" : "حدث خطأ غير معروف",
|
||||
"File could not be uploaded" : "لا يمكن تحميل الملف ",
|
||||
"Uploading …" : "جاري الرفع...",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "التحديث جارٍ … ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} من {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "رفع هذا النوع الملفات غير مدعوم",
|
||||
"Target folder does not exist any more" : "المجلد المراد غير موجود بعد الان",
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
"An unknown error has occurred" : "حدث خطأ غير معروف",
|
||||
"File could not be uploaded" : "لا يمكن تحميل الملف ",
|
||||
"Uploading …" : "جاري الرفع...",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "التحديث جارٍ … ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} من {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "رفع هذا النوع الملفات غير مدعوم",
|
||||
"Target folder does not exist any more" : "المجلد المراد غير موجود بعد الان",
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ OC.L10N.register(
|
|||
"An unknown error has occurred" : "S'ha produït un error desconegut",
|
||||
"File could not be uploaded" : "No s'ha pogut pujar el fitxer",
|
||||
"Uploading …" : "S'està pujant…",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "S'està pujant… ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} de {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "No s'admet la pujada aquest element",
|
||||
"Target folder does not exist any more" : "La carpeta de destinació ja no existeix",
|
||||
|
|
@ -175,6 +177,7 @@ OC.L10N.register(
|
|||
"Rename file" : "Canvia el nom del fitxer",
|
||||
"File name" : "Nom del fitxer",
|
||||
"A long time ago" : "Fa molt de temps",
|
||||
"This node is unavailable" : "Aquest node no està disponible",
|
||||
"Download file {name}" : "Baixa el fitxer {name}",
|
||||
"\"{displayName}\" action executed successfully" : "L'acció «{displayName}» s'ha executat correctament",
|
||||
"\"{displayName}\" action failed" : "S'ha produït un error en l'acció «{displayName}»",
|
||||
|
|
@ -252,6 +255,7 @@ OC.L10N.register(
|
|||
"No favorites yet" : "Encara no teniu preferits",
|
||||
"Files and folders you mark as favorite will show up here" : "Els fitxers i les carpetes que marqueu com a preferits es mostraran aquí",
|
||||
"All files" : "Tots els fitxers",
|
||||
"List of your files and folders." : "Llista dels vostres fitxers i carpetes.",
|
||||
"List of recently modified files and folders." : "Llista de fitxers i carpetes modificats recentment.",
|
||||
"No recently modified files" : "No hi ha cap fitxer modificat recentment",
|
||||
"Files and folders you recently modified will show up here." : "Els fitxers i les carpetes que heu modificat recentment es mostraran aquí",
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
"An unknown error has occurred" : "S'ha produït un error desconegut",
|
||||
"File could not be uploaded" : "No s'ha pogut pujar el fitxer",
|
||||
"Uploading …" : "S'està pujant…",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "S'està pujant… ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} de {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "No s'admet la pujada aquest element",
|
||||
"Target folder does not exist any more" : "La carpeta de destinació ja no existeix",
|
||||
|
|
@ -173,6 +175,7 @@
|
|||
"Rename file" : "Canvia el nom del fitxer",
|
||||
"File name" : "Nom del fitxer",
|
||||
"A long time ago" : "Fa molt de temps",
|
||||
"This node is unavailable" : "Aquest node no està disponible",
|
||||
"Download file {name}" : "Baixa el fitxer {name}",
|
||||
"\"{displayName}\" action executed successfully" : "L'acció «{displayName}» s'ha executat correctament",
|
||||
"\"{displayName}\" action failed" : "S'ha produït un error en l'acció «{displayName}»",
|
||||
|
|
@ -250,6 +253,7 @@
|
|||
"No favorites yet" : "Encara no teniu preferits",
|
||||
"Files and folders you mark as favorite will show up here" : "Els fitxers i les carpetes que marqueu com a preferits es mostraran aquí",
|
||||
"All files" : "Tots els fitxers",
|
||||
"List of your files and folders." : "Llista dels vostres fitxers i carpetes.",
|
||||
"List of recently modified files and folders." : "Llista de fitxers i carpetes modificats recentment.",
|
||||
"No recently modified files" : "No hi ha cap fitxer modificat recentment",
|
||||
"Files and folders you recently modified will show up here." : "Els fitxers i les carpetes que heu modificat recentment es mostraran aquí",
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ OC.L10N.register(
|
|||
"An unknown error has occurred" : "Vyskytla se neznámá chyba",
|
||||
"File could not be uploaded" : "Soubor se nepodařilo nahrát",
|
||||
"Uploading …" : "Nahrávání…",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "Nahrávání… ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} z {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "Nahrání této položky není podporováno",
|
||||
"Target folder does not exist any more" : "Cílová složka už neexistuje",
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
"An unknown error has occurred" : "Vyskytla se neznámá chyba",
|
||||
"File could not be uploaded" : "Soubor se nepodařilo nahrát",
|
||||
"Uploading …" : "Nahrávání…",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "Nahrávání… ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} z {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "Nahrání této položky není podporováno",
|
||||
"Target folder does not exist any more" : "Cílová složka už neexistuje",
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ OC.L10N.register(
|
|||
"An unknown error has occurred" : "Es ist ein unbekannter Fehler aufgetreten",
|
||||
"File could not be uploaded" : "Datei konnte nicht hochgeladen werden.",
|
||||
"Uploading …" : "Lade hoch …",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "Lade hoch … ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} von {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "Hochladen von Daten dieser Art wird nicht unterstützt.",
|
||||
"Target folder does not exist any more" : "Zielordner existiert nicht mehr",
|
||||
|
|
@ -32,6 +34,7 @@ OC.L10N.register(
|
|||
"Move" : "Verschieben",
|
||||
"Copy" : "Kopieren",
|
||||
"Choose target folder" : "Zielordner wählen",
|
||||
"Set reminder" : "Erinnerung erstellen",
|
||||
"Edit locally" : "Lokal bearbeiten",
|
||||
"Open" : "Öffnen",
|
||||
"Delete file" : "Datei löschen",
|
||||
|
|
@ -108,6 +111,8 @@ OC.L10N.register(
|
|||
"Create new folder" : "Neuen Ordner erstellen",
|
||||
"Upload file" : "Datei hochladen",
|
||||
"Recent" : "Neueste",
|
||||
"This file has the tag {tag}" : "Diese Datei trägt das Schlagwort {tag}.",
|
||||
"This file has the tags {firstTags} and {lastTag}" : "Diese Datei trägt die Schlagworte {firstTags} und {lastTag}.",
|
||||
"Not favorited" : "Nicht favorisiert",
|
||||
"Remove from favorites" : "Von Favoriten entfernen",
|
||||
"Add to favorites" : "Zu den Favoriten hinzufügen",
|
||||
|
|
@ -169,11 +174,21 @@ OC.L10N.register(
|
|||
"Reload current directory" : "Aktuelles Verzeichnis neu laden",
|
||||
"Go to the \"{dir}\" directory" : "In das Verzeichnis \"{dir}“ wechseln",
|
||||
"Select the row for {displayName}" : "Zeile für {displayName} auswählen",
|
||||
"Rename file" : "Datei umbenennen",
|
||||
"File name" : "Dateiname",
|
||||
"A long time ago" : "Vor langer Zeit",
|
||||
"This node is unavailable" : "Dieser Knoten ist nicht verfügbar.",
|
||||
"Download file {name}" : "Datei {name} herunterladen",
|
||||
"\"{displayName}\" action executed successfully" : "Aktion \"{displayName}\" erfolgreich ausgeführt",
|
||||
"\"{displayName}\" action failed" : "Aktion \"{displayName}\" fehlgeschlagen",
|
||||
"\"{name}\" is not an allowed filetype." : "\"{name}\" ist kein zulässiger Dateityp.",
|
||||
"{newName} already exists." : "{newName} existiert bereits.",
|
||||
"Name cannot be empty" : "Der Name darf nicht leer sein",
|
||||
"Another entry with the same name already exists" : "Ein anderer Eintrag mit diesem Namen existiert bereits.",
|
||||
"Renamed \"{oldName}\" to \"{newName}\"" : "\"{oldName}\" in \"{newName}\" umbenannt",
|
||||
"Could not rename \"{oldName}\", it does not exist any more" : "\"{oldName}\" konnte nicht umbenannt werden, da es nicht mehr existiert.",
|
||||
"The name \"{newName}\"\" is already used in the folder \"{dir}\". Please choose a different name." : "Der Name \"{targetName}\" wird bereits im Ordner \"{dir}\" benutzt. Bitte wähle einen anderen Namen.",
|
||||
"Could not rename \"{oldName}\"" : "\"{oldName}\" konnte nicht umbenannt werden.",
|
||||
"Total rows summary" : "Zusammenfassung aller Zeilen",
|
||||
"\"{displayName}\" failed on some elements " : "\"{displayName}\" ist bei einigen Elementen fehlgeschlagen",
|
||||
"\"{displayName}\" batch action executed successfully" : "Stapelaktion \"{displayName}\" erfolgreich ausgeführt",
|
||||
|
|
@ -182,6 +197,8 @@ OC.L10N.register(
|
|||
"Sort list by {column} ({direction})" : "Liste sortieren nach {column} ({direction})",
|
||||
"Select all" : "Alle auswählen",
|
||||
"Unselect all" : "Auswahl aufheben",
|
||||
"List of files and folders." : "Liste der Dateien und Ordner",
|
||||
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Diese Liste wird aus Performance-Gründen nicht vollständig angezeigt. Die Dateien werden angezeigt, wenn du durch die Liste navigierst.",
|
||||
"File not found" : "Datei nicht gefunden",
|
||||
"Storage informations" : "Speicherinformationen",
|
||||
"{usedQuotaByte} used" : "{usedQuotaByte} verwendet",
|
||||
|
|
@ -208,6 +225,7 @@ OC.L10N.register(
|
|||
"Files settings" : "Dateien-Einstellungen",
|
||||
"File cannot be accessed" : "Auf die Datei kann nicht zugegriffen werden",
|
||||
"You might not have have permissions to view it, ask the sender to share it" : "Möglicherweise hast du nicht die Berechtigung zur Anzeige. Bitte den Absender, die Datei freizugeben.",
|
||||
"Sort favorites first" : "Favoriten zuerst sortieren",
|
||||
"Show hidden files" : "Versteckte Dateien anzeigen",
|
||||
"Crop image previews" : "Bildvorschauen zuschneiden",
|
||||
"Additional settings" : "Zusätzliche Einstellungen",
|
||||
|
|
@ -226,13 +244,21 @@ OC.L10N.register(
|
|||
"Blank" : "Leer",
|
||||
"Unable to create new file from template" : "Neue Datei konnte nicht aus Vorlage erstellt werden",
|
||||
"Delete permanently" : "Endgültig löschen",
|
||||
"Open folder {displayName}" : "Ordner {displayName} öffnen",
|
||||
"Open in Files" : "In App \"Dateien\" öffnen",
|
||||
"Open details" : "Details öffnen",
|
||||
"Set up templates folder" : "Vorlagenordner einrichten",
|
||||
"Templates" : "Vorlagen",
|
||||
"Create new templates folder" : "Neuen Vorlagenordner erstellen",
|
||||
"Unable to initialize the templates directory" : "Der Vorlagenordner konnte nicht initialisiert werden",
|
||||
"List of favorites files and folders." : "Liste der favorisierten Ordner und Dateien",
|
||||
"No favorites yet" : "Noch keine Favoriten vorhanden",
|
||||
"Files and folders you mark as favorite will show up here" : "Dateien und Ordner, die als Favoriten markiert werden, erscheinen hier",
|
||||
"All files" : "Alle Dateien",
|
||||
"List of your files and folders." : "Liste deiner Dateien und Ordner",
|
||||
"List of recently modified files and folders." : "Liste der zuletzt geänderten Dateien und Ordner",
|
||||
"No recently modified files" : "Keine kürzlich geänderten Dateien",
|
||||
"Files and folders you recently modified will show up here." : "Die von dir kürzlich geänderten Dateien und Ordner werden hier angezeigt.",
|
||||
"Toggle %1$s sublist" : "Unterliste %1$s umschalten",
|
||||
"No entries found in this folder" : "Keine Einträge in diesem Ordner gefunden",
|
||||
"Upload too large" : "Der Upload ist zu groß",
|
||||
|
|
@ -256,7 +282,7 @@ OC.L10N.register(
|
|||
"Deleted shares" : "Gelöschte Freigaben",
|
||||
"Pending shares" : "Ausstehende Freigaben",
|
||||
"Open folder {name}" : "Ordner {name} öffnen",
|
||||
"This list is not fully rendered for performances reasons. The files will be rendered as you navigate through the list." : "Diese Liste ist aus Performance-Gründen nicht vollständig gerendert. Die Dateien werden gerendert, wenn du durch die Liste navigierst.",
|
||||
"This list is not fully rendered for performances reasons. The files will be rendered as you navigate through the list." : "Diese Liste wird aus Performance-Gründen nicht vollständig angezeigt. Die Dateien werden gerendert, wenn du durch die Liste navigierst.",
|
||||
"Search for an account" : "Nach einem Konto suchen",
|
||||
"Choose" : "Auswählen",
|
||||
"No files or folders have been deleted yet" : "Es wurden noch keine Dateien oder Ordner gelöscht"
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
"An unknown error has occurred" : "Es ist ein unbekannter Fehler aufgetreten",
|
||||
"File could not be uploaded" : "Datei konnte nicht hochgeladen werden.",
|
||||
"Uploading …" : "Lade hoch …",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "Lade hoch … ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} von {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "Hochladen von Daten dieser Art wird nicht unterstützt.",
|
||||
"Target folder does not exist any more" : "Zielordner existiert nicht mehr",
|
||||
|
|
@ -30,6 +32,7 @@
|
|||
"Move" : "Verschieben",
|
||||
"Copy" : "Kopieren",
|
||||
"Choose target folder" : "Zielordner wählen",
|
||||
"Set reminder" : "Erinnerung erstellen",
|
||||
"Edit locally" : "Lokal bearbeiten",
|
||||
"Open" : "Öffnen",
|
||||
"Delete file" : "Datei löschen",
|
||||
|
|
@ -106,6 +109,8 @@
|
|||
"Create new folder" : "Neuen Ordner erstellen",
|
||||
"Upload file" : "Datei hochladen",
|
||||
"Recent" : "Neueste",
|
||||
"This file has the tag {tag}" : "Diese Datei trägt das Schlagwort {tag}.",
|
||||
"This file has the tags {firstTags} and {lastTag}" : "Diese Datei trägt die Schlagworte {firstTags} und {lastTag}.",
|
||||
"Not favorited" : "Nicht favorisiert",
|
||||
"Remove from favorites" : "Von Favoriten entfernen",
|
||||
"Add to favorites" : "Zu den Favoriten hinzufügen",
|
||||
|
|
@ -167,11 +172,21 @@
|
|||
"Reload current directory" : "Aktuelles Verzeichnis neu laden",
|
||||
"Go to the \"{dir}\" directory" : "In das Verzeichnis \"{dir}“ wechseln",
|
||||
"Select the row for {displayName}" : "Zeile für {displayName} auswählen",
|
||||
"Rename file" : "Datei umbenennen",
|
||||
"File name" : "Dateiname",
|
||||
"A long time ago" : "Vor langer Zeit",
|
||||
"This node is unavailable" : "Dieser Knoten ist nicht verfügbar.",
|
||||
"Download file {name}" : "Datei {name} herunterladen",
|
||||
"\"{displayName}\" action executed successfully" : "Aktion \"{displayName}\" erfolgreich ausgeführt",
|
||||
"\"{displayName}\" action failed" : "Aktion \"{displayName}\" fehlgeschlagen",
|
||||
"\"{name}\" is not an allowed filetype." : "\"{name}\" ist kein zulässiger Dateityp.",
|
||||
"{newName} already exists." : "{newName} existiert bereits.",
|
||||
"Name cannot be empty" : "Der Name darf nicht leer sein",
|
||||
"Another entry with the same name already exists" : "Ein anderer Eintrag mit diesem Namen existiert bereits.",
|
||||
"Renamed \"{oldName}\" to \"{newName}\"" : "\"{oldName}\" in \"{newName}\" umbenannt",
|
||||
"Could not rename \"{oldName}\", it does not exist any more" : "\"{oldName}\" konnte nicht umbenannt werden, da es nicht mehr existiert.",
|
||||
"The name \"{newName}\"\" is already used in the folder \"{dir}\". Please choose a different name." : "Der Name \"{targetName}\" wird bereits im Ordner \"{dir}\" benutzt. Bitte wähle einen anderen Namen.",
|
||||
"Could not rename \"{oldName}\"" : "\"{oldName}\" konnte nicht umbenannt werden.",
|
||||
"Total rows summary" : "Zusammenfassung aller Zeilen",
|
||||
"\"{displayName}\" failed on some elements " : "\"{displayName}\" ist bei einigen Elementen fehlgeschlagen",
|
||||
"\"{displayName}\" batch action executed successfully" : "Stapelaktion \"{displayName}\" erfolgreich ausgeführt",
|
||||
|
|
@ -180,6 +195,8 @@
|
|||
"Sort list by {column} ({direction})" : "Liste sortieren nach {column} ({direction})",
|
||||
"Select all" : "Alle auswählen",
|
||||
"Unselect all" : "Auswahl aufheben",
|
||||
"List of files and folders." : "Liste der Dateien und Ordner",
|
||||
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Diese Liste wird aus Performance-Gründen nicht vollständig angezeigt. Die Dateien werden angezeigt, wenn du durch die Liste navigierst.",
|
||||
"File not found" : "Datei nicht gefunden",
|
||||
"Storage informations" : "Speicherinformationen",
|
||||
"{usedQuotaByte} used" : "{usedQuotaByte} verwendet",
|
||||
|
|
@ -206,6 +223,7 @@
|
|||
"Files settings" : "Dateien-Einstellungen",
|
||||
"File cannot be accessed" : "Auf die Datei kann nicht zugegriffen werden",
|
||||
"You might not have have permissions to view it, ask the sender to share it" : "Möglicherweise hast du nicht die Berechtigung zur Anzeige. Bitte den Absender, die Datei freizugeben.",
|
||||
"Sort favorites first" : "Favoriten zuerst sortieren",
|
||||
"Show hidden files" : "Versteckte Dateien anzeigen",
|
||||
"Crop image previews" : "Bildvorschauen zuschneiden",
|
||||
"Additional settings" : "Zusätzliche Einstellungen",
|
||||
|
|
@ -224,13 +242,21 @@
|
|||
"Blank" : "Leer",
|
||||
"Unable to create new file from template" : "Neue Datei konnte nicht aus Vorlage erstellt werden",
|
||||
"Delete permanently" : "Endgültig löschen",
|
||||
"Open folder {displayName}" : "Ordner {displayName} öffnen",
|
||||
"Open in Files" : "In App \"Dateien\" öffnen",
|
||||
"Open details" : "Details öffnen",
|
||||
"Set up templates folder" : "Vorlagenordner einrichten",
|
||||
"Templates" : "Vorlagen",
|
||||
"Create new templates folder" : "Neuen Vorlagenordner erstellen",
|
||||
"Unable to initialize the templates directory" : "Der Vorlagenordner konnte nicht initialisiert werden",
|
||||
"List of favorites files and folders." : "Liste der favorisierten Ordner und Dateien",
|
||||
"No favorites yet" : "Noch keine Favoriten vorhanden",
|
||||
"Files and folders you mark as favorite will show up here" : "Dateien und Ordner, die als Favoriten markiert werden, erscheinen hier",
|
||||
"All files" : "Alle Dateien",
|
||||
"List of your files and folders." : "Liste deiner Dateien und Ordner",
|
||||
"List of recently modified files and folders." : "Liste der zuletzt geänderten Dateien und Ordner",
|
||||
"No recently modified files" : "Keine kürzlich geänderten Dateien",
|
||||
"Files and folders you recently modified will show up here." : "Die von dir kürzlich geänderten Dateien und Ordner werden hier angezeigt.",
|
||||
"Toggle %1$s sublist" : "Unterliste %1$s umschalten",
|
||||
"No entries found in this folder" : "Keine Einträge in diesem Ordner gefunden",
|
||||
"Upload too large" : "Der Upload ist zu groß",
|
||||
|
|
@ -254,7 +280,7 @@
|
|||
"Deleted shares" : "Gelöschte Freigaben",
|
||||
"Pending shares" : "Ausstehende Freigaben",
|
||||
"Open folder {name}" : "Ordner {name} öffnen",
|
||||
"This list is not fully rendered for performances reasons. The files will be rendered as you navigate through the list." : "Diese Liste ist aus Performance-Gründen nicht vollständig gerendert. Die Dateien werden gerendert, wenn du durch die Liste navigierst.",
|
||||
"This list is not fully rendered for performances reasons. The files will be rendered as you navigate through the list." : "Diese Liste wird aus Performance-Gründen nicht vollständig angezeigt. Die Dateien werden gerendert, wenn du durch die Liste navigierst.",
|
||||
"Search for an account" : "Nach einem Konto suchen",
|
||||
"Choose" : "Auswählen",
|
||||
"No files or folders have been deleted yet" : "Es wurden noch keine Dateien oder Ordner gelöscht"
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ OC.L10N.register(
|
|||
"An unknown error has occurred" : "Es ist ein unbekannter Fehler aufgetreten",
|
||||
"File could not be uploaded" : "Datei konnte nicht hochgeladen werden",
|
||||
"Uploading …" : "Lade hoch …",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "Lade hoch… ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} von {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "Hochladen von Daten dieser Art wird nicht unterstützt.",
|
||||
"Target folder does not exist any more" : "Zielordner existiert nicht mehr",
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
"An unknown error has occurred" : "Es ist ein unbekannter Fehler aufgetreten",
|
||||
"File could not be uploaded" : "Datei konnte nicht hochgeladen werden",
|
||||
"Uploading …" : "Lade hoch …",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "Lade hoch… ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} von {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "Hochladen von Daten dieser Art wird nicht unterstützt.",
|
||||
"Target folder does not exist any more" : "Zielordner existiert nicht mehr",
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ OC.L10N.register(
|
|||
"An unknown error has occurred" : "An unknown error has occurred",
|
||||
"File could not be uploaded" : "File could not be uploaded",
|
||||
"Uploading …" : "Uploading …",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "Uploading … ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} of {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "Uploading that item is not supported",
|
||||
"Target folder does not exist any more" : "Target folder does not exist any more",
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
"An unknown error has occurred" : "An unknown error has occurred",
|
||||
"File could not be uploaded" : "File could not be uploaded",
|
||||
"Uploading …" : "Uploading …",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "Uploading … ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} of {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "Uploading that item is not supported",
|
||||
"Target folder does not exist any more" : "Target folder does not exist any more",
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ OC.L10N.register(
|
|||
"An unknown error has occurred" : "Ha ocurrido un error desconocido",
|
||||
"File could not be uploaded" : "No se ha podido subir el archivo",
|
||||
"Uploading …" : "Subiendo …",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "Cargando… ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} de {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "Subir este archivo no es compatible",
|
||||
"Target folder does not exist any more" : "La carpeta destino ya no existe",
|
||||
|
|
@ -32,6 +34,7 @@ OC.L10N.register(
|
|||
"Move" : "Mover",
|
||||
"Copy" : "Copiar",
|
||||
"Choose target folder" : "Elegir carpeta de destino",
|
||||
"Set reminder" : "Enviar recordatorio",
|
||||
"Edit locally" : "Editar localmente",
|
||||
"Open" : "Abrir",
|
||||
"Delete file" : "Eliminar archivo",
|
||||
|
|
@ -174,6 +177,7 @@ OC.L10N.register(
|
|||
"Rename file" : "Renombrar archivo",
|
||||
"File name" : "Nombre del archivo",
|
||||
"A long time ago" : "Hace mucho tiempo",
|
||||
"This node is unavailable" : "Este nodo no está disponible",
|
||||
"Download file {name}" : "Descargar archivo {name}",
|
||||
"\"{displayName}\" action executed successfully" : "la acción \"{displayName}\" se ejecutó exitósamente",
|
||||
"\"{displayName}\" action failed" : "la acción \"{displayName}\" falló",
|
||||
|
|
@ -251,6 +255,7 @@ OC.L10N.register(
|
|||
"No favorites yet" : "Aún no hay favoritos",
|
||||
"Files and folders you mark as favorite will show up here" : "Aquí aparecerán los archivos y carpetas que has marcado como favoritos",
|
||||
"All files" : "Todos los archivos",
|
||||
"List of your files and folders." : "Lista de sus archivos y carpetas.",
|
||||
"List of recently modified files and folders." : "Lista de archivos y carpetas modificados recientemente.",
|
||||
"No recently modified files" : "No hay archivos modificados recientemente.",
|
||||
"Files and folders you recently modified will show up here." : "Los archivos y carpetas que ha modificado recientemente aparecerán aquí.",
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
"An unknown error has occurred" : "Ha ocurrido un error desconocido",
|
||||
"File could not be uploaded" : "No se ha podido subir el archivo",
|
||||
"Uploading …" : "Subiendo …",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "Cargando… ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} de {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "Subir este archivo no es compatible",
|
||||
"Target folder does not exist any more" : "La carpeta destino ya no existe",
|
||||
|
|
@ -30,6 +32,7 @@
|
|||
"Move" : "Mover",
|
||||
"Copy" : "Copiar",
|
||||
"Choose target folder" : "Elegir carpeta de destino",
|
||||
"Set reminder" : "Enviar recordatorio",
|
||||
"Edit locally" : "Editar localmente",
|
||||
"Open" : "Abrir",
|
||||
"Delete file" : "Eliminar archivo",
|
||||
|
|
@ -172,6 +175,7 @@
|
|||
"Rename file" : "Renombrar archivo",
|
||||
"File name" : "Nombre del archivo",
|
||||
"A long time ago" : "Hace mucho tiempo",
|
||||
"This node is unavailable" : "Este nodo no está disponible",
|
||||
"Download file {name}" : "Descargar archivo {name}",
|
||||
"\"{displayName}\" action executed successfully" : "la acción \"{displayName}\" se ejecutó exitósamente",
|
||||
"\"{displayName}\" action failed" : "la acción \"{displayName}\" falló",
|
||||
|
|
@ -249,6 +253,7 @@
|
|||
"No favorites yet" : "Aún no hay favoritos",
|
||||
"Files and folders you mark as favorite will show up here" : "Aquí aparecerán los archivos y carpetas que has marcado como favoritos",
|
||||
"All files" : "Todos los archivos",
|
||||
"List of your files and folders." : "Lista de sus archivos y carpetas.",
|
||||
"List of recently modified files and folders." : "Lista de archivos y carpetas modificados recientemente.",
|
||||
"No recently modified files" : "No hay archivos modificados recientemente.",
|
||||
"Files and folders you recently modified will show up here." : "Los archivos y carpetas que ha modificado recientemente aparecerán aquí.",
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ OC.L10N.register(
|
|||
"An unknown error has occurred" : "Tapahtui tuntematon virhe",
|
||||
"File could not be uploaded" : "Tiedostoa ei voi lähettää",
|
||||
"Uploading …" : "Lähetetään…",
|
||||
"Uploading … ({currentNumber}/{total})" : "Lähetetään… ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize}/{totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "Kyseisen kohteen lähettäminen ei ole tuettu",
|
||||
"Target folder does not exist any more" : "Kohdekansiota ei ole enää olemassa",
|
||||
|
|
@ -244,6 +245,7 @@ OC.L10N.register(
|
|||
"No favorites yet" : "Ei vielä suosikkeja",
|
||||
"Files and folders you mark as favorite will show up here" : "Suosikeiksi merkitsemäsi tiedostot ja kansiot näkyvät täällä",
|
||||
"All files" : "Kaikki tiedostot",
|
||||
"List of your files and folders." : "Luettelo tiedostoistasi ja kansioistasi.",
|
||||
"List of recently modified files and folders." : "Luettelo äskettäin muokatuista tiedostoista ja kansioista.",
|
||||
"No recently modified files" : "Ei äskettäin muokattuja tiedostoja",
|
||||
"Files and folders you recently modified will show up here." : "Äskettäin muokkaamasi tiedostot ja kansiot näkyvät täällä.",
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
"An unknown error has occurred" : "Tapahtui tuntematon virhe",
|
||||
"File could not be uploaded" : "Tiedostoa ei voi lähettää",
|
||||
"Uploading …" : "Lähetetään…",
|
||||
"Uploading … ({currentNumber}/{total})" : "Lähetetään… ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize}/{totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "Kyseisen kohteen lähettäminen ei ole tuettu",
|
||||
"Target folder does not exist any more" : "Kohdekansiota ei ole enää olemassa",
|
||||
|
|
@ -242,6 +243,7 @@
|
|||
"No favorites yet" : "Ei vielä suosikkeja",
|
||||
"Files and folders you mark as favorite will show up here" : "Suosikeiksi merkitsemäsi tiedostot ja kansiot näkyvät täällä",
|
||||
"All files" : "Kaikki tiedostot",
|
||||
"List of your files and folders." : "Luettelo tiedostoistasi ja kansioistasi.",
|
||||
"List of recently modified files and folders." : "Luettelo äskettäin muokatuista tiedostoista ja kansioista.",
|
||||
"No recently modified files" : "Ei äskettäin muokattuja tiedostoja",
|
||||
"Files and folders you recently modified will show up here." : "Äskettäin muokkaamasi tiedostot ja kansiot näkyvät täällä.",
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ OC.L10N.register(
|
|||
"An unknown error has occurred" : "Une erreur inconnue est survenue",
|
||||
"File could not be uploaded" : "Le fichier n'a pas pu être téléversé",
|
||||
"Uploading …" : "Envoi en cours...",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "Téléversement en cours… ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} sur {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "L'envoi de cet élément n'est pas supporté",
|
||||
"Target folder does not exist any more" : "Le dossier cible n'existe plus",
|
||||
|
|
@ -32,6 +34,7 @@ OC.L10N.register(
|
|||
"Move" : "Déplacer",
|
||||
"Copy" : "Copier",
|
||||
"Choose target folder" : "Sélectionner le dossier cible",
|
||||
"Set reminder" : "Définir un rappel",
|
||||
"Edit locally" : "Éditer localement",
|
||||
"Open" : "Ouvrir",
|
||||
"Delete file" : "Supprimer le fichier",
|
||||
|
|
@ -241,6 +244,7 @@ OC.L10N.register(
|
|||
"Unable to create new file from template" : "Impossible de créer un nouveau fichier à partir du modèle",
|
||||
"Delete permanently" : "Supprimer définitivement",
|
||||
"Open folder {displayName}" : "Ouvrir le dossier {displayName}",
|
||||
"Open in Files" : "Ouvrir dans Fichiers",
|
||||
"Open details" : "Ouvrir les détails",
|
||||
"Set up templates folder" : "Configurer le dossier des modèles",
|
||||
"Templates" : "Modèles",
|
||||
|
|
@ -250,6 +254,10 @@ OC.L10N.register(
|
|||
"No favorites yet" : "Aucun favori pour l'instant",
|
||||
"Files and folders you mark as favorite will show up here" : "Les fichiers et dossiers ajoutés à vos favoris apparaîtront ici",
|
||||
"All files" : "Tous les fichiers",
|
||||
"List of your files and folders." : "Liste de vos fichiers et dossiers.",
|
||||
"List of recently modified files and folders." : "Liste des fichiers et dossiers récemment modifiés.",
|
||||
"No recently modified files" : "Pas de fichiers récemment modifiés",
|
||||
"Files and folders you recently modified will show up here." : "Les fichiers et dossiers que vous avez récemment modifiés apparaîtront ici.",
|
||||
"Toggle %1$s sublist" : "Basculer %1$s sous-liste",
|
||||
"No entries found in this folder" : "Aucune entrée trouvée dans ce dossier",
|
||||
"Upload too large" : "Données envoyées trop volumineuses",
|
||||
|
|
@ -275,7 +283,7 @@ OC.L10N.register(
|
|||
"Open folder {name}" : "Ouvrir le dossier {name}",
|
||||
"This list is not fully rendered for performances reasons. The files will be rendered as you navigate through the list." : "Cette liste n'est pas affichée en totalité pour des raisons de performances. Les fichiers seront affichés au fur et à mesure que vous parcourrez la liste.",
|
||||
"Search for an account" : "Chercher un compte",
|
||||
"Choose" : "Sélectionner",
|
||||
"Choose" : "Choisir",
|
||||
"No files or folders have been deleted yet" : "Aucun fichier ou dossier n'a encore été supprimé"
|
||||
},
|
||||
"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
"An unknown error has occurred" : "Une erreur inconnue est survenue",
|
||||
"File could not be uploaded" : "Le fichier n'a pas pu être téléversé",
|
||||
"Uploading …" : "Envoi en cours...",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "Téléversement en cours… ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} sur {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "L'envoi de cet élément n'est pas supporté",
|
||||
"Target folder does not exist any more" : "Le dossier cible n'existe plus",
|
||||
|
|
@ -30,6 +32,7 @@
|
|||
"Move" : "Déplacer",
|
||||
"Copy" : "Copier",
|
||||
"Choose target folder" : "Sélectionner le dossier cible",
|
||||
"Set reminder" : "Définir un rappel",
|
||||
"Edit locally" : "Éditer localement",
|
||||
"Open" : "Ouvrir",
|
||||
"Delete file" : "Supprimer le fichier",
|
||||
|
|
@ -239,6 +242,7 @@
|
|||
"Unable to create new file from template" : "Impossible de créer un nouveau fichier à partir du modèle",
|
||||
"Delete permanently" : "Supprimer définitivement",
|
||||
"Open folder {displayName}" : "Ouvrir le dossier {displayName}",
|
||||
"Open in Files" : "Ouvrir dans Fichiers",
|
||||
"Open details" : "Ouvrir les détails",
|
||||
"Set up templates folder" : "Configurer le dossier des modèles",
|
||||
"Templates" : "Modèles",
|
||||
|
|
@ -248,6 +252,10 @@
|
|||
"No favorites yet" : "Aucun favori pour l'instant",
|
||||
"Files and folders you mark as favorite will show up here" : "Les fichiers et dossiers ajoutés à vos favoris apparaîtront ici",
|
||||
"All files" : "Tous les fichiers",
|
||||
"List of your files and folders." : "Liste de vos fichiers et dossiers.",
|
||||
"List of recently modified files and folders." : "Liste des fichiers et dossiers récemment modifiés.",
|
||||
"No recently modified files" : "Pas de fichiers récemment modifiés",
|
||||
"Files and folders you recently modified will show up here." : "Les fichiers et dossiers que vous avez récemment modifiés apparaîtront ici.",
|
||||
"Toggle %1$s sublist" : "Basculer %1$s sous-liste",
|
||||
"No entries found in this folder" : "Aucune entrée trouvée dans ce dossier",
|
||||
"Upload too large" : "Données envoyées trop volumineuses",
|
||||
|
|
@ -273,7 +281,7 @@
|
|||
"Open folder {name}" : "Ouvrir le dossier {name}",
|
||||
"This list is not fully rendered for performances reasons. The files will be rendered as you navigate through the list." : "Cette liste n'est pas affichée en totalité pour des raisons de performances. Les fichiers seront affichés au fur et à mesure que vous parcourrez la liste.",
|
||||
"Search for an account" : "Chercher un compte",
|
||||
"Choose" : "Sélectionner",
|
||||
"Choose" : "Choisir",
|
||||
"No files or folders have been deleted yet" : "Aucun fichier ou dossier n'a encore été supprimé"
|
||||
},"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
|
||||
}
|
||||
|
|
@ -22,6 +22,8 @@ OC.L10N.register(
|
|||
"An unknown error has occurred" : "Produciuse un erro descoñecido",
|
||||
"File could not be uploaded" : "Non foi posíbel enviar o ficheiro",
|
||||
"Uploading …" : "Enviando…",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "Enviando… ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} de {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "Non se admite o envío deste elemento",
|
||||
"Target folder does not exist any more" : "O cartafol de destino xa non existe",
|
||||
|
|
@ -280,7 +282,7 @@ OC.L10N.register(
|
|||
"Deleted shares" : "Comparticións eliminadas",
|
||||
"Pending shares" : "Comparticións pendentes",
|
||||
"Open folder {name}" : "Abrir o cartafol {name}",
|
||||
"This list is not fully rendered for performances reasons. The files will be rendered as you navigate through the list." : "Esta lista non se representa de xeito completo por mor do rendemento. Os ficheiros represéntanse mentres navega pola lista.",
|
||||
"This list is not fully rendered for performances reasons. The files will be rendered as you navigate through the list." : "Esta lista non se representa de xeito completo por mor do rendemento. Os ficheiros represéntanse se despraza pola lista.",
|
||||
"Search for an account" : "Buscar por unha conta",
|
||||
"Choose" : "Escoller",
|
||||
"No files or folders have been deleted yet" : "Aínda non se eliminou ningún ficheiro nin cartafol"
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
"An unknown error has occurred" : "Produciuse un erro descoñecido",
|
||||
"File could not be uploaded" : "Non foi posíbel enviar o ficheiro",
|
||||
"Uploading …" : "Enviando…",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "Enviando… ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} de {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "Non se admite o envío deste elemento",
|
||||
"Target folder does not exist any more" : "O cartafol de destino xa non existe",
|
||||
|
|
@ -278,7 +280,7 @@
|
|||
"Deleted shares" : "Comparticións eliminadas",
|
||||
"Pending shares" : "Comparticións pendentes",
|
||||
"Open folder {name}" : "Abrir o cartafol {name}",
|
||||
"This list is not fully rendered for performances reasons. The files will be rendered as you navigate through the list." : "Esta lista non se representa de xeito completo por mor do rendemento. Os ficheiros represéntanse mentres navega pola lista.",
|
||||
"This list is not fully rendered for performances reasons. The files will be rendered as you navigate through the list." : "Esta lista non se representa de xeito completo por mor do rendemento. Os ficheiros represéntanse se despraza pola lista.",
|
||||
"Search for an account" : "Buscar por unha conta",
|
||||
"Choose" : "Escoller",
|
||||
"No files or folders have been deleted yet" : "Aínda non se eliminou ningún ficheiro nin cartafol"
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ OC.L10N.register(
|
|||
"An unknown error has occurred" : "Um erro desconhecido ocorreu",
|
||||
"File could not be uploaded" : "Não foi possível enviar o arquivo",
|
||||
"Uploading …" : "Enviando...",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "Enviando … ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} de {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "O envio deste item não é suportado",
|
||||
"Target folder does not exist any more" : "Pasta destino não existe mais",
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
"An unknown error has occurred" : "Um erro desconhecido ocorreu",
|
||||
"File could not be uploaded" : "Não foi possível enviar o arquivo",
|
||||
"Uploading …" : "Enviando...",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "Enviando … ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} de {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "O envio deste item não é suportado",
|
||||
"Target folder does not exist any more" : "Pasta destino não existe mais",
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ OC.L10N.register(
|
|||
"Shared with others" : "Sprístupnené ostatným",
|
||||
"Shared with you" : "Vám sprístupnené",
|
||||
"Shared by link" : "Sprístupnené prostredníctvom odkazu",
|
||||
"Deleted shares" : "Vymazané zdieľania",
|
||||
"Deleted shares" : "Zmazané sprístupnenia",
|
||||
"Pending shares" : "Čakajúce prístupy",
|
||||
"Choose" : "Vybrať"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@
|
|||
"Shared with others" : "Sprístupnené ostatným",
|
||||
"Shared with you" : "Vám sprístupnené",
|
||||
"Shared by link" : "Sprístupnené prostredníctvom odkazu",
|
||||
"Deleted shares" : "Vymazané zdieľania",
|
||||
"Deleted shares" : "Zmazané sprístupnenia",
|
||||
"Pending shares" : "Čakajúce prístupy",
|
||||
"Choose" : "Vybrať"
|
||||
},"pluralForm" :"nplurals=4; plural=(n % 1 == 0 && n == 1 ? 0 : n % 1 == 0 && n >= 2 && n <= 4 ? 1 : n % 1 != 0 ? 2: 3);"
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ OC.L10N.register(
|
|||
"An unknown error has occurred" : "Десила се непозната грешка",
|
||||
"File could not be uploaded" : "Фајл не може да се отпреми",
|
||||
"Uploading …" : "Отпремам…",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "Отпремање … ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} од {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "Отпремање те ставке није подржано",
|
||||
"Target folder does not exist any more" : "Одредишна фасцикла више не постоји",
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
"An unknown error has occurred" : "Десила се непозната грешка",
|
||||
"File could not be uploaded" : "Фајл не може да се отпреми",
|
||||
"Uploading …" : "Отпремам…",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "Отпремање … ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} од {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "Отпремање те ставке није подржано",
|
||||
"Target folder does not exist any more" : "Одредишна фасцикла више не постоји",
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ OC.L10N.register(
|
|||
"An unknown error has occurred" : "Ett okänt fel uppstod",
|
||||
"File could not be uploaded" : "Filen kunde inte laddas upp",
|
||||
"Uploading …" : "Laddar upp ..",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "Laddar upp … ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} av {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "Uppladdning av det här objektet stöds inte",
|
||||
"Target folder does not exist any more" : "Målmapp existerar inte längre",
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
"An unknown error has occurred" : "Ett okänt fel uppstod",
|
||||
"File could not be uploaded" : "Filen kunde inte laddas upp",
|
||||
"Uploading …" : "Laddar upp ..",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "Laddar upp … ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} av {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "Uppladdning av det här objektet stöds inte",
|
||||
"Target folder does not exist any more" : "Målmapp existerar inte längre",
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ OC.L10N.register(
|
|||
"An unknown error has occurred" : "Bilinmeyen bir sorun çıktı",
|
||||
"File could not be uploaded" : "Dosya yüklenemedi",
|
||||
"Uploading …" : "Yükleniyor …",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "Yükleniyor… ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} / {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "Bu ögenin yüklenmesi desteklenmiyor",
|
||||
"Target folder does not exist any more" : "Hedef klasör artık yok",
|
||||
|
|
@ -175,6 +177,7 @@ OC.L10N.register(
|
|||
"Rename file" : "Dosyayı yeniden adlandır",
|
||||
"File name" : "Dosya adı",
|
||||
"A long time ago" : "Uzun süre önce",
|
||||
"This node is unavailable" : "Bu düğüm kullanılamıyor",
|
||||
"Download file {name}" : "{name} dosyasını indir",
|
||||
"\"{displayName}\" action executed successfully" : "\"{displayName}\" işlemi tamamlandı",
|
||||
"\"{displayName}\" action failed" : "\"{displayName}\" işlemi tamamlanamadı",
|
||||
|
|
@ -194,7 +197,7 @@ OC.L10N.register(
|
|||
"Sort list by {column} ({direction})" : "Listeyi {column} sütununa göre sırala ({direction})",
|
||||
"Select all" : "Tümünü seç",
|
||||
"Unselect all" : "Tümünü bırak",
|
||||
"List of files and folders." : "Doys ave klasörleri listesi.",
|
||||
"List of files and folders." : "Dosya ve klasörlerin listesi.",
|
||||
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Başarımı olumsuz etkilememek için listenin tümü görüntülenmiyor. Listede ilerledikçe dosyalar görüntülenecek.",
|
||||
"File not found" : "Dosya bulunamadı",
|
||||
"Storage informations" : "Depolama bilgileri",
|
||||
|
|
@ -252,6 +255,7 @@ OC.L10N.register(
|
|||
"No favorites yet" : "Henüz sık kullanılan bir öge yok",
|
||||
"Files and folders you mark as favorite will show up here" : "Sık kullanılanlara eklediğiniz dosya ve klasörler burada görüntülenir",
|
||||
"All files" : "Tüm dosyalar",
|
||||
"List of your files and folders." : "Dosya ve klasörlerinizin listesi",
|
||||
"List of recently modified files and folders." : "Son değiştirilen dosya ve klasörlerin listesi.",
|
||||
"No recently modified files" : "Yakınlarda değiştirilmiş bir dosya yok",
|
||||
"Files and folders you recently modified will show up here." : "Son zamanlarda değiştirdiğiniz dosya ve klasörler burada görüntülenir.",
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
"An unknown error has occurred" : "Bilinmeyen bir sorun çıktı",
|
||||
"File could not be uploaded" : "Dosya yüklenemedi",
|
||||
"Uploading …" : "Yükleniyor …",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "Yükleniyor… ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} / {totalSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "Bu ögenin yüklenmesi desteklenmiyor",
|
||||
"Target folder does not exist any more" : "Hedef klasör artık yok",
|
||||
|
|
@ -173,6 +175,7 @@
|
|||
"Rename file" : "Dosyayı yeniden adlandır",
|
||||
"File name" : "Dosya adı",
|
||||
"A long time ago" : "Uzun süre önce",
|
||||
"This node is unavailable" : "Bu düğüm kullanılamıyor",
|
||||
"Download file {name}" : "{name} dosyasını indir",
|
||||
"\"{displayName}\" action executed successfully" : "\"{displayName}\" işlemi tamamlandı",
|
||||
"\"{displayName}\" action failed" : "\"{displayName}\" işlemi tamamlanamadı",
|
||||
|
|
@ -192,7 +195,7 @@
|
|||
"Sort list by {column} ({direction})" : "Listeyi {column} sütununa göre sırala ({direction})",
|
||||
"Select all" : "Tümünü seç",
|
||||
"Unselect all" : "Tümünü bırak",
|
||||
"List of files and folders." : "Doys ave klasörleri listesi.",
|
||||
"List of files and folders." : "Dosya ve klasörlerin listesi.",
|
||||
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Başarımı olumsuz etkilememek için listenin tümü görüntülenmiyor. Listede ilerledikçe dosyalar görüntülenecek.",
|
||||
"File not found" : "Dosya bulunamadı",
|
||||
"Storage informations" : "Depolama bilgileri",
|
||||
|
|
@ -250,6 +253,7 @@
|
|||
"No favorites yet" : "Henüz sık kullanılan bir öge yok",
|
||||
"Files and folders you mark as favorite will show up here" : "Sık kullanılanlara eklediğiniz dosya ve klasörler burada görüntülenir",
|
||||
"All files" : "Tüm dosyalar",
|
||||
"List of your files and folders." : "Dosya ve klasörlerinizin listesi",
|
||||
"List of recently modified files and folders." : "Son değiştirilen dosya ve klasörlerin listesi.",
|
||||
"No recently modified files" : "Yakınlarda değiştirilmiş bir dosya yok",
|
||||
"Files and folders you recently modified will show up here." : "Son zamanlarda değiştirdiğiniz dosya ve klasörler burada görüntülenir.",
|
||||
|
|
|
|||
|
|
@ -159,14 +159,14 @@ OC.L10N.register(
|
|||
"Upload (max. %s)" : "Завантаження (макс. %s)",
|
||||
"Accept" : "Прийняти",
|
||||
"Reject" : "Відхилити",
|
||||
"Incoming ownership transfer from {user}" : "Запит від користувача {user} на передачу прав власності",
|
||||
"Do you want to accept {path}?\n\nNote: The transfer process after accepting may take up to 1 hour." : "Прийняти {path}?\n\nУвага: процес передачі після прийняття може тривати до 1 години.",
|
||||
"Incoming ownership transfer from {user}" : "Запит від користувача {user} на передавання прав власника",
|
||||
"Do you want to accept {path}?\n\nNote: The transfer process after accepting may take up to 1 hour." : "Прийняти {path}?\n\nУвага: Процес передавання після прийняття запиту може тривати до 1 години.",
|
||||
"Ownership transfer failed" : "Не вдалося передати право власності",
|
||||
"Your ownership transfer of {path} to {user} failed." : "Передача вашого права власності на {path} користувачеві {user} не вдалася.",
|
||||
"The ownership transfer of {path} from {user} failed." : "Передача прав власника на {path} від користувача {user} не вдалася.",
|
||||
"Your ownership transfer of {path} to {user} failed." : "Не вдалося перадати ваші права власника на {path} користувачеві {user}.",
|
||||
"The ownership transfer of {path} from {user} failed." : "Не вдалося передати права власника на {path} від користувача {user}.",
|
||||
"Ownership transfer done" : "Право власності передано",
|
||||
"Your ownership transfer of {path} to {user} has completed." : "Передачу ваших прав власника на {path} користувачеві {user} виконано.",
|
||||
"The ownership transfer of {path} from {user} has completed." : "Передачу прав власника на {path} від користувача {user} завершено.",
|
||||
"Your ownership transfer of {path} to {user} has completed." : "Ваші права власника на {path} успішно передано користувачеві {user}.",
|
||||
"The ownership transfer of {path} from {user} has completed." : "Завершено передавання права власника на {path} від користувача {user}.",
|
||||
"in %s" : "в %s",
|
||||
"File Management" : "Керування файлами",
|
||||
"Reload current directory" : "Перевантажити поточний каталог",
|
||||
|
|
@ -201,16 +201,16 @@ OC.L10N.register(
|
|||
"{usedQuotaByte} used" : "{usedQuotaByte} використано",
|
||||
"{relative}% used" : "{relative}% використано",
|
||||
"Could not refresh storage stats" : "Неможливо оновити статистику сховища",
|
||||
"Transfer ownership of a file or folder" : "Передача прав власника на файл або каталог",
|
||||
"Choose file or folder to transfer" : "Виберіть файл або каталог для передачі",
|
||||
"Transfer ownership of a file or folder" : "Передавання прав власника на файл або каталог",
|
||||
"Choose file or folder to transfer" : "Виберіть файл або каталог для передавання",
|
||||
"Change" : "Змінити",
|
||||
"New owner" : "Новий власник",
|
||||
"Choose a file or folder to transfer" : "Виберіть файл або каталог для передачі",
|
||||
"Choose a file or folder to transfer" : "Виберіть файл або каталог для передавання",
|
||||
"Transfer" : "Передати",
|
||||
"Transfer {path} to {userid}" : "Передати {path} користувачеві {userid}",
|
||||
"Invalid path selected" : "Вибрано неправильний шлях",
|
||||
"Unknown error" : "Невідома помилка",
|
||||
"Ownership transfer request sent" : "Запит на передачу прав власності надіслано",
|
||||
"Ownership transfer request sent" : "Запит на передавання прав власника надіслано",
|
||||
"Cannot transfer ownership of a file or folder you do not own" : "Неможливо передати права власності на файл або каталог, якими ви не володієте",
|
||||
"Select file or folder to link to" : "Виберіть файл або каталог, до якого потрібно застосувати посилання",
|
||||
"Loading current folder" : "Завантаження поточного каталогу",
|
||||
|
|
|
|||
|
|
@ -157,14 +157,14 @@
|
|||
"Upload (max. %s)" : "Завантаження (макс. %s)",
|
||||
"Accept" : "Прийняти",
|
||||
"Reject" : "Відхилити",
|
||||
"Incoming ownership transfer from {user}" : "Запит від користувача {user} на передачу прав власності",
|
||||
"Do you want to accept {path}?\n\nNote: The transfer process after accepting may take up to 1 hour." : "Прийняти {path}?\n\nУвага: процес передачі після прийняття може тривати до 1 години.",
|
||||
"Incoming ownership transfer from {user}" : "Запит від користувача {user} на передавання прав власника",
|
||||
"Do you want to accept {path}?\n\nNote: The transfer process after accepting may take up to 1 hour." : "Прийняти {path}?\n\nУвага: Процес передавання після прийняття запиту може тривати до 1 години.",
|
||||
"Ownership transfer failed" : "Не вдалося передати право власності",
|
||||
"Your ownership transfer of {path} to {user} failed." : "Передача вашого права власності на {path} користувачеві {user} не вдалася.",
|
||||
"The ownership transfer of {path} from {user} failed." : "Передача прав власника на {path} від користувача {user} не вдалася.",
|
||||
"Your ownership transfer of {path} to {user} failed." : "Не вдалося перадати ваші права власника на {path} користувачеві {user}.",
|
||||
"The ownership transfer of {path} from {user} failed." : "Не вдалося передати права власника на {path} від користувача {user}.",
|
||||
"Ownership transfer done" : "Право власності передано",
|
||||
"Your ownership transfer of {path} to {user} has completed." : "Передачу ваших прав власника на {path} користувачеві {user} виконано.",
|
||||
"The ownership transfer of {path} from {user} has completed." : "Передачу прав власника на {path} від користувача {user} завершено.",
|
||||
"Your ownership transfer of {path} to {user} has completed." : "Ваші права власника на {path} успішно передано користувачеві {user}.",
|
||||
"The ownership transfer of {path} from {user} has completed." : "Завершено передавання права власника на {path} від користувача {user}.",
|
||||
"in %s" : "в %s",
|
||||
"File Management" : "Керування файлами",
|
||||
"Reload current directory" : "Перевантажити поточний каталог",
|
||||
|
|
@ -199,16 +199,16 @@
|
|||
"{usedQuotaByte} used" : "{usedQuotaByte} використано",
|
||||
"{relative}% used" : "{relative}% використано",
|
||||
"Could not refresh storage stats" : "Неможливо оновити статистику сховища",
|
||||
"Transfer ownership of a file or folder" : "Передача прав власника на файл або каталог",
|
||||
"Choose file or folder to transfer" : "Виберіть файл або каталог для передачі",
|
||||
"Transfer ownership of a file or folder" : "Передавання прав власника на файл або каталог",
|
||||
"Choose file or folder to transfer" : "Виберіть файл або каталог для передавання",
|
||||
"Change" : "Змінити",
|
||||
"New owner" : "Новий власник",
|
||||
"Choose a file or folder to transfer" : "Виберіть файл або каталог для передачі",
|
||||
"Choose a file or folder to transfer" : "Виберіть файл або каталог для передавання",
|
||||
"Transfer" : "Передати",
|
||||
"Transfer {path} to {userid}" : "Передати {path} користувачеві {userid}",
|
||||
"Invalid path selected" : "Вибрано неправильний шлях",
|
||||
"Unknown error" : "Невідома помилка",
|
||||
"Ownership transfer request sent" : "Запит на передачу прав власності надіслано",
|
||||
"Ownership transfer request sent" : "Запит на передавання прав власника надіслано",
|
||||
"Cannot transfer ownership of a file or folder you do not own" : "Неможливо передати права власності на файл або каталог, якими ви не володієте",
|
||||
"Select file or folder to link to" : "Виберіть файл або каталог, до якого потрібно застосувати посилання",
|
||||
"Loading current folder" : "Завантаження поточного каталогу",
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ OC.L10N.register(
|
|||
"An unknown error has occurred" : "發生了未知的錯誤",
|
||||
"File could not be uploaded" : "檔案無法上傳",
|
||||
"Uploading …" : "上傳中...",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "上傳中 ... ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{totalSize} 中的 {loadedSize}({bitrate})",
|
||||
"Uploading that item is not supported" : "不支援上傳該項目",
|
||||
"Target folder does not exist any more" : "目標資料夾已經不存在了",
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
"An unknown error has occurred" : "發生了未知的錯誤",
|
||||
"File could not be uploaded" : "檔案無法上傳",
|
||||
"Uploading …" : "上傳中...",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "上傳中 ... ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{totalSize} 中的 {loadedSize}({bitrate})",
|
||||
"Uploading that item is not supported" : "不支援上傳該項目",
|
||||
"Target folder does not exist any more" : "目標資料夾已經不存在了",
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ OC.L10N.register(
|
|||
"An unknown error has occurred" : "發生未知的錯誤",
|
||||
"File could not be uploaded" : "檔案無法上傳",
|
||||
"Uploading …" : "正在上傳……",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "正在上傳…… ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{totalSize} 中的 {loadedSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "不支援上傳該項目",
|
||||
"Target folder does not exist any more" : "目標資料夾已經不存在了",
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
"An unknown error has occurred" : "發生未知的錯誤",
|
||||
"File could not be uploaded" : "檔案無法上傳",
|
||||
"Uploading …" : "正在上傳……",
|
||||
"{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})",
|
||||
"Uploading … ({currentNumber}/{total})" : "正在上傳…… ({currentNumber}/{total})",
|
||||
"{loadedSize} of {totalSize} ({bitrate})" : "{totalSize} 中的 {loadedSize} ({bitrate})",
|
||||
"Uploading that item is not supported" : "不支援上傳該項目",
|
||||
"Target folder does not exist any more" : "目標資料夾已經不存在了",
|
||||
|
|
|
|||
|
|
@ -22,12 +22,12 @@
|
|||
"schemas": {
|
||||
"Capabilities": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"files"
|
||||
],
|
||||
"properties": {
|
||||
"files": {
|
||||
"type": [
|
||||
"object",
|
||||
"object"
|
||||
],
|
||||
"type": "object",
|
||||
"required": [
|
||||
"bigfilechunking",
|
||||
"blacklisted_files",
|
||||
|
|
|
|||
|
|
@ -21,22 +21,20 @@
|
|||
*/
|
||||
import { action } from './deleteAction'
|
||||
import { expect } from '@jest/globals'
|
||||
import { File, Folder, Permission } from '@nextcloud/files'
|
||||
import { FileAction } from '../services/FileAction'
|
||||
import { File, Folder, Permission, View, FileAction } from '@nextcloud/files'
|
||||
import * as eventBus from '@nextcloud/event-bus'
|
||||
import axios from '@nextcloud/axios'
|
||||
import logger from '../logger'
|
||||
import type { Navigation } from '../services/Navigation'
|
||||
|
||||
const view = {
|
||||
id: 'files',
|
||||
name: 'Files',
|
||||
} as Navigation
|
||||
} as View
|
||||
|
||||
const trashbinView = {
|
||||
id: 'trashbin',
|
||||
name: 'Trashbin',
|
||||
} as Navigation
|
||||
} as View
|
||||
|
||||
describe('Delete action conditions tests', () => {
|
||||
test('Default values', () => {
|
||||
|
|
|
|||
|
|
@ -20,18 +20,16 @@
|
|||
*
|
||||
*/
|
||||
import { emit } from '@nextcloud/event-bus'
|
||||
import { Permission, Node } from '@nextcloud/files'
|
||||
import { Permission, Node, View, registerFileAction, FileAction } from '@nextcloud/files'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import axios from '@nextcloud/axios'
|
||||
import TrashCanSvg from '@mdi/svg/svg/trash-can.svg?raw'
|
||||
|
||||
import { registerFileAction, FileAction } from '../services/FileAction'
|
||||
import logger from '../logger.js'
|
||||
import type { Navigation } from '../services/Navigation'
|
||||
|
||||
export const action = new FileAction({
|
||||
id: 'delete',
|
||||
displayName(nodes: Node[], view: Navigation) {
|
||||
displayName(nodes: Node[], view: View) {
|
||||
return view.id === 'trashbin'
|
||||
? t('files_trashbin', 'Delete permanently')
|
||||
: t('files', 'Delete')
|
||||
|
|
@ -58,7 +56,7 @@ export const action = new FileAction({
|
|||
return false
|
||||
}
|
||||
},
|
||||
async execBatch(nodes: Node[], view: Navigation, dir: string) {
|
||||
async execBatch(nodes: Node[], view: View, dir: string) {
|
||||
return Promise.all(nodes.map(node => this.exec(node, view, dir)))
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -21,17 +21,12 @@
|
|||
*/
|
||||
import { action } from './downloadAction'
|
||||
import { expect } from '@jest/globals'
|
||||
import { File, Folder, Permission } from '@nextcloud/files'
|
||||
import { FileAction } from '../services/FileAction'
|
||||
import * as eventBus from '@nextcloud/event-bus'
|
||||
import axios from '@nextcloud/axios'
|
||||
import type { Navigation } from '../services/Navigation'
|
||||
import logger from '../logger'
|
||||
import { File, Folder, Permission, View, FileAction } from '@nextcloud/files'
|
||||
|
||||
const view = {
|
||||
id: 'files',
|
||||
name: 'Files',
|
||||
} as Navigation
|
||||
} as View
|
||||
|
||||
describe('Download action conditions tests', () => {
|
||||
test('Default values', () => {
|
||||
|
|
|
|||
|
|
@ -19,14 +19,11 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import { Permission, Node, FileType } from '@nextcloud/files'
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
import { registerFileAction, FileAction, Permission, Node, FileType, View } from '@nextcloud/files'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import ArrowDownSvg from '@mdi/svg/svg/arrow-down.svg?raw'
|
||||
|
||||
import { registerFileAction, FileAction, DefaultType } from '../services/FileAction'
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
import type { Navigation } from '../services/Navigation'
|
||||
|
||||
const triggerDownload = function(url: string) {
|
||||
const hiddenElement = document.createElement('a')
|
||||
hiddenElement.download = ''
|
||||
|
|
@ -55,7 +52,7 @@ export const action = new FileAction({
|
|||
.every(permission => (permission & Permission.READ) !== 0)
|
||||
},
|
||||
|
||||
async exec(node: Node, view: Navigation, dir: string) {
|
||||
async exec(node: Node, view: View, dir: string) {
|
||||
if (node.type === FileType.Folder) {
|
||||
downloadNodes(dir, [node])
|
||||
return null
|
||||
|
|
@ -65,7 +62,7 @@ export const action = new FileAction({
|
|||
return null
|
||||
},
|
||||
|
||||
async execBatch(nodes: Node[], view: Navigation, dir: string) {
|
||||
async execBatch(nodes: Node[], view: View, dir: string) {
|
||||
if (nodes.length === 1) {
|
||||
this.exec(nodes[0], view, dir)
|
||||
return [null]
|
||||
|
|
|
|||
|
|
@ -21,16 +21,14 @@
|
|||
*/
|
||||
import { action } from './editLocallyAction'
|
||||
import { expect } from '@jest/globals'
|
||||
import { File, Permission } from '@nextcloud/files'
|
||||
import { DefaultType, FileAction } from '../services/FileAction'
|
||||
import { File, Permission, View, FileAction } from '@nextcloud/files'
|
||||
import * as ncDialogs from '@nextcloud/dialogs'
|
||||
import axios from '@nextcloud/axios'
|
||||
import type { Navigation } from '../services/Navigation'
|
||||
|
||||
const view = {
|
||||
id: 'files',
|
||||
name: 'Files',
|
||||
} as Navigation
|
||||
} as View
|
||||
|
||||
describe('Edit locally action conditions tests', () => {
|
||||
test('Default values', () => {
|
||||
|
|
|
|||
|
|
@ -20,15 +20,14 @@
|
|||
*
|
||||
*/
|
||||
import { encodePath } from '@nextcloud/paths'
|
||||
import { Permission, type Node } from '@nextcloud/files'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import axios from '@nextcloud/axios'
|
||||
import LaptopSvg from '@mdi/svg/svg/laptop.svg?raw'
|
||||
|
||||
import { generateOcsUrl } from '@nextcloud/router'
|
||||
import { getCurrentUser } from '@nextcloud/auth'
|
||||
import { registerFileAction, FileAction, DefaultType } from '../services/FileAction'
|
||||
import { registerFileAction, FileAction, Permission, type Node } from '@nextcloud/files'
|
||||
import { showError } from '@nextcloud/dialogs'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import axios from '@nextcloud/axios'
|
||||
|
||||
import LaptopSvg from '@mdi/svg/svg/laptop.svg?raw'
|
||||
|
||||
const openLocalClient = async function(path: string) {
|
||||
const link = generateOcsUrl('apps/files/api/v1') + '/openlocaleditor?format=json'
|
||||
|
|
|
|||
|
|
@ -19,25 +19,23 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import * as favoriteAction from './favoriteAction'
|
||||
import { action } from './favoriteAction'
|
||||
import { expect } from '@jest/globals'
|
||||
import { File, Permission } from '@nextcloud/files'
|
||||
import { FileAction } from '../services/FileAction'
|
||||
import { File, Permission, View, FileAction } from '@nextcloud/files'
|
||||
import * as eventBus from '@nextcloud/event-bus'
|
||||
import * as favoriteAction from './favoriteAction'
|
||||
import axios from '@nextcloud/axios'
|
||||
import type { Navigation } from '../services/Navigation'
|
||||
import logger from '../logger'
|
||||
|
||||
const view = {
|
||||
id: 'files',
|
||||
name: 'Files',
|
||||
} as Navigation
|
||||
} as View
|
||||
|
||||
const favoriteView = {
|
||||
id: 'favorites',
|
||||
name: 'Favorites',
|
||||
} as Navigation
|
||||
} as View
|
||||
|
||||
global.window.OC = {
|
||||
TAG_FAVORITE: '_$!<Favorite>!$_',
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
*/
|
||||
import { emit } from '@nextcloud/event-bus'
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
import { Permission, type Node } from '@nextcloud/files'
|
||||
import { Permission, type Node, View, registerFileAction, FileAction } from '@nextcloud/files'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import axios from '@nextcloud/axios'
|
||||
import Vue from 'vue'
|
||||
|
|
@ -29,16 +29,14 @@ import Vue from 'vue'
|
|||
import StarOutlineSvg from '@mdi/svg/svg/star-outline.svg?raw'
|
||||
import StarSvg from '@mdi/svg/svg/star.svg?raw'
|
||||
|
||||
import { registerFileAction, FileAction } from '../services/FileAction'
|
||||
import logger from '../logger.js'
|
||||
import type { Navigation } from '../services/Navigation'
|
||||
|
||||
// If any of the nodes is not favorited, we display the favorite action.
|
||||
const shouldFavorite = (nodes: Node[]): boolean => {
|
||||
return nodes.some(node => node.attributes.favorite !== 1)
|
||||
}
|
||||
|
||||
export const favoriteNode = async (node: Node, view: Navigation, willFavorite: boolean): Promise<boolean> => {
|
||||
export const favoriteNode = async (node: Node, view: View, willFavorite: boolean): Promise<boolean> => {
|
||||
try {
|
||||
// TODO: migrate to webdav tags plugin
|
||||
const url = generateUrl('/apps/files/api/v1/files') + node.path
|
||||
|
|
@ -92,11 +90,11 @@ export const action = new FileAction({
|
|||
&& nodes.every(node => node.permissions !== Permission.NONE)
|
||||
},
|
||||
|
||||
async exec(node: Node, view: Navigation) {
|
||||
async exec(node: Node, view: View) {
|
||||
const willFavorite = shouldFavorite([node])
|
||||
return await favoriteNode(node, view, willFavorite)
|
||||
},
|
||||
async execBatch(nodes: Node[], view: Navigation) {
|
||||
async execBatch(nodes: Node[], view: View) {
|
||||
const willFavorite = shouldFavorite(nodes)
|
||||
return Promise.all(nodes.map(async node => await favoriteNode(node, view, willFavorite)))
|
||||
},
|
||||
|
|
|
|||
|
|
@ -19,18 +19,15 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import type { Navigation } from '../services/Navigation'
|
||||
|
||||
import { expect } from '@jest/globals'
|
||||
import { File, Folder, Node, Permission } from '@nextcloud/files'
|
||||
import { File, Folder, Node, Permission, View, DefaultType, FileAction } from '@nextcloud/files'
|
||||
|
||||
import { action } from './openFolderAction'
|
||||
import { DefaultType, FileAction } from '../services/FileAction'
|
||||
|
||||
const view = {
|
||||
id: 'files',
|
||||
name: 'Files',
|
||||
} as Navigation
|
||||
} as View
|
||||
|
||||
describe('Open folder action conditions tests', () => {
|
||||
test('Default values', () => {
|
||||
|
|
|
|||
|
|
@ -19,14 +19,11 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import { Permission, Node, FileType } from '@nextcloud/files'
|
||||
import { join } from 'path'
|
||||
import { Permission, Node, FileType, View, registerFileAction, FileAction, DefaultType } from '@nextcloud/files'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import FolderSvg from '@mdi/svg/svg/folder.svg?raw'
|
||||
|
||||
import type { Navigation } from '../services/Navigation'
|
||||
import { join } from 'path'
|
||||
import { registerFileAction, FileAction, DefaultType } from '../services/FileAction'
|
||||
|
||||
export const action = new FileAction({
|
||||
id: 'open-folder',
|
||||
displayName(files: Node[]) {
|
||||
|
|
@ -52,7 +49,7 @@ export const action = new FileAction({
|
|||
&& (node.permissions & Permission.READ) !== 0
|
||||
},
|
||||
|
||||
async exec(node: Node, view: Navigation, dir: string) {
|
||||
async exec(node: Node, view: View, dir: string) {
|
||||
if (!node || node.type !== FileType.Folder) {
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,19 +21,17 @@
|
|||
*/
|
||||
import { action } from './openInFilesAction'
|
||||
import { expect } from '@jest/globals'
|
||||
import { File, Folder, Permission } from '@nextcloud/files'
|
||||
import { DefaultType, FileAction } from '../../../files/src/services/FileAction'
|
||||
import type { Navigation } from '../../../files/src/services/Navigation'
|
||||
import { File, Folder, Permission, View, DefaultType, FileAction } from '@nextcloud/files'
|
||||
|
||||
const view = {
|
||||
id: 'files',
|
||||
name: 'Files',
|
||||
} as Navigation
|
||||
} as View
|
||||
|
||||
const recentView = {
|
||||
id: 'recent',
|
||||
name: 'Recent',
|
||||
} as Navigation
|
||||
} as View
|
||||
|
||||
describe('Open in files action conditions tests', () => {
|
||||
test('Default values', () => {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
import { translate as t } from '@nextcloud/l10n'
|
||||
import { FileType, type Node } from '@nextcloud/files'
|
||||
|
||||
import { registerFileAction, FileAction, DefaultType } from '../../../files/src/services/FileAction'
|
||||
import { registerFileAction, FileAction, DefaultType } from '@nextcloud/files'
|
||||
|
||||
/**
|
||||
* TODO: Move away from a redirect and handle
|
||||
|
|
|
|||
|
|
@ -21,15 +21,13 @@
|
|||
*/
|
||||
import { action } from './renameAction'
|
||||
import { expect } from '@jest/globals'
|
||||
import { File, Permission } from '@nextcloud/files'
|
||||
import { FileAction } from '../services/FileAction'
|
||||
import { File, Permission, View, FileAction } from '@nextcloud/files'
|
||||
import * as eventBus from '@nextcloud/event-bus'
|
||||
import type { Navigation } from '../services/Navigation'
|
||||
|
||||
const view = {
|
||||
id: 'files',
|
||||
name: 'Files',
|
||||
} as Navigation
|
||||
} as View
|
||||
|
||||
describe('Rename action conditions tests', () => {
|
||||
test('Default values', () => {
|
||||
|
|
|
|||
|
|
@ -19,13 +19,11 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import { Permission, type Node } from '@nextcloud/files'
|
||||
import { emit } from '@nextcloud/event-bus'
|
||||
import { Permission, type Node, registerFileAction, FileAction } from '@nextcloud/files'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import PencilSvg from '@mdi/svg/svg/pencil.svg?raw'
|
||||
|
||||
import { emit } from '@nextcloud/event-bus'
|
||||
import { registerFileAction, FileAction } from '../services/FileAction'
|
||||
|
||||
export const ACTION_DETAILS = 'details'
|
||||
|
||||
export const action = new FileAction({
|
||||
|
|
|
|||
|
|
@ -19,19 +19,16 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import type { Navigation } from '../services/Navigation'
|
||||
|
||||
import { expect } from '@jest/globals'
|
||||
import { File, Permission } from '@nextcloud/files'
|
||||
import { File, Permission, View, FileAction } from '@nextcloud/files'
|
||||
|
||||
import { action } from './sidebarAction'
|
||||
import { FileAction } from '../services/FileAction'
|
||||
import logger from '../logger'
|
||||
|
||||
const view = {
|
||||
id: 'files',
|
||||
name: 'Files',
|
||||
} as Navigation
|
||||
} as View
|
||||
|
||||
describe('Open sidebar action conditions tests', () => {
|
||||
test('Default values', () => {
|
||||
|
|
|
|||
|
|
@ -19,13 +19,10 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import type { Navigation } from '../services/Navigation'
|
||||
|
||||
import { Permission, type Node } from '@nextcloud/files'
|
||||
import { Permission, type Node, View, registerFileAction, FileAction } from '@nextcloud/files'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import InformationSvg from '@mdi/svg/svg/information-variant.svg?raw'
|
||||
|
||||
import { registerFileAction, FileAction } from '../services/FileAction'
|
||||
import logger from '../logger.js'
|
||||
|
||||
export const ACTION_DETAILS = 'details'
|
||||
|
|
@ -54,7 +51,7 @@ export const action = new FileAction({
|
|||
return (nodes[0].root?.startsWith('/files/') && nodes[0].permissions !== Permission.NONE) ?? false
|
||||
},
|
||||
|
||||
async exec(node: Node, view: Navigation) {
|
||||
async exec(node: Node, view: View) {
|
||||
try {
|
||||
// TODO: migrate Sidebar to use a Node instead
|
||||
await window.OCA.Files.Sidebar.open(node.path)
|
||||
|
|
|
|||
|
|
@ -21,14 +21,12 @@
|
|||
*/
|
||||
import { action } from './viewInFolderAction'
|
||||
import { expect } from '@jest/globals'
|
||||
import { File, Folder, Node, Permission } from '@nextcloud/files'
|
||||
import { FileAction } from '../services/FileAction'
|
||||
import type { Navigation } from '../services/Navigation'
|
||||
import { File, Folder, Node, Permission, View, FileAction } from '@nextcloud/files'
|
||||
|
||||
const view = {
|
||||
id: 'files',
|
||||
name: 'Files',
|
||||
} as Navigation
|
||||
} as View
|
||||
|
||||
describe('View in folder action conditions tests', () => {
|
||||
test('Default values', () => {
|
||||
|
|
|
|||
|
|
@ -19,14 +19,10 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import { Node, FileType, Permission } from '@nextcloud/files'
|
||||
import { Node, FileType, Permission, View, registerFileAction, FileAction } from '@nextcloud/files'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import FolderMoveSvg from '@mdi/svg/svg/folder-move.svg?raw'
|
||||
|
||||
import type { Navigation } from '../services/Navigation'
|
||||
import { join } from 'path'
|
||||
import { registerFileAction, FileAction } from '../services/FileAction'
|
||||
|
||||
export const action = new FileAction({
|
||||
id: 'view-in-folder',
|
||||
displayName() {
|
||||
|
|
@ -53,7 +49,7 @@ export const action = new FileAction({
|
|||
return node.type === FileType.File
|
||||
},
|
||||
|
||||
async exec(node: Node, view: Navigation, dir: string) {
|
||||
async exec(node: Node, view: View, dir: string) {
|
||||
if (!node || node.type !== FileType.File) {
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,8 +170,8 @@ import { CancelablePromise } from 'cancelable-promise'
|
|||
import { debounce } from 'debounce'
|
||||
import { emit } from '@nextcloud/event-bus'
|
||||
import { extname } from 'path'
|
||||
import { formatFileSize, FileType, Permission } from '@nextcloud/files'
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
import { getFileActions, DefaultType, FileType, formatFileSize, Permission } from '@nextcloud/files'
|
||||
import { showError, showSuccess } from '@nextcloud/dialogs'
|
||||
import { translate } from '@nextcloud/l10n'
|
||||
import { vOnClickOutside } from '@vueuse/components'
|
||||
|
|
@ -187,7 +187,6 @@ import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js'
|
|||
import Vue from 'vue'
|
||||
|
||||
import { ACTION_DETAILS } from '../actions/sidebarAction.ts'
|
||||
import { getFileActions, DefaultType } from '../services/FileAction.ts'
|
||||
import { hashCode } from '../utils/hashUtils.ts'
|
||||
import { isCachedPreview } from '../services/PreviewService.ts'
|
||||
import { useActionsMenuStore } from '../store/actionsmenu.ts'
|
||||
|
|
|
|||
|
|
@ -57,9 +57,9 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue'
|
||||
import { formatFileSize } from '@nextcloud/files'
|
||||
import { translate } from '@nextcloud/l10n'
|
||||
import Vue from 'vue'
|
||||
|
||||
import { useFilesStore } from '../store/files.ts'
|
||||
import { usePathsStore } from '../store/paths.ts'
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
enabled() {
|
||||
console.debug('Enabled', this.header.id)
|
||||
return this.header.enabled(this.currentFolder, this.currentView)
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -49,8 +49,7 @@ import NcActions from '@nextcloud/vue/dist/Components/NcActions.js'
|
|||
import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'
|
||||
import Vue from 'vue'
|
||||
|
||||
import { getFileActions } from '../services/FileAction.ts'
|
||||
import { useActionsMenuStore } from '../store/actionsmenu.ts'
|
||||
import { getFileActions, useActionsMenuStore } from '../store/actionsmenu.ts'
|
||||
import { useFilesStore } from '../store/files.ts'
|
||||
import { useSelectionStore } from '../store/selection.ts'
|
||||
import filesListWidthMixin from '../mixins/filesListWidth.ts'
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { getFileActions } from '@nextcloud/files'
|
||||
import { showError, showSuccess } from '@nextcloud/dialogs'
|
||||
import { translate } from '@nextcloud/l10n'
|
||||
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
|
||||
|
|
@ -49,7 +50,6 @@ import NcActions from '@nextcloud/vue/dist/Components/NcActions.js'
|
|||
import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'
|
||||
import Vue from 'vue'
|
||||
|
||||
import { getFileActions } from '../services/FileAction.ts'
|
||||
import { useActionsMenuStore } from '../store/actionsmenu.ts'
|
||||
import { useFilesStore } from '../store/files.ts'
|
||||
import { useSelectionStore } from '../store/selection.ts'
|
||||
|
|
|
|||
|
|
@ -19,11 +19,12 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { debounce, throttle } from 'throttle-debounce'
|
||||
import { formatFileSize } from '@nextcloud/files'
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { showError } from '@nextcloud/dialogs'
|
||||
import { debounce, throttle } from 'throttle-debounce'
|
||||
import { subscribe } from '@nextcloud/event-bus'
|
||||
import { translate } from '@nextcloud/l10n'
|
||||
import axios from '@nextcloud/axios'
|
||||
import ChartPie from 'vue-material-design-icons/ChartPie.vue'
|
||||
|
|
@ -31,7 +32,6 @@ import NcAppNavigationItem from '@nextcloud/vue/dist/Components/NcAppNavigationI
|
|||
import NcProgressBar from '@nextcloud/vue/dist/Components/NcProgressBar.js'
|
||||
|
||||
import logger from '../logger.js'
|
||||
import { subscribe } from '@nextcloud/event-bus'
|
||||
|
||||
export default {
|
||||
name: 'NavigationQuota',
|
||||
|
|
|
|||
|
|
@ -71,7 +71,6 @@ import logger from '../logger.js'
|
|||
|
||||
const picker = getFilePickerBuilder(t('files', 'Choose a file or folder to transfer'))
|
||||
.setMultiSelect(false)
|
||||
.setModal(true)
|
||||
.setType(1)
|
||||
.allowDirectories()
|
||||
.build()
|
||||
|
|
|
|||
|
|
@ -32,8 +32,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { File, Folder } from '@nextcloud/files'
|
||||
import { debounce } from 'debounce'
|
||||
import { File, Folder, debounce } from 'debounce'
|
||||
import Vue from 'vue'
|
||||
import logger from '../logger.js'
|
||||
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ import './actions/viewInFolderAction'
|
|||
|
||||
import Vue from 'vue'
|
||||
import { createPinia, PiniaVuePlugin } from 'pinia'
|
||||
import { getNavigation } from '@nextcloud/files'
|
||||
|
||||
import FilesListView from './views/FilesList.vue'
|
||||
import { NavigationService } from './services/Navigation'
|
||||
import NavigationView from './views/Navigation.vue'
|
||||
import registerFavoritesView from './views/favorites'
|
||||
import registerRecentView from './views/recent'
|
||||
|
|
@ -47,8 +47,7 @@ Vue.use(PiniaVuePlugin)
|
|||
const pinia = createPinia()
|
||||
|
||||
// Init Navigation Service
|
||||
const Navigation = new NavigationService()
|
||||
Object.assign(window.OCP.Files, { Navigation })
|
||||
const Navigation = getNavigation()
|
||||
Vue.prototype.$navigation = Navigation
|
||||
|
||||
// Init Files App Settings Service
|
||||
|
|
|
|||
|
|
@ -23,14 +23,14 @@ import Vue from 'vue'
|
|||
|
||||
import { mapState } from 'pinia'
|
||||
import { useViewConfigStore } from '../store/viewConfig'
|
||||
import type { NavigationService, Navigation } from '../services/Navigation'
|
||||
import { Navigation, View } from '@nextcloud/files'
|
||||
|
||||
export default Vue.extend({
|
||||
computed: {
|
||||
...mapState(useViewConfigStore, ['getConfig', 'setSortingBy', 'toggleSortingDirection']),
|
||||
|
||||
currentView(): Navigation {
|
||||
return (this.$navigation as NavigationService).active as Navigation
|
||||
currentView(): View {
|
||||
return (this.$navigation as Navigation).active as View
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -19,13 +19,15 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import type { ContentsWithRoot } from '@nextcloud/files'
|
||||
import type { FileStat, ResponseDataDetailed, DAVResultResponseProps } from 'webdav'
|
||||
|
||||
import { File, Folder, davParsePermissions } from '@nextcloud/files'
|
||||
import { generateRemoteUrl } from '@nextcloud/router'
|
||||
import { getClient, rootPath } from './WebdavClient'
|
||||
import { getCurrentUser } from '@nextcloud/auth'
|
||||
|
||||
import { getClient, rootPath } from './WebdavClient'
|
||||
import { getDavNameSpaces, getDavProperties, getDefaultPropfind } from './DavProperties'
|
||||
import type { ContentsWithRoot } from './Navigation'
|
||||
import type { FileStat, ResponseDataDetailed, DAVResultResponseProps } from 'webdav'
|
||||
|
||||
const client = getClient()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,191 +0,0 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2023 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
import type { Node } from '@nextcloud/files'
|
||||
import logger from '../logger'
|
||||
import type { Navigation } from './Navigation'
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
OC: any;
|
||||
_nc_fileactions: FileAction[] | undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export enum DefaultType {
|
||||
DEFAULT = 'default',
|
||||
HIDDEN = 'hidden',
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: remove and move to @nextcloud/files
|
||||
* @see https://github.com/nextcloud/nextcloud-files/pull/608
|
||||
*/
|
||||
interface FileActionData {
|
||||
/** Unique ID */
|
||||
id: string
|
||||
/** Translatable string displayed in the menu */
|
||||
displayName: (files: Node[], view: Navigation) => string
|
||||
/** Svg as inline string. <svg><path fill="..." /></svg> */
|
||||
iconSvgInline: (files: Node[], view: Navigation) => string
|
||||
/** Condition wether this action is shown or not */
|
||||
enabled?: (files: Node[], view: Navigation) => boolean
|
||||
/**
|
||||
* Function executed on single file action
|
||||
* @returns true if the action was executed, false otherwise
|
||||
* @throws Error if the action failed
|
||||
*/
|
||||
exec: (file: Node, view: Navigation, dir: string) => Promise<boolean|null>,
|
||||
/**
|
||||
* Function executed on multiple files action
|
||||
* @returns true if the action was executed successfully,
|
||||
* false otherwise and null if the action is silent/undefined.
|
||||
* @throws Error if the action failed
|
||||
*/
|
||||
execBatch?: (files: Node[], view: Navigation, dir: string) => Promise<(boolean|null)[]>
|
||||
/** This action order in the list */
|
||||
order?: number,
|
||||
/** Make this action the default */
|
||||
default?: DefaultType,
|
||||
/**
|
||||
* If true, the renderInline function will be called
|
||||
*/
|
||||
inline?: (file: Node, view: Navigation) => boolean,
|
||||
/**
|
||||
* If defined, the returned html element will be
|
||||
* appended before the actions menu.
|
||||
*/
|
||||
renderInline?: (file: Node, view: Navigation) => Promise<HTMLElement | null>,
|
||||
}
|
||||
|
||||
export class FileAction {
|
||||
|
||||
private _action: FileActionData
|
||||
|
||||
constructor(action: FileActionData) {
|
||||
this.validateAction(action)
|
||||
this._action = action
|
||||
}
|
||||
|
||||
get id() {
|
||||
return this._action.id
|
||||
}
|
||||
|
||||
get displayName() {
|
||||
return this._action.displayName
|
||||
}
|
||||
|
||||
get iconSvgInline() {
|
||||
return this._action.iconSvgInline
|
||||
}
|
||||
|
||||
get enabled() {
|
||||
return this._action.enabled
|
||||
}
|
||||
|
||||
get exec() {
|
||||
return this._action.exec
|
||||
}
|
||||
|
||||
get execBatch() {
|
||||
return this._action.execBatch
|
||||
}
|
||||
|
||||
get order() {
|
||||
return this._action.order
|
||||
}
|
||||
|
||||
get default() {
|
||||
return this._action.default
|
||||
}
|
||||
|
||||
get inline() {
|
||||
return this._action.inline
|
||||
}
|
||||
|
||||
get renderInline() {
|
||||
return this._action.renderInline
|
||||
}
|
||||
|
||||
private validateAction(action: FileActionData) {
|
||||
if (!action.id || typeof action.id !== 'string') {
|
||||
throw new Error('Invalid id')
|
||||
}
|
||||
|
||||
if (!action.displayName || typeof action.displayName !== 'function') {
|
||||
throw new Error('Invalid displayName function')
|
||||
}
|
||||
|
||||
if (!action.iconSvgInline || typeof action.iconSvgInline !== 'function') {
|
||||
throw new Error('Invalid iconSvgInline function')
|
||||
}
|
||||
|
||||
if (!action.exec || typeof action.exec !== 'function') {
|
||||
throw new Error('Invalid exec function')
|
||||
}
|
||||
|
||||
// Optional properties --------------------------------------------
|
||||
if ('enabled' in action && typeof action.enabled !== 'function') {
|
||||
throw new Error('Invalid enabled function')
|
||||
}
|
||||
|
||||
if ('execBatch' in action && typeof action.execBatch !== 'function') {
|
||||
throw new Error('Invalid execBatch function')
|
||||
}
|
||||
|
||||
if ('order' in action && typeof action.order !== 'number') {
|
||||
throw new Error('Invalid order')
|
||||
}
|
||||
|
||||
if (action.default && !Object.values(DefaultType).includes(action.default)) {
|
||||
throw new Error('Invalid default')
|
||||
}
|
||||
|
||||
if ('inline' in action && typeof action.inline !== 'function') {
|
||||
throw new Error('Invalid inline function')
|
||||
}
|
||||
|
||||
if ('renderInline' in action && typeof action.renderInline !== 'function') {
|
||||
throw new Error('Invalid renderInline function')
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const registerFileAction = function(action: FileAction): void {
|
||||
if (typeof window._nc_fileactions === 'undefined') {
|
||||
window._nc_fileactions = []
|
||||
logger.debug('FileActions initialized')
|
||||
}
|
||||
|
||||
// Check duplicates
|
||||
if (window._nc_fileactions.find(search => search.id === action.id)) {
|
||||
logger.error(`FileAction ${action.id} already registered`, { action })
|
||||
return
|
||||
}
|
||||
|
||||
window._nc_fileactions.push(action)
|
||||
}
|
||||
|
||||
export const getFileActions = function(): FileAction[] {
|
||||
return window._nc_fileactions || []
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import type { ContentsWithRoot } from './Navigation'
|
||||
import type { ContentsWithRoot } from '@nextcloud/files'
|
||||
import type { FileStat, ResponseDataDetailed, DAVResultResponseProps } from 'webdav'
|
||||
|
||||
import { File, Folder, davParsePermissions } from '@nextcloud/files'
|
||||
|
|
|
|||
|
|
@ -1,241 +0,0 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2022 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/>.
|
||||
*
|
||||
*/
|
||||
/* eslint-disable no-use-before-define */
|
||||
import type { Folder, Node } from '@nextcloud/files'
|
||||
import isSvg from 'is-svg'
|
||||
|
||||
import logger from '../logger.js'
|
||||
|
||||
export type ContentsWithRoot = {
|
||||
folder: Folder,
|
||||
contents: Node[]
|
||||
}
|
||||
|
||||
export interface Column {
|
||||
/** Unique column ID */
|
||||
id: string
|
||||
/** Translated column title */
|
||||
title: string
|
||||
/** The content of the cell. The element will be appended within */
|
||||
render: (node: Node, view: Navigation) => HTMLElement
|
||||
/** Function used to sort Nodes between them */
|
||||
sort?: (nodeA: Node, nodeB: Node) => number
|
||||
/**
|
||||
* Custom summary of the column to display at the end of the list.
|
||||
* Will not be displayed if nothing is provided
|
||||
*/
|
||||
summary?: (node: Node[], view: Navigation) => string
|
||||
}
|
||||
|
||||
export interface Navigation {
|
||||
/** Unique view ID */
|
||||
id: string
|
||||
/** Translated view name */
|
||||
name: string
|
||||
/** Translated accessible description of the view */
|
||||
caption?: string
|
||||
|
||||
/** Translated title of the empty view */
|
||||
emptyTitle?: string
|
||||
/** Translated description of the empty view */
|
||||
emptyCaption?: string
|
||||
|
||||
/**
|
||||
* Method return the content of the provided path
|
||||
* This ideally should be a cancellable promise.
|
||||
* promise.cancel(reason) will be called when the directory
|
||||
* change and the promise is not resolved yet.
|
||||
* You _must_ also return the current directory
|
||||
* information alongside with its content.
|
||||
*/
|
||||
getContents: (path: string) => Promise<ContentsWithRoot>
|
||||
/** The view icon as an inline svg */
|
||||
icon: string
|
||||
/** The view order */
|
||||
order: number
|
||||
|
||||
/**
|
||||
* This view column(s). Name and actions are
|
||||
* by default always included
|
||||
*/
|
||||
columns?: Column[]
|
||||
/** The empty view element to render your empty content into */
|
||||
emptyView?: (div: HTMLDivElement) => void
|
||||
/** The parent unique ID */
|
||||
parent?: string
|
||||
/** This view is sticky (sent at the bottom) */
|
||||
sticky?: boolean
|
||||
|
||||
/**
|
||||
* This view has children and is expanded or not,
|
||||
* will be overridden by user config.
|
||||
*/
|
||||
expanded?: boolean
|
||||
|
||||
/**
|
||||
* Will be used as default if the user
|
||||
* haven't customized their sorting column
|
||||
*/
|
||||
defaultSortKey?: string
|
||||
}
|
||||
|
||||
export class NavigationService {
|
||||
|
||||
private _views: Navigation[] = []
|
||||
private _currentView: Navigation | null = null
|
||||
|
||||
constructor() {
|
||||
logger.debug('Navigation service initialized')
|
||||
}
|
||||
|
||||
register(view: Navigation) {
|
||||
try {
|
||||
isValidNavigation(view)
|
||||
isUniqueNavigation(view, this._views)
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
logger.error(e.message, { view })
|
||||
}
|
||||
throw e
|
||||
}
|
||||
|
||||
this._views.push(view)
|
||||
}
|
||||
|
||||
remove(id: string) {
|
||||
const index = this._views.findIndex(view => view.id === id)
|
||||
if (index !== -1) {
|
||||
this._views.splice(index, 1)
|
||||
}
|
||||
}
|
||||
|
||||
get views(): Navigation[] {
|
||||
return this._views
|
||||
}
|
||||
|
||||
setActive(view: Navigation | null) {
|
||||
this._currentView = view
|
||||
}
|
||||
|
||||
get active(): Navigation | null {
|
||||
return this._currentView
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure the given view is unique
|
||||
* and not already registered.
|
||||
*/
|
||||
const isUniqueNavigation = function(view: Navigation, views: Navigation[]): boolean {
|
||||
if (views.find(search => search.id === view.id)) {
|
||||
throw new Error(`Navigation id ${view.id} is already registered`)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Typescript cannot validate an interface.
|
||||
* Please keep in sync with the Navigation interface requirements.
|
||||
*/
|
||||
const isValidNavigation = function(view: Navigation): boolean {
|
||||
if (!view.id || typeof view.id !== 'string') {
|
||||
throw new Error('Navigation id is required and must be a string')
|
||||
}
|
||||
|
||||
if (!view.name || typeof view.name !== 'string') {
|
||||
throw new Error('Navigation name is required and must be a string')
|
||||
}
|
||||
|
||||
if (view.columns && view.columns.length > 0
|
||||
&& (!view.caption || typeof view.caption !== 'string')) {
|
||||
throw new Error('Navigation caption is required for top-level views and must be a string')
|
||||
}
|
||||
|
||||
if (!view.getContents || typeof view.getContents !== 'function') {
|
||||
throw new Error('Navigation getContents is required and must be a function')
|
||||
}
|
||||
|
||||
if (!view.icon || typeof view.icon !== 'string' || !isSvg(view.icon)) {
|
||||
throw new Error('Navigation icon is required and must be a valid svg string')
|
||||
}
|
||||
|
||||
if (!('order' in view) || typeof view.order !== 'number') {
|
||||
throw new Error('Navigation order is required and must be a number')
|
||||
}
|
||||
|
||||
// Optional properties
|
||||
if (view.columns) {
|
||||
view.columns.forEach(isValidColumn)
|
||||
}
|
||||
|
||||
if (view.emptyView && typeof view.emptyView !== 'function') {
|
||||
throw new Error('Navigation emptyView must be a function')
|
||||
}
|
||||
|
||||
if (view.parent && typeof view.parent !== 'string') {
|
||||
throw new Error('Navigation parent must be a string')
|
||||
}
|
||||
|
||||
if ('sticky' in view && typeof view.sticky !== 'boolean') {
|
||||
throw new Error('Navigation sticky must be a boolean')
|
||||
}
|
||||
|
||||
if ('expanded' in view && typeof view.expanded !== 'boolean') {
|
||||
throw new Error('Navigation expanded must be a boolean')
|
||||
}
|
||||
|
||||
if (view.defaultSortKey && typeof view.defaultSortKey !== 'string') {
|
||||
throw new Error('Navigation defaultSortKey must be a string')
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Typescript cannot validate an interface.
|
||||
* Please keep in sync with the Column interface requirements.
|
||||
*/
|
||||
const isValidColumn = function(column: Column): boolean {
|
||||
if (!column.id || typeof column.id !== 'string') {
|
||||
throw new Error('A column id is required')
|
||||
}
|
||||
|
||||
if (!column.title || typeof column.title !== 'string') {
|
||||
throw new Error('A column title is required')
|
||||
}
|
||||
|
||||
if (!column.render || typeof column.render !== 'function') {
|
||||
throw new Error('A render function is required')
|
||||
}
|
||||
|
||||
// Optional properties
|
||||
if (column.sort && typeof column.sort !== 'function') {
|
||||
throw new Error('Column sortFunction must be a function')
|
||||
}
|
||||
|
||||
if (column.summary && typeof column.summary !== 'function') {
|
||||
throw new Error('Column summary must be a function')
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
@ -19,13 +19,15 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import type { ContentsWithRoot } from '@nextcloud/files'
|
||||
import type { FileStat, ResponseDataDetailed, DAVResultResponseProps } from 'webdav'
|
||||
|
||||
import { File, Folder, Permission, davParsePermissions } from '@nextcloud/files'
|
||||
import { generateRemoteUrl } from '@nextcloud/router'
|
||||
import { getClient, rootPath } from './WebdavClient'
|
||||
import { getCurrentUser } from '@nextcloud/auth'
|
||||
|
||||
import { getClient, rootPath } from './WebdavClient'
|
||||
import { getDavNameSpaces, getDavProperties } from './DavProperties'
|
||||
import type { ContentsWithRoot } from './Navigation'
|
||||
import type { FileStat, ResponseDataDetailed, DAVResultResponseProps } from 'webdav'
|
||||
|
||||
const client = getClient(generateRemoteUrl('dav'))
|
||||
|
||||
|
|
|
|||
|
|
@ -64,11 +64,9 @@
|
|||
|
||||
<script lang="ts">
|
||||
import type { Route } from 'vue-router'
|
||||
import type { Navigation, ContentsWithRoot } from '../services/Navigation.ts'
|
||||
import type { UserConfig } from '../types.ts'
|
||||
|
||||
import { Folder, Node } from '@nextcloud/files'
|
||||
import { join } from 'path'
|
||||
import { Folder, Node, type View, type ContentsWithRoot, join } from 'path'
|
||||
import { orderBy } from 'natural-orderby'
|
||||
import { translate } from '@nextcloud/l10n'
|
||||
import NcAppContent from '@nextcloud/vue/dist/Components/NcAppContent.js'
|
||||
|
|
@ -132,9 +130,9 @@ export default Vue.extend({
|
|||
return this.userConfigStore.userConfig
|
||||
},
|
||||
|
||||
currentView(): Navigation {
|
||||
currentView(): View {
|
||||
return (this.$navigation.active
|
||||
|| this.$navigation.views.find(view => view.id === 'files')) as Navigation
|
||||
|| this.$navigation.views.find(view => view.id === 'files')) as View
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -2,13 +2,14 @@ import FolderSvg from '@mdi/svg/svg/folder.svg'
|
|||
import ShareSvg from '@mdi/svg/svg/share-variant.svg'
|
||||
import { createTestingPinia } from '@pinia/testing'
|
||||
|
||||
import { NavigationService } from '../services/Navigation'
|
||||
import NavigationView from './Navigation.vue'
|
||||
import router from '../router/router'
|
||||
import { useViewConfigStore } from '../store/viewConfig'
|
||||
import { Folder, View, getNavigation } from '@nextcloud/files'
|
||||
|
||||
describe('Navigation renders', () => {
|
||||
const Navigation = new NavigationService() as NavigationService
|
||||
delete window._nc_navigation
|
||||
const Navigation = getNavigation()
|
||||
|
||||
before(() => {
|
||||
cy.mockInitialState('files', 'storageStats', {
|
||||
|
|
@ -38,16 +39,17 @@ describe('Navigation renders', () => {
|
|||
})
|
||||
|
||||
describe('Navigation API', () => {
|
||||
const Navigation = new NavigationService() as NavigationService
|
||||
delete window._nc_navigation
|
||||
const Navigation = getNavigation()
|
||||
|
||||
it('Check API entries rendering', () => {
|
||||
Navigation.register({
|
||||
Navigation.register(new View({
|
||||
id: 'files',
|
||||
name: 'Files',
|
||||
getContents: () => Promise.resolve(),
|
||||
getContents: async () => ({ folder: {} as Folder, contents: [] }),
|
||||
icon: FolderSvg,
|
||||
order: 1,
|
||||
})
|
||||
}))
|
||||
|
||||
cy.mount(NavigationView, {
|
||||
propsData: {
|
||||
|
|
@ -68,13 +70,13 @@ describe('Navigation API', () => {
|
|||
})
|
||||
|
||||
it('Adds a new entry and render', () => {
|
||||
Navigation.register({
|
||||
Navigation.register(new View({
|
||||
id: 'sharing',
|
||||
name: 'Sharing',
|
||||
getContents: () => Promise.resolve(),
|
||||
getContents: async () => ({ folder: {} as Folder, contents: [] }),
|
||||
icon: ShareSvg,
|
||||
order: 2,
|
||||
})
|
||||
}))
|
||||
|
||||
cy.mount(NavigationView, {
|
||||
propsData: {
|
||||
|
|
@ -95,14 +97,14 @@ describe('Navigation API', () => {
|
|||
})
|
||||
|
||||
it('Adds a new children, render and open menu', () => {
|
||||
Navigation.register({
|
||||
Navigation.register(new View({
|
||||
id: 'sharingin',
|
||||
name: 'Shared with me',
|
||||
getContents: () => Promise.resolve(),
|
||||
getContents: async () => ({ folder: {} as Folder, contents: [] }),
|
||||
parent: 'sharing',
|
||||
icon: ShareSvg,
|
||||
order: 1,
|
||||
})
|
||||
}))
|
||||
|
||||
cy.mount(NavigationView, {
|
||||
propsData: {
|
||||
|
|
@ -142,19 +144,20 @@ describe('Navigation API', () => {
|
|||
|
||||
it('Throws when adding a duplicate entry', () => {
|
||||
expect(() => {
|
||||
Navigation.register({
|
||||
Navigation.register(new View({
|
||||
id: 'files',
|
||||
name: 'Files',
|
||||
getContents: () => Promise.resolve(),
|
||||
getContents: async () => ({ folder: {} as Folder, contents: [] }),
|
||||
icon: FolderSvg,
|
||||
order: 1,
|
||||
})
|
||||
}).to.throw('Navigation id files is already registered')
|
||||
}))
|
||||
}).to.throw('View id files is already registered')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Quota rendering', () => {
|
||||
const Navigation = new NavigationService()
|
||||
delete window._nc_navigation
|
||||
const Navigation = getNavigation()
|
||||
|
||||
afterEach(() => cy.unmockInitialState())
|
||||
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js
|
|||
import { setPageHeading } from '../../../../core/src/OCP/accessibility.js'
|
||||
import { useViewConfigStore } from '../store/viewConfig.ts'
|
||||
import logger from '../logger.js'
|
||||
import type { NavigationService, Navigation } from '../services/Navigation.ts'
|
||||
import type { Navigation, View } from '@nextcloud/files'
|
||||
import NavigationQuota from '../components/NavigationQuota.vue'
|
||||
import SettingsModal from './Settings.vue'
|
||||
|
||||
|
|
@ -125,15 +125,15 @@ export default {
|
|||
return this.$route?.params?.view || 'files'
|
||||
},
|
||||
|
||||
currentView(): Navigation {
|
||||
currentView(): View {
|
||||
return this.views.find(view => view.id === this.currentViewId)
|
||||
},
|
||||
|
||||
views(): Navigation[] {
|
||||
views(): View[] {
|
||||
return this.Navigation.views
|
||||
},
|
||||
|
||||
parentViews(): Navigation[] {
|
||||
parentViews(): View[] {
|
||||
return this.views
|
||||
// filter child views
|
||||
.filter(view => !view.parent)
|
||||
|
|
@ -143,7 +143,7 @@ export default {
|
|||
})
|
||||
},
|
||||
|
||||
childViews(): Navigation[] {
|
||||
childViews(): View[] {
|
||||
return this.views
|
||||
// filter parent views
|
||||
.filter(view => !!view.parent)
|
||||
|
|
@ -165,7 +165,7 @@ export default {
|
|||
this.Navigation.setActive(view)
|
||||
logger.debug('Navigation changed', { id: view.id, view })
|
||||
|
||||
this.showView(view, oldView)
|
||||
this.showView(view)
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
@ -178,7 +178,7 @@ export default {
|
|||
},
|
||||
|
||||
methods: {
|
||||
showView(view: Navigation) {
|
||||
showView(view: View) {
|
||||
// Closing any opened sidebar
|
||||
window?.OCA?.Files?.Sidebar?.close?.()
|
||||
this.Navigation.setActive(view)
|
||||
|
|
@ -190,7 +190,7 @@ export default {
|
|||
* Expand/collapse a a view with children and permanently
|
||||
* save this setting in the server.
|
||||
*/
|
||||
onToggleExpand(view: Navigation) {
|
||||
onToggleExpand(view: View) {
|
||||
// Invert state
|
||||
const isExpanded = this.isExpanded(view)
|
||||
// Update the view expanded state, might not be necessary
|
||||
|
|
@ -202,7 +202,7 @@ export default {
|
|||
* Check if a view is expanded by user config
|
||||
* or fallback to the default value.
|
||||
*/
|
||||
isExpanded(view: Navigation): boolean {
|
||||
isExpanded(view: View): boolean {
|
||||
return typeof this.viewConfigStore.getConfig(view.id)?.expanded === 'boolean'
|
||||
? this.viewConfigStore.getConfig(view.id).expanded === true
|
||||
: view.expanded === true
|
||||
|
|
@ -211,7 +211,7 @@ export default {
|
|||
/**
|
||||
* Generate the route to a view
|
||||
*/
|
||||
generateToNavigation(view: Navigation) {
|
||||
generateToNavigation(view: View) {
|
||||
if (view.params) {
|
||||
const { dir, fileid } = view.params
|
||||
return { name: 'filelist', params: view.params, query: { dir, fileid } }
|
||||
|
|
|
|||
|
|
@ -19,15 +19,14 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import { expect } from '@jest/globals'
|
||||
import * as initialState from '@nextcloud/initial-state'
|
||||
import { Folder } from '@nextcloud/files'
|
||||
import { basename } from 'path'
|
||||
import { expect } from '@jest/globals'
|
||||
import { Folder, Navigation, getNavigation } from '@nextcloud/files'
|
||||
import * as eventBus from '@nextcloud/event-bus'
|
||||
import * as initialState from '@nextcloud/initial-state'
|
||||
|
||||
import { action } from '../actions/favoriteAction'
|
||||
import * as favoritesService from '../services/Favorites'
|
||||
import { NavigationService } from '../services/Navigation'
|
||||
import registerFavoritesView from './favorites'
|
||||
|
||||
jest.mock('webdav/dist/node/request.js', () => ({
|
||||
|
|
@ -38,15 +37,21 @@ global.window.OC = {
|
|||
TAG_FAVORITE: '_$!<Favorite>!$_',
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
_nc_navigation?: Navigation
|
||||
}
|
||||
}
|
||||
|
||||
describe('Favorites view definition', () => {
|
||||
let Navigation
|
||||
beforeEach(() => {
|
||||
Navigation = new NavigationService()
|
||||
window.OCP = { Files: { Navigation } }
|
||||
Navigation = getNavigation()
|
||||
expect(window._nc_navigation).toBeDefined()
|
||||
})
|
||||
|
||||
afterAll(() => {
|
||||
delete window.OCP
|
||||
afterEach(() => {
|
||||
delete window._nc_navigation
|
||||
})
|
||||
|
||||
test('Default empty favorite view', () => {
|
||||
|
|
@ -114,12 +119,11 @@ describe('Favorites view definition', () => {
|
|||
describe('Dynamic update of favourite folders', () => {
|
||||
let Navigation
|
||||
beforeEach(() => {
|
||||
Navigation = new NavigationService()
|
||||
window.OCP = { Files: { Navigation } }
|
||||
Navigation = getNavigation()
|
||||
})
|
||||
|
||||
afterAll(() => {
|
||||
delete window.OCP
|
||||
afterEach(() => {
|
||||
delete window._nc_navigation
|
||||
})
|
||||
|
||||
test('Add a favorite folder creates a new entry in the navigation', async () => {
|
||||
|
|
|
|||
|
|
@ -19,21 +19,20 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import type { Navigation, NavigationService } from '../services/Navigation'
|
||||
import { basename } from 'path'
|
||||
import { getLanguage, translate as t } from '@nextcloud/l10n'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { Node, FileType, View, getNavigation } from '@nextcloud/files'
|
||||
import { subscribe } from '@nextcloud/event-bus'
|
||||
import FolderSvg from '@mdi/svg/svg/folder.svg?raw'
|
||||
import StarSvg from '@mdi/svg/svg/star.svg?raw'
|
||||
|
||||
import { basename } from 'path'
|
||||
import { getContents } from '../services/Favorites'
|
||||
import { hashCode } from '../utils/hashUtils'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { Node, FileType } from '@nextcloud/files'
|
||||
import { subscribe } from '@nextcloud/event-bus'
|
||||
import logger from '../logger'
|
||||
|
||||
export const generateFolderView = function(folder: string, index = 0): Navigation {
|
||||
return {
|
||||
export const generateFolderView = function(folder: string, index = 0): View {
|
||||
return new View({
|
||||
id: generateIdFromPath(folder),
|
||||
name: basename(folder),
|
||||
|
||||
|
|
@ -49,7 +48,7 @@ export const generateFolderView = function(folder: string, index = 0): Navigatio
|
|||
columns: [],
|
||||
|
||||
getContents,
|
||||
} as Navigation
|
||||
})
|
||||
}
|
||||
|
||||
export const generateIdFromPath = function(path: string): string {
|
||||
|
|
@ -59,10 +58,10 @@ export const generateIdFromPath = function(path: string): string {
|
|||
export default () => {
|
||||
// Load state in function for mock testing purposes
|
||||
const favoriteFolders = loadState<string[]>('files', 'favoriteFolders', [])
|
||||
const favoriteFoldersViews = favoriteFolders.map((folder, index) => generateFolderView(folder, index))
|
||||
const favoriteFoldersViews = favoriteFolders.map((folder, index) => generateFolderView(folder, index)) as View[]
|
||||
|
||||
const Navigation = window.OCP.Files.Navigation as NavigationService
|
||||
Navigation.register({
|
||||
const Navigation = getNavigation()
|
||||
Navigation.register(new View({
|
||||
id: 'favorites',
|
||||
name: t('files', 'Favorites'),
|
||||
caption: t('files', 'List of favorites files and folders.'),
|
||||
|
|
@ -76,7 +75,7 @@ export default () => {
|
|||
columns: [],
|
||||
|
||||
getContents,
|
||||
} as Navigation)
|
||||
}))
|
||||
|
||||
favoriteFoldersViews.forEach(view => Navigation.register(view))
|
||||
|
||||
|
|
|
|||
|
|
@ -19,16 +19,15 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import type { NavigationService, Navigation } from '../services/Navigation'
|
||||
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import FolderSvg from '@mdi/svg/svg/folder.svg?raw'
|
||||
|
||||
import { getContents } from '../services/Files'
|
||||
import { View, getNavigation } from '@nextcloud/files'
|
||||
|
||||
export default () => {
|
||||
const Navigation = window.OCP.Files.Navigation as NavigationService
|
||||
Navigation.register({
|
||||
const Navigation = getNavigation()
|
||||
Navigation.register(new View({
|
||||
id: 'files',
|
||||
name: t('files', 'All files'),
|
||||
caption: t('files', 'List of your files and folders.'),
|
||||
|
|
@ -37,5 +36,5 @@ export default () => {
|
|||
order: 0,
|
||||
|
||||
getContents,
|
||||
} as Navigation)
|
||||
}))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,16 +19,15 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import type { NavigationService, Navigation } from '../services/Navigation'
|
||||
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import HistorySvg from '@mdi/svg/svg/history.svg?raw'
|
||||
|
||||
import { getContents } from '../services/Recent'
|
||||
import { View, getNavigation } from '@nextcloud/files'
|
||||
|
||||
export default () => {
|
||||
const Navigation = window.OCP.Files.Navigation as NavigationService
|
||||
Navigation.register({
|
||||
const Navigation = getNavigation()
|
||||
Navigation.register(new View({
|
||||
id: 'recent',
|
||||
name: t('files', 'Recent'),
|
||||
caption: t('files', 'List of recently modified files and folders.'),
|
||||
|
|
@ -42,5 +41,5 @@ export default () => {
|
|||
defaultSortKey: 'mtime',
|
||||
|
||||
getContents,
|
||||
} as Navigation)
|
||||
}))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,21 +21,19 @@
|
|||
*/
|
||||
import { action } from './enterCredentialsAction'
|
||||
import { expect } from '@jest/globals'
|
||||
import { File, Folder, Permission } from '@nextcloud/files'
|
||||
import { DefaultType, FileAction } from '../../../files/src/services/FileAction'
|
||||
import type { Navigation } from '../../../files/src/services/Navigation'
|
||||
import { File, Folder, Permission, View, DefaultType, FileAction } from '@nextcloud/files'
|
||||
import type { StorageConfig } from '../services/externalStorage'
|
||||
import { STORAGE_STATUS } from '../utils/credentialsUtils'
|
||||
|
||||
const view = {
|
||||
id: 'files',
|
||||
name: 'Files',
|
||||
} as Navigation
|
||||
} as View
|
||||
|
||||
const externalStorageView = {
|
||||
id: 'extstoragemounts',
|
||||
name: 'External storage',
|
||||
} as Navigation
|
||||
} as View
|
||||
|
||||
describe('Enter credentials action conditions tests', () => {
|
||||
test('Default values', () => {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import axios from '@nextcloud/axios'
|
|||
import LoginSvg from '@mdi/svg/svg/login.svg?raw'
|
||||
import Vue from 'vue'
|
||||
|
||||
import { registerFileAction, FileAction, DefaultType } from '../../../files/src/services/FileAction'
|
||||
import { registerFileAction, FileAction, DefaultType } from '@nextcloud/files'
|
||||
import { STORAGE_STATUS, isMissingAuthConfig } from '../utils/credentialsUtils'
|
||||
import { isNodeExternalStorage } from '../utils/externalStorageUtils'
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ import '../css/fileEntryStatus.scss'
|
|||
import { getStatus, type StorageConfig } from '../services/externalStorage'
|
||||
import { isMissingAuthConfig, STORAGE_STATUS } from '../utils/credentialsUtils'
|
||||
import { isNodeExternalStorage } from '../utils/externalStorageUtils'
|
||||
import { registerFileAction, FileAction } from '../../../files/src/services/FileAction'
|
||||
import { registerFileAction, FileAction } from '@nextcloud/files'
|
||||
|
||||
export const action = new FileAction({
|
||||
id: 'check-external-storage',
|
||||
|
|
|
|||
|
|
@ -21,21 +21,19 @@
|
|||
*/
|
||||
import { action } from './openInFilesAction'
|
||||
import { expect } from '@jest/globals'
|
||||
import { File, Folder, Permission } from '@nextcloud/files'
|
||||
import { DefaultType, FileAction } from '../../../files/src/services/FileAction'
|
||||
import type { Navigation } from '../../../files/src/services/Navigation'
|
||||
import { Folder, Permission, View, DefaultType, FileAction } from '@nextcloud/files'
|
||||
import type { StorageConfig } from '../services/externalStorage'
|
||||
import { STORAGE_STATUS } from '../utils/credentialsUtils'
|
||||
|
||||
const view = {
|
||||
id: 'files',
|
||||
name: 'Files',
|
||||
} as Navigation
|
||||
} as View
|
||||
|
||||
const externalStorageView = {
|
||||
id: 'extstoragemounts',
|
||||
name: 'External storage',
|
||||
} as Navigation
|
||||
} as View
|
||||
|
||||
describe('Open in files action conditions tests', () => {
|
||||
test('Default values', () => {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import type { StorageConfig } from '../services/externalStorage'
|
|||
import { generateUrl } from '@nextcloud/router'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
|
||||
import { registerFileAction, FileAction, DefaultType } from '../../../files/src/services/FileAction'
|
||||
import { registerFileAction, FileAction, DefaultType } from '@nextcloud/files'
|
||||
import { STORAGE_STATUS } from '../utils/credentialsUtils'
|
||||
|
||||
export const action = new FileAction({
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import type { NavigationService, Navigation } from '../../files/src/services/Navigation'
|
||||
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import FolderNetworkSvg from '@mdi/svg/svg/folder-network.svg?raw'
|
||||
|
|
@ -29,11 +27,12 @@ import './actions/enterCredentialsAction'
|
|||
import './actions/inlineStorageCheckAction'
|
||||
import './actions/openInFilesAction'
|
||||
import { getContents } from './services/externalStorage'
|
||||
import { View, getNavigation, Column } from '@nextcloud/files'
|
||||
|
||||
const allowUserMounting = loadState('files_external', 'allowUserMounting', false)
|
||||
|
||||
const Navigation = window.OCP.Files.Navigation as NavigationService
|
||||
Navigation.register({
|
||||
const Navigation = getNavigation()
|
||||
Navigation.register(new View({
|
||||
id: 'extstoragemounts',
|
||||
name: t('files_external', 'External storage'),
|
||||
caption: t('files_external', 'List of external storage.'),
|
||||
|
|
@ -47,7 +46,7 @@ Navigation.register({
|
|||
order: 30,
|
||||
|
||||
columns: [
|
||||
{
|
||||
new Column({
|
||||
id: 'storage-type',
|
||||
title: t('files_external', 'Storage type'),
|
||||
render(node) {
|
||||
|
|
@ -56,8 +55,8 @@ Navigation.register({
|
|||
span.textContent = backend
|
||||
return span
|
||||
},
|
||||
},
|
||||
{
|
||||
}),
|
||||
new Column({
|
||||
id: 'scope',
|
||||
title: t('files_external', 'Scope'),
|
||||
render(node) {
|
||||
|
|
@ -69,8 +68,8 @@ Navigation.register({
|
|||
span.textContent = scope
|
||||
return span
|
||||
},
|
||||
},
|
||||
}),
|
||||
],
|
||||
|
||||
getContents,
|
||||
} as Navigation)
|
||||
}))
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@
|
|||
*/
|
||||
// eslint-disable-next-line n/no-extraneous-import
|
||||
import type { AxiosResponse } from 'axios'
|
||||
import type { ContentsWithRoot } from '../../../files/src/services/Navigation'
|
||||
import type { OCSResponse } from '../../../files_sharing/src/services/SharingService'
|
||||
import type { ContentsWithRoot } from '@nextcloud/files'
|
||||
|
||||
import { Folder, Permission } from '@nextcloud/files'
|
||||
import { generateOcsUrl, generateRemoteUrl, generateUrl } from '@nextcloud/router'
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import { expect } from '@jest/globals'
|
||||
import { File, Folder, Permission } from '@nextcloud/files'
|
||||
import { isNodeExternalStorage } from './externalStorageUtils'
|
||||
import { expect } from '@jest/globals'
|
||||
|
||||
describe('Is node an external storage', () => {
|
||||
test('A Folder with a backend and a valid scope is an external storage', () => {
|
||||
|
|
|
|||
29
apps/files_reminders/l10n/es.js
Normal file
29
apps/files_reminders/l10n/es.js
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
OC.L10N.register(
|
||||
"files_reminders",
|
||||
{
|
||||
"File reminders" : "Recordatorios de archivo",
|
||||
"Reminder for {name}" : "Recordatorio para {name}",
|
||||
"View file" : "Ver archivo",
|
||||
"View folder" : "Ver carpeta",
|
||||
"Set file reminders" : "Establecer recordatorios de archivo",
|
||||
"**📣 File reminders**\n\nSet file reminders." : "**📣 Recordatorios de archivo**\n\nEstablecer recordatorios de archivo.",
|
||||
"Back" : "Volver",
|
||||
"Clear reminder" : "Borrar recordatorio",
|
||||
"Set custom reminder" : "Configurar recordatorio personalizado",
|
||||
"Later today" : "Más tarde hoy",
|
||||
"Set reminder for later today" : "Configurar recordatorio para hoy, más tarde",
|
||||
"Tomorrow" : "Mañana",
|
||||
"Set reminder for tomorrow" : "Configurar recordatorio para mañana",
|
||||
"This weekend" : "Este fin de semana",
|
||||
"Set reminder for this weekend" : "Configurar recordatorio para este fin de semana",
|
||||
"Next week" : "Semana siguiente",
|
||||
"Set reminder for next week" : "Configurar recordatorio para la semana que viene",
|
||||
"Set reminder at custom date & time" : "Establecer recordatorio a una fecha y hora personalizada",
|
||||
"Reminder set for \"{fileName}\"" : "Se estableció recordatorio para \"{fileName}\"",
|
||||
"Failed to set reminder" : "No se pudo configurar el recordatorio",
|
||||
"Please choose a valid date & time" : "Por favor, escoja una fecha y hora válidas",
|
||||
"Reminder cleared" : "Se quitó el recordatorio",
|
||||
"Failed to clear reminder" : "Fallo al quitar el recordatorio",
|
||||
"Failed to load reminder" : "Fallo al cargar el recordatorio"
|
||||
},
|
||||
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
|
||||
27
apps/files_reminders/l10n/es.json
Normal file
27
apps/files_reminders/l10n/es.json
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
{ "translations": {
|
||||
"File reminders" : "Recordatorios de archivo",
|
||||
"Reminder for {name}" : "Recordatorio para {name}",
|
||||
"View file" : "Ver archivo",
|
||||
"View folder" : "Ver carpeta",
|
||||
"Set file reminders" : "Establecer recordatorios de archivo",
|
||||
"**📣 File reminders**\n\nSet file reminders." : "**📣 Recordatorios de archivo**\n\nEstablecer recordatorios de archivo.",
|
||||
"Back" : "Volver",
|
||||
"Clear reminder" : "Borrar recordatorio",
|
||||
"Set custom reminder" : "Configurar recordatorio personalizado",
|
||||
"Later today" : "Más tarde hoy",
|
||||
"Set reminder for later today" : "Configurar recordatorio para hoy, más tarde",
|
||||
"Tomorrow" : "Mañana",
|
||||
"Set reminder for tomorrow" : "Configurar recordatorio para mañana",
|
||||
"This weekend" : "Este fin de semana",
|
||||
"Set reminder for this weekend" : "Configurar recordatorio para este fin de semana",
|
||||
"Next week" : "Semana siguiente",
|
||||
"Set reminder for next week" : "Configurar recordatorio para la semana que viene",
|
||||
"Set reminder at custom date & time" : "Establecer recordatorio a una fecha y hora personalizada",
|
||||
"Reminder set for \"{fileName}\"" : "Se estableció recordatorio para \"{fileName}\"",
|
||||
"Failed to set reminder" : "No se pudo configurar el recordatorio",
|
||||
"Please choose a valid date & time" : "Por favor, escoja una fecha y hora válidas",
|
||||
"Reminder cleared" : "Se quitó el recordatorio",
|
||||
"Failed to clear reminder" : "Fallo al quitar el recordatorio",
|
||||
"Failed to load reminder" : "Fallo al cargar el recordatorio"
|
||||
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
|
||||
}
|
||||
|
|
@ -210,6 +210,7 @@ OC.L10N.register(
|
|||
"Expires {relativetime}" : "Läuft {relativetime} ab",
|
||||
"this share just expired." : "Diese Freigabe ist gerade abgelaufen.",
|
||||
"Shared with you by {owner}" : "{owner} hat dies mit dir geteilt",
|
||||
"Open in Files" : "In Dateien öffnen",
|
||||
"Link to a file" : "Mit einer Datei verknüpfen",
|
||||
"Error creating the share: {errorMessage}" : "Fehler beim Erstellen der Freigabe: {errorMessage}",
|
||||
"Error creating the share" : "Fehler beim Erstellen der Freigabe",
|
||||
|
|
|
|||
|
|
@ -208,6 +208,7 @@
|
|||
"Expires {relativetime}" : "Läuft {relativetime} ab",
|
||||
"this share just expired." : "Diese Freigabe ist gerade abgelaufen.",
|
||||
"Shared with you by {owner}" : "{owner} hat dies mit dir geteilt",
|
||||
"Open in Files" : "In Dateien öffnen",
|
||||
"Link to a file" : "Mit einer Datei verknüpfen",
|
||||
"Error creating the share: {errorMessage}" : "Fehler beim Erstellen der Freigabe: {errorMessage}",
|
||||
"Error creating the share" : "Fehler beim Erstellen der Freigabe",
|
||||
|
|
|
|||
|
|
@ -211,7 +211,8 @@ OC.L10N.register(
|
|||
"this share just expired." : "ce partage vient d'expirer",
|
||||
"Shared with you by {owner}" : "Partagé avec vous par {owner}",
|
||||
"_Accept share_::_Accept shares_" : ["Accepter le partage","Accepter les partages","Accepter les partages"],
|
||||
"_Reject share_::_Reject shares_" : ["Refuser le partage","Refuser les partages","Refuser les partages"],
|
||||
"Open in Files" : "Ouvrir dans Fichiers",
|
||||
"_Reject share_::_Reject shares_" : ["Rejeter le partage","Rejeter les partages","Rejeter les partages"],
|
||||
"_Restore share_::_Restore shares_" : ["Restaurer le partage","Restaurer les partages","Restaurer les partages"],
|
||||
"Link to a file" : "Relier à un fichier",
|
||||
"Error creating the share: {errorMessage}" : "Erreur à la création du partage : {errorMessage} ",
|
||||
|
|
@ -232,7 +233,7 @@ OC.L10N.register(
|
|||
"Shared with you and the conversation {conversation} by {owner}" : "Partagé avec vous et la conversation {conversation} par {owner}",
|
||||
"Shared with you in a conversation by {owner}" : "Partagé avec vous dans une conversation de {owner}",
|
||||
"Shares" : "Partages",
|
||||
"Overview of shared files." : "Aperçu des fichiers partagés.",
|
||||
"Overview of shared files." : "Vue d'ensemble des fichiers partagés.",
|
||||
"No shares" : "Aucun partage",
|
||||
"Files and folders you shared or have been shared with you will show up here" : "Les fichiers et les dossiers que vous avez partagés ou qui vous ont été partagés apparaîtront ici",
|
||||
"Shared with you" : "Partagés avec vous",
|
||||
|
|
@ -248,9 +249,9 @@ OC.L10N.register(
|
|||
"No shared links" : "Aucun partage par lien",
|
||||
"Files and folders you shared by link will show up here" : "Les fichiers et les dossiers que vous avez partagés par lien apparaîtront ici",
|
||||
"Deleted shares" : "Partages supprimés",
|
||||
"List of shares you left." : "Liste des partages auxquels vous avez mis fin.",
|
||||
"List of shares you left." : "Liste des partages que vous avez quittés.",
|
||||
"No deleted shares" : "Aucun partage supprimé",
|
||||
"Shares you have left will show up here" : "Les partages auxquels vous avez mis fin apparaîtront ici",
|
||||
"Shares you have left will show up here" : "Les partages que vous avez quittés s'afficheront ici",
|
||||
"Pending shares" : "Partages en attente",
|
||||
"List of unapproved shares." : "Liste des partages non approuvés.",
|
||||
"No pending shares" : "Aucun partage en attente",
|
||||
|
|
|
|||
|
|
@ -209,7 +209,8 @@
|
|||
"this share just expired." : "ce partage vient d'expirer",
|
||||
"Shared with you by {owner}" : "Partagé avec vous par {owner}",
|
||||
"_Accept share_::_Accept shares_" : ["Accepter le partage","Accepter les partages","Accepter les partages"],
|
||||
"_Reject share_::_Reject shares_" : ["Refuser le partage","Refuser les partages","Refuser les partages"],
|
||||
"Open in Files" : "Ouvrir dans Fichiers",
|
||||
"_Reject share_::_Reject shares_" : ["Rejeter le partage","Rejeter les partages","Rejeter les partages"],
|
||||
"_Restore share_::_Restore shares_" : ["Restaurer le partage","Restaurer les partages","Restaurer les partages"],
|
||||
"Link to a file" : "Relier à un fichier",
|
||||
"Error creating the share: {errorMessage}" : "Erreur à la création du partage : {errorMessage} ",
|
||||
|
|
@ -230,7 +231,7 @@
|
|||
"Shared with you and the conversation {conversation} by {owner}" : "Partagé avec vous et la conversation {conversation} par {owner}",
|
||||
"Shared with you in a conversation by {owner}" : "Partagé avec vous dans une conversation de {owner}",
|
||||
"Shares" : "Partages",
|
||||
"Overview of shared files." : "Aperçu des fichiers partagés.",
|
||||
"Overview of shared files." : "Vue d'ensemble des fichiers partagés.",
|
||||
"No shares" : "Aucun partage",
|
||||
"Files and folders you shared or have been shared with you will show up here" : "Les fichiers et les dossiers que vous avez partagés ou qui vous ont été partagés apparaîtront ici",
|
||||
"Shared with you" : "Partagés avec vous",
|
||||
|
|
@ -246,9 +247,9 @@
|
|||
"No shared links" : "Aucun partage par lien",
|
||||
"Files and folders you shared by link will show up here" : "Les fichiers et les dossiers que vous avez partagés par lien apparaîtront ici",
|
||||
"Deleted shares" : "Partages supprimés",
|
||||
"List of shares you left." : "Liste des partages auxquels vous avez mis fin.",
|
||||
"List of shares you left." : "Liste des partages que vous avez quittés.",
|
||||
"No deleted shares" : "Aucun partage supprimé",
|
||||
"Shares you have left will show up here" : "Les partages auxquels vous avez mis fin apparaîtront ici",
|
||||
"Shares you have left will show up here" : "Les partages que vous avez quittés s'afficheront ici",
|
||||
"Pending shares" : "Partages en attente",
|
||||
"List of unapproved shares." : "Liste des partages non approuvés.",
|
||||
"No pending shares" : "Aucun partage en attente",
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ use OCP\Files\Search\ISearchOperator;
|
|||
use OCP\Files\StorageNotAvailableException;
|
||||
use OCP\ICacheFactory;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Share\IShare;
|
||||
|
||||
/**
|
||||
* Metadata cache for shared files
|
||||
|
|
@ -55,15 +56,22 @@ class Cache extends CacheJail {
|
|||
private ?string $ownerDisplayName = null;
|
||||
private $numericId;
|
||||
private DisplayNameCache $displayNameCache;
|
||||
private IShare $share;
|
||||
|
||||
/**
|
||||
* @param SharedStorage $storage
|
||||
*/
|
||||
public function __construct($storage, ICacheEntry $sourceRootInfo, DisplayNameCache $displayNameCache) {
|
||||
public function __construct(
|
||||
$storage,
|
||||
ICacheEntry $sourceRootInfo,
|
||||
DisplayNameCache $displayNameCache,
|
||||
IShare $share
|
||||
) {
|
||||
$this->storage = $storage;
|
||||
$this->sourceRootInfo = $sourceRootInfo;
|
||||
$this->numericId = $sourceRootInfo->getStorageId();
|
||||
$this->displayNameCache = $displayNameCache;
|
||||
$this->share = $share;
|
||||
|
||||
parent::__construct(
|
||||
null,
|
||||
|
|
@ -150,7 +158,7 @@ class Cache extends CacheJail {
|
|||
|
||||
try {
|
||||
if (isset($entry['permissions'])) {
|
||||
$entry['permissions'] &= $this->storage->getShare()->getPermissions();
|
||||
$entry['permissions'] &= $this->share->getPermissions();
|
||||
} else {
|
||||
$entry['permissions'] = $this->storage->getPermissions($entry['path']);
|
||||
}
|
||||
|
|
@ -159,7 +167,7 @@ class Cache extends CacheJail {
|
|||
// (IDE may say the exception is never thrown – false negative)
|
||||
$sharePermissions = 0;
|
||||
}
|
||||
$entry['uid_owner'] = $this->storage->getOwner('');
|
||||
$entry['uid_owner'] = $this->share->getShareOwner();
|
||||
$entry['displayname_owner'] = $this->getOwnerDisplayName();
|
||||
if ($path === '') {
|
||||
$entry['is_share_mount_point'] = true;
|
||||
|
|
@ -169,7 +177,7 @@ class Cache extends CacheJail {
|
|||
|
||||
private function getOwnerDisplayName() {
|
||||
if (!$this->ownerDisplayName) {
|
||||
$uid = $this->storage->getOwner('');
|
||||
$uid = $this->share->getShareOwner();
|
||||
$this->ownerDisplayName = $this->displayNameCache->getDisplayName($uid) ?? $uid;
|
||||
}
|
||||
return $this->ownerDisplayName;
|
||||
|
|
|
|||
|
|
@ -113,8 +113,9 @@ class CleanupRemoteStorages extends Command {
|
|||
$queryBuilder->createNamedParameter($numericId, IQueryBuilder::PARAM_STR),
|
||||
IQueryBuilder::PARAM_STR)
|
||||
);
|
||||
$result = $queryBuilder->execute();
|
||||
$result = $queryBuilder->executeQuery();
|
||||
$count = $result->fetchOne();
|
||||
$result->closeCursor();
|
||||
$output->writeln("$count files can be deleted for storage $numericId");
|
||||
}
|
||||
|
||||
|
|
@ -127,7 +128,7 @@ class CleanupRemoteStorages extends Command {
|
|||
IQueryBuilder::PARAM_STR)
|
||||
);
|
||||
$output->write("deleting $id [$numericId] ... ");
|
||||
$count = $queryBuilder->execute();
|
||||
$count = $queryBuilder->executeStatement();
|
||||
$output->writeln("deleted $count storage");
|
||||
$this->deleteFiles($numericId, $output);
|
||||
}
|
||||
|
|
@ -141,7 +142,7 @@ class CleanupRemoteStorages extends Command {
|
|||
IQueryBuilder::PARAM_STR)
|
||||
);
|
||||
$output->write("deleting files for storage $numericId ... ");
|
||||
$count = $queryBuilder->execute();
|
||||
$count = $queryBuilder->executeStatement();
|
||||
$output->writeln("deleted $count files");
|
||||
}
|
||||
|
||||
|
|
@ -160,14 +161,16 @@ class CleanupRemoteStorages extends Command {
|
|||
// but not the ones starting with a '/', they are for normal shares
|
||||
$queryBuilder->createNamedParameter($this->connection->escapeLikeParameter('shared::/') . '%'),
|
||||
IQueryBuilder::PARAM_STR)
|
||||
)->orderBy('numeric_id');
|
||||
$query = $queryBuilder->execute();
|
||||
)
|
||||
->orderBy('numeric_id');
|
||||
$result = $queryBuilder->executeQuery();
|
||||
|
||||
$remoteStorages = [];
|
||||
|
||||
while ($row = $query->fetch()) {
|
||||
while ($row = $result->fetch()) {
|
||||
$remoteStorages[$row['id']] = $row['numeric_id'];
|
||||
}
|
||||
$result->closeCursor();
|
||||
|
||||
return $remoteStorages;
|
||||
}
|
||||
|
|
@ -176,16 +179,17 @@ class CleanupRemoteStorages extends Command {
|
|||
$queryBuilder = $this->connection->getQueryBuilder();
|
||||
$queryBuilder->select(['id', 'share_token', 'owner', 'remote'])
|
||||
->from('share_external');
|
||||
$query = $queryBuilder->execute();
|
||||
$result = $queryBuilder->executeQuery();
|
||||
|
||||
$remoteShareIds = [];
|
||||
|
||||
while ($row = $query->fetch()) {
|
||||
while ($row = $result->fetch()) {
|
||||
$cloudId = $this->cloudIdManager->getCloudId($row['owner'], $row['remote']);
|
||||
$remote = $cloudId->getRemote();
|
||||
|
||||
$remoteShareIds[$row['id']] = 'shared::' . md5($row['share_token'] . '@' . $remote);
|
||||
}
|
||||
$result->closeCursor();
|
||||
|
||||
return $remoteShareIds;
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue