mirror of
https://github.com/ImranR98/Obtainium.git
synced 2025-07-23 17:39:42 +02:00
Merge remote-tracking branch 'origin/main' into dev
This commit is contained in:
@@ -167,7 +167,7 @@
|
||||
"lastUpdateCheckX": "Vérification de la dernière mise à jour : {}",
|
||||
"remove": "Retirer",
|
||||
"yesMarkUpdated": "Oui, marquer comme mis à jour",
|
||||
"fdroid": "F-Droïde Officiel",
|
||||
"fdroid": "F-Droid Officiel",
|
||||
"appIdOrName": "ID ou nom de l'application",
|
||||
"appId": "ID de l'application",
|
||||
"appWithIdOrNameNotFound": "Aucune application n'a été trouvée avec cet identifiant ou ce nom",
|
||||
|
@@ -281,14 +281,14 @@
|
||||
"parallelDownloads": "Párhuzamos letöltéseket enged",
|
||||
"installMethod": "Telepítési mód",
|
||||
"normal": "Normál",
|
||||
"root": "Gyökér",
|
||||
"root": "Root",
|
||||
"shizukuBinderNotFound": "A Shizuku nem fut",
|
||||
"useSystemFont": "Használja a rendszer betűtípusát",
|
||||
"systemFontError": "Hiba a rendszer betűtípusának betöltésekor: {}",
|
||||
"useVersionCodeAsOSVersion": "Az app verziókód használata a rendszer által észlelt verzióként",
|
||||
"requestHeader": "Kérelem fejléc",
|
||||
"useLatestAssetDateAsReleaseDate": "Használja a legújabb tartalomfeltöltést megjelenési dátumként",
|
||||
"defaultPseudoVersioningMethod": "Alapértelmezett álversziós módszer",
|
||||
"defaultPseudoVersioningMethod": "Alapértelmezett álverziós módszer",
|
||||
"partialAPKHash": "Részleges APK Hash",
|
||||
"APKLinkHash": "APK Link Hash",
|
||||
"directAPKLink": "Közvetlen APK Link",
|
||||
|
359
assets/translations/uk.json
Normal file
359
assets/translations/uk.json
Normal file
@@ -0,0 +1,359 @@
|
||||
{
|
||||
"invalidURLForSource": "Неправильна URL-адреса для джерела застосунку {}",
|
||||
"noReleaseFound": "Не вдалося знайти відповідне видання",
|
||||
"noVersionFound": "Не вдалося визначити версію видання",
|
||||
"urlMatchesNoSource": "URL не відповідає відомому джерелу",
|
||||
"cantInstallOlderVersion": "Не можна встановити старішу версію застосунку",
|
||||
"appIdMismatch": "Ідентифікатор пакета, завантажений, не відповідає ідентифікатору існуючого застосунку",
|
||||
"functionNotImplemented": "Цей клас не реалізував цю функцію",
|
||||
"placeholder": "Заповнювач",
|
||||
"someErrors": "Виникла деяка помилка",
|
||||
"unexpectedError": "Неочікувана помилка",
|
||||
"ok": "Добре",
|
||||
"and": "та",
|
||||
"githubPATLabel": "Персональний ключ доступу GitHub (збільшує обмеження на швидкість)",
|
||||
"includePrereleases": "Включити попередні видання",
|
||||
"fallbackToOlderReleases": "Повернутися до старіших видань",
|
||||
"filterReleaseTitlesByRegEx": "Фільтрувати заголовки видань за допомогою регулярного виразу",
|
||||
"invalidRegEx": "Неприпустимий регулярний вираз",
|
||||
"noDescription": "Немає опису",
|
||||
"cancel": "Скасувати",
|
||||
"continue": "Продовжити",
|
||||
"requiredInBrackets": "(Обов'язково)",
|
||||
"dropdownNoOptsError": "ПОМИЛКА: В ВИПАДАЮЧОМУ СПИСКУ МАЄ БУТИ ХОЧА Б ОДИН ЕЛЕМЕНТ",
|
||||
"colour": "Колір",
|
||||
"githubStarredRepos": "Відзначені репозиторії GitHub",
|
||||
"uname": "Ім'я користувача",
|
||||
"wrongArgNum": "Надано неправильну кількість аргументів",
|
||||
"xIsTrackOnly": "{} - тільки відстежування",
|
||||
"source": "Джерело",
|
||||
"app": "застосунок",
|
||||
"appsFromSourceAreTrackOnly": "Додатки з цього джерела є лише для відстежування.",
|
||||
"youPickedTrackOnly": "Ви вибрали опцію лише для відстежування.",
|
||||
"trackOnlyAppDescription": "Застосунок буде відстежуватися для оновлень, але Obtainium не зможе його завантажити або встановити.",
|
||||
"cancelled": "Скасовано",
|
||||
"appAlreadyAdded": "Застосунок вже додано",
|
||||
"alreadyUpToDateQuestion": "Застосунок вже оновлено?",
|
||||
"addApp": "Додати Застосунок",
|
||||
"appSourceURL": "URL-адреса джерела застосунку",
|
||||
"error": "Помилка",
|
||||
"add": "Додати",
|
||||
"searchSomeSourcesLabel": "Пошук (Лише деякі джерела)",
|
||||
"search": "Пошук",
|
||||
"additionalOptsFor": "Додаткові опції для {}",
|
||||
"supportedSources": "Підтримувані джерела",
|
||||
"trackOnlyInBrackets": "(Тільки для відстеження)",
|
||||
"searchableInBrackets": "(Можливий пошук)",
|
||||
"appsString": "Додатки",
|
||||
"noApps": "Додатків немає",
|
||||
"noAppsForFilter": "Додатків для фільтрації немає",
|
||||
"byX": "За {}",
|
||||
"percentProgress": "Прогрес: {}%",
|
||||
"pleaseWait": "Будь ласка, зачекайте",
|
||||
"updateAvailable": "Доступно оновлення",
|
||||
"notInstalled": "Не встановлено",
|
||||
"pseudoVersion": "псевдо-версія",
|
||||
"selectAll": "Вибрати все",
|
||||
"deselectX": "Скасувати вибір {}",
|
||||
"xWillBeRemovedButRemainInstalled": "{} буде видалено з Obtainium, але залишиться встановленим на пристрої.",
|
||||
"removeSelectedAppsQuestion": "Видалити вибрані додатки?",
|
||||
"removeSelectedApps": "Видалити вибрані додатки",
|
||||
"updateX": "Оновити {}",
|
||||
"installX": "Встановити {}",
|
||||
"markXTrackOnlyAsUpdated": "Позначити {}\n(Тільки відстежування)\nяк оновлено",
|
||||
"changeX": "Змінити {}",
|
||||
"installUpdateApps": "Встановити/Оновити додатки",
|
||||
"installUpdateSelectedApps": "Встановити/Оновити вибрані додатки",
|
||||
"markXSelectedAppsAsUpdated": "Позначити {} вибрані додатки як оновлені?",
|
||||
"no": "Ні",
|
||||
"yes": "Так",
|
||||
"markSelectedAppsUpdated": "Позначити вибрані додатки як оновлені",
|
||||
"pinToTop": "Закріпити угорі",
|
||||
"unpinFromTop": "Відкріпити зверху",
|
||||
"resetInstallStatusForSelectedAppsQuestion": "Скинути статус встановлення для вибраних додатків?",
|
||||
"installStatusOfXWillBeResetExplanation": "Статус встановлення будь-яких вибраних додатків буде скинутий.\n\nЦе може допомогти, коли версія застосунку, відображена в Obtainium, є неправильною через невдалі оновлення або інші проблеми.",
|
||||
"customLinkMessage": "Ці посилання працюють на пристроях з встановленим Obtainium",
|
||||
"shareAppConfigLinks": "Поділитися посиланнями на конфігурацію Застосунку як HTML",
|
||||
"shareSelectedAppURLs": "Поділитися вибраними URL-адресами додатків",
|
||||
"resetInstallStatus": "Скинути статус встановлення",
|
||||
"more": "Більше",
|
||||
"removeOutdatedFilter": "Видалити фільтр застарілих додатків",
|
||||
"showOutdatedOnly": "Показати лише застарілі додатки",
|
||||
"filter": "Фільтр",
|
||||
"filterApps": "Фільтрувати додатки",
|
||||
"appName": "Назва застосунку",
|
||||
"author": "Автор",
|
||||
"upToDateApps": "Актуальні додатки",
|
||||
"nonInstalledApps": "Невстановлені додатки",
|
||||
"importExport": "Імпорт/Експорт",
|
||||
"settings": "Налаштування",
|
||||
"exportedTo": "Експортовано в {}",
|
||||
"obtainiumExport": "Експорт з Obtainium",
|
||||
"invalidInput": "Недійсний ввід",
|
||||
"importedX": "Імпортовано {}",
|
||||
"obtainiumImport": "Імпорт в Obtainium",
|
||||
"importFromURLList": "Імпорт зі списку URL-адрес",
|
||||
"searchQuery": "Пошуковий запит",
|
||||
"appURLList": "Список URL-адрес додатків",
|
||||
"line": "Лінія",
|
||||
"searchX": "Пошук {}",
|
||||
"noResults": "Результати відсутні",
|
||||
"importX": "Імпорт {}",
|
||||
"importedAppsIdDisclaimer": "Імпортовані додатки можуть неправильно відображатися як \"Не встановлені\".\nДля виправлення цього перевстановіть їх через Obtainium.\nЦе не повинно вплинути на дані додатків.\n\nПов'язано лише з URL-адресами та імпортом від третіх сторін.",
|
||||
"importErrors": "Помилки імпорту",
|
||||
"importedXOfYApps": "Імпортовано {} з {} додатків.",
|
||||
"followingURLsHadErrors": "Помилки в наступних URL-адресах:",
|
||||
"selectURL": "Вибрати URL",
|
||||
"selectURLs": "Вибрати URL-адреси",
|
||||
"pick": "Вибрати",
|
||||
"theme": "Тема",
|
||||
"dark": "Темна",
|
||||
"light": "Світла",
|
||||
"followSystem": "Дотримуватися системи",
|
||||
"useBlackTheme": "Використовувати чисто чорну темну тему",
|
||||
"appSortBy": "Сортувати додатки за",
|
||||
"authorName": "Автор/Назва",
|
||||
"nameAuthor": "Назва/Автор",
|
||||
"asAdded": "За додаванням",
|
||||
"appSortOrder": "Порядок сортування додатків",
|
||||
"ascending": "За зростанням",
|
||||
"descending": "За спаданням",
|
||||
"bgUpdateCheckInterval": "Інтервал перевірки оновлень у фоновому режимі",
|
||||
"neverManualOnly": "Ніколи - Тільки вручну",
|
||||
"appearance": "Вигляд",
|
||||
"showWebInAppView": "Показати джерело застосунку у вигляді веб-сторінки",
|
||||
"pinUpdates": "Закріпити оновлення у верхній частині вигляду додатків",
|
||||
"updates": "Оновлення",
|
||||
"sourceSpecific": "Певне джерело",
|
||||
"appSource": "Джерело застосунку",
|
||||
"noLogs": "Немає логів",
|
||||
"appLogs": "Лог застосунку",
|
||||
"close": "Закрити",
|
||||
"share": "Поділитися",
|
||||
"appNotFound": "Застосунок не знайдено",
|
||||
"obtainiumExportHyphenatedLowercase": "експорт з Obtainium",
|
||||
"pickAnAPK": "Вибрати APK",
|
||||
"appHasMoreThanOnePackage": "{} має більше одного пакету:",
|
||||
"deviceSupportsXArch": "Ваш пристрій підтримує архітектуру процесора {}.",
|
||||
"deviceSupportsFollowingArchs": "Ваш пристрій підтримує наступні архітектури процесора:",
|
||||
"warning": "Попередження",
|
||||
"sourceIsXButPackageFromYPrompt": "Джерело застосунку - '{}' але пакет випуску походить з '{}'. Продовжити?",
|
||||
"updatesAvailable": "Доступні оновлення",
|
||||
"updatesAvailableNotifDescription": "Повідомляє користувача, що доступні оновлення для одного чи декількох додатків, які відстежує Obtainium",
|
||||
"noNewUpdates": "Немає нових оновлень.",
|
||||
"xHasAnUpdate": "{} має оновлення.",
|
||||
"appsUpdated": "Додатки оновлено",
|
||||
"appsUpdatedNotifDescription": "Повідомляє користувача, що оновлення одного чи декількох додатків було застосовано в фоновому режимі",
|
||||
"xWasUpdatedToY": "{} було оновлено до {}.",
|
||||
"errorCheckingUpdates": "Помилка перевірки оновлень",
|
||||
"errorCheckingUpdatesNotifDescription": "Повідомлення, яке з'являється, коли перевірка оновлень в фоновому режимі завершується невдачею",
|
||||
"appsRemoved": "Додатки видалено",
|
||||
"appsRemovedNotifDescription": "Повідомляє користувача, що один чи декілька додатків були видалені через помилки при завантаженні",
|
||||
"xWasRemovedDueToErrorY": "{} було видалено через цю помилку: {}",
|
||||
"completeAppInstallation": "Завершення установки застосунку",
|
||||
"obtainiumMustBeOpenToInstallApps": "Для встановлення додатків Obtainium має бути відкритий",
|
||||
"completeAppInstallationNotifDescription": "Прохання користувача повернутися до Obtainium для завершення установки застосунку",
|
||||
"checkingForUpdates": "Перевірка оновлень",
|
||||
"checkingForUpdatesNotifDescription": "Тимчасове повідомлення, яке з'являється при перевірці оновлень",
|
||||
"pleaseAllowInstallPerm": "Будь ласка, дозвольте Obtainium встановлювати додатки",
|
||||
"trackOnly": "Тільки відстеження",
|
||||
"errorWithHttpStatusCode": "Помилка {} HTTP-коду",
|
||||
"versionCorrectionDisabled": "Виправлення версії вимкнено (здається, плагін не працює)",
|
||||
"unknown": "Невідомо",
|
||||
"none": "Нічого",
|
||||
"never": "Ніколи",
|
||||
"latestVersionX": "Остання версія: {}",
|
||||
"installedVersionX": "Встановлено: {}",
|
||||
"lastUpdateCheckX": "Остання перевірка оновлень: {}",
|
||||
"remove": "Видалити",
|
||||
"yesMarkUpdated": "Так, позначити як оновлене",
|
||||
"fdroid": "F-Droid Офіційний",
|
||||
"appIdOrName": "Ідентифікатор або назва застосунку",
|
||||
"appId": "Ідентифікатор застосунку",
|
||||
"appWithIdOrNameNotFound": "Застосунок з таким ідентифікатором або назвою не знайдено",
|
||||
"reposHaveMultipleApps": "Сховища можуть містити кілька додатків",
|
||||
"fdroidThirdPartyRepo": "F-Droid Стороннє сховище",
|
||||
"steamMobile": "Мобільний Steam",
|
||||
"steamChat": "Чат Steam",
|
||||
"install": "Встановити",
|
||||
"markInstalled": "Позначити як встановлене",
|
||||
"update": "Оновити",
|
||||
"markUpdated": "Позначити як оновлене",
|
||||
"additionalOptions": "Додаткові опції",
|
||||
"disableVersionDetection": "Вимкнути визначення версії",
|
||||
"noVersionDetectionExplanation": "Цю опцію слід використовувати лише для додатків, де визначення версії працює неправильно.",
|
||||
"downloadingX": "Завантаження {}",
|
||||
"downloadNotifDescription": "Повідомляє користувача про прогрес завантаження застосунку",
|
||||
"noAPKFound": "APK не знайдено",
|
||||
"noVersionDetection": "Визначення версії відключено",
|
||||
"categorize": "Категоризувати",
|
||||
"categories": "Категорії",
|
||||
"category": "Категорія",
|
||||
"noCategory": "Без категорії",
|
||||
"noCategories": "Немає категорій",
|
||||
"deleteCategoriesQuestion": "Видалити категорії?",
|
||||
"categoryDeleteWarning": "Усі додатки у видалених категоріях будуть переведені у некатегоризовані.",
|
||||
"addCategory": "Додати категорію",
|
||||
"label": "Мітка",
|
||||
"language": "Мова",
|
||||
"copiedToClipboard": "Скопійовано в буфер обміну",
|
||||
"storagePermissionDenied": "Відмовлено у дозволі на доступ до сховища",
|
||||
"selectedCategorizeWarning": "Це замінить будь-які існуючі налаштування категорій для вибраних додатків.",
|
||||
"filterAPKsByRegEx": "Фільтрувати APK за регулярним виразом",
|
||||
"removeFromObtainium": "Видалити з Obtainium",
|
||||
"uninstallFromDevice": "Видалити з пристрою",
|
||||
"onlyWorksWithNonVersionDetectApps": "Працює лише з застосунками з вимкненим визначенням версії.",
|
||||
"releaseDateAsVersion": "Використовувати дату випуску як рядок версії",
|
||||
"releaseDateAsVersionExplanation": "Цю опцію слід використовувати лише для додатків, де визначення версії працює неправильно, але є дата випуску.",
|
||||
"changes": "Зміни",
|
||||
"releaseDate": "Дата випуску",
|
||||
"importFromURLsInFile": "Імпорт з URL-адрес у файлі (наприклад, OPML)",
|
||||
"versionDetectionExplanation": "Порівняти рядок версії з версією, визначеною операційною системою",
|
||||
"versionDetection": "Визначення версії",
|
||||
"standardVersionDetection": "Стандартне визначення версії",
|
||||
"groupByCategory": "Групувати за категоріями",
|
||||
"autoApkFilterByArch": "Спробувати фільтрувати APK за архітектурою ЦП, якщо можливо",
|
||||
"overrideSource": "Перевизначити джерело",
|
||||
"dontShowAgain": "Не показувати це знову",
|
||||
"dontShowTrackOnlyWarnings": "Не показувати попередження про 'Тільки відстеження'",
|
||||
"dontShowAPKOriginWarnings": "Не показувати попередження про походження APK",
|
||||
"moveNonInstalledAppsToBottom": "Перемістити невстановлені додатки вниз у перегляді додатків",
|
||||
"gitlabPATLabel": "Особистий токен GitLab (Увімкнення пошуку та краще виявлення APK)",
|
||||
"about": "Про програму",
|
||||
"requiresCredentialsInSettings": "{} потребує додаткових облікових даних (у налаштуваннях)",
|
||||
"checkOnStart": "Перевірити наявність оновлень при запуску",
|
||||
"tryInferAppIdFromCode": "Спробувати вивести ідентифікатор застосунку з вихідного коду",
|
||||
"removeOnExternalUninstall": "Автоматично видаляти додатки, які було видалено зовнішнім чином",
|
||||
"pickHighestVersionCode": "Автоматично вибрати APK з найвищим кодом версії",
|
||||
"checkUpdateOnDetailPage": "Перевіряти наявність оновлень при відкритті сторінки деталей застосунку",
|
||||
"disablePageTransitions": "Вимкнути анімації переходів між сторінками",
|
||||
"reversePageTransitions": "Зворотні анімації переходів між сторінками",
|
||||
"minStarCount": "Мінімальна кількість зірок",
|
||||
"addInfoBelow": "Додати цю інформацію нижче.",
|
||||
"addInfoInSettings": "Додати цю інформацію у налаштуваннях.",
|
||||
"githubSourceNote": "Лімітування швидкості GitHub можна уникнути, використовуючи ключ API.",
|
||||
"gitlabSourceNote": "Вилучення APK з GitLab може не працювати без ключа API.",
|
||||
"sortByLastLinkSegment": "Сортувати лише за останнім сегментом посилання",
|
||||
"filterReleaseNotesByRegEx": "Фільтрувати примітки до релізу за регулярним виразом",
|
||||
"customLinkFilterRegex": "Фільтр кастомного посилання на APK за регулярним виразом (за замовчуванням '.apk$')",
|
||||
"appsPossiblyUpdated": "Оновлення додатків спробовано",
|
||||
"appsPossiblyUpdatedNotifDescription": "Повідомляє користувача, що оновлення одного або декількох додатків можливо були застосовані в фоновому режимі",
|
||||
"xWasPossiblyUpdatedToY": "{} можливо було оновлено до {}.",
|
||||
"enableBackgroundUpdates": "Увімкнути оновлення в фоновому режимі",
|
||||
"backgroundUpdateReqsExplanation": "Оновлення в фоновому режимі може бути неможливим для всіх додатків.",
|
||||
"backgroundUpdateLimitsExplanation": "Успіх фонової установки може бути визначений лише після відкриття Obtainium.",
|
||||
"verifyLatestTag": "Перевірити тег 'latest'",
|
||||
"intermediateLinkRegex": "Фільтр для 'Проміжного' Посилання для Відвідування",
|
||||
"filterByLinkText": "Фільтрувати посилання за текстом посилання",
|
||||
"intermediateLinkNotFound": "Проміжне посилання не знайдено",
|
||||
"intermediateLink": "Проміжне посилання",
|
||||
"exemptFromBackgroundUpdates": "Виключено з фонових оновлень (якщо ввімкнено)",
|
||||
"bgUpdatesOnWiFiOnly": "Вимкнути фонові оновлення поза Wi-Fi",
|
||||
"autoSelectHighestVersionCode": "Автоматичний вибір APK з найвищим кодом версії",
|
||||
"versionExtractionRegEx": "Регулярний вираз для вилучення рядка версії",
|
||||
"matchGroupToUse": "Група співпадінь для використання в регулярному виразі вилучення версії",
|
||||
"highlightTouchTargets": "Підсвічувати менш очевидні області дотику",
|
||||
"pickExportDir": "Вибрати каталог експорту",
|
||||
"autoExportOnChanges": "Автоматичний експорт при змінах",
|
||||
"includeSettings": "Включити налаштування",
|
||||
"filterVersionsByRegEx": "Фільтрувати версії за регулярним виразом",
|
||||
"trySelectingSuggestedVersionCode": "Спробуйте вибрати запропонований код версії APK",
|
||||
"dontSortReleasesList": "Зберігати порядок випуску з API",
|
||||
"reverseSort": "Зворотне сортування",
|
||||
"takeFirstLink": "Вибрати перше посилання",
|
||||
"skipSort": "Пропустити сортування",
|
||||
"debugMenu": "Меню налагодження",
|
||||
"bgTaskStarted": "Запущено фонове завдання - перевірте журнали.",
|
||||
"runBgCheckNow": "Запустити перевірку оновлень в фоновому режимі зараз",
|
||||
"versionExtractWholePage": "Застосувати регулярний вираз вилучення версії до всієї сторінки",
|
||||
"installing": "Встановлення",
|
||||
"skipUpdateNotifications": "Пропустити сповіщення про оновлення",
|
||||
"updatesAvailableNotifChannel": "Доступні оновлення",
|
||||
"appsUpdatedNotifChannel": "Додатки оновлені",
|
||||
"appsPossiblyUpdatedNotifChannel": "Спроба оновлення додатків",
|
||||
"errorCheckingUpdatesNotifChannel": "Помилка перевірки оновлень",
|
||||
"appsRemovedNotifChannel": "Додатки видалені",
|
||||
"downloadingXNotifChannel": "Завантаження {}",
|
||||
"completeAppInstallationNotifChannel": "Завершення встановлення застосунку",
|
||||
"checkingForUpdatesNotifChannel": "Перевірка оновлень",
|
||||
"onlyCheckInstalledOrTrackOnlyApps": "Перевіряти лише встановлені та додатки, які відстежуються для оновлень",
|
||||
"supportFixedAPKURL": "Підтримка фіксованих посилань на APK",
|
||||
"selectX": "Вибрати {}",
|
||||
"parallelDownloads": "Дозволити паралельні завантаження",
|
||||
"installMethod": "Метод встановлення",
|
||||
"normal": "Звичайний",
|
||||
"root": "Root",
|
||||
"shizukuBinderNotFound": "Сумісний сервіс Shizuku не було знайдено",
|
||||
"useSystemFont": "Використовувати системний шрифт",
|
||||
"systemFontError": "Помилка завантаження системного шрифту: {}",
|
||||
"useVersionCodeAsOSVersion": "Використовувати код версії застосунку як версію, визначену операційною системою",
|
||||
"requestHeader": "Заголовок запиту",
|
||||
"useLatestAssetDateAsReleaseDate": "Використовувати останню дату завантаження ресурсу як дату випуску",
|
||||
"defaultPseudoVersioningMethod": "Метод за замовчуванням псевдо-версіонування",
|
||||
"partialAPKHash": "Хеш часткового APK",
|
||||
"APKLinkHash": "Хеш посилання на APK",
|
||||
"directAPKLink": "Пряме посилання на APK",
|
||||
"pseudoVersionInUse": "Використовується псевдо-версія",
|
||||
"installed": "Встановлено",
|
||||
"latest": "Остання",
|
||||
"invertRegEx": "Інвертувати регулярний вираз",
|
||||
"note": "Примітка",
|
||||
"selfHostedNote": "Випадаючий список \"{}\" може використовуватися для доступу до власних/призначених для самостійного використання екземплярів будь-якого джерела.",
|
||||
"badDownload": "APK не вдалося розпарсити (несумісний або часткове завантаження)",
|
||||
"removeAppQuestion": {
|
||||
"one": "Видалити Застосунок?",
|
||||
"other": "Видалити додатки?"
|
||||
},
|
||||
"tooManyRequestsTryAgainInMinutes": {
|
||||
"one": "Забагато запитів (обмеження швидкості) - повторіть спробу через {} хвилину",
|
||||
"other": "Забагато запитів (обмеження швидкості) - повторіть спробу через {} хвилин"
|
||||
},
|
||||
"bgUpdateGotErrorRetryInMinutes": {
|
||||
"one": "Помилка перевірки оновлень у фоновому режимі - спробую знову через {} хвилину",
|
||||
"other": "Помилка перевірки оновлень у фоновому режимі - спробую знову через {} хвилин"
|
||||
},
|
||||
"bgCheckFoundUpdatesWillNotifyIfNeeded": {
|
||||
"one": "Фонова перевірка оновлень знайшла {} оновлення - сповістить користувача, якщо це необхідно",
|
||||
"other": "Фонова перевірка оновлень знайшла {} оновлень - сповістить користувача, якщо це необхідно"
|
||||
},
|
||||
"apps": {
|
||||
"one": "{} Застосунок",
|
||||
"other": "{} Додатки"
|
||||
},
|
||||
"url": {
|
||||
"one": "{} URL",
|
||||
"other": "{} URL-адреси"
|
||||
},
|
||||
"minute": {
|
||||
"one": "{} Хвилина",
|
||||
"other": "{} Хвилин"
|
||||
},
|
||||
"hour": {
|
||||
"one": "{} Година",
|
||||
"other": "{} Годин"
|
||||
},
|
||||
"day": {
|
||||
"one": "{} День",
|
||||
"other": "{} Днів"
|
||||
},
|
||||
"clearedNLogsBeforeXAfterY": {
|
||||
"one": "Очищено {n} журнал (до = {before}, після = {after})",
|
||||
"other": "Очищено {n} журналів (до = {before}, після = {after})"
|
||||
},
|
||||
"xAndNMoreUpdatesAvailable": {
|
||||
"one": "{} і 1 інше Застосунок мають оновлення.",
|
||||
"other": "{} і {} інших додатки мають оновлення."
|
||||
},
|
||||
"xAndNMoreUpdatesInstalled": {
|
||||
"one": "{} і 1 інше Застосунок було оновлено.",
|
||||
"other": "{} і {} інших додатків було оновлено."
|
||||
},
|
||||
"xAndNMoreUpdatesPossiblyInstalled": {
|
||||
"one": "{} і 1 інше Застосунок можливо було оновлено.",
|
||||
"other": "{} і {} інших додатків можливо було оновлено."
|
||||
},
|
||||
"apk": {
|
||||
"one": "{} APK",
|
||||
"other": "{} APK-файли"
|
||||
}
|
||||
}
|
@@ -52,7 +52,7 @@
|
||||
"pleaseWait": "请稍候",
|
||||
"updateAvailable": "更新可用",
|
||||
"notInstalled": "未安装",
|
||||
"pseudoVersion": "伪版本",
|
||||
"pseudoVersion": "虚拟版本号",
|
||||
"selectAll": "全选",
|
||||
"deselectX": "取消选择 {}",
|
||||
"xWillBeRemovedButRemainInstalled": "“{}”将从 Obtainium 中删除,但仍安装在您的设备中。",
|
||||
@@ -208,7 +208,7 @@
|
||||
"changes": "更新日志",
|
||||
"releaseDate": "发行日期",
|
||||
"importFromURLsInFile": "从文件中的 URL 导入(如 OPML)",
|
||||
"versionDetectionExplanation": "将版本字符串与操作系统检测到的版本进行协调",
|
||||
"versionDetectionExplanation": "使发行版本号与应用定义的版本号一致",
|
||||
"versionDetection": "版本检测",
|
||||
"standardVersionDetection": "常规版本检测",
|
||||
"groupByCategory": "按类别分组显示",
|
||||
@@ -224,7 +224,7 @@
|
||||
"checkOnStart": "启动时进行一次检查",
|
||||
"tryInferAppIdFromCode": "尝试从源代码推断应用 ID",
|
||||
"removeOnExternalUninstall": "自动删除列表中已卸载的应用",
|
||||
"pickHighestVersionCode": "自动选择版本号最高的 APK 文件",
|
||||
"pickHighestVersionCode": "自动选取内部版本号最高的 APK 文件",
|
||||
"checkUpdateOnDetailPage": "打开应用详情页时进行检查",
|
||||
"disablePageTransitions": "禁用页面过渡动画效果",
|
||||
"reversePageTransitions": "反转页面过渡动画效果",
|
||||
@@ -248,7 +248,7 @@
|
||||
"intermediateLink": "中转链接",
|
||||
"exemptFromBackgroundUpdates": "禁用后台更新(如果已经全局启用)",
|
||||
"bgUpdatesOnWiFiOnly": "未连接 Wi-Fi 时禁用后台更新",
|
||||
"autoSelectHighestVersionCode": "自动选择版本号最高的 APK 文件",
|
||||
"autoSelectHighestVersionCode": "自动选择内部版本号最高的 APK 文件",
|
||||
"versionExtractionRegEx": "版本号提取规则(正则表达式)",
|
||||
"matchGroupToUse": "引用的捕获组",
|
||||
"highlightTouchTargets": "突出展示不明显的触摸区域",
|
||||
@@ -285,20 +285,20 @@
|
||||
"shizukuBinderNotFound": "未发现兼容的 Shizuku 服务",
|
||||
"useSystemFont": "使用系统字体",
|
||||
"systemFontError": "加载系统字体出错:{}",
|
||||
"useVersionCodeAsOSVersion": "使用应用程序版本代码作为操作系统检测到的版本",
|
||||
"useVersionCodeAsOSVersion": "使用内部版本号代替应用定义的版本号",
|
||||
"requestHeader": "请求标头",
|
||||
"useLatestAssetDateAsReleaseDate": "使用最新资产上传作为发布日期",
|
||||
"defaultPseudoVersioningMethod": "默认伪版本控制方法",
|
||||
"partialAPKHash": "部分 APK 哈希值",
|
||||
"APKLinkHash": "APK 链接哈希",
|
||||
"directAPKLink": "直接 APK 链接",
|
||||
"pseudoVersionInUse": "伪版本正在使用",
|
||||
"installed": "已安装",
|
||||
"latest": "最新的",
|
||||
"invertRegEx": "反转正则表达式",
|
||||
"useLatestAssetDateAsReleaseDate": "使用最近文件上传时间作为发行日期",
|
||||
"defaultPseudoVersioningMethod": "默认虚拟版本方案",
|
||||
"partialAPKHash": "APK 文件散列值片段",
|
||||
"APKLinkHash": "APK 文件链接散列值",
|
||||
"directAPKLink": "APK 文件直链",
|
||||
"pseudoVersionInUse": "正在使用虚拟版本号",
|
||||
"installed": "当前版本",
|
||||
"latest": "最新版本",
|
||||
"invertRegEx": "反转匹配",
|
||||
"note": "备注",
|
||||
"selfHostedNote": "{}\"下拉菜单可用于访问任何来源的自托管/自定义实例。",
|
||||
"badDownload": "无法解析 APK(不兼容或部分下载)",
|
||||
"selfHostedNote": "可以通过“{}”下拉菜单来指向任意来源的自托管/自定义实例。",
|
||||
"badDownload": "无法解析 APK 文件(不兼容或文件不完整)",
|
||||
"removeAppQuestion": {
|
||||
"one": "是否删除应用?",
|
||||
"other": "是否删除应用?"
|
||||
|
@@ -2,7 +2,6 @@ import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:html/parser.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:obtainium/app_sources/github.dart';
|
||||
import 'package:obtainium/custom_errors.dart';
|
||||
@@ -117,91 +116,58 @@ class GitLab extends AppSource {
|
||||
String standardUrl,
|
||||
Map<String, dynamic> additionalSettings,
|
||||
) async {
|
||||
bool fallbackToOlderReleases =
|
||||
additionalSettings['fallbackToOlderReleases'] == true;
|
||||
// Prepare request params
|
||||
var names = GitHub().getAppNames(standardUrl);
|
||||
String? PAT = await getPATIfAny(hostChanged ? additionalSettings : {});
|
||||
Iterable<APKDetails> apkDetailsList = [];
|
||||
if (PAT != null) {
|
||||
var names = GitHub().getAppNames(standardUrl);
|
||||
Response res = await sourceRequest(
|
||||
'https://${hosts[0]}/api/v4/projects/${names.author}%2F${names.name}/releases?private_token=$PAT',
|
||||
additionalSettings);
|
||||
if (res.statusCode != 200) {
|
||||
throw getObtainiumHttpError(res);
|
||||
}
|
||||
var json = jsonDecode(res.body) as List<dynamic>;
|
||||
apkDetailsList = json.map((e) {
|
||||
var apkUrlsFromAssets = (e['assets']?['links'] as List<dynamic>? ?? [])
|
||||
.map((e) {
|
||||
return (e['direct_asset_url'] ?? e['url'] ?? '') as String;
|
||||
})
|
||||
.where((s) => s.isNotEmpty)
|
||||
.toList();
|
||||
List<String> uploadedAPKsFromDescription =
|
||||
((e['description'] ?? '') as String)
|
||||
.split('](')
|
||||
.join('\n')
|
||||
.split('.apk)')
|
||||
.join('.apk\n')
|
||||
.split('\n')
|
||||
.where((s) => s.startsWith('/uploads/') && s.endsWith('apk'))
|
||||
.map((s) => '$standardUrl$s')
|
||||
.toList();
|
||||
var apkUrlsSet = apkUrlsFromAssets.toSet();
|
||||
apkUrlsSet.addAll(uploadedAPKsFromDescription);
|
||||
var releaseDateString = e['released_at'] ?? e['created_at'];
|
||||
DateTime? releaseDate = releaseDateString != null
|
||||
? DateTime.parse(releaseDateString)
|
||||
: null;
|
||||
return APKDetails(
|
||||
e['tag_name'] ?? e['name'],
|
||||
getApkUrlsFromUrls(apkUrlsSet.toList()),
|
||||
GitHub().getAppNames(standardUrl),
|
||||
releaseDate: releaseDate);
|
||||
});
|
||||
} else {
|
||||
Response res = await sourceRequest(
|
||||
'$standardUrl/-/tags?format=atom', additionalSettings);
|
||||
if (res.statusCode != 200) {
|
||||
throw getObtainiumHttpError(res);
|
||||
}
|
||||
var standardUri = Uri.parse(standardUrl);
|
||||
var parsedHtml = parse(res.body);
|
||||
apkDetailsList = parsedHtml.querySelectorAll('entry').map((entry) {
|
||||
var entryContent = parse(
|
||||
parseFragment(entry.querySelector('content')!.innerHtml).text);
|
||||
var apkUrls = [
|
||||
...getLinksFromParsedHTML(
|
||||
entryContent,
|
||||
RegExp(
|
||||
'^${standardUri.path.replaceAllMapped(RegExp(r'[.*+?^${}()|[\]\\]'), (x) {
|
||||
return '\\${x[0]}';
|
||||
})}/uploads/[^/]+/[^/]+\\.apk\$',
|
||||
caseSensitive: false),
|
||||
standardUri.origin),
|
||||
// GitLab releases may contain links to externally hosted APKs
|
||||
...getLinksFromParsedHTML(entryContent,
|
||||
RegExp('/[^/]+\\.apk\$', caseSensitive: false), '')
|
||||
.where((element) => Uri.parse(element).host != '')
|
||||
];
|
||||
var entryId = entry.querySelector('id')?.innerHtml;
|
||||
var version =
|
||||
entryId == null ? null : Uri.parse(entryId).pathSegments.last;
|
||||
var releaseDateString = entry.querySelector('updated')?.innerHtml;
|
||||
DateTime? releaseDate = releaseDateString != null
|
||||
? DateTime.parse(releaseDateString)
|
||||
: null;
|
||||
if (version == null) {
|
||||
throw NoVersionError();
|
||||
}
|
||||
return APKDetails(version, getApkUrlsFromUrls(apkUrls),
|
||||
GitHub().getAppNames(standardUrl),
|
||||
releaseDate: releaseDate);
|
||||
});
|
||||
String optionalAuth = (PAT != null) ? 'private_token=$PAT' : '';
|
||||
|
||||
// Request data from REST API
|
||||
Response res = await sourceRequest(
|
||||
'https://${hosts[0]}/api/v4/projects/${names.author}%2F${names.name}/releases?$optionalAuth',
|
||||
additionalSettings);
|
||||
if (res.statusCode != 200) {
|
||||
throw getObtainiumHttpError(res);
|
||||
}
|
||||
|
||||
// Extract .apk details from received data
|
||||
Iterable<APKDetails> apkDetailsList = [];
|
||||
var json = jsonDecode(res.body) as List<dynamic>;
|
||||
apkDetailsList = json.map((e) {
|
||||
var apkUrlsFromAssets = (e['assets']?['links'] as List<dynamic>? ?? [])
|
||||
.map((e) {
|
||||
return (e['direct_asset_url'] ?? e['url'] ?? '') as String;
|
||||
})
|
||||
.where((s) => s.isNotEmpty)
|
||||
.toList();
|
||||
List<String> uploadedAPKsFromDescription =
|
||||
((e['description'] ?? '') as String)
|
||||
.split('](')
|
||||
.join('\n')
|
||||
.split('.apk)')
|
||||
.join('.apk\n')
|
||||
.split('\n')
|
||||
.where((s) => s.startsWith('/uploads/') && s.endsWith('apk'))
|
||||
.map((s) => '$standardUrl$s')
|
||||
.toList();
|
||||
var apkUrlsSet = apkUrlsFromAssets.toSet();
|
||||
apkUrlsSet.addAll(uploadedAPKsFromDescription);
|
||||
var releaseDateString = e['released_at'] ?? e['created_at'];
|
||||
DateTime? releaseDate = releaseDateString != null
|
||||
? DateTime.parse(releaseDateString)
|
||||
: null;
|
||||
return APKDetails(
|
||||
e['tag_name'] ?? e['name'],
|
||||
getApkUrlsFromUrls(apkUrlsSet.toList()),
|
||||
GitHub().getAppNames(standardUrl),
|
||||
releaseDate: releaseDate);
|
||||
});
|
||||
if (apkDetailsList.isEmpty) {
|
||||
throw NoReleasesError();
|
||||
}
|
||||
|
||||
// Fallback procedure
|
||||
bool fallbackToOlderReleases =
|
||||
additionalSettings['fallbackToOlderReleases'] == true;
|
||||
if (fallbackToOlderReleases) {
|
||||
if (additionalSettings['trackOnly'] != true) {
|
||||
apkDetailsList =
|
||||
@@ -211,6 +177,7 @@ class GitLab extends AppSource {
|
||||
throw NoReleasesError();
|
||||
}
|
||||
}
|
||||
|
||||
return apkDetailsList.first;
|
||||
}
|
||||
}
|
||||
|
@@ -38,6 +38,7 @@ List<MapEntry<Locale, String>> supportedLocales = const [
|
||||
MapEntry(Locale('nl'), 'Nederlands'),
|
||||
MapEntry(Locale('vi'), 'Tiếng Việt'),
|
||||
MapEntry(Locale('tr'), 'Türkçe'),
|
||||
MapEntry(Locale('uk'), 'Українська'),
|
||||
];
|
||||
const fallbackLocale = Locale('en');
|
||||
const localeDir = 'assets/translations';
|
||||
|
Reference in New Issue
Block a user