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