mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-02-03 00:33:49 +03:00
Merge branch 'rc/v2.0' of github.com:hydralauncher/hydra into rc/v2.0
This commit is contained in:
commit
d62d73e04a
@ -110,7 +110,9 @@
|
|||||||
"danger_zone_section_description": "Remove this game from your library or the files downloaded by Hydra",
|
"danger_zone_section_description": "Remove this game from your library or the files downloaded by Hydra",
|
||||||
"download_in_progress": "Download in progress",
|
"download_in_progress": "Download in progress",
|
||||||
"download_paused": "Download paused",
|
"download_paused": "Download paused",
|
||||||
"last_downloaded_option": "Last downloaded option"
|
"last_downloaded_option": "Last downloaded option",
|
||||||
|
"create_shortcut_success": "Shortcut created successfully",
|
||||||
|
"create_shortcut_error": "Error creating shortcut"
|
||||||
},
|
},
|
||||||
"activation": {
|
"activation": {
|
||||||
"title": "Activate Hydra",
|
"title": "Activate Hydra",
|
||||||
|
@ -106,7 +106,9 @@
|
|||||||
"danger_zone_section_description": "Remova o jogo da sua biblioteca ou os arquivos que foram baixados pelo Hydra",
|
"danger_zone_section_description": "Remova o jogo da sua biblioteca ou os arquivos que foram baixados pelo Hydra",
|
||||||
"download_in_progress": "Download em andamento",
|
"download_in_progress": "Download em andamento",
|
||||||
"download_paused": "Download pausado",
|
"download_paused": "Download pausado",
|
||||||
"last_downloaded_option": "Última opção baixada"
|
"last_downloaded_option": "Última opção baixada",
|
||||||
|
"create_shortcut_success": "Atalho criado com sucesso",
|
||||||
|
"create_shortcut_error": "Erro ao criar atalho"
|
||||||
},
|
},
|
||||||
"activation": {
|
"activation": {
|
||||||
"title": "Ativação",
|
"title": "Ativação",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"app": {
|
"app": {
|
||||||
"successfully_signed_in": "Successfully signed in (TRANSLATE ME)"
|
"successfully_signed_in": "Успешный вход"
|
||||||
},
|
},
|
||||||
"home": {
|
"home": {
|
||||||
"featured": "Рекомендованное",
|
"featured": "Рекомендованное",
|
||||||
@ -20,7 +20,7 @@
|
|||||||
"home": "Главная",
|
"home": "Главная",
|
||||||
"queued": "{{title}} (В очереди)",
|
"queued": "{{title}} (В очереди)",
|
||||||
"game_has_no_executable": "Файл запуска игры не выбран",
|
"game_has_no_executable": "Файл запуска игры не выбран",
|
||||||
"sign_in": "Sign in (TRANSLATE ME)"
|
"sign_in": "Войти"
|
||||||
},
|
},
|
||||||
"header": {
|
"header": {
|
||||||
"search": "Поиск",
|
"search": "Поиск",
|
||||||
@ -110,7 +110,9 @@
|
|||||||
"danger_zone_section_description": "Удалить эту игру из вашей библиотеки или файлы скачанные Hydra",
|
"danger_zone_section_description": "Удалить эту игру из вашей библиотеки или файлы скачанные Hydra",
|
||||||
"download_in_progress": "Идёт загрузка",
|
"download_in_progress": "Идёт загрузка",
|
||||||
"download_paused": "Загрузка приостановлена",
|
"download_paused": "Загрузка приостановлена",
|
||||||
"last_downloaded_option": "Последний вариант загрузки"
|
"last_downloaded_option": "Последний вариант загрузки",
|
||||||
|
"create_shortcut_success": "Ярлык создан",
|
||||||
|
"create_shortcut_error": "Не удалось создать ярлык"
|
||||||
},
|
},
|
||||||
"activation": {
|
"activation": {
|
||||||
"title": "Активировать Hydra",
|
"title": "Активировать Hydra",
|
||||||
@ -183,12 +185,12 @@
|
|||||||
"sync_download_sources": "Синхронизировать источники",
|
"sync_download_sources": "Синхронизировать источники",
|
||||||
"removed_download_source": "Источник загрузок удален",
|
"removed_download_source": "Источник загрузок удален",
|
||||||
"added_download_source": "Источник загрузок добавлен",
|
"added_download_source": "Источник загрузок добавлен",
|
||||||
"download_sources_synced": "All download sources are synced (TRANSLATE ME)",
|
"download_sources_synced": "Все источники загрузок синхронизированы",
|
||||||
"insert_valid_json_url": "Insert a valid JSON url (TRANSLATE ME)",
|
"insert_valid_json_url": "Вставьте действительный URL JSON-файла",
|
||||||
"found_download_option_zero": "No download option found (TRANSLATE ME)",
|
"found_download_option_zero": "Не найдено вариантов загрузки",
|
||||||
"found_download_option_one": "Found {{countFormatted}} download option (TRANSLATE ME)",
|
"found_download_option_one": "Найден {{countFormatted}} вариант загрузки",
|
||||||
"found_download_option_other": "Found {{countFormatted}} download options (TRANSLATE ME)",
|
"found_download_option_other": "Найдено {{countFormatted}} вариантов загрузки",
|
||||||
"import": "Import (TRANSLATE ME)"
|
"import": "Импортировать"
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"download_complete": "Загрузка завершена",
|
"download_complete": "Загрузка завершена",
|
||||||
@ -216,25 +218,25 @@
|
|||||||
"toggle_password_visibility": "Показывать пароль"
|
"toggle_password_visibility": "Показывать пароль"
|
||||||
},
|
},
|
||||||
"user_profile": {
|
"user_profile": {
|
||||||
"amount_hours": "{{amount}} hours (TRANSLATE ME)",
|
"amount_hours": "{{amount}} часов",
|
||||||
"amount_minutes": "{{amount}} minutes (TRANSLATE ME)",
|
"amount_minutes": "{{amount}} минут",
|
||||||
"last_time_played": "Last played {{period}} (TRANSLATE ME)",
|
"last_time_played": "Последняя игра {{period}}",
|
||||||
"activity": "Recent activity (TRANSLATE ME)",
|
"activity": "Недавняя активность",
|
||||||
"library": "Library (TRANSLATE ME)",
|
"library": "Библиотека",
|
||||||
"total_play_time": "Total playtime: {{amount}} (TRANSLATE ME)",
|
"total_play_time": "Всего сыграно: {{amount}}",
|
||||||
"no_recent_activity_title": "Hmmm… nothing here (TRANSLATE ME)",
|
"no_recent_activity_title": "Хммм... Тут ничего нет",
|
||||||
"no_recent_activity_description": "You haven't played any games recently. It's time to change that! (TRANSLATE ME)",
|
"no_recent_activity_description": "Вы давно ни во что не играли. Пора это изменить!",
|
||||||
"display_name": "Display name (TRANSLATE ME)",
|
"display_name": "Отображаемое имя",
|
||||||
"saving": "Saving (TRANSLATE ME)",
|
"saving": "Сохранение",
|
||||||
"save": "Save (TRANSLATE ME)",
|
"save": "Сохранено",
|
||||||
"edit_profile": "Edit Profile (TRANSLATE ME)",
|
"edit_profile": "Редактировать Профиль",
|
||||||
"saved_successfully": "Saved successfully (TRANSLATE ME)",
|
"saved_successfully": "Успешно сохранено",
|
||||||
"try_again": "Please, try again (TRANSLATE ME)",
|
"try_again": "Пожалуйста, попробуйте ещё раз",
|
||||||
"sign_out_modal_title": "Are you sure? (TRANSLATE ME)",
|
"sign_out_modal_title": "Вы уверены?",
|
||||||
"cancel": "Cancel (TRANSLATE ME)",
|
"cancel": "Отменить",
|
||||||
"successfully_signed_out": "Successfully signed out (TRANSLATE ME)",
|
"successfully_signed_out": "Успешный выход из аккаунта",
|
||||||
"sign_out": "Sign out (TRANSLATE ME)",
|
"sign_out": "Выйти",
|
||||||
"playing_for": "Playing for {{amount}} (TRANSLATE ME)",
|
"playing_for": "Сыграно {{amount}}",
|
||||||
"sign_out_modal_text": "Your library is linked with your current account. When signing out, your library will not be visible anymore, and any progress will not be saved. Continue with sign out? (TRANSLATE ME)"
|
"sign_out_modal_text": "Ваша библиотека связана с текущей учетной записью. При выходе из системы ваша библиотека станет недоступна, и прогресс не будет сохранен. Выйти?"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
{
|
{
|
||||||
|
"app": {
|
||||||
|
"successfully_signed_in": "Успішний вхід в систему"
|
||||||
|
},
|
||||||
"home": {
|
"home": {
|
||||||
"featured": "Рекомендоване",
|
"featured": "Рекомендоване",
|
||||||
"trending": "У тренді",
|
"trending": "У тренді",
|
||||||
@ -14,7 +17,10 @@
|
|||||||
"paused": "{{title}} (Призупинено)",
|
"paused": "{{title}} (Призупинено)",
|
||||||
"downloading": "{{title}} ({{percentage}} - Завантаження…)",
|
"downloading": "{{title}} ({{percentage}} - Завантаження…)",
|
||||||
"filter": "Фільтр бібліотеки",
|
"filter": "Фільтр бібліотеки",
|
||||||
"home": "Головна"
|
"home": "Головна",
|
||||||
|
"game_has_no_executable": "Не було вибрано файл для запуску гри",
|
||||||
|
"queued": "{{title}} в черзі",
|
||||||
|
"sign_in": "Увійти"
|
||||||
},
|
},
|
||||||
"header": {
|
"header": {
|
||||||
"search": "Пошук",
|
"search": "Пошук",
|
||||||
@ -22,12 +28,15 @@
|
|||||||
"catalogue": "Каталог",
|
"catalogue": "Каталог",
|
||||||
"downloads": "Завантаження",
|
"downloads": "Завантаження",
|
||||||
"search_results": "Результати пошуку",
|
"search_results": "Результати пошуку",
|
||||||
"settings": "Налаштування"
|
"settings": "Налаштування",
|
||||||
|
"version_available_download": "Доступна версія {{version}}. Натисніть тут, щоб перезапустити та встановити.",
|
||||||
|
"version_available_install": "Доступна версія {{version}}. Натисніть тут для завантаження."
|
||||||
},
|
},
|
||||||
"bottom_panel": {
|
"bottom_panel": {
|
||||||
"no_downloads_in_progress": "Немає активних завантажень",
|
"no_downloads_in_progress": "Немає активних завантажень",
|
||||||
"downloading_metadata": "Завантаження метаданих {{title}}…",
|
"downloading_metadata": "Завантаження метаданих {{title}}…",
|
||||||
"downloading": "Завантаження {{title}}… ({{percentage}} завершено) - Закінчення {{eta}} - {{speed}}"
|
"downloading": "Завантаження {{title}}… ({{percentage}} завершено) - Закінчення {{eta}} - {{speed}}",
|
||||||
|
"calculating_eta": "Завантаження {{title}}… ({{percentage}} завершено) - Обчислення залишкового часу…"
|
||||||
},
|
},
|
||||||
"catalogue": {
|
"catalogue": {
|
||||||
"next_page": "Наступна сторінка",
|
"next_page": "Наступна сторінка",
|
||||||
@ -72,13 +81,42 @@
|
|||||||
"change": "Змінити",
|
"change": "Змінити",
|
||||||
"repacks_modal_description": "Виберіть репак, який хочете завантажити",
|
"repacks_modal_description": "Виберіть репак, який хочете завантажити",
|
||||||
"select_folder_hint": "Щоб змінити теку за замовчуванням, відкрийте",
|
"select_folder_hint": "Щоб змінити теку за замовчуванням, відкрийте",
|
||||||
"download_now": "Завантажити зараз"
|
"download_now": "Завантажити зараз",
|
||||||
|
"calculating_eta": "Обчислення залишкового часу…",
|
||||||
|
"create_shortcut": "Створити ярлик на робочому столі",
|
||||||
|
"danger_zone_section_description": "Видалити цю гру з вашої бібліотеки або файли скачані Hydra",
|
||||||
|
"danger_zone_section_title": "Небезпечна зона",
|
||||||
|
"download_in_progress": "Триває завантаження.",
|
||||||
|
"download_options": "Варіантів завантаження",
|
||||||
|
"download_path": "Тека для завантажень",
|
||||||
|
"download_paused": "Завантаження призупинено",
|
||||||
|
"download_settings": "Налаштування завантаження",
|
||||||
|
"downloader": "Завантажувач",
|
||||||
|
"downloads_secion_title": "Завантаження",
|
||||||
|
"downloads_section_description": "Перевірити наявність оновлень або інших версій гри",
|
||||||
|
"executable_section_description": "Шлях до файлу, який буде запущений при натисканні на кнопку \"Play\"",
|
||||||
|
"executable_section_title": "Файл",
|
||||||
|
"last_downloaded_option": "Останній варіант завантаження",
|
||||||
|
"next_screenshot": "Наступний скрішнот",
|
||||||
|
"no_executable_selected": "Файл не вибрано",
|
||||||
|
"no_shop_details": "Не вдалося отримати опис",
|
||||||
|
"open_download_location": "Переглянути папку завантажень",
|
||||||
|
"open_folder": "Відкрити папку",
|
||||||
|
"open_screenshot": "Відкрити скріншот",
|
||||||
|
"options": "Налаштування",
|
||||||
|
"paused": "Призупинено",
|
||||||
|
"previous_screenshot": "Попередній скріншот",
|
||||||
|
"remove_files": "Видалити файли",
|
||||||
|
"remove_from_library_description": "{{game}} буде видалено з вашої бібліотеки",
|
||||||
|
"remove_from_library_title": "Ви впевнені?",
|
||||||
|
"screenshot": "Скріншот",
|
||||||
|
"select_executable": "Обрати"
|
||||||
},
|
},
|
||||||
"activation": {
|
"activation": {
|
||||||
"title": "Активувати Hydra",
|
"title": "Активувати Hydra",
|
||||||
"installation_id": "ID установки:",
|
"installation_id": "ID установки:",
|
||||||
"enter_activation_code": "Введіть ваш активаційний код",
|
"enter_activation_code": "Введіть ваш активаційний код",
|
||||||
"message": "Якщо ви не знаєте, де його запросити, то не повинні мати цього.",
|
"message": "Якщо ви не знаєте, де його запросити, то не повинні мати його.",
|
||||||
"activate": "Активувати",
|
"activate": "Активувати",
|
||||||
"loading": "Завантаження…"
|
"loading": "Завантаження…"
|
||||||
},
|
},
|
||||||
@ -97,7 +135,14 @@
|
|||||||
"delete": "Видалити інсталятор",
|
"delete": "Видалити інсталятор",
|
||||||
"delete_modal_title": "Ви впевнені?",
|
"delete_modal_title": "Ви впевнені?",
|
||||||
"delete_modal_description": "Це видалить усі інсталяційні файли з вашого комп'ютера",
|
"delete_modal_description": "Це видалить усі інсталяційні файли з вашого комп'ютера",
|
||||||
"install": "Встановити"
|
"install": "Встановити",
|
||||||
|
"download_in_progress": "В процесі",
|
||||||
|
"downloads_completed": "Завершено",
|
||||||
|
"no_downloads_description": "Ви ще нічого не завантажили через Hydra, але ніколи не пізно почати.",
|
||||||
|
"no_downloads_title": "Тут так пусто...",
|
||||||
|
"queued": "В черзі",
|
||||||
|
"queued_downloads": "Завантаження в черзі",
|
||||||
|
"removed": "Не завантажено"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"downloads_path": "Тека завантажень",
|
"downloads_path": "Тека завантажень",
|
||||||
@ -106,8 +151,44 @@
|
|||||||
"enable_download_notifications": "Після завершення завантаження",
|
"enable_download_notifications": "Після завершення завантаження",
|
||||||
"enable_repack_list_notifications": "Коли додається новий репак",
|
"enable_repack_list_notifications": "Коли додається новий репак",
|
||||||
"behavior": "Поведінка",
|
"behavior": "Поведінка",
|
||||||
"quit_app_instead_hiding": "Закривати програму замість того, щоб згортати її в трей",
|
"quit_app_instead_hiding": "Закривати Hydra замість того, щоб згортати її в трей",
|
||||||
"launch_with_system": "Запускати програми із запуском комп'ютера"
|
"launch_with_system": "Запускати Hydra із запуском комп'ютера",
|
||||||
|
"add_download_source": "Добавити джерело",
|
||||||
|
"add_download_source_description": "Введіть посилання на .json-файл",
|
||||||
|
"added_download_source": "Джерело для завантаження було додано",
|
||||||
|
"changes_saved": "Зміни успішно збережено",
|
||||||
|
"download_count_one": "{{countFormatted}} завантаження в списку",
|
||||||
|
"download_count_other": "{{countFormatted}} завантажень в списку",
|
||||||
|
"download_count_zero": "В списку немає завантажень",
|
||||||
|
"download_options_one": "{{countFormatted}} доступний варіант завантаження",
|
||||||
|
"download_options_other": "{{countFormatted}} доступних варіантів завантаження",
|
||||||
|
"download_options_zero": "Немає доступних завантажень",
|
||||||
|
"download_source_errored": "Помилка",
|
||||||
|
"download_source_up_to_date": "Оновлено",
|
||||||
|
"download_source_url": "Посилання на джерело",
|
||||||
|
"download_sources": "Джерела для завантаження",
|
||||||
|
"download_sources_description": "Hydra буде отримувати посилання для завантажень із цих джерел. URL має містити пряме посилання на .json-файл із посиланнями для завантажень.",
|
||||||
|
"download_sources_synced": "Всі джерела для завантаження синхронізовано",
|
||||||
|
"enable_real_debrid": "Включити Real-Debrid",
|
||||||
|
"found_download_option_one": "Знайдено {{countFormatted}} варіант завантаження",
|
||||||
|
"found_download_option_other": "Знайдено {{countFormatted}} варіантів завантаження",
|
||||||
|
"found_download_option_zero": "Немає доступних завантажень",
|
||||||
|
"general": "Основні",
|
||||||
|
"import": "Імпортувати",
|
||||||
|
"insert_valid_json_url": "Вставте дійсний URL JSON-файлу",
|
||||||
|
"language": "Мова",
|
||||||
|
"real_debrid_api_token": "API-токен",
|
||||||
|
"real_debrid_api_token_hint": "API токен можливо отримати <0>тут</0>",
|
||||||
|
"real_debrid_api_token_label": "Real-Debrid API-токен",
|
||||||
|
"real_debrid_description": "Real-Debrid — це необмежений завантажувач, який дозволяє швидко завантажувати файли, розміщені в Інтернеті, або миттєво передавати їх у плеєр через приватну мережу, що дозволяє обходити будь-які блокування.",
|
||||||
|
"real_debrid_free_account_error": "Акаунт \"{{username}}\" - не має наявної підписки. Будь ласка, оформіть підписку на Real-Debrid",
|
||||||
|
"real_debrid_invalid_token": "Невірний API-токен",
|
||||||
|
"real_debrid_linked_message": "Акаунт \"{{username}}\" привязаний",
|
||||||
|
"remove_download_source": "Видалити",
|
||||||
|
"removed_download_source": "Джерело завантажень було видалено",
|
||||||
|
"save_changes": "Зберегти зміни",
|
||||||
|
"sync_download_sources": "Синхронізувати джерела",
|
||||||
|
"validate_download_source": "Перевірити"
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"download_complete": "Завантаження завершено",
|
"download_complete": "Завантаження завершено",
|
||||||
@ -130,5 +211,30 @@
|
|||||||
},
|
},
|
||||||
"modal": {
|
"modal": {
|
||||||
"close": "Закрити"
|
"close": "Закрити"
|
||||||
|
},
|
||||||
|
"forms": {
|
||||||
|
"toggle_password_visibility": "Показувати пароль"
|
||||||
|
},
|
||||||
|
"user_profile": {
|
||||||
|
"activity": "Остання активність",
|
||||||
|
"amount_hours": "{{amount}} годин",
|
||||||
|
"amount_minutes": "{{amount}} хвилин",
|
||||||
|
"cancel": "Скасувати",
|
||||||
|
"display_name": "Відображуване ім'я",
|
||||||
|
"edit_profile": "Редагувати профіль",
|
||||||
|
"last_time_played": "Остання гра {{period}}",
|
||||||
|
"library": "Бібліотека",
|
||||||
|
"no_recent_activity_description": "Ви давно не грали в ігри. Пора це змінити!",
|
||||||
|
"no_recent_activity_title": "Хммм... Тут нічого немає",
|
||||||
|
"playing_for": "Зіграно {{amount}}",
|
||||||
|
"save": "Збережено",
|
||||||
|
"saved_successfully": "Успішно збережено",
|
||||||
|
"saving": "Збереження",
|
||||||
|
"sign_out": "Вийти",
|
||||||
|
"sign_out_modal_text": "Ваша бібліотека пов'язана з поточним обліковим записом. При виході з системи ваша бібліотека буде недоступною, і прогрес не буде збережено. Продовжити вихід?",
|
||||||
|
"sign_out_modal_title": "Ви впевнені?",
|
||||||
|
"successfully_signed_out": "Успішний вихід з акаунту",
|
||||||
|
"total_play_time": "Всього зіграно: {{amount}}",
|
||||||
|
"try_again": "Будь ласка, попробуйте ще раз"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ export const downloadSourceSchema = z.object({
|
|||||||
downloads: z.array(
|
downloads: z.array(
|
||||||
z.object({
|
z.object({
|
||||||
title: z.string().max(255),
|
title: z.string().max(255),
|
||||||
downloaders: z.array(z.enum(["real_debrid", "torrent"])),
|
|
||||||
uris: z.array(z.string()),
|
uris: z.array(z.string()),
|
||||||
uploadDate: z.string().max(255),
|
uploadDate: z.string().max(255),
|
||||||
fileSize: z.string().max(255),
|
fileSize: z.string().max(255),
|
||||||
|
@ -73,7 +73,16 @@ app.on("browser-window-created", (_, window) => {
|
|||||||
optimizer.watchWindowShortcuts(window);
|
optimizer.watchWindowShortcuts(window);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.on("second-instance", (_event) => {
|
const handleDeepLinkPath = (uri?: string) => {
|
||||||
|
if (!uri) return;
|
||||||
|
const url = new URL(uri);
|
||||||
|
|
||||||
|
if (url.host === "install-source") {
|
||||||
|
WindowManager.redirect(`settings${url.search}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
app.on("second-instance", (_event, commandLine) => {
|
||||||
// Someone tried to run a second instance, we should focus our window.
|
// Someone tried to run a second instance, we should focus our window.
|
||||||
if (WindowManager.mainWindow) {
|
if (WindowManager.mainWindow) {
|
||||||
if (WindowManager.mainWindow.isMinimized())
|
if (WindowManager.mainWindow.isMinimized())
|
||||||
@ -84,16 +93,12 @@ app.on("second-instance", (_event) => {
|
|||||||
WindowManager.createMainWindow();
|
WindowManager.createMainWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
// const [, path] = commandLine.pop()?.split("://") ?? [];
|
handleDeepLinkPath(commandLine.pop());
|
||||||
// if (path) {
|
|
||||||
// WindowManager.redirect(path);
|
|
||||||
// }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// app.on("open-url", (_event, url) => {
|
app.on("open-url", (_event, url) => {
|
||||||
// const [, path] = url.split("://");
|
handleDeepLinkPath(url);
|
||||||
// WindowManager.redirect(path);
|
});
|
||||||
// });
|
|
||||||
|
|
||||||
// Quit when all windows are closed, except on macOS. There, it's common
|
// Quit when all windows are closed, except on macOS. There, it's common
|
||||||
// for applications and their menu bar to stay active until the user quits
|
// for applications and their menu bar to stay active until the user quits
|
||||||
|
@ -9,7 +9,7 @@ import {
|
|||||||
shell,
|
shell,
|
||||||
} from "electron";
|
} from "electron";
|
||||||
import { is } from "@electron-toolkit/utils";
|
import { is } from "@electron-toolkit/utils";
|
||||||
import { t } from "i18next";
|
import i18next, { t } from "i18next";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import icon from "@resources/icon.png?asset";
|
import icon from "@resources/icon.png?asset";
|
||||||
import trayIcon from "@resources/tray-icon.png?asset";
|
import trayIcon from "@resources/tray-icon.png?asset";
|
||||||
@ -100,7 +100,13 @@ export class WindowManager {
|
|||||||
|
|
||||||
authWindow.removeMenu();
|
authWindow.removeMenu();
|
||||||
|
|
||||||
authWindow.loadURL("https://auth.hydra.losbroxas.org/");
|
const searchParams = new URLSearchParams({
|
||||||
|
lng: i18next.language,
|
||||||
|
});
|
||||||
|
|
||||||
|
authWindow.loadURL(
|
||||||
|
`https://auth.hydra.losbroxas.org/?${searchParams.toString()}`
|
||||||
|
);
|
||||||
|
|
||||||
authWindow.once("ready-to-show", () => {
|
authWindow.once("ready-to-show", () => {
|
||||||
authWindow.show();
|
authWindow.show();
|
||||||
|
@ -1 +1,2 @@
|
|||||||
export * from "./game-details/game-details.context";
|
export * from "./game-details/game-details.context";
|
||||||
|
export * from "./settings/settings.context";
|
||||||
|
73
src/renderer/src/context/settings/settings.context.tsx
Normal file
73
src/renderer/src/context/settings/settings.context.tsx
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import { createContext, useEffect, useState } from "react";
|
||||||
|
|
||||||
|
import { setUserPreferences } from "@renderer/features";
|
||||||
|
import { useAppDispatch } from "@renderer/hooks";
|
||||||
|
import type { UserPreferences } from "@types";
|
||||||
|
import { useSearchParams } from "react-router-dom";
|
||||||
|
|
||||||
|
export interface SettingsContext {
|
||||||
|
updateUserPreferences: (values: Partial<UserPreferences>) => Promise<void>;
|
||||||
|
setCurrentCategoryIndex: React.Dispatch<React.SetStateAction<number>>;
|
||||||
|
clearSourceUrl: () => void;
|
||||||
|
sourceUrl: string | null;
|
||||||
|
currentCategoryIndex: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const settingsContext = createContext<SettingsContext>({
|
||||||
|
updateUserPreferences: async () => {},
|
||||||
|
setCurrentCategoryIndex: () => {},
|
||||||
|
clearSourceUrl: () => {},
|
||||||
|
sourceUrl: null,
|
||||||
|
currentCategoryIndex: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { Provider } = settingsContext;
|
||||||
|
export const { Consumer: SettingsContextConsumer } = settingsContext;
|
||||||
|
|
||||||
|
export interface SettingsContextProviderProps {
|
||||||
|
children: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SettingsContextProvider({
|
||||||
|
children,
|
||||||
|
}: SettingsContextProviderProps) {
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const [sourceUrl, setSourceUrl] = useState<string | null>(null);
|
||||||
|
const [currentCategoryIndex, setCurrentCategoryIndex] = useState(0);
|
||||||
|
|
||||||
|
const [searchParams] = useSearchParams();
|
||||||
|
const defaultSourceUrl = searchParams.get("urls");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (sourceUrl) setCurrentCategoryIndex(2);
|
||||||
|
}, [sourceUrl]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (defaultSourceUrl) {
|
||||||
|
setSourceUrl(defaultSourceUrl);
|
||||||
|
}
|
||||||
|
}, [defaultSourceUrl]);
|
||||||
|
|
||||||
|
const clearSourceUrl = () => setSourceUrl(null);
|
||||||
|
|
||||||
|
const updateUserPreferences = async (values: Partial<UserPreferences>) => {
|
||||||
|
await window.electron.updateUserPreferences(values);
|
||||||
|
window.electron.getUserPreferences().then((userPreferences) => {
|
||||||
|
dispatch(setUserPreferences(userPreferences));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Provider
|
||||||
|
value={{
|
||||||
|
updateUserPreferences,
|
||||||
|
setCurrentCategoryIndex,
|
||||||
|
clearSourceUrl,
|
||||||
|
currentCategoryIndex,
|
||||||
|
sourceUrl,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
}
|
@ -5,7 +5,7 @@ import type { Game } from "@types";
|
|||||||
import * as styles from "./game-options-modal.css";
|
import * as styles from "./game-options-modal.css";
|
||||||
import { gameDetailsContext } from "@renderer/context";
|
import { gameDetailsContext } from "@renderer/context";
|
||||||
import { DeleteGameModal } from "@renderer/pages/downloads/delete-game-modal";
|
import { DeleteGameModal } from "@renderer/pages/downloads/delete-game-modal";
|
||||||
import { useDownload } from "@renderer/hooks";
|
import { useDownload, useToast } from "@renderer/hooks";
|
||||||
import { RemoveGameFromLibraryModal } from "./remove-from-library-modal";
|
import { RemoveGameFromLibraryModal } from "./remove-from-library-modal";
|
||||||
|
|
||||||
export interface GameOptionsModalProps {
|
export interface GameOptionsModalProps {
|
||||||
@ -21,6 +21,8 @@ export function GameOptionsModal({
|
|||||||
}: GameOptionsModalProps) {
|
}: GameOptionsModalProps) {
|
||||||
const { t } = useTranslation("game_details");
|
const { t } = useTranslation("game_details");
|
||||||
|
|
||||||
|
const { showSuccessToast, showErrorToast } = useToast();
|
||||||
|
|
||||||
const { updateGame, setShowRepacksModal, selectGameExecutable } =
|
const { updateGame, setShowRepacksModal, selectGameExecutable } =
|
||||||
useContext(gameDetailsContext);
|
useContext(gameDetailsContext);
|
||||||
|
|
||||||
@ -61,7 +63,13 @@ export function GameOptionsModal({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleCreateShortcut = async () => {
|
const handleCreateShortcut = async () => {
|
||||||
await window.electron.createGameShortcut(game.id);
|
window.electron.createGameShortcut(game.id).then((success) => {
|
||||||
|
if (success) {
|
||||||
|
showSuccessToast(t("create_shortcut_success"));
|
||||||
|
} else {
|
||||||
|
showErrorToast(t("create_shortcut_error"));
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOpenDownloadFolder = async () => {
|
const handleOpenDownloadFolder = async () => {
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useCallback, useContext, useEffect, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
import { Button, Modal, TextField } from "@renderer/components";
|
import { Button, Modal, TextField } from "@renderer/components";
|
||||||
import { SPACING_UNIT } from "@renderer/theme.css";
|
import { SPACING_UNIT } from "@renderer/theme.css";
|
||||||
|
import { settingsContext } from "@renderer/context";
|
||||||
|
|
||||||
interface AddDownloadSourceModalProps {
|
interface AddDownloadSourceModalProps {
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
@ -23,24 +24,31 @@ export function AddDownloadSourceModal({
|
|||||||
downloadCount: number;
|
downloadCount: number;
|
||||||
} | null>(null);
|
} | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setValue("");
|
|
||||||
setIsLoading(false);
|
|
||||||
setValidationResult(null);
|
|
||||||
}, [visible]);
|
|
||||||
|
|
||||||
const { t } = useTranslation("settings");
|
const { t } = useTranslation("settings");
|
||||||
|
|
||||||
const handleValidateDownloadSource = async () => {
|
const { sourceUrl } = useContext(settingsContext);
|
||||||
|
|
||||||
|
const handleValidateDownloadSource = useCallback(async (url: string) => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await window.electron.validateDownloadSource(value);
|
const result = await window.electron.validateDownloadSource(url);
|
||||||
setValidationResult(result);
|
setValidationResult(result);
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
};
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setValue("");
|
||||||
|
setIsLoading(false);
|
||||||
|
setValidationResult(null);
|
||||||
|
|
||||||
|
if (sourceUrl) {
|
||||||
|
setValue(sourceUrl);
|
||||||
|
handleValidateDownloadSource(sourceUrl);
|
||||||
|
}
|
||||||
|
}, [visible, handleValidateDownloadSource, sourceUrl]);
|
||||||
|
|
||||||
const handleAddDownloadSource = async () => {
|
const handleAddDownloadSource = async () => {
|
||||||
await window.electron.addDownloadSource(value);
|
await window.electron.addDownloadSource(value);
|
||||||
@ -73,7 +81,7 @@ export function AddDownloadSourceModal({
|
|||||||
type="button"
|
type="button"
|
||||||
theme="outline"
|
theme="outline"
|
||||||
style={{ alignSelf: "flex-end" }}
|
style={{ alignSelf: "flex-end" }}
|
||||||
onClick={handleValidateDownloadSource}
|
onClick={() => handleValidateDownloadSource(value)}
|
||||||
disabled={isLoading || !value}
|
disabled={isLoading || !value}
|
||||||
>
|
>
|
||||||
{t("validate_download_source")}
|
{t("validate_download_source")}
|
||||||
|
@ -1,22 +1,17 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useContext, useEffect, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
import type { UserPreferences } from "@types";
|
|
||||||
|
|
||||||
import { CheckboxField } from "@renderer/components";
|
import { CheckboxField } from "@renderer/components";
|
||||||
import { useAppSelector } from "@renderer/hooks";
|
import { useAppSelector } from "@renderer/hooks";
|
||||||
|
import { settingsContext } from "@renderer/context";
|
||||||
|
|
||||||
export interface SettingsBehaviorProps {
|
export function SettingsBehavior() {
|
||||||
updateUserPreferences: (values: Partial<UserPreferences>) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function SettingsBehavior({
|
|
||||||
updateUserPreferences,
|
|
||||||
}: SettingsBehaviorProps) {
|
|
||||||
const userPreferences = useAppSelector(
|
const userPreferences = useAppSelector(
|
||||||
(state) => state.userPreferences.value
|
(state) => state.userPreferences.value
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { updateUserPreferences } = useContext(settingsContext);
|
||||||
|
|
||||||
const [form, setForm] = useState({
|
const [form, setForm] = useState({
|
||||||
preferQuitInsteadOfHiding: false,
|
preferQuitInsteadOfHiding: false,
|
||||||
runAtStartup: false,
|
runAtStartup: false,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useContext, useEffect, useState } from "react";
|
||||||
|
|
||||||
import { TextField, Button, Badge } from "@renderer/components";
|
import { TextField, Button, Badge } from "@renderer/components";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
@ -10,6 +10,7 @@ import { AddDownloadSourceModal } from "./add-download-source-modal";
|
|||||||
import { useToast } from "@renderer/hooks";
|
import { useToast } from "@renderer/hooks";
|
||||||
import { DownloadSourceStatus } from "@shared";
|
import { DownloadSourceStatus } from "@shared";
|
||||||
import { SPACING_UNIT } from "@renderer/theme.css";
|
import { SPACING_UNIT } from "@renderer/theme.css";
|
||||||
|
import { settingsContext } from "@renderer/context";
|
||||||
|
|
||||||
export function SettingsDownloadSources() {
|
export function SettingsDownloadSources() {
|
||||||
const [showAddDownloadSourceModal, setShowAddDownloadSourceModal] =
|
const [showAddDownloadSourceModal, setShowAddDownloadSourceModal] =
|
||||||
@ -18,8 +19,9 @@ export function SettingsDownloadSources() {
|
|||||||
const [isSyncingDownloadSources, setIsSyncingDownloadSources] =
|
const [isSyncingDownloadSources, setIsSyncingDownloadSources] =
|
||||||
useState(false);
|
useState(false);
|
||||||
|
|
||||||
const { t } = useTranslation("settings");
|
const { sourceUrl, clearSourceUrl } = useContext(settingsContext);
|
||||||
|
|
||||||
|
const { t } = useTranslation("settings");
|
||||||
const { showSuccessToast } = useToast();
|
const { showSuccessToast } = useToast();
|
||||||
|
|
||||||
const getDownloadSources = async () => {
|
const getDownloadSources = async () => {
|
||||||
@ -32,6 +34,10 @@ export function SettingsDownloadSources() {
|
|||||||
getDownloadSources();
|
getDownloadSources();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (sourceUrl) setShowAddDownloadSourceModal(true);
|
||||||
|
}, [sourceUrl]);
|
||||||
|
|
||||||
const handleRemoveSource = async (id: number) => {
|
const handleRemoveSource = async (id: number) => {
|
||||||
await window.electron.removeDownloadSource(id);
|
await window.electron.removeDownloadSource(id);
|
||||||
showSuccessToast(t("removed_download_source"));
|
showSuccessToast(t("removed_download_source"));
|
||||||
@ -63,11 +69,16 @@ export function SettingsDownloadSources() {
|
|||||||
[DownloadSourceStatus.Errored]: t("download_source_errored"),
|
[DownloadSourceStatus.Errored]: t("download_source_errored"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleModalClose = () => {
|
||||||
|
clearSourceUrl();
|
||||||
|
setShowAddDownloadSourceModal(false);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<AddDownloadSourceModal
|
<AddDownloadSourceModal
|
||||||
visible={showAddDownloadSourceModal}
|
visible={showAddDownloadSourceModal}
|
||||||
onClose={() => setShowAddDownloadSourceModal(false)}
|
onClose={handleModalClose}
|
||||||
onAddDownloadSource={handleAddDownloadSource}
|
onAddDownloadSource={handleAddDownloadSource}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useContext, useEffect, useState } from "react";
|
||||||
import ISO6391 from "iso-639-1";
|
import ISO6391 from "iso-639-1";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -8,27 +8,24 @@ import {
|
|||||||
SelectField,
|
SelectField,
|
||||||
} from "@renderer/components";
|
} from "@renderer/components";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import type { UserPreferences } from "@types";
|
|
||||||
import { useAppSelector } from "@renderer/hooks";
|
import { useAppSelector } from "@renderer/hooks";
|
||||||
|
|
||||||
import { changeLanguage } from "i18next";
|
import { changeLanguage } from "i18next";
|
||||||
import * as languageResources from "@locales";
|
import * as languageResources from "@locales";
|
||||||
import { orderBy } from "lodash-es";
|
import { orderBy } from "lodash-es";
|
||||||
|
import { settingsContext } from "@renderer/context";
|
||||||
|
|
||||||
interface LanguageOption {
|
interface LanguageOption {
|
||||||
option: string;
|
option: string;
|
||||||
nativeName: string;
|
nativeName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SettingsGeneralProps {
|
export function SettingsGeneral() {
|
||||||
updateUserPreferences: (values: Partial<UserPreferences>) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function SettingsGeneral({
|
|
||||||
updateUserPreferences,
|
|
||||||
}: SettingsGeneralProps) {
|
|
||||||
const { t } = useTranslation("settings");
|
const { t } = useTranslation("settings");
|
||||||
|
|
||||||
|
const { updateUserPreferences } = useContext(settingsContext);
|
||||||
|
|
||||||
const userPreferences = useAppSelector(
|
const userPreferences = useAppSelector(
|
||||||
(state) => state.userPreferences.value
|
(state) => state.userPreferences.value
|
||||||
);
|
);
|
||||||
|
@ -1,26 +1,23 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useContext, useEffect, useState } from "react";
|
||||||
import { Trans, useTranslation } from "react-i18next";
|
import { Trans, useTranslation } from "react-i18next";
|
||||||
|
|
||||||
import { Button, CheckboxField, Link, TextField } from "@renderer/components";
|
import { Button, CheckboxField, Link, TextField } from "@renderer/components";
|
||||||
import * as styles from "./settings-real-debrid.css";
|
import * as styles from "./settings-real-debrid.css";
|
||||||
import type { UserPreferences } from "@types";
|
|
||||||
import { useAppSelector, useToast } from "@renderer/hooks";
|
import { useAppSelector, useToast } from "@renderer/hooks";
|
||||||
|
|
||||||
import { SPACING_UNIT } from "@renderer/theme.css";
|
import { SPACING_UNIT } from "@renderer/theme.css";
|
||||||
|
import { settingsContext } from "@renderer/context";
|
||||||
|
|
||||||
const REAL_DEBRID_API_TOKEN_URL = "https://real-debrid.com/apitoken";
|
const REAL_DEBRID_API_TOKEN_URL = "https://real-debrid.com/apitoken";
|
||||||
|
|
||||||
export interface SettingsRealDebridProps {
|
export function SettingsRealDebrid() {
|
||||||
updateUserPreferences: (values: Partial<UserPreferences>) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function SettingsRealDebrid({
|
|
||||||
updateUserPreferences,
|
|
||||||
}: SettingsRealDebridProps) {
|
|
||||||
const userPreferences = useAppSelector(
|
const userPreferences = useAppSelector(
|
||||||
(state) => state.userPreferences.value
|
(state) => state.userPreferences.value
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { updateUserPreferences } = useContext(settingsContext);
|
||||||
|
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [form, setForm] = useState({
|
const [form, setForm] = useState({
|
||||||
useRealDebrid: false,
|
useRealDebrid: false,
|
||||||
|
@ -1,21 +1,20 @@
|
|||||||
import { useState } from "react";
|
|
||||||
import { Button } from "@renderer/components";
|
import { Button } from "@renderer/components";
|
||||||
|
|
||||||
import * as styles from "./settings.css";
|
import * as styles from "./settings.css";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { UserPreferences } from "@types";
|
|
||||||
import { SettingsRealDebrid } from "./settings-real-debrid";
|
import { SettingsRealDebrid } from "./settings-real-debrid";
|
||||||
import { SettingsGeneral } from "./settings-general";
|
import { SettingsGeneral } from "./settings-general";
|
||||||
import { SettingsBehavior } from "./settings-behavior";
|
import { SettingsBehavior } from "./settings-behavior";
|
||||||
import { useAppDispatch } from "@renderer/hooks";
|
|
||||||
import { setUserPreferences } from "@renderer/features";
|
|
||||||
import { SettingsDownloadSources } from "./settings-download-sources";
|
import { SettingsDownloadSources } from "./settings-download-sources";
|
||||||
|
import {
|
||||||
|
SettingsContextConsumer,
|
||||||
|
SettingsContextProvider,
|
||||||
|
} from "@renderer/context";
|
||||||
|
|
||||||
export function Settings() {
|
export function Settings() {
|
||||||
const { t } = useTranslation("settings");
|
const { t } = useTranslation("settings");
|
||||||
|
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
|
|
||||||
const categories = [
|
const categories = [
|
||||||
t("general"),
|
t("general"),
|
||||||
t("behavior"),
|
t("behavior"),
|
||||||
@ -23,37 +22,24 @@ export function Settings() {
|
|||||||
"Real-Debrid",
|
"Real-Debrid",
|
||||||
];
|
];
|
||||||
|
|
||||||
const [currentCategoryIndex, setCurrentCategoryIndex] = useState(0);
|
return (
|
||||||
|
<SettingsContextProvider>
|
||||||
const handleUpdateUserPreferences = async (
|
<SettingsContextConsumer>
|
||||||
values: Partial<UserPreferences>
|
{({ currentCategoryIndex, setCurrentCategoryIndex }) => {
|
||||||
) => {
|
|
||||||
await window.electron.updateUserPreferences(values);
|
|
||||||
window.electron.getUserPreferences().then((userPreferences) => {
|
|
||||||
dispatch(setUserPreferences(userPreferences));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const renderCategory = () => {
|
const renderCategory = () => {
|
||||||
if (currentCategoryIndex === 0) {
|
if (currentCategoryIndex === 0) {
|
||||||
return (
|
return <SettingsGeneral />;
|
||||||
<SettingsGeneral updateUserPreferences={handleUpdateUserPreferences} />
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentCategoryIndex === 1) {
|
if (currentCategoryIndex === 1) {
|
||||||
return (
|
return <SettingsBehavior />;
|
||||||
<SettingsBehavior updateUserPreferences={handleUpdateUserPreferences} />
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentCategoryIndex === 2) {
|
if (currentCategoryIndex === 2) {
|
||||||
return <SettingsDownloadSources />;
|
return <SettingsDownloadSources />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return <SettingsRealDebrid />;
|
||||||
<SettingsRealDebrid updateUserPreferences={handleUpdateUserPreferences} />
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -63,7 +49,9 @@ export function Settings() {
|
|||||||
{categories.map((category, index) => (
|
{categories.map((category, index) => (
|
||||||
<Button
|
<Button
|
||||||
key={category}
|
key={category}
|
||||||
theme={currentCategoryIndex === index ? "primary" : "outline"}
|
theme={
|
||||||
|
currentCategoryIndex === index ? "primary" : "outline"
|
||||||
|
}
|
||||||
onClick={() => setCurrentCategoryIndex(index)}
|
onClick={() => setCurrentCategoryIndex(index)}
|
||||||
>
|
>
|
||||||
{category}
|
{category}
|
||||||
@ -76,4 +64,8 @@ export function Settings() {
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
}}
|
||||||
|
</SettingsContextConsumer>
|
||||||
|
</SettingsContextProvider>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ export const UserEditProfileModal = ({
|
|||||||
filters: [
|
filters: [
|
||||||
{
|
{
|
||||||
name: "Image",
|
name: "Image",
|
||||||
extensions: ["jpg", "jpeg", "png", "gif", "webp", "bmp"],
|
extensions: ["jpg", "jpeg", "png", "webp"],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
@ -22,7 +22,7 @@ export const vars = createGlobalTheme(":root", {
|
|||||||
small: "12px",
|
small: "12px",
|
||||||
},
|
},
|
||||||
zIndex: {
|
zIndex: {
|
||||||
toast: "2",
|
toast: "5",
|
||||||
bottomPanel: "3",
|
bottomPanel: "3",
|
||||||
titleBar: "4",
|
titleBar: "4",
|
||||||
backdrop: "4",
|
backdrop: "4",
|
||||||
|
Loading…
Reference in New Issue
Block a user