mirror of
https://github.com/ImranR98/Obtainium.git
synced 2025-08-05 14:50:15 +02:00
Compare commits
21 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
1e3815ca20 | ||
|
0e2fa96b9f | ||
|
389aebe54e | ||
|
fbfeaf2a91 | ||
|
485812d076 | ||
|
68e98ec719 | ||
|
cbe41de734 | ||
|
abb8641105 | ||
|
dbcb4b3c09 | ||
|
b231c756e6 | ||
|
3cb3f7fdd4 | ||
|
9837e8e325 | ||
|
73d4814f18 | ||
|
0a9219c314 | ||
|
56c5a73d9a | ||
|
a30e063246 | ||
|
bd26b6514a | ||
|
3ea8c7e888 | ||
|
5f2ec5ce6f | ||
|
783ce9d555 | ||
|
a719b2475b |
2
.flutter
2
.flutter
Submodule .flutter updated: 54e66469a9...5dcb86f68f
@@ -6,7 +6,8 @@
|
|||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:requestLegacyExternalStorage="true"
|
android:requestLegacyExternalStorage="true"
|
||||||
android:usesCleartextTraffic="true">
|
android:usesCleartextTraffic="true"
|
||||||
|
android:localeConfig="@xml/locales_config">
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
|
22
android/app/src/main/res/xml/locales_config.xml
Normal file
22
android/app/src/main/res/xml/locales_config.xml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<locale android:name="bs"/>
|
||||||
|
<locale android:name="cs"/>
|
||||||
|
<locale android:name="de"/>
|
||||||
|
<locale android:name="en"/>
|
||||||
|
<locale android:name="es"/>
|
||||||
|
<locale android:name="fa"/>
|
||||||
|
<locale android:name="fr"/>
|
||||||
|
<locale android:name="hu"/>
|
||||||
|
<locale android:name="it"/>
|
||||||
|
<locale android:name="ja"/>
|
||||||
|
<locale android:name="nl"/>
|
||||||
|
<locale android:name="pl"/>
|
||||||
|
<locale android:name="pt"/>
|
||||||
|
<locale android:name="ru"/>
|
||||||
|
<locale android:name="sv"/>
|
||||||
|
<locale android:name="tr"/>
|
||||||
|
<locale android:name="uk"/>
|
||||||
|
<locale android:name="vi"/>
|
||||||
|
<locale android:name="zh"/>
|
||||||
|
</locale-config>
|
@@ -113,7 +113,7 @@
|
|||||||
"dark": "تاریک",
|
"dark": "تاریک",
|
||||||
"light": "روشن",
|
"light": "روشن",
|
||||||
"followSystem": "هماهنگ با سیستم",
|
"followSystem": "هماهنگ با سیستم",
|
||||||
"followSystemThemeExplanation": "Following system theme is possible only by using third-party applications",
|
"followSystemThemeExplanation": "دنبال کردن تم سیستم فقط با استفاده از برنامه های شخص ثالث امکان پذیر است",
|
||||||
"useBlackTheme": "استفاده از تم تیره سیاه خالص",
|
"useBlackTheme": "استفاده از تم تیره سیاه خالص",
|
||||||
"appSortBy": "مرتب سازی برنامه بر اساس",
|
"appSortBy": "مرتب سازی برنامه بر اساس",
|
||||||
"authorName": "سازنده/اسم",
|
"authorName": "سازنده/اسم",
|
||||||
@@ -147,10 +147,10 @@
|
|||||||
"noNewUpdates": "به روز رسانی جدیدی وجود ندارد.",
|
"noNewUpdates": "به روز رسانی جدیدی وجود ندارد.",
|
||||||
"xHasAnUpdate": "{} یک به روز رسانی دارد.",
|
"xHasAnUpdate": "{} یک به روز رسانی دارد.",
|
||||||
"appsUpdated": "برنامه ها به روز شدند",
|
"appsUpdated": "برنامه ها به روز شدند",
|
||||||
"appsNotUpdated": "Failed to update applications",
|
"appsNotUpdated": "به روز رسانی برنامه ها ناموفق بود",
|
||||||
"appsUpdatedNotifDescription": "به کاربر اطلاع می دهد که به روز رسانی یک یا چند برنامه در پس زمینه اعمال شده است",
|
"appsUpdatedNotifDescription": "به کاربر اطلاع می دهد که به روز رسانی یک یا چند برنامه در پس زمینه اعمال شده است",
|
||||||
"xWasUpdatedToY": "{} به {} به روز شد.",
|
"xWasUpdatedToY": "{} به {} به روز شد.",
|
||||||
"xWasNotUpdatedToY": "Failed to update {} to {}.",
|
"xWasNotUpdatedToY": "به روز رسانی {} به {} انجام نشد.",
|
||||||
"errorCheckingUpdates": "خطا در بررسی بهروزرسانیها",
|
"errorCheckingUpdates": "خطا در بررسی بهروزرسانیها",
|
||||||
"errorCheckingUpdatesNotifDescription": "اعلانی که وقتی بررسی بهروزرسانی پسزمینه ناموفق است نشان میدهد",
|
"errorCheckingUpdatesNotifDescription": "اعلانی که وقتی بررسی بهروزرسانی پسزمینه ناموفق است نشان میدهد",
|
||||||
"appsRemoved": "برنامه ها حذف شدند",
|
"appsRemoved": "برنامه ها حذف شدند",
|
||||||
@@ -189,9 +189,9 @@
|
|||||||
"disableVersionDetection": "غیرفعال کردن تشخیص نسخه",
|
"disableVersionDetection": "غیرفعال کردن تشخیص نسخه",
|
||||||
"noVersionDetectionExplanation": "این گزینه فقط باید برای برنامه هایی استفاده شود که تشخیص نسخه به درستی کار نمی کند.",
|
"noVersionDetectionExplanation": "این گزینه فقط باید برای برنامه هایی استفاده شود که تشخیص نسخه به درستی کار نمی کند.",
|
||||||
"downloadingX": "در حال دانلود {}",
|
"downloadingX": "در حال دانلود {}",
|
||||||
"downloadX": "Download {}",
|
"downloadX": "دانلود {}",
|
||||||
"downloadedX": "Downloaded {}",
|
"downloadedX": "دانلود شده {}",
|
||||||
"releaseAsset": "Release Asset",
|
"releaseAsset": "انتشار دارایی",
|
||||||
"downloadNotifDescription": "کاربر را از پیشرفت دانلود یک برنامه مطلع می کند",
|
"downloadNotifDescription": "کاربر را از پیشرفت دانلود یک برنامه مطلع می کند",
|
||||||
"noAPKFound": "APK پیدا نشد فایل",
|
"noAPKFound": "APK پیدا نشد فایل",
|
||||||
"noVersionDetection": "بدون تشخیص نسخه",
|
"noVersionDetection": "بدون تشخیص نسخه",
|
||||||
@@ -305,13 +305,13 @@
|
|||||||
"installed": "نصب شده است",
|
"installed": "نصب شده است",
|
||||||
"latest": "آخرین",
|
"latest": "آخرین",
|
||||||
"invertRegEx": "معکوس کردن عبارت منظم",
|
"invertRegEx": "معکوس کردن عبارت منظم",
|
||||||
"note": "Note",
|
"note": "یادداشت",
|
||||||
"selfHostedNote": "The \"{}\" dropdown can be used to reach self-hosted/custom instances of any source.",
|
"selfHostedNote": "از منوی کرکره ای \"{}\" می توان برای دسترسی به نمونه های خود میزبانی/سفارشی از هر منبعی استفاده کرد.",
|
||||||
"badDownload": "The APK could not be parsed (incompatible or partial download)",
|
"badDownload": "APK قابل تجزیه نیست (دانلود ناسازگار یا جزئی)",
|
||||||
"beforeNewInstallsShareToAppVerifier": "Share new Apps with AppVerifier (if available)",
|
"beforeNewInstallsShareToAppVerifier": "اشتراکگذاری برنامههای جدید با AppVerifier (در صورت وجود)",
|
||||||
"appVerifierInstructionToast": "Share to AppVerifier, then return here when ready.",
|
"appVerifierInstructionToast": "در AppVerifier به اشتراک بگذارید، سپس پس از آماده شدن به اینجا برگردید.",
|
||||||
"wiki": "Help/Wiki",
|
"wiki": "راهنما/ویکی",
|
||||||
"crowdsourcedConfigsLabel": "Crowdsourced App Configurations (use at your own risk)",
|
"crowdsourcedConfigsLabel": "تنظیمات برنامه Crowdsourced (با مسئولیت خود استفاده کنید)",
|
||||||
"removeAppQuestion": {
|
"removeAppQuestion": {
|
||||||
"one": "برنامه حذف شود؟",
|
"one": "برنامه حذف شود؟",
|
||||||
"other": "برنامه ها حذف شوند؟"
|
"other": "برنامه ها حذف شوند؟"
|
||||||
@@ -361,8 +361,8 @@
|
|||||||
"other": "{} و {} برنامه دیگر به روز شدند."
|
"other": "{} و {} برنامه دیگر به روز شدند."
|
||||||
},
|
},
|
||||||
"xAndNMoreUpdatesFailed": {
|
"xAndNMoreUpdatesFailed": {
|
||||||
"one": "Failed to update {} and 1 more app.",
|
"one": "{} و 1 برنامه دیگر به روز نشد.",
|
||||||
"other": "Failed to update {} and {} more apps."
|
"other": "{} و {} برنامه دیگر به روز نشد."
|
||||||
},
|
},
|
||||||
"xAndNMoreUpdatesPossiblyInstalled": {
|
"xAndNMoreUpdatesPossiblyInstalled": {
|
||||||
"one": "{} و 1 برنامه دیگر ممکن است به روز شده باشند.",
|
"one": "{} و 1 برنامه دیگر ممکن است به روز شده باشند.",
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
"placeholder": "Заполнитель",
|
"placeholder": "Заполнитель",
|
||||||
"someErrors": "Возникли некоторые ошибки",
|
"someErrors": "Возникли некоторые ошибки",
|
||||||
"unexpectedError": "Неожиданная ошибка",
|
"unexpectedError": "Неожиданная ошибка",
|
||||||
"ok": "Ok",
|
"ok": "Ок",
|
||||||
"and": "и",
|
"and": "и",
|
||||||
"githubPATLabel": "Персональный токен доступа GitHub\n(увеличивает лимит запросов)",
|
"githubPATLabel": "Персональный токен доступа GitHub\n(увеличивает лимит запросов)",
|
||||||
"includePrereleases": "Включить предварительные релизы",
|
"includePrereleases": "Включить предварительные релизы",
|
||||||
@@ -135,7 +135,7 @@
|
|||||||
"close": "Закрыть",
|
"close": "Закрыть",
|
||||||
"share": "Поделиться",
|
"share": "Поделиться",
|
||||||
"appNotFound": "Приложение не найдено",
|
"appNotFound": "Приложение не найдено",
|
||||||
"obtainiumExportHyphenatedLowercase": "получение-экспорт",
|
"obtainiumExportHyphenatedLowercase": "экспорт-obtainium",
|
||||||
"pickAnAPK": "Выберите APK-файл",
|
"pickAnAPK": "Выберите APK-файл",
|
||||||
"appHasMoreThanOnePackage": "{} имеет более одного пакета:",
|
"appHasMoreThanOnePackage": "{} имеет более одного пакета:",
|
||||||
"deviceSupportsXArch": "Ваше устройство поддерживает архитектуру процессора {}",
|
"deviceSupportsXArch": "Ваше устройство поддерживает архитектуру процессора {}",
|
||||||
@@ -179,8 +179,8 @@
|
|||||||
"appWithIdOrNameNotFound": "Приложение с таким ID или названием не было найдено",
|
"appWithIdOrNameNotFound": "Приложение с таким ID или названием не было найдено",
|
||||||
"reposHaveMultipleApps": "В хранилище несколько приложений",
|
"reposHaveMultipleApps": "В хранилище несколько приложений",
|
||||||
"fdroidThirdPartyRepo": "Сторонние репозитории F-Droid",
|
"fdroidThirdPartyRepo": "Сторонние репозитории F-Droid",
|
||||||
"steamMobile": "Стим Мобайл",
|
"steamMobile": "Приложение Steam",
|
||||||
"steamChat": "Стим-чат",
|
"steamChat": "Steam Chat",
|
||||||
"install": "Установить",
|
"install": "Установить",
|
||||||
"markInstalled": "Пометить как установленное",
|
"markInstalled": "Пометить как установленное",
|
||||||
"update": "Обновить",
|
"update": "Обновить",
|
||||||
@@ -191,7 +191,7 @@
|
|||||||
"downloadingX": "Загрузка {}",
|
"downloadingX": "Загрузка {}",
|
||||||
"downloadX": "Скачать {}",
|
"downloadX": "Скачать {}",
|
||||||
"downloadedX": "Загружено {}",
|
"downloadedX": "Загружено {}",
|
||||||
"releaseAsset": "Освобождение актива",
|
"releaseAsset": "Релизный объект",
|
||||||
"downloadNotifDescription": "Уведомляет пользователя о прогрессе загрузки приложения",
|
"downloadNotifDescription": "Уведомляет пользователя о прогрессе загрузки приложения",
|
||||||
"noAPKFound": "APK не найден",
|
"noAPKFound": "APK не найден",
|
||||||
"noVersionDetection": "Обнаружение версий отключено",
|
"noVersionDetection": "Обнаружение версий отключено",
|
||||||
@@ -254,7 +254,7 @@
|
|||||||
"intermediateLinkRegex": "Фильтр для \"промежуточной\" ссылки для посещения",
|
"intermediateLinkRegex": "Фильтр для \"промежуточной\" ссылки для посещения",
|
||||||
"filterByLinkText": "Фильтрация ссылок по тексту ссылки",
|
"filterByLinkText": "Фильтрация ссылок по тексту ссылки",
|
||||||
"intermediateLinkNotFound": "Промежуточная ссылка не найдена",
|
"intermediateLinkNotFound": "Промежуточная ссылка не найдена",
|
||||||
"intermediateLink": "Промежуточное звено",
|
"intermediateLink": "Промежуточная ссылка",
|
||||||
"exemptFromBackgroundUpdates": "Исключить из фоновых обновлений (если включено)",
|
"exemptFromBackgroundUpdates": "Исключить из фоновых обновлений (если включено)",
|
||||||
"bgUpdatesOnWiFiOnly": "Отключить фоновые обновления, если нет соединения с Wi-Fi",
|
"bgUpdatesOnWiFiOnly": "Отключить фоновые обновления, если нет соединения с Wi-Fi",
|
||||||
"autoSelectHighestVersionCode": "Автоматически выбирать APK с актуальной версией кода",
|
"autoSelectHighestVersionCode": "Автоматически выбирать APK с актуальной версией кода",
|
||||||
|
@@ -24,7 +24,7 @@
|
|||||||
"colour": "配色",
|
"colour": "配色",
|
||||||
"standard": "标准",
|
"standard": "标准",
|
||||||
"custom": "定制",
|
"custom": "定制",
|
||||||
"useMaterialYou": "使用 Material You 配色",
|
"useMaterialYou": "使用 Material You",
|
||||||
"githubStarredRepos": "已星标的 GitHub 仓库",
|
"githubStarredRepos": "已星标的 GitHub 仓库",
|
||||||
"uname": "用户名",
|
"uname": "用户名",
|
||||||
"wrongArgNum": "参数数量错误",
|
"wrongArgNum": "参数数量错误",
|
||||||
@@ -45,8 +45,8 @@
|
|||||||
"search": "搜索",
|
"search": "搜索",
|
||||||
"additionalOptsFor": "{} 的更多选项",
|
"additionalOptsFor": "{} 的更多选项",
|
||||||
"supportedSources": "支持的来源",
|
"supportedSources": "支持的来源",
|
||||||
"trackOnlyInBrackets": "(仅追踪)",
|
"trackOnlyInBrackets": "(仅追踪)",
|
||||||
"searchableInBrackets": "(可搜索)",
|
"searchableInBrackets": "(可搜索)",
|
||||||
"appsString": "应用列表",
|
"appsString": "应用列表",
|
||||||
"noApps": "无应用",
|
"noApps": "无应用",
|
||||||
"noAppsForFilter": "没有符合条件的应用",
|
"noAppsForFilter": "没有符合条件的应用",
|
||||||
@@ -125,7 +125,7 @@
|
|||||||
"bgUpdateCheckInterval": "后台更新检查间隔",
|
"bgUpdateCheckInterval": "后台更新检查间隔",
|
||||||
"neverManualOnly": "手动",
|
"neverManualOnly": "手动",
|
||||||
"appearance": "外观",
|
"appearance": "外观",
|
||||||
"showWebInAppView": "应用详情页显示来源网页",
|
"showWebInAppView": "应用详情页显示来源网站内容",
|
||||||
"pinUpdates": "将待更新应用置顶",
|
"pinUpdates": "将待更新应用置顶",
|
||||||
"updates": "更新",
|
"updates": "更新",
|
||||||
"sourceSpecific": "来源",
|
"sourceSpecific": "来源",
|
||||||
@@ -147,7 +147,7 @@
|
|||||||
"noNewUpdates": "全部应用已是最新。",
|
"noNewUpdates": "全部应用已是最新。",
|
||||||
"xHasAnUpdate": "“{}”可以更新了。",
|
"xHasAnUpdate": "“{}”可以更新了。",
|
||||||
"appsUpdated": "应用已更新",
|
"appsUpdated": "应用已更新",
|
||||||
"appsNotUpdated": "更新应用程序失败",
|
"appsNotUpdated": "更新应用失败",
|
||||||
"appsUpdatedNotifDescription": "当应用在后台安装更新时发送通知",
|
"appsUpdatedNotifDescription": "当应用在后台安装更新时发送通知",
|
||||||
"xWasUpdatedToY": "“{}”已更新至 {}。",
|
"xWasUpdatedToY": "“{}”已更新至 {}。",
|
||||||
"xWasNotUpdatedToY": "未能将 {} 更新为 {}。",
|
"xWasNotUpdatedToY": "未能将 {} 更新为 {}。",
|
||||||
@@ -191,7 +191,7 @@
|
|||||||
"downloadingX": "正在下载“{}”",
|
"downloadingX": "正在下载“{}”",
|
||||||
"downloadX": "下载 {}",
|
"downloadX": "下载 {}",
|
||||||
"downloadedX": "下载 {}",
|
"downloadedX": "下载 {}",
|
||||||
"releaseAsset": "APK 文件",
|
"releaseAsset": "发行版附件",
|
||||||
"downloadNotifDescription": "提示应用的下载进度",
|
"downloadNotifDescription": "提示应用的下载进度",
|
||||||
"noAPKFound": "未找到 APK 文件",
|
"noAPKFound": "未找到 APK 文件",
|
||||||
"noVersionDetection": "禁用版本检测",
|
"noVersionDetection": "禁用版本检测",
|
||||||
@@ -201,7 +201,7 @@
|
|||||||
"noCategory": "无类别",
|
"noCategory": "无类别",
|
||||||
"noCategories": "无类别",
|
"noCategories": "无类别",
|
||||||
"deleteCategoriesQuestion": "是否删除选中的类别?",
|
"deleteCategoriesQuestion": "是否删除选中的类别?",
|
||||||
"categoryDeleteWarning": "被删除类别下的应用将恢复为未分类状态。",
|
"categoryDeleteWarning": "被删除类别的应用将恢复为未分类状态。",
|
||||||
"addCategory": "添加类别",
|
"addCategory": "添加类别",
|
||||||
"label": "标签",
|
"label": "标签",
|
||||||
"language": "语言",
|
"language": "语言",
|
||||||
@@ -247,7 +247,7 @@
|
|||||||
"appsPossiblyUpdated": "已尝试更新应用",
|
"appsPossiblyUpdated": "已尝试更新应用",
|
||||||
"appsPossiblyUpdatedNotifDescription": "当应用已尝试在后台更新时发送通知",
|
"appsPossiblyUpdatedNotifDescription": "当应用已尝试在后台更新时发送通知",
|
||||||
"xWasPossiblyUpdatedToY": "已尝试将“{}”更新至 {}。",
|
"xWasPossiblyUpdatedToY": "已尝试将“{}”更新至 {}。",
|
||||||
"enableBackgroundUpdates": "启用后台更新",
|
"enableBackgroundUpdates": "启用全局后台更新",
|
||||||
"backgroundUpdateReqsExplanation": "后台更新未必适用于所有的应用。",
|
"backgroundUpdateReqsExplanation": "后台更新未必适用于所有的应用。",
|
||||||
"backgroundUpdateLimitsExplanation": "只有在启动 Obtainium 时才能确认安装是否成功。",
|
"backgroundUpdateLimitsExplanation": "只有在启动 Obtainium 时才能确认安装是否成功。",
|
||||||
"verifyLatestTag": "验证“Latest”标签",
|
"verifyLatestTag": "验证“Latest”标签",
|
||||||
@@ -255,12 +255,12 @@
|
|||||||
"filterByLinkText": "根据链接文本进行筛选",
|
"filterByLinkText": "根据链接文本进行筛选",
|
||||||
"intermediateLinkNotFound": "未找到中转链接",
|
"intermediateLinkNotFound": "未找到中转链接",
|
||||||
"intermediateLink": "中转链接",
|
"intermediateLink": "中转链接",
|
||||||
"exemptFromBackgroundUpdates": "禁用后台更新(如果已经全局启用)",
|
"exemptFromBackgroundUpdates": "禁用后台更新(仅此应用生效,即使已启用全局后台更新)",
|
||||||
"bgUpdatesOnWiFiOnly": "未连接 Wi-Fi 时禁用后台更新",
|
"bgUpdatesOnWiFiOnly": "未连接 Wi-Fi 时禁用后台更新",
|
||||||
"autoSelectHighestVersionCode": "自动选择内部版本号最高的 APK 文件",
|
"autoSelectHighestVersionCode": "自动选择内部版本号最高的 APK 文件",
|
||||||
"versionExtractionRegEx": "提取版本号的正则表达式",
|
"versionExtractionRegEx": "提取版本号的正则表达式",
|
||||||
"matchGroupToUse": "从上述匹配结果中引用的捕获组",
|
"matchGroupToUse": "从上述匹配结果中引用的捕获组",
|
||||||
"highlightTouchTargets": "突出展示不明显的触摸区域",
|
"highlightTouchTargets": "突出展示不明显的可交互区域",
|
||||||
"pickExportDir": "选择导出文件夹",
|
"pickExportDir": "选择导出文件夹",
|
||||||
"autoExportOnChanges": "数据变更时自动导出",
|
"autoExportOnChanges": "数据变更时自动导出",
|
||||||
"includeSettings": "同时导出应用设置",
|
"includeSettings": "同时导出应用设置",
|
||||||
@@ -291,12 +291,12 @@
|
|||||||
"useShizuku": "使用 Shizuku 或 Sui 安装",
|
"useShizuku": "使用 Shizuku 或 Sui 安装",
|
||||||
"shizukuBinderNotFound": "未发现兼容的 Shizuku 服务",
|
"shizukuBinderNotFound": "未发现兼容的 Shizuku 服务",
|
||||||
"shizukuOld": "Shizuku 版本过低(<11)- 请更新",
|
"shizukuOld": "Shizuku 版本过低(<11)- 请更新",
|
||||||
"shizukuOldAndroidWithADB": "正在低版本 Android(<8.1)系统中以 ADB 模式运行 Shizuku - 请更新 Android 版本或使用 Sui 代替",
|
"shizukuOldAndroidWithADB": "正在低版本 Android(<8.1)系统中以 ADB 模式运行 Shizuku - 请更新 Android 系统版本或使用 Sui 代替",
|
||||||
"shizukuPretendToBeGooglePlay": "使用 Shizuku 时,将安装来源伪装为“Google Play”",
|
"shizukuPretendToBeGooglePlay": "将安装来源伪装为 Google Play(需要使用 Shizuku)",
|
||||||
"useSystemFont": "使用系统字体",
|
"useSystemFont": "使用系统字体",
|
||||||
"useVersionCodeAsOSVersion": "使用内部版本号代替应用定义的版本号",
|
"useVersionCodeAsOSVersion": "使用内部版本号代替应用定义的版本号",
|
||||||
"requestHeader": "请求标头",
|
"requestHeader": "请求标头",
|
||||||
"useLatestAssetDateAsReleaseDate": "使用最近文件上传时间作为发行日期",
|
"useLatestAssetDateAsReleaseDate": "使用最新文件上传时间作为发行日期",
|
||||||
"defaultPseudoVersioningMethod": "默认虚拟版本方案",
|
"defaultPseudoVersioningMethod": "默认虚拟版本方案",
|
||||||
"partialAPKHash": "APK 文件散列值片段",
|
"partialAPKHash": "APK 文件散列值片段",
|
||||||
"APKLinkHash": "APK 文件链接散列值",
|
"APKLinkHash": "APK 文件链接散列值",
|
||||||
@@ -310,19 +310,19 @@
|
|||||||
"badDownload": "无法解析 APK 文件(不兼容或文件不完整)",
|
"badDownload": "无法解析 APK 文件(不兼容或文件不完整)",
|
||||||
"beforeNewInstallsShareToAppVerifier": "通过 AppVerifier 校验新应用(如果可用)",
|
"beforeNewInstallsShareToAppVerifier": "通过 AppVerifier 校验新应用(如果可用)",
|
||||||
"appVerifierInstructionToast": "分享至 AppVerifier,完成后返回此处。",
|
"appVerifierInstructionToast": "分享至 AppVerifier,完成后返回此处。",
|
||||||
"wiki": "帮助/维基",
|
"wiki": "帮助/Wiki",
|
||||||
"crowdsourcedConfigsLabel": "众包应用程序配置(使用风险自负)",
|
"crowdsourcedConfigsLabel": "众包应用程序配置(使用风险自负)",
|
||||||
"removeAppQuestion": {
|
"removeAppQuestion": {
|
||||||
"one": "是否删除应用?",
|
"one": "是否删除应用?",
|
||||||
"other": "是否删除应用?"
|
"other": "是否删除应用?"
|
||||||
},
|
},
|
||||||
"tooManyRequestsTryAgainInMinutes": {
|
"tooManyRequestsTryAgainInMinutes": {
|
||||||
"one": "API 请求过于频繁(速率限制)- 在 {} 分钟后重试",
|
"one": "API 请求过于频繁(速率限制)- 请在 {} 分钟后重试",
|
||||||
"other": "API 请求过于频繁(速率限制)- 在 {} 分钟后重试"
|
"other": "API 请求过于频繁(速率限制)- 请在 {} 分钟后重试"
|
||||||
},
|
},
|
||||||
"bgUpdateGotErrorRetryInMinutes": {
|
"bgUpdateGotErrorRetryInMinutes": {
|
||||||
"one": "后台更新检查遇到了“{}”问题,预定于 {} 分钟后重试",
|
"one": "后台更新检查遇到了“{}”问题,将于 {} 分钟后重试",
|
||||||
"other": "后台更新检查遇到了“{}”问题,预定于 {} 分钟后重试"
|
"other": "后台更新检查遇到了“{}”问题,将于 {} 分钟后重试"
|
||||||
},
|
},
|
||||||
"bgCheckFoundUpdatesWillNotifyIfNeeded": {
|
"bgCheckFoundUpdatesWillNotifyIfNeeded": {
|
||||||
"one": "后台检查发现 {} 个应用更新 - 如有需要将发送通知",
|
"one": "后台检查发现 {} 个应用更新 - 如有需要将发送通知",
|
||||||
@@ -361,8 +361,8 @@
|
|||||||
"other": "“{}”和另外 {} 个应用已更新。"
|
"other": "“{}”和另外 {} 个应用已更新。"
|
||||||
},
|
},
|
||||||
"xAndNMoreUpdatesFailed": {
|
"xAndNMoreUpdatesFailed": {
|
||||||
"one": "更新 {} 和另外 1 个应用程序失败。",
|
"one": "{} 和另外 1 个应用更新失败。",
|
||||||
"other": "未能更新 {} 和 {} 更多应用程序。"
|
"other": "{} 和另外 {} 个应用更新失败。"
|
||||||
},
|
},
|
||||||
"xAndNMoreUpdatesPossiblyInstalled": {
|
"xAndNMoreUpdatesPossiblyInstalled": {
|
||||||
"one": "{} 和另外 1 个应用已尝试更新。",
|
"one": "{} 和另外 1 个应用已尝试更新。",
|
||||||
@@ -372,4 +372,4 @@
|
|||||||
"one": "{}APK",
|
"one": "{}APK",
|
||||||
"other": "{}APK"
|
"other": "{}APK"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -73,21 +73,23 @@ class HuaweiAppGallery extends AppSource {
|
|||||||
throw NoReleasesError();
|
throw NoReleasesError();
|
||||||
}
|
}
|
||||||
String appId = appIdFromRedirectDlUrl(res.headers['location']!);
|
String appId = appIdFromRedirectDlUrl(res.headers['location']!);
|
||||||
|
if (appId.isEmpty) {
|
||||||
|
throw NoReleasesError();
|
||||||
|
}
|
||||||
var relDateStr =
|
var relDateStr =
|
||||||
res.headers['location']?.split('?')[0].split('.').reversed.toList()[1];
|
res.headers['location']?.split('?')[0].split('.').reversed.toList()[1];
|
||||||
var relDateStrAdj = relDateStr?.split('');
|
if (relDateStr == null || relDateStr.length != 10) {
|
||||||
var tempLen = relDateStrAdj?.length ?? 0;
|
|
||||||
var i = 2;
|
|
||||||
while (i < tempLen) {
|
|
||||||
relDateStrAdj?.insert((i + i ~/ 2 - 1), '-');
|
|
||||||
i += 2;
|
|
||||||
}
|
|
||||||
var relDate = relDateStrAdj == null
|
|
||||||
? null
|
|
||||||
: DateFormat('yy-MM-dd-HH-mm', 'en_US').parse(relDateStrAdj.join(''));
|
|
||||||
if (relDateStr == null) {
|
|
||||||
throw NoVersionError();
|
throw NoVersionError();
|
||||||
}
|
}
|
||||||
|
var relDateStrAdj = relDateStr.split('');
|
||||||
|
var tempLen = relDateStrAdj.length;
|
||||||
|
var i = 2;
|
||||||
|
while (i < tempLen) {
|
||||||
|
relDateStrAdj.insert((i + i ~/ 2 - 1), '-');
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
var relDate =
|
||||||
|
DateFormat('yy-MM-dd-HH-mm', 'en_US').parse(relDateStrAdj.join(''));
|
||||||
return APKDetails(
|
return APKDetails(
|
||||||
relDateStr, [MapEntry('$appId.apk', dlUrl)], AppNames(name, appId),
|
relDateStr, [MapEntry('$appId.apk', dlUrl)], AppNames(name, appId),
|
||||||
releaseDate: relDate);
|
releaseDate: relDate);
|
||||||
|
@@ -224,7 +224,7 @@ class _ObtainiumState extends State<Obtainium> {
|
|||||||
// set the background and surface colors to pure black in the amoled theme
|
// set the background and surface colors to pure black in the amoled theme
|
||||||
if (settingsProvider.useBlackTheme) {
|
if (settingsProvider.useBlackTheme) {
|
||||||
darkColorScheme = darkColorScheme
|
darkColorScheme = darkColorScheme
|
||||||
.copyWith(background: Colors.black, surface: Colors.black)
|
.copyWith(surface: Colors.black)
|
||||||
.harmonized();
|
.harmonized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -286,7 +286,7 @@ class _AppPageState extends State<AppPage> {
|
|||||||
? WebViewWidget(
|
? WebViewWidget(
|
||||||
controller: WebViewController()
|
controller: WebViewController()
|
||||||
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
||||||
..setBackgroundColor(Theme.of(context).colorScheme.background)
|
..setBackgroundColor(Theme.of(context).colorScheme.surface)
|
||||||
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
||||||
..setNavigationDelegate(
|
..setNavigationDelegate(
|
||||||
NavigationDelegate(
|
NavigationDelegate(
|
||||||
|
@@ -503,7 +503,7 @@ class AppsPageState extends State<AppsPage> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
var transparent =
|
var transparent =
|
||||||
Theme.of(context).colorScheme.background.withAlpha(0).value;
|
Theme.of(context).colorScheme.surface.withAlpha(0).value;
|
||||||
List<double> stops = [
|
List<double> stops = [
|
||||||
...listedApps[index].app.categories.asMap().entries.map(
|
...listedApps[index].app.categories.asMap().entries.map(
|
||||||
(e) => ((e.key / (listedApps[index].app.categories.length - 1)))),
|
(e) => ((e.key / (listedApps[index].app.categories.length - 1)))),
|
||||||
@@ -893,7 +893,8 @@ class AppsPageState extends State<AppsPage> {
|
|||||||
'preferredApkIndex':
|
'preferredApkIndex':
|
||||||
a.preferredApkIndex,
|
a.preferredApkIndex,
|
||||||
'additionalSettings':
|
'additionalSettings':
|
||||||
jsonEncode(a.additionalSettings)
|
jsonEncode(a.additionalSettings),
|
||||||
|
'overrideSource': a.overrideSource
|
||||||
}))}\n\n';
|
}))}\n\n';
|
||||||
}
|
}
|
||||||
Share.share(urls,
|
Share.share(urls,
|
||||||
|
@@ -13,6 +13,7 @@ import 'package:obtainium/pages/import_export.dart';
|
|||||||
import 'package:obtainium/pages/settings.dart';
|
import 'package:obtainium/pages/settings.dart';
|
||||||
import 'package:obtainium/providers/apps_provider.dart';
|
import 'package:obtainium/providers/apps_provider.dart';
|
||||||
import 'package:obtainium/providers/settings_provider.dart';
|
import 'package:obtainium/providers/settings_provider.dart';
|
||||||
|
import 'package:obtainium/providers/source_provider.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class HomePage extends StatefulWidget {
|
class HomePage extends StatefulWidget {
|
||||||
@@ -102,13 +103,22 @@ class _HomePageState extends State<HomePage> {
|
|||||||
}) !=
|
}) !=
|
||||||
null) {
|
null) {
|
||||||
// ignore: use_build_context_synchronously
|
// ignore: use_build_context_synchronously
|
||||||
var result = await context.read<AppsProvider>().import(
|
var appsProvider = context.read<AppsProvider>();
|
||||||
action == 'app'
|
var result = await appsProvider.import(action == 'app'
|
||||||
? '{ "apps": [$dataStr] }'
|
? '{ "apps": [$dataStr] }'
|
||||||
: '{ "apps": $dataStr }');
|
: '{ "apps": $dataStr }');
|
||||||
// ignore: use_build_context_synchronously
|
// ignore: use_build_context_synchronously
|
||||||
showMessage(
|
showMessage(
|
||||||
tr('importedX', args: [plural('apps', result.key)]), context);
|
tr('importedX', args: [plural('apps', result.key.length)]),
|
||||||
|
context);
|
||||||
|
await appsProvider
|
||||||
|
.checkUpdates(specificIds: result.key.map((e) => e.id).toList())
|
||||||
|
.catchError((e) {
|
||||||
|
if (e is Map && e['errors'] is MultiAppMultiError) {
|
||||||
|
showError(e['errors'].toString(), context);
|
||||||
|
}
|
||||||
|
return <App>[];
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw ObtainiumError(tr('unknown'));
|
throw ObtainiumError(tr('unknown'));
|
||||||
|
@@ -33,7 +33,7 @@ class _ImportExportPageState extends State<ImportExportPage> {
|
|||||||
var settingsProvider = context.watch<SettingsProvider>();
|
var settingsProvider = context.watch<SettingsProvider>();
|
||||||
|
|
||||||
var outlineButtonStyle = ButtonStyle(
|
var outlineButtonStyle = ButtonStyle(
|
||||||
shape: MaterialStateProperty.all(
|
shape: WidgetStateProperty.all(
|
||||||
StadiumBorder(
|
StadiumBorder(
|
||||||
side: BorderSide(
|
side: BorderSide(
|
||||||
width: 1,
|
width: 1,
|
||||||
@@ -144,7 +144,7 @@ class _ImportExportPageState extends State<ImportExportPage> {
|
|||||||
appsProvider.addMissingCategories(settingsProvider);
|
appsProvider.addMissingCategories(settingsProvider);
|
||||||
showMessage(
|
showMessage(
|
||||||
'${tr('importedX', args: [
|
'${tr('importedX', args: [
|
||||||
plural('apps', value.key)
|
plural('apps', value.key.length)
|
||||||
])}${value.value ? ' + ${tr('settings')}' : ''}',
|
])}${value.value ? ' + ${tr('settings')}' : ''}',
|
||||||
context);
|
context);
|
||||||
});
|
});
|
||||||
|
@@ -421,7 +421,8 @@ class AppsProvider with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<Object> downloadApp(App app, BuildContext? context,
|
Future<Object> downloadApp(App app, BuildContext? context,
|
||||||
{NotificationsProvider? notificationsProvider}) async {
|
{NotificationsProvider? notificationsProvider,
|
||||||
|
bool useExisting = true}) async {
|
||||||
var notifId = DownloadNotification(app.finalName, 0).id;
|
var notifId = DownloadNotification(app.finalName, 0).id;
|
||||||
if (apps[app.id] != null) {
|
if (apps[app.id] != null) {
|
||||||
apps[app.id]!.downloadProgress = 0;
|
apps[app.id]!.downloadProgress = 0;
|
||||||
@@ -453,7 +454,7 @@ class AppsProvider with ChangeNotifier {
|
|||||||
notificationsProvider?.notify(notif);
|
notificationsProvider?.notify(notif);
|
||||||
}
|
}
|
||||||
prevProg = prog;
|
prevProg = prog;
|
||||||
}, APKDir.path);
|
}, APKDir.path, useExisting: useExisting);
|
||||||
// Set to 90 for remaining steps, will make null in 'finally'
|
// Set to 90 for remaining steps, will make null in 'finally'
|
||||||
if (apps[app.id] != null) {
|
if (apps[app.id] != null) {
|
||||||
apps[app.id]!.downloadProgress = -1;
|
apps[app.id]!.downloadProgress = -1;
|
||||||
@@ -766,7 +767,8 @@ class AppsProvider with ChangeNotifier {
|
|||||||
Future<List<String>> downloadAndInstallLatestApps(
|
Future<List<String>> downloadAndInstallLatestApps(
|
||||||
List<String> appIds, BuildContext? context,
|
List<String> appIds, BuildContext? context,
|
||||||
{NotificationsProvider? notificationsProvider,
|
{NotificationsProvider? notificationsProvider,
|
||||||
bool forceParallelDownloads = false}) async {
|
bool forceParallelDownloads = false,
|
||||||
|
bool useExisting = true}) async {
|
||||||
notificationsProvider =
|
notificationsProvider =
|
||||||
notificationsProvider ?? context?.read<NotificationsProvider>();
|
notificationsProvider ?? context?.read<NotificationsProvider>();
|
||||||
List<String> appsToInstall = [];
|
List<String> appsToInstall = [];
|
||||||
@@ -818,21 +820,82 @@ class AppsProvider with ChangeNotifier {
|
|||||||
appsToInstall =
|
appsToInstall =
|
||||||
moveStrToEnd(appsToInstall, obtainiumId, strB: obtainiumTempId);
|
moveStrToEnd(appsToInstall, obtainiumId, strB: obtainiumTempId);
|
||||||
|
|
||||||
Future<String> updateFn(String id, {bool skipInstalls = false}) async {
|
Future<void> installFn(String id, bool willBeSilent,
|
||||||
|
DownloadedApk? downloadedFile, DownloadedXApkDir? downloadedDir) async {
|
||||||
|
apps[id]?.downloadProgress = -1;
|
||||||
|
notifyListeners();
|
||||||
|
try {
|
||||||
|
bool sayInstalled = true;
|
||||||
|
var contextIfNewInstall =
|
||||||
|
apps[id]?.installedInfo == null ? context : null;
|
||||||
|
bool needBGWorkaround =
|
||||||
|
willBeSilent && context == null && !settingsProvider.useShizuku;
|
||||||
|
if (downloadedFile != null) {
|
||||||
|
if (needBGWorkaround) {
|
||||||
|
// ignore: use_build_context_synchronously
|
||||||
|
installApk(downloadedFile, contextIfNewInstall,
|
||||||
|
needsBGWorkaround: true);
|
||||||
|
} else {
|
||||||
|
// ignore: use_build_context_synchronously
|
||||||
|
sayInstalled = await installApk(downloadedFile, contextIfNewInstall,
|
||||||
|
shizukuPretendToBeGooglePlay: apps[id]!
|
||||||
|
.app
|
||||||
|
.additionalSettings['shizukuPretendToBeGooglePlay'] ==
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (needBGWorkaround) {
|
||||||
|
// ignore: use_build_context_synchronously
|
||||||
|
installXApkDir(downloadedDir!, contextIfNewInstall,
|
||||||
|
needsBGWorkaround: true);
|
||||||
|
} else {
|
||||||
|
// ignore: use_build_context_synchronously
|
||||||
|
sayInstalled = await installXApkDir(
|
||||||
|
downloadedDir!, contextIfNewInstall,
|
||||||
|
shizukuPretendToBeGooglePlay: apps[id]!
|
||||||
|
.app
|
||||||
|
.additionalSettings['shizukuPretendToBeGooglePlay'] ==
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (willBeSilent && context == null) {
|
||||||
|
if (!settingsProvider.useShizuku) {
|
||||||
|
notificationsProvider?.notify(SilentUpdateAttemptNotification(
|
||||||
|
[apps[id]!.app],
|
||||||
|
id: id.hashCode));
|
||||||
|
} else {
|
||||||
|
notificationsProvider?.notify(SilentUpdateNotification(
|
||||||
|
[apps[id]!.app], sayInstalled,
|
||||||
|
id: id.hashCode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sayInstalled) {
|
||||||
|
installedIds.add(id);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
apps[id]?.downloadProgress = null;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Map<Object?, Object?>> downloadFn(String id,
|
||||||
|
{bool skipInstalls = false}) async {
|
||||||
|
bool willBeSilent = false;
|
||||||
|
DownloadedApk? downloadedFile;
|
||||||
|
DownloadedXApkDir? downloadedDir;
|
||||||
try {
|
try {
|
||||||
var downloadedArtifact =
|
var downloadedArtifact =
|
||||||
// ignore: use_build_context_synchronously
|
// ignore: use_build_context_synchronously
|
||||||
await downloadApp(apps[id]!.app, context,
|
await downloadApp(apps[id]!.app, context,
|
||||||
notificationsProvider: notificationsProvider);
|
notificationsProvider: notificationsProvider,
|
||||||
DownloadedApk? downloadedFile;
|
useExisting: useExisting);
|
||||||
DownloadedXApkDir? downloadedDir;
|
|
||||||
if (downloadedArtifact is DownloadedApk) {
|
if (downloadedArtifact is DownloadedApk) {
|
||||||
downloadedFile = downloadedArtifact;
|
downloadedFile = downloadedArtifact;
|
||||||
} else {
|
} else {
|
||||||
downloadedDir = downloadedArtifact as DownloadedXApkDir;
|
downloadedDir = downloadedArtifact as DownloadedXApkDir;
|
||||||
}
|
}
|
||||||
id = downloadedFile?.appId ?? downloadedDir!.appId;
|
id = downloadedFile?.appId ?? downloadedDir!.appId;
|
||||||
bool willBeSilent = await canInstallSilently(apps[id]!.app);
|
willBeSilent = await canInstallSilently(apps[id]!.app);
|
||||||
if (!settingsProvider.useShizuku) {
|
if (!settingsProvider.useShizuku) {
|
||||||
if (!(await settingsProvider.getInstallPermission(enforce: false))) {
|
if (!(await settingsProvider.getInstallPermission(enforce: false))) {
|
||||||
throw ObtainiumError(tr('cancelled'));
|
throw ObtainiumError(tr('cancelled'));
|
||||||
@@ -853,80 +916,33 @@ class AppsProvider with ChangeNotifier {
|
|||||||
// ignore: use_build_context_synchronously
|
// ignore: use_build_context_synchronously
|
||||||
await waitForUserToReturnToForeground(context);
|
await waitForUserToReturnToForeground(context);
|
||||||
}
|
}
|
||||||
apps[id]?.downloadProgress = -1;
|
|
||||||
notifyListeners();
|
|
||||||
try {
|
|
||||||
if (!skipInstalls) {
|
|
||||||
bool sayInstalled = true;
|
|
||||||
var contextIfNewInstall =
|
|
||||||
apps[id]?.installedInfo == null ? context : null;
|
|
||||||
bool needBGWorkaround =
|
|
||||||
willBeSilent && context == null && !settingsProvider.useShizuku;
|
|
||||||
if (downloadedFile != null) {
|
|
||||||
if (needBGWorkaround) {
|
|
||||||
// ignore: use_build_context_synchronously
|
|
||||||
installApk(downloadedFile, contextIfNewInstall,
|
|
||||||
needsBGWorkaround: true);
|
|
||||||
} else {
|
|
||||||
// ignore: use_build_context_synchronously
|
|
||||||
sayInstalled = await installApk(
|
|
||||||
downloadedFile, contextIfNewInstall,
|
|
||||||
shizukuPretendToBeGooglePlay:
|
|
||||||
apps[id]!.app.additionalSettings[
|
|
||||||
'shizukuPretendToBeGooglePlay'] ==
|
|
||||||
true);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (needBGWorkaround) {
|
|
||||||
// ignore: use_build_context_synchronously
|
|
||||||
installXApkDir(downloadedDir!, contextIfNewInstall,
|
|
||||||
needsBGWorkaround: true);
|
|
||||||
} else {
|
|
||||||
// ignore: use_build_context_synchronously
|
|
||||||
sayInstalled = await installXApkDir(
|
|
||||||
downloadedDir!, contextIfNewInstall,
|
|
||||||
shizukuPretendToBeGooglePlay:
|
|
||||||
apps[id]!.app.additionalSettings[
|
|
||||||
'shizukuPretendToBeGooglePlay'] ==
|
|
||||||
true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (willBeSilent && context == null) {
|
|
||||||
if (!settingsProvider.useShizuku) {
|
|
||||||
notificationsProvider?.notify(SilentUpdateAttemptNotification(
|
|
||||||
[apps[id]!.app],
|
|
||||||
id: id.hashCode));
|
|
||||||
} else {
|
|
||||||
notificationsProvider?.notify(SilentUpdateNotification(
|
|
||||||
[apps[id]!.app], sayInstalled,
|
|
||||||
id: id.hashCode));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sayInstalled) {
|
|
||||||
installedIds.add(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
apps[id]?.downloadProgress = null;
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
errors.add(id, e, appName: apps[id]?.name);
|
errors.add(id, e, appName: apps[id]?.name);
|
||||||
}
|
}
|
||||||
return id;
|
return {
|
||||||
|
'id': id,
|
||||||
|
'willBeSilent': willBeSilent,
|
||||||
|
'downloadedFile': downloadedFile,
|
||||||
|
'downloadedDir': downloadedDir
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Map<Object?, Object?>> downloadResults = [];
|
||||||
if (forceParallelDownloads || !settingsProvider.parallelDownloads) {
|
if (forceParallelDownloads || !settingsProvider.parallelDownloads) {
|
||||||
for (var id in appsToInstall) {
|
for (var id in appsToInstall) {
|
||||||
await updateFn(id);
|
downloadResults.add(await downloadFn(id));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
List<String> ids = await Future.wait(
|
downloadResults = await Future.wait(
|
||||||
appsToInstall.map((id) => updateFn(id, skipInstalls: true)));
|
appsToInstall.map((id) => downloadFn(id, skipInstalls: true)));
|
||||||
for (var id in ids) {
|
}
|
||||||
if (!errors.appIdNames.containsKey(id)) {
|
for (var res in downloadResults) {
|
||||||
await updateFn(id);
|
if (!errors.appIdNames.containsKey(res['id'])) {
|
||||||
}
|
await installFn(
|
||||||
|
res['id'] as String,
|
||||||
|
res['willBeSilent'] as bool,
|
||||||
|
res['downloadedFile'] as DownloadedApk?,
|
||||||
|
res['downloadedDir'] as DownloadedXApkDir?);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1163,40 +1179,38 @@ class AppsProvider with ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
var sp = SourceProvider();
|
var sp = SourceProvider();
|
||||||
List<List<String>> errors = [];
|
List<List<String>> errors = [];
|
||||||
List<App?> newApps = (await getAppsDir()) // Parse Apps from JSON
|
await Future.wait((await getAppsDir()) // Parse Apps from JSON
|
||||||
.listSync()
|
.listSync()
|
||||||
.where((item) => item.path.toLowerCase().endsWith('.json'))
|
.map((item) async {
|
||||||
.where((item) =>
|
App? app;
|
||||||
singleId == null ||
|
if (item.path.toLowerCase().endsWith('.json') &&
|
||||||
item.path.split('/').last.toLowerCase() ==
|
(singleId == null ||
|
||||||
'${singleId.toLowerCase()}.json')
|
item.path.split('/').last.toLowerCase() ==
|
||||||
.map((e) {
|
'${singleId.toLowerCase()}.json')) {
|
||||||
try {
|
try {
|
||||||
return App.fromJson(jsonDecode(File(e.path).readAsStringSync()));
|
app = App.fromJson(jsonDecode(File(item.path).readAsStringSync()));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err is FormatException) {
|
if (err is FormatException) {
|
||||||
logs.add('Corrupt JSON when loading App (will be ignored): $e');
|
logs.add('Corrupt JSON when loading App (will be ignored): $e');
|
||||||
e.renameSync('${e.path}.corrupt');
|
item.renameSync('${item.path}.corrupt');
|
||||||
} else {
|
} else {
|
||||||
rethrow;
|
rethrow;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).toList();
|
|
||||||
for (var app in newApps) {
|
|
||||||
// Put Apps into memory to list them (fast)
|
|
||||||
if (app != null) {
|
if (app != null) {
|
||||||
try {
|
try {
|
||||||
sp.getSource(app.url, overrideSource: app.overrideSource);
|
sp.getSource(app.url, overrideSource: app.overrideSource);
|
||||||
apps.update(
|
apps.update(
|
||||||
app.id,
|
app.id,
|
||||||
(value) => AppInMemory(
|
(value) => AppInMemory(app!, value.downloadProgress,
|
||||||
app, value.downloadProgress, value.installedInfo, value.icon),
|
value.installedInfo, value.icon),
|
||||||
ifAbsent: () => AppInMemory(app, null, null, null));
|
ifAbsent: () => AppInMemory(app!, null, null, null));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
errors.add([app.id, app.finalName, e.toString()]);
|
errors.add([app.id, app.finalName, e.toString()]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}));
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
if (errors.isNotEmpty) {
|
if (errors.isNotEmpty) {
|
||||||
removeApps(errors.map((e) => e[0]).toList());
|
removeApps(errors.map((e) => e[0]).toList());
|
||||||
@@ -1204,19 +1218,17 @@ class AppsProvider with ChangeNotifier {
|
|||||||
AppsRemovedNotification(errors.map((e) => [e[1], e[2]]).toList()));
|
AppsRemovedNotification(errors.map((e) => [e[1], e[2]]).toList()));
|
||||||
}
|
}
|
||||||
// Get install status and other OS info for each App (slow)
|
// Get install status and other OS info for each App (slow)
|
||||||
await Future.wait(apps.values.map((app) {
|
|
||||||
return updateInstallStatusInMemory(app);
|
|
||||||
}));
|
|
||||||
notifyListeners();
|
|
||||||
// Reconcile version differences
|
|
||||||
List<App> modifiedApps = [];
|
List<App> modifiedApps = [];
|
||||||
for (var app in apps.values) {
|
await Future.wait(apps.values.map((app) async {
|
||||||
|
await updateInstallStatusInMemory(app);
|
||||||
var moddedApp =
|
var moddedApp =
|
||||||
getCorrectedInstallStatusAppIfPossible(app.app, app.installedInfo);
|
getCorrectedInstallStatusAppIfPossible(app.app, app.installedInfo);
|
||||||
if (moddedApp != null) {
|
if (moddedApp != null) {
|
||||||
modifiedApps.add(moddedApp);
|
modifiedApps.add(moddedApp);
|
||||||
}
|
}
|
||||||
}
|
}));
|
||||||
|
notifyListeners();
|
||||||
|
// Reconcile version differences
|
||||||
if (modifiedApps.isNotEmpty) {
|
if (modifiedApps.isNotEmpty) {
|
||||||
await saveApps(modifiedApps, attemptToCorrectInstallStatus: false);
|
await saveApps(modifiedApps, attemptToCorrectInstallStatus: false);
|
||||||
var removedAppIds = modifiedApps
|
var removedAppIds = modifiedApps
|
||||||
@@ -1238,7 +1250,7 @@ class AppsProvider with ChangeNotifier {
|
|||||||
{bool attemptToCorrectInstallStatus = true,
|
{bool attemptToCorrectInstallStatus = true,
|
||||||
bool onlyIfExists = true}) async {
|
bool onlyIfExists = true}) async {
|
||||||
attemptToCorrectInstallStatus = attemptToCorrectInstallStatus;
|
attemptToCorrectInstallStatus = attemptToCorrectInstallStatus;
|
||||||
for (var a in apps) {
|
await Future.wait(apps.map((a) async {
|
||||||
var app = a.deepCopy();
|
var app = a.deepCopy();
|
||||||
PackageInfo? info = await getInstalledInfo(app.id);
|
PackageInfo? info = await getInstalledInfo(app.id);
|
||||||
var icon = await info?.applicationInfo?.getAppIcon();
|
var icon = await info?.applicationInfo?.getAppIcon();
|
||||||
@@ -1260,14 +1272,14 @@ class AppsProvider with ChangeNotifier {
|
|||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}));
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
export(isAuto: true);
|
export(isAuto: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> removeApps(List<String> appIds) async {
|
Future<void> removeApps(List<String> appIds) async {
|
||||||
var apkFiles = APKDir.listSync();
|
var apkFiles = APKDir.listSync();
|
||||||
for (var appId in appIds) {
|
await Future.wait(appIds.map((appId) async {
|
||||||
File file = File('${(await getAppsDir()).path}/$appId.json');
|
File file = File('${(await getAppsDir()).path}/$appId.json');
|
||||||
if (file.existsSync()) {
|
if (file.existsSync()) {
|
||||||
file.deleteSync(recursive: true);
|
file.deleteSync(recursive: true);
|
||||||
@@ -1281,7 +1293,7 @@ class AppsProvider with ChangeNotifier {
|
|||||||
if (apps.containsKey(appId)) {
|
if (apps.containsKey(appId)) {
|
||||||
apps.remove(appId);
|
apps.remove(appId);
|
||||||
}
|
}
|
||||||
}
|
}));
|
||||||
if (appIds.isNotEmpty) {
|
if (appIds.isNotEmpty) {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
export(isAuto: true);
|
export(isAuto: true);
|
||||||
@@ -1516,7 +1528,7 @@ class AppsProvider with ChangeNotifier {
|
|||||||
return returnPath;
|
return returnPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<MapEntry<int, bool>> import(String appsJSON) async {
|
Future<MapEntry<List<App>, bool>> import(String appsJSON) async {
|
||||||
var decodedJSON = jsonDecode(appsJSON);
|
var decodedJSON = jsonDecode(appsJSON);
|
||||||
var newFormat = decodedJSON is! List;
|
var newFormat = decodedJSON is! List;
|
||||||
List<App> importedApps =
|
List<App> importedApps =
|
||||||
@@ -1540,6 +1552,8 @@ class AppsProvider with ChangeNotifier {
|
|||||||
settingsMap.forEach((key, value) {
|
settingsMap.forEach((key, value) {
|
||||||
if (value is int) {
|
if (value is int) {
|
||||||
settingsProvider.prefs?.setInt(key, value);
|
settingsProvider.prefs?.setInt(key, value);
|
||||||
|
} else if (value is double) {
|
||||||
|
settingsProvider.prefs?.setDouble(key, value);
|
||||||
} else if (value is bool) {
|
} else if (value is bool) {
|
||||||
settingsProvider.prefs?.setBool(key, value);
|
settingsProvider.prefs?.setBool(key, value);
|
||||||
} else if (value is List) {
|
} else if (value is List) {
|
||||||
@@ -1550,8 +1564,8 @@ class AppsProvider with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return MapEntry<int, bool>(
|
return MapEntry<List<App>, bool>(
|
||||||
importedApps.length, newFormat && decodedJSON['settings'] != null);
|
importedApps, newFormat && decodedJSON['settings'] != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -1927,7 +1941,8 @@ Future<void> bgUpdateCheck(String taskId, Map<String, dynamic>? params) async {
|
|||||||
await appsProvider.downloadAndInstallLatestApps(
|
await appsProvider.downloadAndInstallLatestApps(
|
||||||
toInstall.map((e) => e.key).toList(), null,
|
toInstall.map((e) => e.key).toList(), null,
|
||||||
notificationsProvider: notificationsProvider,
|
notificationsProvider: notificationsProvider,
|
||||||
forceParallelDownloads: true);
|
forceParallelDownloads: true,
|
||||||
|
useExisting: false);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e is MultiAppMultiError) {
|
if (e is MultiAppMultiError) {
|
||||||
e.idsByErrorString.forEach((key, value) {
|
e.idsByErrorString.forEach((key, value) {
|
||||||
|
86
pubspec.lock
86
pubspec.lock
@@ -47,10 +47,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: app_links
|
name: app_links
|
||||||
sha256: "1c2b9e9c56d80d17610bcbd111b37187875c5d0ded8654caa1bda14ea753d001"
|
sha256: "8c6ef5ba9e26b720d4c9073826befb87df2ab5e7a81c22b6c3145080b5e736c9"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.1"
|
version: "6.0.2"
|
||||||
archive:
|
archive:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -215,10 +215,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: easy_localization
|
name: easy_localization
|
||||||
sha256: "432698c31a488dd64c56d4759f20d04844baba5e9e4f2cb1abb9676257918b17"
|
sha256: fa59bcdbbb911a764aa6acf96bbb6fa7a5cf8234354fc45ec1a43a0349ef0201
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.6"
|
version: "3.0.7"
|
||||||
easy_logger:
|
easy_logger:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -279,18 +279,18 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flex_color_picker
|
name: flex_color_picker
|
||||||
sha256: "5c846437069fb7afdd7ade6bf37e628a71d2ab0787095ddcb1253bf9345d5f3a"
|
sha256: "31b27677d8d8400e4cff5edb3f189f606dd964d608779b6ae1b7ddad37ea48c6"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.4.1"
|
version: "3.5.0"
|
||||||
flex_seed_scheme:
|
flex_seed_scheme:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: flex_seed_scheme
|
name: flex_seed_scheme
|
||||||
sha256: "4cee2f1d07259f77e8b36f4ec5f35499d19e74e17c7dce5b819554914082bc01"
|
sha256: fb66cdb8ca89084e79efcad2bc2d9deb144666875116f08cdd8d9f8238c8b3ab
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.5.0"
|
version: "2.0.0"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
@@ -324,18 +324,18 @@ packages:
|
|||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: flutter_lints
|
name: flutter_lints
|
||||||
sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1"
|
sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.2"
|
version: "4.0.0"
|
||||||
flutter_local_notifications:
|
flutter_local_notifications:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_local_notifications
|
name: flutter_local_notifications
|
||||||
sha256: "84a3af6c7fb43c85c3528b434dacc7a7ed4551d1209d93773bf6045cec9ace68"
|
sha256: "40e6fbd2da7dcc7ed78432c5cdab1559674b4af035fddbfb2f9a8f9c2112fcef"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "17.1.1"
|
version: "17.1.2"
|
||||||
flutter_local_notifications_linux:
|
flutter_local_notifications_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -451,10 +451,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: intl
|
name: intl
|
||||||
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
|
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.18.1"
|
version: "0.19.0"
|
||||||
json_annotation:
|
json_annotation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -467,36 +467,36 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker
|
name: leak_tracker
|
||||||
sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
|
sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.0.0"
|
version: "10.0.4"
|
||||||
leak_tracker_flutter_testing:
|
leak_tracker_flutter_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker_flutter_testing
|
name: leak_tracker_flutter_testing
|
||||||
sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
|
sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "3.0.3"
|
||||||
leak_tracker_testing:
|
leak_tracker_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker_testing
|
name: leak_tracker_testing
|
||||||
sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
|
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "3.0.1"
|
||||||
lints:
|
lints:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: lints
|
name: lints
|
||||||
sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290
|
sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.0"
|
version: "4.0.0"
|
||||||
markdown:
|
markdown:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: markdown
|
name: markdown
|
||||||
sha256: ef2a1298144e3f985cc736b22e0ccdaf188b5b3970648f2d9dc13efd1d9df051
|
sha256: ef2a1298144e3f985cc736b22e0ccdaf188b5b3970648f2d9dc13efd1d9df051
|
||||||
@@ -523,10 +523,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
|
sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.11.0"
|
version: "1.12.0"
|
||||||
mime:
|
mime:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -579,10 +579,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_foundation
|
name: path_provider_foundation
|
||||||
sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f"
|
sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.2"
|
version: "2.4.0"
|
||||||
path_provider_linux:
|
path_provider_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -723,10 +723,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_foundation
|
name: shared_preferences_foundation
|
||||||
sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c"
|
sha256: "0a8a893bf4fd1152f93fec03a415d11c27c74454d96e2318a7ac38dd18683ab7"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.5"
|
version: "2.4.0"
|
||||||
shared_preferences_linux:
|
shared_preferences_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -857,10 +857,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
|
sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.1"
|
version: "0.7.0"
|
||||||
timezone:
|
timezone:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -897,10 +897,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_ios
|
name: url_launcher_ios
|
||||||
sha256: "9149d493b075ed740901f3ee844a38a00b33116c7c5c10d7fb27df8987fb51d5"
|
sha256: "7068716403343f6ba4969b4173cbf3b84fc768042124bc2c011e5d782b24fe89"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.2.5"
|
version: "6.3.0"
|
||||||
url_launcher_linux:
|
url_launcher_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -913,10 +913,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_macos
|
name: url_launcher_macos
|
||||||
sha256: b7244901ea3cf489c5335bdacda07264a6e960b1c1b1a9f91e4bc371d9e68234
|
sha256: "9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.0"
|
version: "3.2.0"
|
||||||
url_launcher_platform_interface:
|
url_launcher_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -961,10 +961,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vm_service
|
name: vm_service
|
||||||
sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
|
sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "13.0.0"
|
version: "14.2.1"
|
||||||
web:
|
web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1001,18 +1001,18 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: webview_flutter_wkwebview
|
name: webview_flutter_wkwebview
|
||||||
sha256: f12f8d8a99784b863e8b85e4a9a5e3cf1839d6803d2c0c3e0533a8f3c5a992a7
|
sha256: "7affdf9d680c015b11587181171d3cad8093e449db1f7d9f0f08f4f33d24f9a0"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.13.0"
|
version: "3.13.1"
|
||||||
win32:
|
win32:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: win32
|
name: win32
|
||||||
sha256: "0eaf06e3446824099858367950a813472af675116bf63f008a4c2a75ae13e9cb"
|
sha256: a79dbe579cb51ecd6d30b17e0cae4e0ea15e2c0e66f69ad4198f22a6789e94f4
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.5.0"
|
version: "5.5.1"
|
||||||
win32_registry:
|
win32_registry:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1046,5 +1046,5 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.2"
|
version: "3.1.2"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.3.3 <4.0.0"
|
dart: ">=3.4.0 <4.0.0"
|
||||||
flutter: ">=3.19.0"
|
flutter: ">=3.22.0"
|
||||||
|
@@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 1.1.7+2264
|
version: 1.1.9+2266
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=3.0.0 <4.0.0'
|
sdk: '>=3.0.0 <4.0.0'
|
||||||
@@ -79,6 +79,7 @@ dependencies:
|
|||||||
url: https://github.com/re7gog/shizuku_apk_installer
|
url: https://github.com/re7gog/shizuku_apk_installer
|
||||||
ref: master
|
ref: master
|
||||||
|
|
||||||
|
markdown: any
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
@@ -89,7 +90,7 @@ dev_dependencies:
|
|||||||
# activated in the `analysis_options.yaml` file located at the root of your
|
# activated in the `analysis_options.yaml` file located at the root of your
|
||||||
# package. See that file for information about deactivating specific lint
|
# package. See that file for information about deactivating specific lint
|
||||||
# rules and activating additional ones.
|
# rules and activating additional ones.
|
||||||
flutter_lints: ^3.0.0
|
flutter_lints: ^4.0.0
|
||||||
|
|
||||||
flutter_launcher_icons:
|
flutter_launcher_icons:
|
||||||
android: "ic_launcher"
|
android: "ic_launcher"
|
||||||
|
Reference in New Issue
Block a user