mirror of
				https://github.com/ImranR98/Obtainium.git
				synced 2025-10-25 03:43:46 +02:00 
			
		
		
		
	Merge branch 'ImranR98:main' into main
This commit is contained in:
		| @@ -22,11 +22,11 @@ | ||||
|     "requiredInBrackets": "(必填)", | ||||
|     "dropdownNoOptsError": "错误:下拉菜单必须包含至少一个选项", | ||||
|     "colour": "配色", | ||||
|     "githubStarredRepos": "GitHub 已星标仓库", | ||||
|     "githubStarredRepos": "已星标的 GitHub 仓库", | ||||
|     "uname": "用户名", | ||||
|     "wrongArgNum": "参数数量错误", | ||||
|     "xIsTrackOnly": "{}为“仅追踪”模式", | ||||
|     "source": "源代码", | ||||
|     "xIsTrackOnly": "“{}”为“仅追踪”模式", | ||||
|     "source": "来源", | ||||
|     "app": "应用", | ||||
|     "appsFromSourceAreTrackOnly": "此来源的应用为“仅追踪”模式。", | ||||
|     "youPickedTrackOnly": "您选择了“仅追踪”。", | ||||
| @@ -56,12 +56,12 @@ | ||||
|     "estimateInBrackets": "(推测)", | ||||
|     "selectAll": "全选", | ||||
|     "deselectX": "取消选择 {}", | ||||
|     "xWillBeRemovedButRemainInstalled": "{} 将从 Obtainium 中删除,但仍安装在您的设备中。", | ||||
|     "xWillBeRemovedButRemainInstalled": "“{}”将从 Obtainium 中删除,但仍安装在您的设备中。", | ||||
|     "removeSelectedAppsQuestion": "是否删除选中的应用?", | ||||
|     "removeSelectedApps": "删除选中的应用", | ||||
|     "updateX": "更新 {}", | ||||
|     "installX": "安装 {}", | ||||
|     "markXTrackOnlyAsUpdated": "将 {}\n(仅追踪)\n标记为已更新", | ||||
|     "markXTrackOnlyAsUpdated": "将“{}”\n(仅追踪)\n标记为已更新", | ||||
|     "changeX": "更改 {}", | ||||
|     "installUpdateApps": "安装/更新应用", | ||||
|     "installUpdateSelectedApps": "安装/更新选中的应用", | ||||
| @@ -88,17 +88,17 @@ | ||||
|     "importExport": "导入/导出", | ||||
|     "settings": "设置", | ||||
|     "exportedTo": "已导出至 {}", | ||||
|     "obtainiumExport": "Obtainium 导出", | ||||
|     "obtainiumExport": "导出 Obtainium", | ||||
|     "invalidInput": "无效的输入", | ||||
|     "importedX": "已导入 {}", | ||||
|     "obtainiumImport": "Obtainium 导入", | ||||
|     "obtainiumImport": "导入 Obtainium", | ||||
|     "importFromURLList": "从 URL 列表导入", | ||||
|     "searchQuery": "搜索查询", | ||||
|     "appURLList": "应用 URL 列表", | ||||
|     "line": "行", | ||||
|     "searchX": "搜索 {}", | ||||
|     "searchX": "搜索{}", | ||||
|     "noResults": "无结果", | ||||
|     "importX": "导入 {}", | ||||
|     "importX": "导入{}", | ||||
|     "importedAppsIdDisclaimer": "导入的应用可能会错误地显示为“未安装”状态。\n请通过 Obtainium 重新安装这些应用来解决此问题。", | ||||
|     "importErrors": "导入错误", | ||||
|     "importedXOfYApps": "已导入 {} 中的 {} 个应用。", | ||||
| @@ -123,7 +123,7 @@ | ||||
|     "bgUpdateCheckInterval": "后台更新检查间隔", | ||||
|     "neverManualOnly": "手动", | ||||
|     "appearance": "外观", | ||||
|     "showWebInAppView": "在应用详情页显示来源网页", | ||||
|     "showWebInAppView": "应用详情页显示来源网页", | ||||
|     "pinUpdates": "将待更新应用置顶", | ||||
|     "updates": "更新", | ||||
|     "sourceSpecific": "来源", | ||||
| @@ -135,7 +135,7 @@ | ||||
|     "appNotFound": "未找到应用", | ||||
|     "obtainiumExportHyphenatedLowercase": "obtainium-export", | ||||
|     "pickAnAPK": "选择一个 APK 文件", | ||||
|     "appHasMoreThanOnePackage": "{} 有多个架构可用:", | ||||
|     "appHasMoreThanOnePackage": "“{}”有多个架构可用:", | ||||
|     "deviceSupportsXArch": "您的设备支持 {} 架构。", | ||||
|     "deviceSupportsFollowingArchs": "您的设备支持下列架构:", | ||||
|     "warning": "警告", | ||||
| @@ -143,15 +143,15 @@ | ||||
|     "updatesAvailable": "更新可用", | ||||
|     "updatesAvailableNotifDescription": "Obtainium 追踪的应用有更新时发送通知", | ||||
|     "noNewUpdates": "全部应用已是最新。", | ||||
|     "xHasAnUpdate": "{} 可以更新了。", | ||||
|     "xHasAnUpdate": "“{}”可以更新了。", | ||||
|     "appsUpdated": "应用已更新", | ||||
|     "appsUpdatedNotifDescription": "当应用在后台安装更新时发送通知", | ||||
|     "xWasUpdatedToY": "{} 已更新至 {}。", | ||||
|     "xWasUpdatedToY": "“{}”已更新至 {}。", | ||||
|     "errorCheckingUpdates": "检查更新出错", | ||||
|     "errorCheckingUpdatesNotifDescription": "当后台检查更新失败时显示的通知", | ||||
|     "appsRemoved": "应用已删除", | ||||
|     "appsRemovedNotifDescription": "当应用因加载出错而被删除时发送通知", | ||||
|     "xWasRemovedDueToErrorY": "{} 由于以下错误被删除:{}", | ||||
|     "xWasRemovedDueToErrorY": "“{}”由于以下错误被删除:{}", | ||||
|     "completeAppInstallation": "完成应用安装", | ||||
|     "obtainiumMustBeOpenToInstallApps": "必须启动 Obtainium 才能安装应用", | ||||
|     "completeAppInstallationNotifDescription": "提示返回 Obtainium 以完成应用的安装", | ||||
| @@ -159,7 +159,7 @@ | ||||
|     "checkingForUpdatesNotifDescription": "检查更新时短暂显示的通知", | ||||
|     "pleaseAllowInstallPerm": "请授予 Obtainium 安装应用的权限", | ||||
|     "trackOnly": "仅追踪", | ||||
|     "errorWithHttpStatusCode": "错误 {}", | ||||
|     "errorWithHttpStatusCode": "{} 错误", | ||||
|     "versionCorrectionDisabled": "禁用版本号更正(插件似乎未起作用)", | ||||
|     "unknown": "未知", | ||||
|     "none": "无", | ||||
| @@ -185,11 +185,11 @@ | ||||
|     "additionalOptions": "附加选项", | ||||
|     "disableVersionDetection": "禁用版本检测", | ||||
|     "noVersionDetectionExplanation": "此选项应该仅用于无法进行版本检测的应用。", | ||||
|     "downloadingX": "正在下载{}", | ||||
|     "downloadingX": "正在下载“{}”", | ||||
|     "downloadNotifDescription": "提示应用的下载进度", | ||||
|     "noAPKFound": "未找到 APK 文件", | ||||
|     "noVersionDetection": "禁用版本检测", | ||||
|     "categorize": "分类", | ||||
|     "categorize": "归类", | ||||
|     "categories": "类别", | ||||
|     "category": "类别", | ||||
|     "noCategory": "无类别", | ||||
| @@ -217,17 +217,17 @@ | ||||
|     "autoApkFilterByArch": "如果可能,尝试按设备支持的 CPU 架构筛选 APK 文件", | ||||
|     "overrideSource": "覆盖来源", | ||||
|     "dontShowAgain": "不再显示", | ||||
|     "dontShowTrackOnlyWarnings": "不显示“仅追踪”模式警告", | ||||
|     "dontShowAPKOriginWarnings": "不显示 APK 文件来源警告", | ||||
|     "dontShowTrackOnlyWarnings": "忽略“仅追踪”模式警告", | ||||
|     "dontShowAPKOriginWarnings": "忽略 APK 文件来源警告", | ||||
|     "moveNonInstalledAppsToBottom": "将未安装应用置底", | ||||
|     "gitlabPATLabel": "GitLab 个人访问令牌(启用搜索功能并增强 APK 发现)", | ||||
|     "about": "相关文档", | ||||
|     "requiresCredentialsInSettings": "{}:此功能需要额外的凭据(在“设置”中添加)", | ||||
|     "checkOnStart": "启动时进行一次检查", | ||||
|     "tryInferAppIdFromCode": "尝试从源代码推断应用 ID", | ||||
|     "removeOnExternalUninstall": "自动删除已卸载的外部应用", | ||||
|     "removeOnExternalUninstall": "自动删除列表中已卸载的应用", | ||||
|     "pickHighestVersionCode": "自动选择版本号最高的 APK 文件", | ||||
|     "checkUpdateOnDetailPage": "打开应用详情页时检查更新", | ||||
|     "checkUpdateOnDetailPage": "打开应用详情页时进行检查", | ||||
|     "disablePageTransitions": "禁用页面过渡动画效果", | ||||
|     "reversePageTransitions": "反转页面过渡动画效果", | ||||
|     "minStarCount": "最小星标数", | ||||
| @@ -275,18 +275,20 @@ | ||||
|     "appsPossiblyUpdatedNotifChannel": "已尝试更新应用", | ||||
|     "errorCheckingUpdatesNotifChannel": "检查更新出错", | ||||
|     "appsRemovedNotifChannel": "应用已删除", | ||||
|     "downloadingXNotifChannel": "正在下载{}", | ||||
|     "downloadingXNotifChannel": "正在下载“{}”", | ||||
|     "completeAppInstallationNotifChannel": "完成应用安装", | ||||
|     "checkingForUpdatesNotifChannel": "正在检查更新", | ||||
|     "onlyCheckInstalledOrTrackOnlyApps": "只对已安装和“仅追踪”的应用进行更新检查", | ||||
|     "onlyCheckInstalledOrTrackOnlyApps": "只检查已安装和“仅追踪”的应用", | ||||
|     "supportFixedAPKURL": "支持固定的 APK 文件链接", | ||||
|     "selectX": "选择 {}", | ||||
|     "selectX": "选择{}", | ||||
|     "parallelDownloads": "启用并行下载", | ||||
|     "installMethod": "安装方式", | ||||
|     "normal": "常规", | ||||
|     "shizuku": "Shizuku", | ||||
|     "root": "Root", | ||||
|     "shizukuBinderNotFound": "Shizuku 服务未运行", | ||||
|     "shizukuBinderNotFound": "未发现兼容的 Shizuku 服务", | ||||
|     "useSystemFont": "使用系统字体", | ||||
|     "systemFontError": "加载系统字体出错:{}", | ||||
|     "removeAppQuestion": { | ||||
|         "one": "是否删除应用?", | ||||
|         "other": "是否删除应用?" | ||||
| @@ -328,15 +330,15 @@ | ||||
|         "other": "清除了 {n} 个日志({before} 之前,{after} 之后)" | ||||
|     }, | ||||
|     "xAndNMoreUpdatesAvailable": { | ||||
|         "one": "{} 和另外 1 个应用可以更新了。", | ||||
|         "other": "{} 和另外 {} 个应用可以更新了。" | ||||
|         "one": "“{}”和另外 1 个应用可以更新了。", | ||||
|         "other": "“{}”和另外 {} 个应用可以更新了。" | ||||
|     }, | ||||
|     "xAndNMoreUpdatesInstalled": { | ||||
|         "one": "{} 和另外 1 个应用已更新。", | ||||
|         "other": "{} 和另外 {} 个应用已更新。" | ||||
|         "other": "“{}”和另外 {} 个应用已更新。" | ||||
|     }, | ||||
|     "xAndNMoreUpdatesPossiblyInstalled": { | ||||
|         "one": "{} 和另外 1 个应用已尝试更新。", | ||||
|         "other": "{} 和另外 {} 个应用已尝试更新。" | ||||
|         "other": "“{}”和另外 {} 个应用已尝试更新。" | ||||
|     } | ||||
| } | ||||
| @@ -85,17 +85,30 @@ class FDroid extends AppSource { | ||||
|       try { | ||||
|         var res = await sourceRequest( | ||||
|             'https://gitlab.com/fdroid/fdroiddata/-/raw/master/metadata/$appId.yml'); | ||||
|         String author = res.body | ||||
|             .split('\n') | ||||
|         var lines = res.body.split('\n'); | ||||
|         String author = lines | ||||
|             .where((l) => l.startsWith('AuthorName: ')) | ||||
|             .first | ||||
|             .split(': ') | ||||
|             .sublist(1) | ||||
|             .join(': '); | ||||
|         details.names.author = author; | ||||
|         var changelogUrls = lines.where((l) => l.startsWith('Changelog: ')); | ||||
|         if (changelogUrls.isNotEmpty) { | ||||
|           details.changeLog = changelogUrls.first; | ||||
|           details.changeLog = (await sourceRequest(details.changeLog! | ||||
|                   .split(': ') | ||||
|                   .sublist(1) | ||||
|                   .join(': ') | ||||
|                   .replaceFirst('/blob/', '/raw/'))) | ||||
|               .body; | ||||
|         } | ||||
|       } catch (e) { | ||||
|         // Fail silently | ||||
|       } | ||||
|       if ((details.changeLog?.length ?? 0) > 1000) { | ||||
|         details.changeLog = '${details.changeLog!.substring(0, 2048)}...'; | ||||
|       } | ||||
|     } | ||||
|     return details; | ||||
|   } | ||||
|   | ||||
| @@ -17,13 +17,17 @@ String ensureAbsoluteUrl(String ambiguousUrl, Uri referenceAbsoluteUrl) { | ||||
|       .split('/') | ||||
|       .where((element) => element.trim().isNotEmpty) | ||||
|       .toList(); | ||||
|   String absoluteUrl; | ||||
|   if (ambiguousUrl.startsWith('/') || currPathSegments.isEmpty) { | ||||
|     return '${referenceAbsoluteUrl.origin}/$ambiguousUrl'; | ||||
|     absoluteUrl = '${referenceAbsoluteUrl.origin}/$ambiguousUrl'; | ||||
|   } else if (ambiguousUrl.split('/').where((e) => e.isNotEmpty).length == 1) { | ||||
|     return '${referenceAbsoluteUrl.origin}/${currPathSegments.join('/')}/$ambiguousUrl'; | ||||
|     absoluteUrl = | ||||
|         '${referenceAbsoluteUrl.origin}/${currPathSegments.join('/')}/$ambiguousUrl'; | ||||
|   } else { | ||||
|     return '${referenceAbsoluteUrl.origin}/${currPathSegments.sublist(0, currPathSegments.length - (currPathSegments.last.contains('.') ? 1 : 0)).join('/')}/$ambiguousUrl'; | ||||
|     absoluteUrl = | ||||
|         '${referenceAbsoluteUrl.origin}/${currPathSegments.sublist(0, currPathSegments.length - (currPathSegments.last.contains('.') ? 1 : 0)).join('/')}/$ambiguousUrl'; | ||||
|   } | ||||
|   return Uri.parse(absoluteUrl).toString(); | ||||
| } | ||||
|  | ||||
| int compareAlphaNumeric(String a, String b) { | ||||
| @@ -172,6 +176,8 @@ class HTML extends AppSource { | ||||
|                 ? element.text | ||||
|                 : (element.attributes['href'] ?? '').split('/').last)) | ||||
|         .where((element) => element.key.isNotEmpty) | ||||
|         .map((e) => | ||||
|             MapEntry(ensureAbsoluteUrl(e.key, res.request!.url), e.value)) | ||||
|         .toList(); | ||||
|     if (allLinks.isEmpty) { | ||||
|       allLinks = RegExp( | ||||
| @@ -258,7 +264,6 @@ class HTML extends AppSource { | ||||
|         additionalSettings['versionExtractWholePage'] == true | ||||
|             ? res.body.split('\r\n').join('\n').split('\n').join('\\n') | ||||
|             : rel); | ||||
|     rel = ensureAbsoluteUrl(rel, uri); | ||||
|     version ??= (await checkDownloadHash(rel)).toString(); | ||||
|     return APKDetails(version, [rel].map((e) => MapEntry(e, e)).toList(), | ||||
|         AppNames(uri.host, tr('app'))); | ||||
|   | ||||
| @@ -19,7 +19,7 @@ import 'package:easy_localization/src/easy_localization_controller.dart'; | ||||
| // ignore: implementation_imports | ||||
| import 'package:easy_localization/src/localization.dart'; | ||||
|  | ||||
| const String currentVersion = '0.15.5'; | ||||
| const String currentVersion = '0.15.7'; | ||||
| const String currentReleaseTag = | ||||
|     'v$currentVersion-beta'; // KEEP THIS IN SYNC WITH GITHUB RELEASES | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
| # 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. | ||||
| version: 0.15.5+241 # When changing this, update the tag in main() accordingly | ||||
| version: 0.15.7+243 # When changing this, update the tag in main() accordingly | ||||
|  | ||||
| environment: | ||||
|   sdk: '>=3.0.0 <4.0.0' | ||||
|   | ||||
		Reference in New Issue
	
	Block a user