Compare commits

..

24 Commits

Author SHA1 Message Date
Zamitto
260a11ba6a Merge pull request #1465 from hydralauncher/fix/lazy-loading-messing-up-custom-css
fix: lazy loading messing up custom css
2025-02-19 18:40:37 -03:00
Zamitto
adf3bf38a8 chore: fix gh actions concurrency 2025-02-18 22:36:49 -03:00
Zamitto
b6193636dd chore: fix gh actions concurrency 2025-02-18 22:33:48 -03:00
Zamitto
923601bdef feat: add readonly to test pipeline 2025-02-18 22:32:13 -03:00
Zamitto
58855a93a8 feat: add readonly to test pipeline 2025-02-18 22:31:19 -03:00
Zamitto
d879f2e3df chore: bump version 2025-02-18 22:29:38 -03:00
Zamitto
73ab3872a7 fix: lazy loading messing up custom css 2025-02-18 22:25:41 -03:00
Zamitto
726a39a430 chore: bump version 2025-02-17 22:44:09 -03:00
Zamitto
741364e922 Merge pull request #1459 from hydrasources/patch-12
Update RU translation.json
2025-02-17 22:43:50 -03:00
Zamitto
92ac5b0d1a Merge pull request #1462 from hydralauncher/feat/improve-theming
Feat/improve theming
2025-02-17 22:41:42 -03:00
Zamitto
4641b1967e Merge branch 'main' into patch-12 2025-02-17 22:41:29 -03:00
Zamitto
0bf70ffebd Merge pull request #1463 from hydralauncher/feat/user-badges
Feat/user badges
2025-02-17 22:38:21 -03:00
Hachi-R
21cec50e2e lint 2025-02-17 22:32:07 -03:00
Hachi-R
0724a40cb7 fix: improve theme import modal flow and navigation 2025-02-17 22:29:42 -03:00
Zamitto
e066ea3503 feat: css 2025-02-17 21:14:32 -03:00
Zamitto
cf202c8f01 feat: add user badges 2025-02-17 21:04:33 -03:00
Hachi-R
75a44bed3f refactor: minor hero panel formatting cleanup 2025-02-17 20:07:16 -03:00
Hachi-R
c5206c68ee refactor: simplify game details hero section layout and scrolling 2025-02-17 20:06:39 -03:00
Hachi-R
0b4c3a6cd2 fix: make title bar overlay fully transparent 2025-02-17 18:59:57 -03:00
Zamitto
86847ec50e Merge branch 'main' into patch-12 2025-02-17 17:58:05 -03:00
Zamitto
e086369b13 Merge pull request #1461 from 7ROBE/patch-8
Update translation.json
2025-02-17 17:57:40 -03:00
7ROBE
e695d599de Update translation.json 2025-02-17 22:38:36 +03:00
hydrasources
ad55165078 Update translation.json 2025-02-17 11:21:15 +03:00
hydrasources
385e29262c Update translation.json 2025-02-17 08:29:52 +03:00
22 changed files with 340 additions and 209 deletions

View File

@@ -1,5 +1,9 @@
name: Build name: Build
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on: pull_request on: pull_request
jobs: jobs:

View File

@@ -1,5 +1,9 @@
name: Lint name: Lint
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on: pull_request on: pull_request
jobs: jobs:

View File

@@ -1,5 +1,9 @@
name: Release name: Release
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on: on:
push: push:
branches: main branches: main

View File

@@ -1,6 +1,6 @@
{ {
"name": "hydralauncher", "name": "hydralauncher",
"version": "3.2.0", "version": "3.2.2",
"description": "Hydra", "description": "Hydra",
"main": "./out/main/index.js", "main": "./out/main/index.js",
"author": "Los Broxas", "author": "Los Broxas",

View File

@@ -7,18 +7,18 @@
"featured": "مميز", "featured": "مميز",
"surprise_me": "مفاجئني", "surprise_me": "مفاجئني",
"no_results": "لم يتم العثور على نتائج", "no_results": "لم يتم العثور على نتائج",
"start_typing": "ابدأ الكتابة للبحث...", "start_typing": "ابدأ بالكتابة للبحث...",
"hot": "الأكثر شيوعًا الآن", "hot": "الأكثر شهرة الآن",
"weekly": "📅 أفضل ألعاب الأسبوع", "weekly": "📅 أفضل ألعاب الأسبوع",
"achievements": "🏆 ألعاب للتغلب عليها" "achievements": "🏆 ألعاب يجب إكمالها"
}, },
"sidebar": { "sidebar": {
"catalogue": "الكـتالوج", "catalogue": "الفهرس",
"downloads": "التنزيلات", "downloads": "التنزيلات",
"settings": "الإعدادات", "settings": "الإعدادات",
"my_library": "مكتبتي", "my_library": "مكتبتي",
"downloading_metadata": "{{title}} (جارٍ تنزيل البيانات الوصفية...)", "downloading_metadata": "{{title}} (جاري تنزيل البيانات الوصفية...)",
"paused": "{{title}} (معلّق)", "paused": "{{title}} (معلق)",
"downloading": "{{title}} ({{percentage}} - جاري التنزيل...)", "downloading": "{{title}} ({{percentage}} - جاري التنزيل...)",
"filter": "تصفية المكتبة", "filter": "تصفية المكتبة",
"home": "الرئيسية", "home": "الرئيسية",
@@ -26,12 +26,13 @@
"game_has_no_executable": "اللعبة لا تحتوي على ملف تشغيل", "game_has_no_executable": "اللعبة لا تحتوي على ملف تشغيل",
"sign_in": "تسجيل الدخول", "sign_in": "تسجيل الدخول",
"friends": "الأصدقاء", "friends": "الأصدقاء",
"need_help": "تحتاج مساعدة؟" "need_help": "تحتاج مساعدة؟",
"favorites": "المفضلة"
}, },
"header": { "header": {
"search": "ابحث عن الألعاب", "search": "بحث الألعاب",
"home": "الرئيسية", "home": "الرئيسية",
"catalogue": "الكـتالوج", "catalogue": "الفهرس",
"downloads": "التنزيلات", "downloads": "التنزيلات",
"search_results": "نتائج البحث", "search_results": "نتائج البحث",
"settings": "الإعدادات", "settings": "الإعدادات",
@@ -40,16 +41,16 @@
}, },
"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}} اكتمال) - جاري حساب الوقت المتبقي...", "calculating_eta": "جاري تنزيل {{title}}... ({{percentage}} مكتمل) - جاري حساب الوقت المتبقي...",
"checking_files": "جارٍ فحص ملفات {{title}}... ({{percentage}} اكتمال)" "checking_files": "جاري فحص ملفات {{title}}... ({{percentage}} مكتمل)"
}, },
"catalogue": { "catalogue": {
"search": "تصفية...", "search": "تصفية...",
"developers": "المطورون", "developers": "المطورون",
"genres": "الأنواع", "genres": "الأنواع",
"tags": "العلامات", "tags": "الوسوم",
"publishers": "الناشرون", "publishers": "الناشرون",
"download_sources": "مصادر التنزيل", "download_sources": "مصادر التنزيل",
"result_count": "{{resultCount}} نتيجة", "result_count": "{{resultCount}} نتيجة",
@@ -68,34 +69,34 @@
"cancel": "إلغاء", "cancel": "إلغاء",
"remove": "إزالة", "remove": "إزالة",
"space_left_on_disk": "{{space}} متبقي على القرص", "space_left_on_disk": "{{space}} متبقي على القرص",
"eta": "الانتهاء {{eta}}", "eta": "الانتهاء المتوقع {{eta}}",
"calculating_eta": "جارٍ حساب الوقت المتبقي...", "calculating_eta": "جاري حساب الوقت المتبقي...",
"downloading_metadata": "جارٍ تنزيل البيانات الوصفية...", "downloading_metadata": "جاري تنزيل البيانات الوصفية...",
"filter": "تصفية الحزم المعاد تعبئتها", "filter": "تصفية الإصدارات المعادة",
"requirements": "متطلبات النظام", "requirements": "متطلبات النظام",
"minimum": "الحد الأدنى", "minimum": "الحد الأدنى",
"recommended": ُوصى به", "recommended": ستحسن",
"paused": "معلّق", "paused": "معلق",
"release_date": "تاريخ الإصدار {{date}}", "release_date": "تاريخ الإصدار {{date}}",
"publisher": "نشر بواسطة {{publisher}}", "publisher": "نشر بواسطة {{publisher}}",
"hours": "ساعات", "hours": "ساعات",
"minutes": "دقائق", "minutes": "دقائق",
"amount_hours": "{{amount}} ساعات", "amount_hours": "{{amount}} ساعة",
"amount_minutes": "{{amount}} دقائق", "amount_minutes": "{{amount}} دقيقة",
"accuracy": "دقة {{accuracy}}%", "accuracy": "دقة {{accuracy}}%",
"add_to_library": "إضافة إلى المكتبة", "add_to_library": "إضافة إلى المكتبة",
"remove_from_library": "إزالة من المكتبة", "remove_from_library": "إزالة من المكتبة",
"no_downloads": "لا توجد تنزيلات متاحة", "no_downloads": "لا توجد تنزيلات متاحة",
"play_time": "لعب لمدة {{amount}}", "play_time": "وقت اللعب {{amount}}",
"last_time_played": "آخر تشغيل {{period}}", "last_time_played": "آخر مرة لعب {{period}}",
"not_played_yet": "لم تلعب {{title}} بعد", "not_played_yet": "لم تلعب {{title}} بعد",
"next_suggestion": "الاقتراح التالي", "next_suggestion": "الاقتراح التالي",
"play": "تشغيل", "play": "تشغيل",
"deleting": "جارٍ حذف المثبت...", "deleting": "جاري حذف المثبت...",
"close": "إغلاق", "close": "إغلاق",
"playing_now": تم التشغيل الآن", "playing_now": "جاري التشغيل الآن",
"change": "تغيير", "change": "تغيير",
"repacks_modal_description": "اختر الحزمة المعاد تعبئتها التي تريد تنزيلها", "repacks_modal_description": "اختر الإصدار المعاد الذي تريد تنزيله",
"select_folder_hint": "لتغيير المجلد الافتراضي، انتقل إلى <0>الإعدادات</0>", "select_folder_hint": "لتغيير المجلد الافتراضي، انتقل إلى <0>الإعدادات</0>",
"download_now": "تنزيل الآن", "download_now": "تنزيل الآن",
"no_shop_details": "تعذر الحصول على تفاصيل المتجر.", "no_shop_details": "تعذر الحصول على تفاصيل المتجر.",
@@ -110,12 +111,12 @@
"select_executable": "تحديد", "select_executable": "تحديد",
"no_executable_selected": "لم يتم تحديد ملف تشغيل", "no_executable_selected": "لم يتم تحديد ملف تشغيل",
"open_folder": "فتح المجلد", "open_folder": "فتح المجلد",
"open_download_location": "عرض الملفات المحملة", "open_download_location": "عرض الملفات المنزلة",
"create_shortcut": "إنشاء اختصار على سطح المكتب", "create_shortcut": "إنشاء اختصار على سطح المكتب",
"clear": "مسح", "clear": "مسح",
"remove_files": "إزالة الملفات", "remove_files": "إزالة الملفات",
"remove_from_library_title": "هل أنت متأكد؟", "remove_from_library_title": "هل أنت متأكد؟",
"remove_from_library_description": "سيؤدي هذا إلى إزالة {{game}} من مكتبتك", "remove_from_library_description": "سيتم إزالة {{game}} من مكتبتك",
"options": "خيارات", "options": "خيارات",
"executable_section_title": "ملف التشغيل", "executable_section_title": "ملف التشغيل",
"executable_section_description": "مسار الملف الذي سيتم تشغيله عند النقر على \"تشغيل\"", "executable_section_description": "مسار الملف الذي سيتم تشغيله عند النقر على \"تشغيل\"",
@@ -123,35 +124,35 @@
"downloads_section_description": "تحقق من التحديثات أو الإصدارات الأخرى لهذه اللعبة", "downloads_section_description": "تحقق من التحديثات أو الإصدارات الأخرى لهذه اللعبة",
"danger_zone_section_title": "منطقة الخطر", "danger_zone_section_title": "منطقة الخطر",
"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_success": "تم إنشاء الاختصار بنجاح",
"create_shortcut_error": "خطأ في إنشاء الاختصار", "create_shortcut_error": "خطأ في إنشاء الاختصار",
"nsfw_content_title": "هذه اللعبة تحتوي على محتوى غير لائق", "nsfw_content_title": "هذه اللعبة تحتوي على محتوى غير لائق",
"nsfw_content_description": "{{title}} يحتوي على محتوى قد لا يناسب جميع الأعمار. هل تريد المتابعة؟", "nsfw_content_description": "{{title}} يحتوي على محتوى قد لا يكون مناسبًا لجميع الأعمار. هل تريد المتابعة؟",
"allow_nsfw_content": "متابعة", "allow_nsfw_content": "متابعة",
"refuse_nsfw_content": "رجوع", "refuse_nsfw_content": "رجوع",
"stats": "الإحصائيات", "stats": "الإحصائيات",
"download_count": "مرات التنزيل", "download_count": "التنزيلات",
"player_count": "اللاعبون النشطون", "player_count": "اللاعبون النشطون",
"download_error": "خيار التنزيل هذا غير متاح", "download_error": "خيار التنزيل هذا غير متاح",
"download": "تنزيل", "download": "تنزيل",
"executable_path_in_use": "مسار التشغيل مستخدم بالفعل بواسطة \"{{game}}\"", "executable_path_in_use": "مسار التشغيل مستخدم بالفعل بواسطة \"{{game}}\"",
"warning": "تحذير:", "warning": "تحذير:",
"hydra_needs_to_remain_open": "لهذا التنزيل، يجب أن يبقى Hydra مفتوحًا حتى اكتماله. إذا أغلق Hydra قبل الاكتمال، ستفقد تقدمك.", "hydra_needs_to_remain_open": "لهذا التنزيل، يجب أن يظل Hydra مفتوحًا حتى اكتماله. إذا تم إغلاق Hydra قبل الاكتمال، ستفقد تقدمك.",
"achievements": "الإنجازات", "achievements": "الإنجازات",
"achievements_count": "الإنجازات {{unlockedCount}}/{{achievementsCount}}", "achievements_count": "الإنجازات {{unlockedCount}}/{{achievementsCount}}",
"cloud_save": "حفظ سحابي", "cloud_save": "حفظ سحابي",
"cloud_save_description": "احفظ تقدمك على السحابة واستمر في اللعب من أي جهاز", "cloud_save_description": "احفظ تقدمك في السحابة واستمر في اللعب من أي جهاز",
"backups": "النسخ الاحتياطية", "backups": "النسخ الاحتياطية",
"install_backup": "تثبيت", "install_backup": "تثبيت",
"delete_backup": "حذف", "delete_backup": "حذف",
"create_backup": "نسخة احتياطية جديدة", "create_backup": "نسخة احتياطية جديدة",
"last_backup_date": "آخر نسخة احتياطية في {{date}}", "last_backup_date": "آخر نسخة احتياطية في {{date}}",
"no_backup_preview": "لم يتم العثور على حفظات لهذا العنوان", "no_backup_preview": "لم يتم العثور على حفظات لهذا العنوان",
"restoring_backup": "جارٍ استعادة النسخة الاحتياطية ({{progress}} اكتمال)...", "restoring_backup": "جاري استعادة النسخة الاحتياطية ({{progress}} مكتمل)...",
"uploading_backup": "جارٍ رفع النسخة الاحتياطية...", "uploading_backup": "جاري رفع النسخة الاحتياطية...",
"no_backups": "لم تقم بإنشاء أي نسخ احتياطية لهذه اللعبة بعد", "no_backups": "لم تقم بإنشاء أي نسخ احتياطية لهذه اللعبة بعد",
"backup_uploaded": "تم رفع النسخة الاحتياطية", "backup_uploaded": "تم رفع النسخة الاحتياطية",
"backup_deleted": "تم حذف النسخة الاحتياطية", "backup_deleted": "تم حذف النسخة الاحتياطية",
@@ -164,61 +165,67 @@
"files_automatically_mapped": "تم تعيين الملفات تلقائيًا", "files_automatically_mapped": "تم تعيين الملفات تلقائيًا",
"no_backups_created": "لم يتم إنشاء نسخ احتياطية لهذه اللعبة", "no_backups_created": "لم يتم إنشاء نسخ احتياطية لهذه اللعبة",
"manage_files": "إدارة الملفات", "manage_files": "إدارة الملفات",
"loading_save_preview": "جارٍ البحث عن حفظات الألعاب...", "loading_save_preview": "جاري البحث عن حفظات اللعبة...",
"wine_prefix": "بادئة Wine", "wine_prefix": "بادئة Wine",
"wine_prefix_description": "بادئة Wine المستخدمة لتشغيل هذه اللعبة", "wine_prefix_description": "بادئة Wine المستخدمة لتشغيل هذه اللعبة",
"launch_options": "خيارات التشغيل", "launch_options": "خيارات التشغيل",
"launch_options_description": "يمكن للمستخدمين المتقدمين إدخال تعديلات على خيارات التشغيل (ميزة تجريبية)", "launch_options_description": "يمكن للمستخدمين المتقدمين إدخال تعديلات على خيارات التشغيل (ميزة تجريبية)",
"launch_options_placeholder": م يتم تحديد أي معاملات", "launch_options_placeholder": ا توجد معلمات محددة",
"no_download_option_info": "لا توجد معلومات متاحة", "no_download_option_info": "لا توجد معلومات متاحة",
"backup_deletion_failed": "فشل حذف النسخة الاحتياطية", "backup_deletion_failed": "فشل في حذف النسخة الاحتياطية",
"max_number_of_artifacts_reached": "تم الوصول إلى الحد الأقصى لعدد النسخ الاحتياطية لهذه اللعبة", "max_number_of_artifacts_reached": "تم الوصول إلى الحد الأقصى من النسخ الاحتياطية لهذه اللعبة",
"achievements_not_sync": "تعرف على كيفية مزامنة إنجازاتك", "achievements_not_sync": "شاهد كيفية مزامنة إنجازاتك",
"manage_files_description": "إدارة الملفات التي سيتم نسخها احتياطيًا واستعادتها", "manage_files_description": "إدارة الملفات التي سيتم نسخها احتياطيًا واستعادتها",
"select_folder": "حدد المجلد", "select_folder": "حدد المجلد",
"backup_from": "نسخة احتياطية من {{date}}", "backup_from": "نسخة احتياطية من {{date}}",
"custom_backup_location_set": "تم تعيين موقع نسخ احتياطي مخصص", "custom_backup_location_set": "تم تعيين موقع نسخ احتياطي مخصص",
"no_directory_selected": "لم يتم تحديد مجلد", "no_directory_selected": "لم يتم تحديد مجلد",
"no_write_permission": "لا يمكن التنزيل إلى هذا المجلد. انقر هنا لمعرفة المزيد.", "no_write_permission": "لا يمكن التنزيل إلى هذا المجلد. انقر هنا للمزيد من المعلومات.",
"reset_achievements": "إعادة تعيين الإنجازات", "reset_achievements": "إعادة تعيين الإنجازات",
"reset_achievements_description": "سيؤدي هذا إلى إعادة تعيين جميع إنجازات {{game}}", "reset_achievements_description": "سيؤدي هذا إلى إعادة تعيين جميع إنجازات {{game}}",
"reset_achievements_title": "هل أنت متأكد؟", "reset_achievements_title": "هل أنت متأكد؟",
"reset_achievements_success": "تم إعادة تعيين الإنجازات بنجاح", "reset_achievements_success": "تم إعادة تعيين الإنجازات بنجاح",
"reset_achievements_error": "فشل إعادة تعيين الإنجازات" "reset_achievements_error": "فشل في إعادة تعيين الإنجازات",
"download_error_gofile_quota_exceeded": "لقد تجاوزت الحصة الشهرية لـ Gofile. يرجى الانتظار حتى إعادة تعيين الحصة.",
"download_error_real_debrid_account_not_authorized": "حساب Real-Debrid الخاص بك غير مصرح له بإجراء تنزيلات جديدة. يرجى مراجعة إعدادات الحساب والمحاولة مرة أخرى.",
"download_error_not_cached_in_real_debrid": "هذا التنزيل غير متوفر على Real-Debrid وجلب حالة التنزيل من Real-Debrid غير متاح حاليًا.",
"download_error_not_cached_in_torbox": "هذا التنزيل غير متوفر على Torbox وجلب حالة التنزيل من Torbox غير متاح حاليًا.",
"game_removed_from_favorites": "تمت إزالة اللعبة من المفضلة",
"game_added_to_favorites": "تمت إضافة اللعبة إلى المفضلة"
}, },
"activation": { "activation": {
"title": "تفعيل Hydra", "title": "تفعيل Hydra",
"installation_id": "معرف التثبيت:", "installation_id": "معرف التثبيت:",
"enter_activation_code": "أدخل رمز التفعيل الخاص بك", "enter_activation_code": "أدخل رمز التفعيل الخاص بك",
"message": "إذا كنت لا تعرف أين تطلب هذا، فلا يجب أن يكون لديك هذا.", "message": "إذا كنت لا تعرف أين تطلب هذا، فأنت لا يجب أن يكون لديك هذا.",
"activate": "تفعيل", "activate": "تفعيل",
"loading": "جارٍ التحميل..." "loading": "جاري التحميل..."
}, },
"downloads": { "downloads": {
"resume": "استئناف", "resume": "استئناف",
"pause": "إيقاف مؤقت", "pause": "إيقاف مؤقت",
"eta": "الانتهاء {{eta}}", "eta": "الانتهاء المتوقع {{eta}}",
"paused": "معلّق", "paused": "معلق",
"verifying": "جارٍ التحقق...", "verifying": "جاري التحقق...",
"completed": "مكتمل", "completed": "مكتمل",
"removed": "غير محمل", "removed": "غير منزّل",
"cancel": "إلغاء", "cancel": "إلغاء",
"filter": "تصفية الألعاب المحملة", "filter": "تصفية الألعاب المنزلة",
"remove": "إزالة", "remove": "إزالة",
"downloading_metadata": "جارٍ تنزيل البيانات الوصفية...", "downloading_metadata": "جاري تنزيل البيانات الوصفية...",
"deleting": "جارٍ حذف المثبت...", "deleting": "جاري حذف المثبت...",
"delete": "إزالة المثبت", "delete": "حذف المثبت",
"delete_modal_title": "هل أنت متأكد؟", "delete_modal_title": "هل أنت متأكد؟",
"delete_modal_description": "سيؤدي هذا إلى إزالة جميع ملفات التثبيت من جهازك", "delete_modal_description": "سيؤدي هذا إلى إزالة جميع ملفات التثبيت من جهازك",
"install": "تثبيت", "install": "تثبيت",
"download_in_progress": "قيد التقدم", "download_in_progress": "قيد التقدم",
"queued_downloads": "التنزيلات في قائمة الانتظار", "queued_downloads": "التنزيلات في قائمة الانتظار",
"downloads_completed": "مكتمل", "downloads_completed": "مكتملة",
"queued": "في قائمة الانتظار", "queued": "في قائمة الانتظار",
"no_downloads_title": "فارغ جدًا", "no_downloads_title": "لا شيء هنا",
"no_downloads_description": "لم تقم بتنزيل أي شيء باستخدام Hydra بعد، ولكن لم يفت الأوان للبدء.", "no_downloads_description": "لم تقم بتنزيل أي شيء باستخدام Hydra بعد، ولكن لم يفت الأوان للبدء.",
"checking_files": "جارٍ فحص الملفات...", "checking_files": "جاري فحص الملفات...",
"seeding": "التوزيع", "seeding": "جاري التوزيع",
"stop_seeding": "إيقاف التوزيع", "stop_seeding": "إيقاف التوزيع",
"resume_seeding": "استئناف التوزيع", "resume_seeding": "استئناف التوزيع",
"options": "إدارة" "options": "إدارة"
@@ -228,8 +235,8 @@
"change": "تحديث", "change": "تحديث",
"notifications": "الإشعارات", "notifications": "الإشعارات",
"enable_download_notifications": "عند اكتمال التنزيل", "enable_download_notifications": "عند اكتمال التنزيل",
"enable_repack_list_notifications": "عند إضافة حزمة معاد تعبئتها جديدة", "enable_repack_list_notifications": "عند إضافة إصدار معاد جديد",
"real_debrid_api_token_label": "رمز واجهة برمجة تطبيقات Real-Debrid", "real_debrid_api_token_label": "رمز Real-Debrid API",
"quit_app_instead_hiding": "لا تخفي Hydra عند الإغلاق", "quit_app_instead_hiding": "لا تخفي Hydra عند الإغلاق",
"launch_with_system": "تشغيل Hydra مع بدء النظام", "launch_with_system": "تشغيل Hydra مع بدء النظام",
"general": "عام", "general": "عام",
@@ -238,21 +245,21 @@
"language": "اللغة", "language": "اللغة",
"api_token": "رمز API", "api_token": "رمز API",
"enable_real_debrid": "تفعيل Real-Debrid", "enable_real_debrid": "تفعيل Real-Debrid",
"real_debrid_description": "Real-Debrid هو أداة تنزيل غير مقيدة تتيح لك تنزيل الملفات بسرعة، مقيدة فقط بسرعة الإنترنت لديك.", "real_debrid_description": "Real-Debrid هو أداة تنزيل غير مقيدة تتيح لك تنزيل الملفات بسرعة، محدودة فقط بسرعة اتصالك بالإنترنت.",
"debrid_invalid_token": "رمز API غير صالح", "debrid_invalid_token": "رمز API غير صالح",
"debrid_api_token_hint": "يمكنك الحصول على رمز API الخاص بك <0>هنا</0>", "debrid_api_token_hint": "يمكنك الحصول على رمز API الخاص بك <0>هنا</0>",
"real_debrid_free_account_error": "الحساب \"{{username}}\" هو حساب مجاني. يرجى الاشتراك في Real-Debrid", "real_debrid_free_account_error": "الحساب \"{{username}}\" حساب مجاني. يرجى الاشتراك في Real-Debrid",
"debrid_linked_message": "تم ربط الحساب \"{{username}}\"", "debrid_linked_message": "تم ربط الحساب \"{{username}}\"",
"save_changes": "حفظ التغييرات", "save_changes": "حفظ التغييرات",
"changes_saved": "تم حفظ التغييرات بنجاح", "changes_saved": "تم حفظ التغييرات بنجاح",
"download_sources_description": "سيقوم Hydra بجلب روابط التنزيل من هذه المصادر. يجب أن يكون عنوان URL المصدر رابطًا مباشرًا لملف .json يحتوي على روابط التنزيل.", "download_sources_description": "سيقوم Hydra بجلب روابط التنزيل من هذه المصادر. يجب أن يكون عنوان URL للمصدر رابطًا مباشرًا لملف .json يحتوي على روابط التنزيل.",
"validate_download_source": "تحقق", "validate_download_source": "تحقق",
"remove_download_source": "إزالة", "remove_download_source": "إزالة",
"add_download_source": "إضافة مصدر", "add_download_source": "إضافة مصدر",
"download_count_zero": "لا توجد خيارات تنزيل", "download_count_zero": "لا توجد خيارات تنزيل",
"download_count_one": "{{countFormatted}} خيار تنزيل", "download_count_one": "{{countFormatted}} خيار تنزيل",
"download_count_other": "{{countFormatted}} خيارات تنزيل", "download_count_other": "{{countFormatted}} خيارات تنزيل",
"download_source_url": "عنوان URL لمصدر التنزيل", "download_source_url": "عنوان مصدر التنزيل",
"add_download_source_description": "أدخل عنوان URL لملف .json", "add_download_source_description": "أدخل عنوان URL لملف .json",
"download_source_up_to_date": "محدث", "download_source_up_to_date": "محدث",
"download_source_errored": "خطأ", "download_source_errored": "خطأ",
@@ -272,13 +279,13 @@
"profile_visibility": "رؤية الملف الشخصي", "profile_visibility": "رؤية الملف الشخصي",
"profile_visibility_description": "اختر من يمكنه رؤية ملفك الشخصي ومكتبتك", "profile_visibility_description": "اختر من يمكنه رؤية ملفك الشخصي ومكتبتك",
"required_field": "هذا الحقل مطلوب", "required_field": "هذا الحقل مطلوب",
"source_already_exists": "تمت إضافة هذا المصدر مسبقًا", "source_already_exists": "هذا المصدر مضاف مسبقًا",
"must_be_valid_url": "يجب أن يكون المصدر عنوان URL صالحًا", "must_be_valid_url": "يجب أن يكون المصدر عنوان URL صالح",
"blocked_users": "المستخدمون المحظورون", "blocked_users": "المستخدمون المحظورون",
"user_unblocked": "تم إلغاء حظر المستخدم", "user_unblocked": "تم إلغاء حظر المستخدم",
"enable_achievement_notifications": "عند فتح إنجاز", "enable_achievement_notifications": "عند فتح إنجاز",
"launch_minimized": "تشغيل Hydra مصغرًا", "launch_minimized": "تشغيل Hydra مصغرًا",
"disable_nsfw_alert": "تعطيل تنبيه المحتوى غير اللائق", "disable_nsfw_alert": "تعطيل تنبيهات المحتوى غير اللائق",
"seed_after_download_complete": "التوزيع بعد اكتمال التنزيل", "seed_after_download_complete": "التوزيع بعد اكتمال التنزيل",
"show_hidden_achievement_description": "عرض وصف الإنجازات المخفية قبل فتحها", "show_hidden_achievement_description": "عرض وصف الإنجازات المخفية قبل فتحها",
"account": "الحساب", "account": "الحساب",
@@ -296,18 +303,47 @@
"become_subscriber": "كن مشتركًا في Hydra Cloud", "become_subscriber": "كن مشتركًا في Hydra Cloud",
"subscription_renew_cancelled": "تم تعطيل التجديد التلقائي", "subscription_renew_cancelled": "تم تعطيل التجديد التلقائي",
"subscription_renews_on": "سيتم تجديد اشتراكك في {{date}}", "subscription_renews_on": "سيتم تجديد اشتراكك في {{date}}",
"bill_sent_until": "سيتم إرسال فاتورتك التالية حتى هذا اليوم" "bill_sent_until": "سيتم إرسال فاتورتك القادمة حتى هذا اليوم",
"no_themes": "يبدو أنه ليس لديك أي سمات بعد، لكن لا تقلق، انقر هنا لإنشاء أول تحفة فنية لك.",
"editor_tab_code": "الكود",
"editor_tab_info": "معلومات",
"editor_tab_save": "حفظ",
"web_store": "المتجر الإلكتروني",
"clear_themes": "مسح",
"create_theme": "إنشاء",
"create_theme_modal_title": "إنشاء سمة مخصصة",
"create_theme_modal_description": "إنشاء سمة جديدة لتخصيص مظهر Hydra",
"theme_name": "الاسم",
"insert_theme_name": "أدخل اسم السمة",
"set_theme": "تعيين السمة",
"unset_theme": "إلغاء تعيين السمة",
"delete_theme": "حذف السمة",
"edit_theme": "تعديل السمة",
"delete_all_themes": "حذف جميع السمات",
"delete_all_themes_description": "سيؤدي هذا إلى حذف جميع السمات المخصصة الخاصة بك",
"delete_theme_description": "سيؤدي هذا إلى حذف السمة {{theme}}",
"cancel": "إلغاء",
"appearance": "المظهر",
"enable_torbox": "تفعيل Torbox",
"torbox_description": "TorBox هي خدمة seedbox متميزة تنافس أفضل الخوادم في السوق.",
"torbox_account_linked": "تم ربط حساب TorBox",
"real_debrid_account_linked": "تم ربط حساب Real-Debrid",
"name_min_length": "يجب أن يكون اسم السمة على الأقل 3 أحرف",
"import_theme": "استيراد سمة",
"import_theme_description": "ستقوم باستيراد {{theme}} من متجر السمات",
"error_importing_theme": "خطأ في استيراد السمة",
"theme_imported": "تم استيراد السمة بنجاح"
}, },
"notifications": { "notifications": {
"download_complete": "اكتمل التنزيل", "download_complete": "اكتمل التنزيل",
"game_ready_to_install": "{{title}} جاهز للتثبيت", "game_ready_to_install": "{{title}} جاهز للتثبيت",
"repack_list_updated": "تم تحديث قائمة الحزم المعاد تعبئتها", "repack_list_updated": "تم تحديث قائمة الإصدارات المعادة",
"repack_count_one": "تمت إضافة {{count}} حزمة معاد تعبئتها", "repack_count_one": "تمت إضافة {{count}} إصدار معاد",
"repack_count_other": "تمت إضافة {{count}} حزم معاد تعبئتها", "repack_count_other": "تمت إضافة {{count}} إصدارات معادة",
"new_update_available": "الإصدار {{version}} متوفر", "new_update_available": "الإصدار {{version}} متوفر",
"restart_to_install_update": "أعد تشغيل Hydra لتثبيت التحديث", "restart_to_install_update": "أعد تشغيل Hydra لتثبيت التحديث",
"notification_achievement_unlocked_title": "تم فتح إنجاز لـ {{game}}", "notification_achievement_unlocked_title": "تم فتح إنجاز لـ {{game}}",
"notification_achievement_unlocked_body": "{{achievement}} و {{count}} آخرين تم فتحهم" "notification_achievement_unlocked_body": "{{achievement}} و {{count}} أخرى تم فتحها"
}, },
"system_tray": { "system_tray": {
"open": "فتح Hydra", "open": "فتح Hydra",
@@ -319,7 +355,7 @@
"binary_not_found_modal": { "binary_not_found_modal": {
"title": "البرامج غير مثبتة", "title": "البرامج غير مثبتة",
"description": "لم يتم العثور على ملفات تشغيل Wine أو Lutris على نظامك", "description": "لم يتم العثور على ملفات تشغيل Wine أو Lutris على نظامك",
"instructions": "تحقق من الطريقة الصحيحة لتثبيت أي منها على توزيعة لينكس الخاصة بك حتى تعمل اللعبة بشكل طبيعي" "instructions": "تحقق من الطريقة الصحيحة لتثبيت أي منها على توزيعة Linux الخاصة بك حتى تعمل اللعبة بشكل طبيعي"
}, },
"modal": { "modal": {
"close": "زر الإغلاق" "close": "زر الإغلاق"
@@ -328,16 +364,16 @@
"toggle_password_visibility": "تبديل رؤية كلمة المرور" "toggle_password_visibility": "تبديل رؤية كلمة المرور"
}, },
"user_profile": { "user_profile": {
"amount_hours": "{{amount}} ساعات", "amount_hours": "{{amount}} ساعة",
"amount_minutes": "{{amount}} دقائق", "amount_minutes": "{{amount}} دقيقة",
"last_time_played": "آخر تشغيل {{period}}", "last_time_played": "آخر مرة لعب {{period}}",
"activity": "النشاط الأخير", "activity": "النشاط الأخير",
"library": "المكتبة", "library": "المكتبة",
"total_play_time": "إجمالي وقت اللعب", "total_play_time": "إجمالي وقت اللعب",
"no_recent_activity_title": "همم... لا شيء هنا", "no_recent_activity_title": "لا شيء هنا...",
"no_recent_activity_description": "لم تلعب أي ألعاب مؤخرًا. حان الوقت لتغيير ذلك!", "no_recent_activity_description": "لم تلعب أي ألعاب مؤخرًا. حان الوقت لتغيير ذلك!",
"display_name": "اسم العرض", "display_name": "اسم العرض",
"saving": "جارٍ الحفظ", "saving": "جاري الحفظ",
"save": "حفظ", "save": "حفظ",
"edit_profile": "تعديل الملف الشخصي", "edit_profile": "تعديل الملف الشخصي",
"saved_successfully": "تم الحفظ بنجاح", "saved_successfully": "تم الحفظ بنجاح",
@@ -346,13 +382,13 @@
"cancel": "إلغاء", "cancel": "إلغاء",
"successfully_signed_out": "تم تسجيل الخروج بنجاح", "successfully_signed_out": "تم تسجيل الخروج بنجاح",
"sign_out": "تسجيل الخروج", "sign_out": "تسجيل الخروج",
"playing_for": "يلعب لمدة {{amount}}", "playing_for": "جاري اللعب لمدة {{amount}}",
"sign_out_modal_text": "مكتبتك مرتبطة بحسابك الحالي. عند تسجيل الخروج، لن تكون مكتبتك مرئية بعد الآن، ولن يتم حفظ أي تقدم. هل تتابع تسجيل الخروج؟", "sign_out_modal_text": "مكتبتك مرتبطة بحسابك الحالي. عند تسجيل الخروج، لن تكون مكتبتك مرئية، ولن يتم حفظ أي تقدم. هل تتابع تسجيل الخروج؟",
"add_friends": "إضافة أصدقاء", "add_friends": "إضافة أصدقاء",
"add": "إضافة", "add": "إضافة",
"friend_code": "رمز الصديق", "friend_code": "رمز الصديق",
"see_profile": "عرض الملف الشخصي", "see_profile": "عرض الملف الشخصي",
"sending": "جارٍ الإرسال", "sending": "جاري الإرسال",
"friend_request_sent": "تم إرسال طلب الصداقة", "friend_request_sent": "تم إرسال طلب الصداقة",
"friends": "الأصدقاء", "friends": "الأصدقاء",
"friends_list": "قائمة الأصدقاء", "friends_list": "قائمة الأصدقاء",
@@ -371,19 +407,19 @@
"blocked_users": "المستخدمون المحظورون", "blocked_users": "المستخدمون المحظورون",
"unblock": "إلغاء الحظر", "unblock": "إلغاء الحظر",
"no_friends_added": "ليس لديك أصدقاء مضافون", "no_friends_added": "ليس لديك أصدقاء مضافون",
"pending": يد الانتظار", "pending": "معلق",
"no_pending_invites": "ليس لديك دعوات معلقة", "no_pending_invites": "ليس لديك دعوات معلقة",
"no_blocked_users": "ليس لديك مستخدمون محظورون", "no_blocked_users": "ليس لديك مستخدمون محظورون",
"friend_code_copied": "تم نسخ رمز الصديق", "friend_code_copied": "تم نسخ رمز الصديق",
"undo_friendship_modal_text": "سيؤدي هذا إلى إلغاء صداقتك مع {{displayName}}", "undo_friendship_modal_text": "سيؤدي هذا إلى إلغاء صداقتك مع {{displayName}}",
"privacy_hint": "لضبط من يمكنه رؤية هذا، انتقل إلى <0>الإعدادات</0>", "privacy_hint": "لضبط من يمكنه رؤية هذا، انتقل إلى <0>الإعدادات</0>",
"locked_profile": "هذا الملف الشخصي خاص", "locked_profile": "هذا الملف الشخصي خاص",
"image_process_failure": "فشل معالجة الصورة", "image_process_failure": "فشل في معالجة الصورة",
"required_field": "هذا الحقل مطلوب", "required_field": "هذا الحقل مطلوب",
"displayname_min_length": "يجب أن يكون اسم العرض على الأقل 3 أحرف", "displayname_min_length": "يجب أن يكون اسم العرض على الأقل 3 أحرف",
"displayname_max_length": "يجب ألا يتجاوز اسم العرض 50 حرفًا", "displayname_max_length": "يجب أن لا يتجاوز اسم العرض 50 حرفًا",
"report_profile": "الإبلاغ عن هذا الملف الشخصي", "report_profile": "الإبلاغ عن هذا الملف",
"report_reason": "لماذا تقوم بالإبلاغ عن هذا الملف الشخصي؟", "report_reason": "لماذا تقوم بالإبلاغ عن هذا الملف؟",
"report_description": "معلومات إضافية", "report_description": "معلومات إضافية",
"report_description_placeholder": "معلومات إضافية", "report_description_placeholder": "معلومات إضافية",
"report": "الإبلاغ", "report": "الإبلاغ",
@@ -393,32 +429,32 @@
"report_reason_spam": "بريد عشوائي", "report_reason_spam": "بريد عشوائي",
"report_reason_other": "أخرى", "report_reason_other": "أخرى",
"profile_reported": "تم الإبلاغ عن الملف الشخصي", "profile_reported": "تم الإبلاغ عن الملف الشخصي",
"your_friend_code": "رمز صديقك:", "your_friend_code": "رمز الصديق الخاص بك:",
"upload_banner": "تحميل بانر", "upload_banner": "رفع بانر",
"uploading_banner": "جارٍ تحميل البانر...", "uploading_banner": "جاري رفع البانر...",
"background_image_updated": "تم تحديث صورة الخلفية", "background_image_updated": "تم تحديث صورة الخلفية",
"stats": "الإحصائيات", "stats": "الإحصائيات",
"achievements": "إنجازات", "achievements": "الإنجازات",
"games": "الألعاب", "games": "الألعاب",
"top_percentile": "ال{{percentile}}% الأعلى", "top_percentile": "الأعلى {{percentile}}%",
"ranking_updated_weekly": "يتم تحديث التصنيف أسبوعيًا", "ranking_updated_weekly": "يتم تحديث التصنيف أسبوعيًا",
"playing": "يلعب {{game}}", "playing": "جاري لعب {{game}}",
"achievements_unlocked": "الإنجازات المفتوحة", "achievements_unlocked": "الإنجازات المفتوحة",
"earned_points": "النقاط المكتسبة", "earned_points": "النقاط المكتسبة",
"show_achievements_on_profile": "عرض إنجازاتك على ملفك الشخصي", "show_achievements_on_profile": "عرض إنجازاتك في ملفك الشخصي",
"show_points_on_profile": "عرض نقاطك المكتسبة على ملفك الشخصي" "show_points_on_profile": "عرض نقاطك المكتسبة في ملفك الشخصي"
}, },
"achievement": { "achievement": {
"achievement_unlocked": "تم فتح الإنجاز", "achievement_unlocked": "تم فتح الإنجاز",
"user_achievements": "إنجازات {{displayName}}", "user_achievements": "إنجازات {{displayName}}",
"your_achievements": "إنجازاتك", "your_achievements": "إنجازاتك",
"unlocked_at": "تم الفتح في: {{date}}", "unlocked_at": "تم الفتح في: {{date}}",
"subscription_needed": "يحتاج إلى اشتراك Hydra Cloud لرؤية هذا المحتوى", "subscription_needed": "يحتاج إلى اشتراك Hydra Cloud لعرض هذا المحتوى",
"new_achievements_unlocked": "تم فتح {{achievementCount}} إنجازات جديدة من {{gameCount}} ألعاب", "new_achievements_unlocked": "تم فتح {{achievementCount}} إنجازات جديدة من {{gameCount}} ألعاب",
"achievement_progress": "{{unlockedCount}}/{{totalCount}} إنجازات", "achievement_progress": "{{unlockedCount}}/{{totalCount}} إنجازات",
"achievements_unlocked_for_game": "تم فتح {{achievementCount}} إنجازات جديدة لـ {{gameTitle}}", "achievements_unlocked_for_game": "تم فتح {{achievementCount}} إنجازات جديدة لـ {{gameTitle}}",
"hidden_achievement_tooltip": "هذا إنجاز مخفي", "hidden_achievement_tooltip": "هذا إنجاز مخفي",
"achievement_earn_points": "اكسب {{points}} نقطة مع هذا الإنجاز", "achievement_earn_points": "احصل على {{points}} نقاط مع هذا الإنجاز",
"earned_points": "النقاط المكتسبة:", "earned_points": "النقاط المكتسبة:",
"available_points": "النقاط المتاحة:", "available_points": "النقاط المتاحة:",
"how_to_earn_achievements_points": "كيفية كسب نقاط الإنجازات؟" "how_to_earn_achievements_points": "كيفية كسب نقاط الإنجازات؟"
@@ -428,10 +464,10 @@
"subscribe_now": "اشترك الآن", "subscribe_now": "اشترك الآن",
"cloud_saving": "حفظ سحابي", "cloud_saving": "حفظ سحابي",
"cloud_achievements": "احفظ إنجازاتك على السحابة", "cloud_achievements": "احفظ إنجازاتك على السحابة",
"animated_profile_picture": "صورة ملف شخصي متحركة", "animated_profile_picture": "صورة ملف متحركة",
"premium_support": "دعم ممتاز", "premium_support": "دعم ممتاز",
"show_and_compare_achievements": "اعرض وقارن إنجازاتك مع المستخدمين الآخرين", "show_and_compare_achievements": "اعرض وقارن إنجازاتك مع المستخدمين الآخرين",
"animated_profile_banner": "بانر ملف شخصي متحرك", "animated_profile_banner": "بانر ملف متحرك",
"hydra_cloud": "Hydra Cloud", "hydra_cloud": "Hydra Cloud",
"hydra_cloud_feature_found": "لقد اكتشفت ميزة Hydra Cloud!", "hydra_cloud_feature_found": "لقد اكتشفت ميزة Hydra Cloud!",
"learn_more": "معرفة المزيد" "learn_more": "معرفة المزيد"

View File

@@ -444,6 +444,9 @@
"show_achievements_on_profile": "Show your achievements on your profile", "show_achievements_on_profile": "Show your achievements on your profile",
"show_points_on_profile": "Show your earned points on your profile" "show_points_on_profile": "Show your earned points on your profile"
}, },
"badge": {
"badge_description_theme_creator": "Awarded to those who created a custom theme"
},
"achievement": { "achievement": {
"achievement_unlocked": "Achievement unlocked", "achievement_unlocked": "Achievement unlocked",
"user_achievements": "{{displayName}}'s Achievements", "user_achievements": "{{displayName}}'s Achievements",

View File

@@ -440,6 +440,9 @@
"show_achievements_on_profile": "Exiba suas conquistas no perfil", "show_achievements_on_profile": "Exiba suas conquistas no perfil",
"show_points_on_profile": "Exiba seus pontos ganhos no perfil" "show_points_on_profile": "Exiba seus pontos ganhos no perfil"
}, },
"badge": {
"badge_description_theme_creator": "Concedido àqueles que criaram um tema customizado"
},
"achievement": { "achievement": {
"achievement_unlocked": "Conquista desbloqueada", "achievement_unlocked": "Conquista desbloqueada",
"your_achievements": "Suas Conquistas", "your_achievements": "Suas Conquistas",

View File

@@ -183,7 +183,13 @@
"no_write_permission": "Невозможно загрузить в эту директорию. Нажмите здесь, чтобы узнать больше.", "no_write_permission": "Невозможно загрузить в эту директорию. Нажмите здесь, чтобы узнать больше.",
"reset_achievements_title": "Вы уверены?", "reset_achievements_title": "Вы уверены?",
"reset_achievements_success": "Достижения успешно сброшены", "reset_achievements_success": "Достижения успешно сброшены",
"reset_achievements_error": "Не удалось сбросить достижения" "reset_achievements_error": "Не удалось сбросить достижения",
"download_error_gofile_quota_exceeded": "Вы превысили месячную квоту Gofile. Пожалуйста, подождите, пока квота не будет восстановлена.",
"download_error_real_debrid_account_not_authorized": "Ваш аккаунт Real-Debrid не авторизован для осуществления новых загрузок. Пожалуйста, проверьте настройки учетной записи и повторите попытку.",
"download_error_not_cached_in_real_debrid": "Эта загрузка недоступна на Real-Debrid, а опрос статуса загрузки с Real-Debrid пока недоступен.",
"download_error_not_cached_in_torbox": "Эта загрузка недоступна на Torbox, и опросить статус загрузки с Torbox пока невозможно.",
"game_added_to_favorites": "Игра добавлена в избранное",
"game_removed_from_favorites": "Игра удалена из избранного"
}, },
"activation": { "activation": {
"title": "Активировать Hydra", "title": "Активировать Hydra",
@@ -295,7 +301,36 @@
"become_subscriber": "Станьте обладателем Hydra Cloud", "become_subscriber": "Станьте обладателем Hydra Cloud",
"subscription_renew_cancelled": "Автоматическое продление отключено", "subscription_renew_cancelled": "Автоматическое продление отключено",
"subscription_renews_on": "Ваша подписка продлевается на {{date}}", "subscription_renews_on": "Ваша подписка продлевается на {{date}}",
"bill_sent_until": "Ваш следующий счет будет отправлен до этого дня" "bill_sent_until": "Ваш следующий счет будет отправлен до этого дня",
"no_themes": "Похоже, что у вас еще нет тем, но не волнуйтесь, нажмите здесь, чтобы создать свой первый шедевр",
"editor_tab_code": "Код",
"editor_tab_info": "Информация",
"editor_tab_save": "Сохранить",
"web_store": "Веб-магазин",
"clear_themes": "Очистить",
"create_theme": "Создать",
"create_theme_modal_title": "Создать пользовательскую тему",
"create_theme_modal_description": "Создать новую тему для настройки внешнего вида Hydra",
"theme_name": "Название",
"insert_theme_name": "Вставить название темы",
"set_theme": "Установить тему",
"unset_theme": "Снять тему",
"delete_theme": "Удалить тему",
"edit_theme": "Редактировать тему",
"delete_all_themes": "Удалить все темы",
"delete_all_themes_description": "Это удалит все ваши пользовательские темы",
"delete_theme_description": "Это приведет к удалению темы {{theme}}",
"cancel": "Отменить",
"appearance": "Внешний вид",
"enable_torbox": "Включить Torbox",
"torbox_description": "TorBox - это ваш премиум-сервис, конкурирующий даже с лучшими серверами на рынке.",
"torbox_account_linked": "Аккаунт TorBox привязан",
"real_debrid_account_linked": "Аккаунт Real-Debrid привязан",
"name_min_length": "Название темы должно содержать не менее 3 символов",
"import_theme": "Импортировать тему",
"import_theme_description": "Вы импортируете {{theme}} из магазина тем",
"error_importing_theme": "Ошибка при импорте темы",
"theme_imported": "Тема успешно импортирована"
}, },
"notifications": { "notifications": {
"download_complete": "Загрузка завершена", "download_complete": "Загрузка завершена",

View File

@@ -57,7 +57,7 @@ export class WindowManager {
trafficLightPosition: { x: 16, y: 16 }, trafficLightPosition: { x: 16, y: 16 },
titleBarOverlay: { titleBarOverlay: {
symbolColor: "#DADBE1", symbolColor: "#DADBE1",
color: "#151515", color: "#00000000",
height: 34, height: 34,
}, },
webPreferences: { webPreferences: {

View File

@@ -263,9 +263,7 @@ export function App() {
useEffect(() => { useEffect(() => {
const unsubscribe = window.electron.onCssInjected((cssString) => { const unsubscribe = window.electron.onCssInjected((cssString) => {
if (cssString) { injectCustomCss(cssString);
injectCustomCss(cssString);
}
}); });
return () => unsubscribe(); return () => unsubscribe();

View File

@@ -0,0 +1,29 @@
<svg width="240" height="246" viewBox="0 0 240 246" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M117.681 8.44054C120.27 4.75592 125.73 4.75592 128.319 8.44054L149.273 38.2669C151.08 40.8399 154.301 42.0121 157.339 41.203L192.563 31.8236C196.914 30.6649 201.097 34.1747 200.712 38.6612L197.591 74.9784C197.322 78.1113 199.036 81.0795 201.884 82.4128L234.895 97.8691C238.974 99.7785 239.922 105.156 236.743 108.345L211.008 134.16C208.788 136.387 208.193 139.762 209.517 142.614L224.871 175.674C226.767 179.758 224.037 184.486 219.552 184.886L183.245 188.119C180.113 188.398 177.487 190.601 176.669 193.637L167.18 228.832C166.007 233.179 160.876 235.047 157.184 232.47L127.292 211.609C124.714 209.809 121.286 209.809 118.708 211.609L88.8163 232.47C85.1236 235.047 79.9927 233.179 78.8204 228.832L69.3314 193.637C68.5129 190.601 65.8873 188.398 62.7553 188.119L26.4479 184.886C21.9627 184.486 19.2326 179.758 21.1293 175.674L36.4827 142.614C37.8072 139.762 37.212 136.387 34.992 134.16L9.25738 108.345C6.07823 105.156 7.02639 99.7785 11.1045 97.8691L44.1164 82.4128C46.9642 81.0795 48.6778 78.1113 48.4087 74.9784L45.2883 38.6611C44.9028 34.1747 49.0856 30.6649 53.437 31.8236L88.6606 41.203C91.6992 42.0121 94.9198 40.8399 96.7274 38.2669L117.681 8.44054Z" fill="url(#paint0_linear_1378_2496)"/>
<path d="M117.681 8.44054C120.27 4.75592 125.73 4.75592 128.319 8.44054L149.273 38.2669C151.08 40.8399 154.301 42.0121 157.339 41.203L192.563 31.8236C196.914 30.6649 201.097 34.1747 200.712 38.6612L197.591 74.9784C197.322 78.1113 199.036 81.0795 201.884 82.4128L234.895 97.8691C238.974 99.7785 239.922 105.156 236.743 108.345L211.008 134.16C208.788 136.387 208.193 139.762 209.517 142.614L224.871 175.674C226.767 179.758 224.037 184.486 219.552 184.886L183.245 188.119C180.113 188.398 177.487 190.601 176.669 193.637L167.18 228.832C166.007 233.179 160.876 235.047 157.184 232.47L127.292 211.609C124.714 209.809 121.286 209.809 118.708 211.609L88.8163 232.47C85.1236 235.047 79.9927 233.179 78.8204 228.832L69.3314 193.637C68.5129 190.601 65.8873 188.398 62.7553 188.119L26.4479 184.886C21.9627 184.486 19.2326 179.758 21.1293 175.674L36.4827 142.614C37.8072 139.762 37.212 136.387 34.992 134.16L9.25738 108.345C6.07823 105.156 7.02639 99.7785 11.1045 97.8691L44.1164 82.4128C46.9642 81.0795 48.6778 78.1113 48.4087 74.9784L45.2883 38.6611C44.9028 34.1747 49.0856 30.6649 53.437 31.8236L88.6606 41.203C91.6992 42.0121 94.9198 40.8399 96.7274 38.2669L117.681 8.44054Z" fill="url(#paint1_linear_1378_2496)"/>
<path d="M117.681 8.44054C120.27 4.75592 125.73 4.75592 128.319 8.44054L149.273 38.2669C151.08 40.8399 154.301 42.0121 157.339 41.203L192.563 31.8236C196.914 30.6649 201.097 34.1747 200.712 38.6612L197.591 74.9784C197.322 78.1113 199.036 81.0795 201.884 82.4128L234.895 97.8691C238.974 99.7785 239.922 105.156 236.743 108.345L211.008 134.16C208.788 136.387 208.193 139.762 209.517 142.614L224.871 175.674C226.767 179.758 224.037 184.486 219.552 184.886L183.245 188.119C180.113 188.398 177.487 190.601 176.669 193.637L167.18 228.832C166.007 233.179 160.876 235.047 157.184 232.47L127.292 211.609C124.714 209.809 121.286 209.809 118.708 211.609L88.8163 232.47C85.1236 235.047 79.9927 233.179 78.8204 228.832L69.3314 193.637C68.5129 190.601 65.8873 188.398 62.7553 188.119L26.4479 184.886C21.9627 184.486 19.2326 179.758 21.1293 175.674L36.4827 142.614C37.8072 139.762 37.212 136.387 34.992 134.16L9.25738 108.345C6.07823 105.156 7.02639 99.7785 11.1045 97.8691L44.1164 82.4128C46.9642 81.0795 48.6778 78.1113 48.4087 74.9784L45.2883 38.6611C44.9028 34.1747 49.0856 30.6649 53.437 31.8236L88.6606 41.203C91.6992 42.0121 94.9198 40.8399 96.7274 38.2669L117.681 8.44054Z" stroke="url(#paint2_linear_1378_2496)"/>
<g opacity="0.9">
<g style="mix-blend-mode:overlay">
<path d="M113.207 107.103L113.873 107.307L114.295 106.754C120.652 98.4238 129.53 87.9999 139.582 79.6678C149.661 71.3136 160.772 65.1865 171.609 65.1865C172.421 65.1865 173.2 65.5092 173.775 66.0835C174.349 66.6578 174.672 67.4368 174.672 68.249C174.672 79.0868 168.546 90.1972 160.192 100.276C151.861 110.328 141.437 119.207 133.105 125.563L132.551 125.985L132.755 126.651C134.104 131.057 134.402 135.718 133.623 140.26C132.844 144.802 131.011 149.098 128.271 152.803C125.531 156.508 121.96 159.519 117.845 161.594C113.73 163.668 109.186 164.749 104.578 164.749H65.9851C65.3296 164.748 64.6916 164.538 64.1649 164.147C63.6381 163.757 63.2505 163.208 63.059 162.581C62.8674 161.954 62.8821 161.283 63.1008 160.665C63.3195 160.047 63.7307 159.515 64.274 159.149L64.2813 159.144C64.8739 158.736 75.1093 151.439 75.1093 135.28C75.1093 130.672 76.19 126.128 78.2646 122.013C80.3393 117.898 83.35 114.328 87.055 111.587C90.76 108.847 95.056 107.014 99.598 106.235C104.14 105.457 108.801 105.754 113.207 107.103ZM120.25 109.05L119.585 109.911L120.499 110.501C124.047 112.792 127.067 115.811 129.357 119.359L129.948 120.275L130.809 119.608C133.07 117.857 135.204 116.141 137.212 114.46L137.904 113.881L137.399 113.133C134.556 108.926 130.933 105.302 126.725 102.459L125.979 101.955L125.4 102.645C123.714 104.65 121.997 106.785 120.25 109.05ZM141.909 108.878L142.566 109.805L143.402 109.036C161.044 92.7992 166.529 80.4502 168.029 72.9963L168.328 71.5152L166.848 71.8195C159.403 73.3505 147.056 78.8076 130.817 96.4511L130.048 97.2872L130.975 97.9442C135.21 100.946 138.907 104.643 141.909 108.878Z" fill="black"/>
<path d="M113.207 107.103L113.873 107.307L114.295 106.754C120.652 98.4238 129.53 87.9999 139.582 79.6678C149.661 71.3136 160.772 65.1865 171.609 65.1865C172.421 65.1865 173.2 65.5092 173.775 66.0835C174.349 66.6578 174.672 67.4368 174.672 68.249C174.672 79.0868 168.546 90.1972 160.192 100.276C151.861 110.328 141.437 119.207 133.105 125.563L132.551 125.985L132.755 126.651C134.104 131.057 134.402 135.718 133.623 140.26C132.844 144.802 131.011 149.098 128.271 152.803C125.531 156.508 121.96 159.519 117.845 161.594C113.73 163.668 109.186 164.749 104.578 164.749H65.9851C65.3296 164.748 64.6916 164.538 64.1649 164.147C63.6381 163.757 63.2505 163.208 63.059 162.581C62.8674 161.954 62.8821 161.283 63.1008 160.665C63.3195 160.047 63.7307 159.515 64.274 159.149L64.2813 159.144C64.8739 158.736 75.1093 151.439 75.1093 135.28C75.1093 130.672 76.19 126.128 78.2646 122.013C80.3393 117.898 83.35 114.328 87.055 111.587C90.76 108.847 95.056 107.014 99.598 106.235C104.14 105.457 108.801 105.754 113.207 107.103ZM120.25 109.05L119.585 109.911L120.499 110.501C124.047 112.792 127.067 115.811 129.357 119.359L129.948 120.275L130.809 119.608C133.07 117.857 135.204 116.141 137.212 114.46L137.904 113.881L137.399 113.133C134.556 108.926 130.933 105.302 126.725 102.459L125.979 101.955L125.4 102.645C123.714 104.65 121.997 106.785 120.25 109.05ZM141.909 108.878L142.566 109.805L143.402 109.036C161.044 92.7992 166.529 80.4502 168.029 72.9963L168.328 71.5152L166.848 71.8195C159.403 73.3505 147.056 78.8076 130.817 96.4511L130.048 97.2872L130.975 97.9442C135.21 100.946 138.907 104.643 141.909 108.878Z" stroke="url(#paint3_linear_1378_2496)" stroke-width="2"/>
</g>
</g>
<defs>
<linearGradient id="paint0_linear_1378_2496" x1="5.63736e-07" y1="12.92" x2="246" y2="233.08" gradientUnits="userSpaceOnUse">
<stop stop-color="#0CF1CA"/>
<stop offset="1" stop-color="#1DCCEB"/>
</linearGradient>
<linearGradient id="paint1_linear_1378_2496" x1="19.8951" y1="-3.50306e-06" x2="226.105" y2="246" gradientUnits="userSpaceOnUse">
<stop stop-color="#0DDEBB"/>
<stop offset="1" stop-color="#052520"/>
</linearGradient>
<linearGradient id="paint2_linear_1378_2496" x1="-1.9947e-06" y1="18.0561" x2="246" y2="227.944" gradientUnits="userSpaceOnUse">
<stop stop-color="white" stop-opacity="0.7"/>
<stop offset="1" stop-color="white" stop-opacity="0.1"/>
</linearGradient>
<linearGradient id="paint3_linear_1378_2496" x1="61.9253" y1="71.6411" x2="164.664" y2="169.814" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.2"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

@@ -6,7 +6,10 @@ export interface BackdropProps {
children: React.ReactNode; children: React.ReactNode;
} }
export function Backdrop({ isClosing = false, children }: BackdropProps) { export function Backdrop({
isClosing = false,
children,
}: Readonly<BackdropProps>) {
return ( return (
<div <div
className={cn("backdrop", { className={cn("backdrop", {

View File

@@ -15,7 +15,7 @@ export function Button({
theme = "primary", theme = "primary",
className, className,
...props ...props
}: ButtonProps) { }: Readonly<ButtonProps>) {
return ( return (
<button <button
type="button" type="button"

View File

@@ -41,7 +41,7 @@ export interface UserProfileContextProviderProps {
export function UserProfileContextProvider({ export function UserProfileContextProvider({
children, children,
userId, userId,
}: UserProfileContextProviderProps) { }: Readonly<UserProfileContextProviderProps>) {
const { userDetails } = useAppSelector((state) => state.userDetails); const { userDetails } = useAppSelector((state) => state.userDetails);
const [userStats, setUserStats] = useState<UserStats | null>(null); const [userStats, setUserStats] = useState<UserStats | null>(null);

View File

@@ -18,26 +18,17 @@ import { store } from "./store";
import resources from "@locales"; import resources from "@locales";
import { SuspenseWrapper } from "./components";
import { logger } from "./logger"; import { logger } from "./logger";
import { addCookieInterceptor } from "./cookies"; import { addCookieInterceptor } from "./cookies";
const Home = React.lazy(() => import("./pages/home/home"));
const GameDetails = React.lazy(
() => import("./pages/game-details/game-details")
);
const Downloads = React.lazy(() => import("./pages/downloads/downloads"));
const Settings = React.lazy(() => import("./pages/settings/settings"));
const Catalogue = React.lazy(() => import("./pages/catalogue/catalogue"));
const Profile = React.lazy(() => import("./pages/profile/profile"));
const Achievements = React.lazy(
() => import("./pages/achievements/achievements")
);
const ThemeEditor = React.lazy(
() => import("./pages/theme-editor/theme-editor")
);
import * as Sentry from "@sentry/react"; import * as Sentry from "@sentry/react";
import Catalogue from "./pages/catalogue/catalogue";
import Home from "./pages/home/home";
import Downloads from "./pages/downloads/downloads";
import GameDetails from "./pages/game-details/game-details";
import Settings from "./pages/settings/settings";
import Profile from "./pages/profile/profile";
import Achievements from "./pages/achievements/achievements";
import ThemeEditor from "./pages/theme-editor/theme-editor";
Sentry.init({ Sentry.init({
dsn: import.meta.env.RENDERER_VITE_SENTRY_DSN, dsn: import.meta.env.RENDERER_VITE_SENTRY_DSN,
@@ -82,37 +73,16 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
<HashRouter> <HashRouter>
<Routes> <Routes>
<Route element={<App />}> <Route element={<App />}>
<Route path="/" element={<SuspenseWrapper Component={Home} />} /> <Route path="/" element={<Home />} />
<Route <Route path="/catalogue" element={<Catalogue />} />
path="/catalogue" <Route path="/downloads" element={<Downloads />} />
element={<SuspenseWrapper Component={Catalogue} />} <Route path="/game/:shop/:objectId" element={<GameDetails />} />
/> <Route path="/settings" element={<Settings />} />
<Route <Route path="/profile/:userId" element={<Profile />} />
path="/downloads" <Route path="/achievements" element={<Achievements />} />
element={<SuspenseWrapper Component={Downloads} />}
/>
<Route
path="/game/:shop/:objectId"
element={<SuspenseWrapper Component={GameDetails} />}
/>
<Route
path="/settings"
element={<SuspenseWrapper Component={Settings} />}
/>
<Route
path="/profile/:userId"
element={<SuspenseWrapper Component={Profile} />}
/>
<Route
path="/achievements"
element={<SuspenseWrapper Component={Achievements} />}
/>
</Route> </Route>
<Route <Route path="/theme-editor" element={<ThemeEditor />} />
path="/theme-editor"
element={<SuspenseWrapper Component={ThemeEditor} />}
/>
</Routes> </Routes>
</HashRouter> </HashRouter>
</Provider> </Provider>

View File

@@ -16,13 +16,8 @@ import { useUserDetails } from "@renderer/hooks";
import { useSubscription } from "@renderer/hooks/use-subscription"; import { useSubscription } from "@renderer/hooks/use-subscription";
import "./game-details.scss"; import "./game-details.scss";
const HERO_HEIGHT = 300;
const HERO_ANIMATION_THRESHOLD = 25;
export function GameDetailsContent() { export function GameDetailsContent() {
const heroRef = useRef<HTMLDivElement | null>(null); const heroRef = useRef<HTMLDivElement | null>(null);
const containerRef = useRef<HTMLDivElement | null>(null);
const [isHeaderStuck, setIsHeaderStuck] = useState(false);
const { t } = useTranslation("game_details"); const { t } = useTranslation("game_details");
@@ -61,7 +56,7 @@ export function GameDetailsContent() {
return t("no_shop_details"); return t("no_shop_details");
}, [shopDetails, t]); }, [shopDetails, t]);
const [backdropOpactiy, setBackdropOpacity] = useState(1); const [backdropOpacity, setBackdropOpacity] = useState(1);
const handleHeroLoad = async () => { const handleHeroLoad = async () => {
const output = await average(steamUrlBuilder.libraryHero(objectId!), { const output = await average(steamUrlBuilder.libraryHero(objectId!), {
@@ -80,26 +75,6 @@ export function GameDetailsContent() {
setBackdropOpacity(1); setBackdropOpacity(1);
}, [objectId]); }, [objectId]);
const onScroll: React.UIEventHandler<HTMLElement> = (event) => {
const heroHeight = heroRef.current?.clientHeight ?? HERO_HEIGHT;
const scrollY = (event.target as HTMLDivElement).scrollTop;
const opacity = Math.max(
0,
1 - scrollY / (heroHeight - HERO_ANIMATION_THRESHOLD)
);
if (scrollY >= heroHeight && !isHeaderStuck) {
setIsHeaderStuck(true);
}
if (scrollY <= heroHeight && isHeaderStuck) {
setIsHeaderStuck(false);
}
setBackdropOpacity(opacity);
};
const handleCloudSaveButtonClick = () => { const handleCloudSaveButtonClick = () => {
if (!userDetails) { if (!userDetails) {
window.electron.openAuthWindow(AuthPage.SignIn); window.electron.openAuthWindow(AuthPage.SignIn);
@@ -122,31 +97,25 @@ export function GameDetailsContent() {
<div <div
className={`game-details__wrapper ${hasNSFWContentBlocked ? "game-details__wrapper--blurred" : ""}`} className={`game-details__wrapper ${hasNSFWContentBlocked ? "game-details__wrapper--blurred" : ""}`}
> >
<img <section className="game-details__container">
src={steamUrlBuilder.libraryHero(objectId!)}
className="game-details__hero-image"
alt={game?.title}
onLoad={handleHeroLoad}
/>
<section
ref={containerRef}
onScroll={onScroll}
className="game-details__container"
>
<div ref={heroRef} className="game-details__hero"> <div ref={heroRef} className="game-details__hero">
<img
src={steamUrlBuilder.libraryHero(objectId!)}
className="game-details__hero-image"
alt={game?.title}
onLoad={handleHeroLoad}
/>
<div <div
className="game-details__hero-backdrop" className="game-details__hero-backdrop"
style={{ style={{
backgroundColor: gameColor, backgroundColor: gameColor,
flex: 1, flex: 1,
opacity: Math.min(1, 1 - backdropOpactiy),
}} }}
/> />
<div <div
className="game-details__hero-logo-backdrop" className="game-details__hero-logo-backdrop"
style={{ opacity: backdropOpactiy }} style={{ opacity: backdropOpacity }}
> >
<div className="game-details__hero-content"> <div className="game-details__hero-content">
<img <img
@@ -173,7 +142,7 @@ export function GameDetailsContent() {
</div> </div>
</div> </div>
<HeroPanel isHeaderStuck={isHeaderStuck} /> <HeroPanel />
<div className="game-details__description-container"> <div className="game-details__description-container">
<div className="game-details__description-content"> <div className="game-details__description-content">

View File

@@ -9,11 +9,7 @@ import { HeroPanelPlaytime } from "./hero-panel-playtime";
import { gameDetailsContext } from "@renderer/context"; import { gameDetailsContext } from "@renderer/context";
import "./hero-panel.scss"; import "./hero-panel.scss";
export interface HeroPanelProps { export function HeroPanel() {
isHeaderStuck: boolean;
}
export function HeroPanel({ isHeaderStuck }: HeroPanelProps) {
const { t } = useTranslation("game_details"); const { t } = useTranslation("game_details");
const { formatDate } = useDate(); const { formatDate } = useDate();
@@ -54,10 +50,7 @@ export function HeroPanel({ isHeaderStuck }: HeroPanelProps) {
game?.download?.status === "paused"; game?.download?.status === "paused";
return ( return (
<div <div style={{ backgroundColor: gameColor }} className="hero-panel">
style={{ backgroundColor: gameColor }}
className={`hero-panel ${isHeaderStuck ? "hero-panel--stuck" : ""}`}
>
<div className="hero-panel__content">{getInfo()}</div> <div className="hero-panel__content">{getInfo()}</div>
<div className="hero-panel__actions"> <div className="hero-panel__actions">
<HeroPanelActions /> <HeroPanelActions />

View File

@@ -65,6 +65,12 @@
overflow: hidden; overflow: hidden;
} }
&__display-name-container {
display: flex;
gap: globals.$spacing-unit;
align-items: center;
}
&__display-name { &__display-name {
font-weight: bold; font-weight: bold;
overflow: hidden; overflow: hidden;
@@ -76,6 +82,12 @@
text-shadow: 0 0 5px rgb(0 0 0 / 40%); text-shadow: 0 0 5px rgb(0 0 0 / 40%);
} }
&__display-name-badges-container {
display: flex;
gap: globals.$spacing-unit;
align-items: center;
}
&__current-game { &__current-game {
&-wrapper { &-wrapper {
display: flex; display: flex;

View File

@@ -25,6 +25,7 @@ import { EditProfileModal } from "../edit-profile-modal/edit-profile-modal";
import Skeleton from "react-loading-skeleton"; import Skeleton from "react-loading-skeleton";
import { UploadBackgroundImageButton } from "../upload-background-image-button/upload-background-image-button"; import { UploadBackgroundImageButton } from "../upload-background-image-button/upload-background-image-button";
import "./profile-hero.scss"; import "./profile-hero.scss";
import { UserBadges } from "./user-badges";
type FriendAction = type FriendAction =
| FriendRequestAction | FriendRequestAction
@@ -307,9 +308,12 @@ export function ProfileHero() {
<div className="profile-hero__information"> <div className="profile-hero__information">
{userProfile ? ( {userProfile ? (
<h2 className="profile-hero__display-name"> <div className="profile-hero__display-name-container">
{userProfile?.displayName} <h2 className="profile-hero__display-name">
</h2> {userProfile?.displayName}
</h2>
<UserBadges />
</div>
) : ( ) : (
<Skeleton width={150} height={28} /> <Skeleton width={150} height={28} />
)} )}

View File

@@ -0,0 +1,40 @@
import BadgeThemeCreator from "@renderer/assets/icons/badge-theme-creator.svg?react";
import "./profile-hero.scss";
import { useContext } from "react";
import { userProfileContext } from "@renderer/context";
import { UserBadge } from "@types";
import { useTranslation } from "react-i18next";
export function UserBadges() {
const { t } = useTranslation("badge");
const { userProfile } = useContext(userProfileContext);
if (!userProfile?.badges?.length) return null;
const getBadgeIcon = (badge: UserBadge) => {
if (badge === "THEME_CREATOR") {
return <BadgeThemeCreator width={24} height={24} />;
}
return null;
};
return (
<div className="profile-hero__display-name-badges-container">
{userProfile.badges.map((badge) => {
const badgeIcon = getBadgeIcon(badge);
if (!badgeIcon) return null;
return (
<div
className={`badge__${badge.toLowerCase()}`}
key={badge}
title={t(`badge_description_${badge.toLowerCase()}`)}
>
{badgeIcon}
</div>
);
})}
</div>
);
}

View File

@@ -4,6 +4,7 @@ import { ThemeActions, ThemeCard, ThemePlaceholder } from "./index";
import type { Theme } from "@types"; import type { Theme } from "@types";
import { ImportThemeModal } from "./modals/import-theme-modal"; import { ImportThemeModal } from "./modals/import-theme-modal";
import { settingsContext } from "@renderer/context"; import { settingsContext } from "@renderer/context";
import { useNavigate } from "react-router-dom";
interface SettingsAppearanceProps { interface SettingsAppearanceProps {
appearance: { appearance: {
@@ -24,8 +25,10 @@ export function SettingsAppearance({
authorId: string; authorId: string;
authorName: string; authorName: string;
} | null>(null); } | null>(null);
const [hasShownModal, setHasShownModal] = useState(false);
const { clearTheme } = useContext(settingsContext); const { clearTheme } = useContext(settingsContext);
const navigate = useNavigate();
const loadThemes = useCallback(async () => { const loadThemes = useCallback(async () => {
const themesList = await window.electron.getAllCustomThemes(); const themesList = await window.electron.getAllCustomThemes();
@@ -45,20 +48,37 @@ export function SettingsAppearance({
}, [loadThemes]); }, [loadThemes]);
useEffect(() => { useEffect(() => {
if (appearance.theme && appearance.authorId && appearance.authorName) { if (
appearance.theme &&
appearance.authorId &&
appearance.authorName &&
!hasShownModal
) {
setIsImportThemeModalVisible(true); setIsImportThemeModalVisible(true);
setImportTheme({ setImportTheme({
theme: appearance.theme, theme: appearance.theme,
authorId: appearance.authorId, authorId: appearance.authorId,
authorName: appearance.authorName, authorName: appearance.authorName,
}); });
setHasShownModal(true);
navigate("/settings", { replace: true });
clearTheme();
} }
}, [appearance.theme, appearance.authorId, appearance.authorName]); }, [
appearance.theme,
appearance.authorId,
appearance.authorName,
navigate,
hasShownModal,
clearTheme,
]);
const onThemeImported = useCallback(() => { const onThemeImported = useCallback(() => {
setIsImportThemeModalVisible(false); setIsImportThemeModalVisible(false);
setImportTheme(null);
loadThemes(); loadThemes();
}, [clearTheme, loadThemes]); }, [loadThemes]);
return ( return (
<div className="settings-appearance"> <div className="settings-appearance">
@@ -90,6 +110,7 @@ export function SettingsAppearance({
onClose={() => { onClose={() => {
setIsImportThemeModalVisible(false); setIsImportThemeModalVisible(false);
clearTheme(); clearTheme();
setHasShownModal(false);
}} }}
onThemeImported={onThemeImported} onThemeImported={onThemeImported}
themeName={importTheme.theme} themeName={importTheme.theme}

View File

@@ -130,6 +130,8 @@ export interface UserProfileCurrentGame extends Omit<GameRunning, "objectId"> {
export type ProfileVisibility = "PUBLIC" | "PRIVATE" | "FRIENDS"; export type ProfileVisibility = "PUBLIC" | "PRIVATE" | "FRIENDS";
export type UserBadge = "THEME_CREATOR";
export interface UserDetails { export interface UserDetails {
id: string; id: string;
username: string; username: string;
@@ -164,6 +166,7 @@ export interface UserProfile {
quirks: { quirks: {
backupsPerGameLimit: number; backupsPerGameLimit: number;
}; };
badges: UserBadge[];
} }
export interface UpdateProfileRequest { export interface UpdateProfileRequest {