mirror of
https://github.com/ImranR98/Obtainium.git
synced 2025-07-13 05:16:43 +02:00
Compare commits
46 Commits
v0.13.19-b
...
v0.13.23-b
Author | SHA1 | Date | |
---|---|---|---|
2a5118a2cf | |||
347c56da55 | |||
8073723e1f | |||
c8e90a755d | |||
aeb0a5d8ea | |||
09fe7f3ecd | |||
a549411589 | |||
f426b5e118 | |||
12a8ef5e31 | |||
8210279a4c | |||
999d13b80d | |||
0573c0b270 | |||
5a36a7980c | |||
6bf9b5297f | |||
fdc6b0ff00 | |||
73c20a53d2 | |||
16ae8d8e4d | |||
3f8cfae64e | |||
6861a71efb | |||
2a603f410f | |||
6d22788f92 | |||
e36e6bbaca | |||
ac3a13ed73 | |||
202f7df5cb | |||
1b902b1a18 | |||
1765d399c8 | |||
5dd79707f1 | |||
14755134bf | |||
cccde7e135 | |||
3dafd643c0 | |||
76f8cd4102 | |||
a8bfb03f58 | |||
10ead4f3e0 | |||
af5a6857ba | |||
d9225fd639 | |||
995d44551c | |||
68c0224b98 | |||
7767468d5d | |||
f9f83d8243 | |||
cc4cec829f | |||
f665bf1eb2 | |||
bccd52054e | |||
3a4c782aab | |||
6e047e96fa | |||
42f8753166 | |||
b6a64129b3 |
@ -240,6 +240,12 @@
|
||||
"disablePageTransitions": "Ugasite animaciju prijelaza stranice",
|
||||
"reversePageTransitions": "Reverzne animacije prijelaza stranice",
|
||||
"minStarCount": "Minimum Star Count",
|
||||
"addInfoBelow": "Add this info below.",
|
||||
"addInfoInSettings": "Add this info in the Settings.",
|
||||
"githubSourceNote": "GitHub rate limiting can be avoided using an API key.",
|
||||
"gitlabSourceNote": "GitLab APK extraction may not work without an API key.",
|
||||
"sortByFileNamesNotLinks": "Sort by file names instead of full links",
|
||||
"filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression",
|
||||
"removeAppQuestion": {
|
||||
"one": "Želite li ukloniti aplikaciju?",
|
||||
"other": "Želite li ukloniti aplikacije?"
|
||||
|
@ -233,13 +233,19 @@
|
||||
"about": "Über",
|
||||
"requiresCredentialsInSettings": "Benötigt zusätzliche Anmeldedaten (in den Einstellungen)",
|
||||
"checkOnStart": "Überprüfe einmalig beim Start",
|
||||
"tryInferAppIdFromCode": "Try inferring App ID from source code",
|
||||
"removeOnExternalUninstall": "Automatically remove externally uninstalled Apps",
|
||||
"pickHighestVersionCode": "Auto-select highest version code APK",
|
||||
"checkUpdateOnDetailPage": "Check for updates on opening an App detail page",
|
||||
"disablePageTransitions": "Disable page transition animations",
|
||||
"reversePageTransitions": "Reverse page transition animations",
|
||||
"minStarCount": "Minimum Star Count",
|
||||
"tryInferAppIdFromCode": "Versuche, die App-ID aus dem Quellcode zu ermitteln",
|
||||
"removeOnExternalUninstall": "Automatisches Entfernen von extern deinstallierten Apps",
|
||||
"pickHighestVersionCode": "Automatische Auswahl des APK mit höchstem Versionscode",
|
||||
"checkUpdateOnDetailPage": "Nach Updates suchen, wenn eine App-Detailseite geöffnet wird",
|
||||
"disablePageTransitions": "Animationen für Seitenübergänge deaktivieren",
|
||||
"reversePageTransitions": "Umgekehrte Animationen für Seitenübergänge",
|
||||
"minStarCount": "Minimale Anzahl von Sternen",
|
||||
"addInfoBelow": "Fügen Sie diese Informationen unten hinzu.",
|
||||
"addInfoInSettings": "Fügen Sie diese Info in den Einstellungen hinzu.",
|
||||
"githubSourceNote": "Die GitHub-Ratenbegrenzung kann mit einem API-Schlüssel umgangen werden.",
|
||||
"gitlabSourceNote": "GitLab APK-Extraktion funktioniert möglicherweise nicht ohne API-Schlüssel",
|
||||
"sortByFileNamesNotLinks": "Sort by file names instead of full links",
|
||||
"filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression",
|
||||
"removeAppQuestion": {
|
||||
"one": "App entfernen?",
|
||||
"other": "Apps entfernen?"
|
||||
|
@ -240,6 +240,12 @@
|
||||
"disablePageTransitions": "Disable page transition animations",
|
||||
"reversePageTransitions": "Reverse page transition animations",
|
||||
"minStarCount": "Minimum Star Count",
|
||||
"addInfoBelow": "Add this info below.",
|
||||
"addInfoInSettings": "Add this info in the Settings.",
|
||||
"githubSourceNote": "GitHub rate limiting can be avoided using an API key.",
|
||||
"gitlabSourceNote": "GitLab APK extraction may not work without an API key.",
|
||||
"sortByFileNamesNotLinks": "Sort by file names instead of full links",
|
||||
"filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression",
|
||||
"removeAppQuestion": {
|
||||
"one": "Remove App?",
|
||||
"other": "Remove Apps?"
|
||||
|
@ -240,6 +240,12 @@
|
||||
"disablePageTransitions": "Disable page transition animations",
|
||||
"reversePageTransitions": "Reverse page transition animations",
|
||||
"minStarCount": "Minimum Star Count",
|
||||
"addInfoBelow": "Add this info below.",
|
||||
"addInfoInSettings": "Add this info in the Settings.",
|
||||
"githubSourceNote": "GitHub rate limiting can be avoided using an API key.",
|
||||
"gitlabSourceNote": "GitLab APK extraction may not work without an API key.",
|
||||
"sortByFileNamesNotLinks": "Sort by file names instead of full links",
|
||||
"filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression",
|
||||
"removeAppQuestion": {
|
||||
"one": "¿Eliminar Aplicación?",
|
||||
"other": "¿Eliminar Aplicaciones?"
|
||||
|
@ -240,6 +240,12 @@
|
||||
"disablePageTransitions": "Disable page transition animations",
|
||||
"reversePageTransitions": "Reverse page transition animations",
|
||||
"minStarCount": "Minimum Star Count",
|
||||
"addInfoBelow": "Add this info below.",
|
||||
"addInfoInSettings": "Add this info in the Settings.",
|
||||
"githubSourceNote": "GitHub rate limiting can be avoided using an API key.",
|
||||
"gitlabSourceNote": "GitLab APK extraction may not work without an API key.",
|
||||
"sortByFileNamesNotLinks": "Sort by file names instead of full links",
|
||||
"filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression",
|
||||
"removeAppQuestion": {
|
||||
"one": "برنامه حذف شود؟",
|
||||
"other": "برنامه ها حذف شوند؟"
|
||||
|
@ -45,7 +45,7 @@
|
||||
"addApp": "Ajouter une application",
|
||||
"appSourceURL": "URL de la source de l'application",
|
||||
"error": "Erreur",
|
||||
"add": "Ajoutée",
|
||||
"add": "Ajouter",
|
||||
"searchSomeSourcesLabel": "Rechercher (certaines sources uniquement)",
|
||||
"search": "Rechercher",
|
||||
"additionalOptsFor": "Options supplémentaires pour {}",
|
||||
@ -240,6 +240,12 @@
|
||||
"disablePageTransitions": "Disable page transition animations",
|
||||
"reversePageTransitions": "Reverse page transition animations",
|
||||
"minStarCount": "Minimum Star Count",
|
||||
"addInfoBelow": "Add this info below.",
|
||||
"addInfoInSettings": "Add this info in the Settings.",
|
||||
"githubSourceNote": "GitHub rate limiting can be avoided using an API key.",
|
||||
"gitlabSourceNote": "GitLab APK extraction may not work without an API key.",
|
||||
"sortByFileNamesNotLinks": "Sort by file names instead of full links",
|
||||
"filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression",
|
||||
"removeAppQuestion": {
|
||||
"one": "Supprimer l'application ?",
|
||||
"other": "Supprimer les applications ?"
|
||||
|
@ -17,7 +17,7 @@
|
||||
"bgUpdateTaskFinished": "A háttérfrissítés ellenőrzési feladat befejeződött",
|
||||
"firstRun": "Ez az Obtainium első futása",
|
||||
"settingUpdateCheckIntervalTo": "A frissítési intervallum beállítása erre: {}",
|
||||
"githubPATLabel": "GitHub személyes hozzáférési token (megnöveli a díjkorlátot)",
|
||||
"githubPATLabel": "GitHub Personal Access Token (megnöveli a díjkorlátot)",
|
||||
"githubPATHint": "A PAT-nak a következő formátumban kell lennie: felhasználónév:token",
|
||||
"githubPATFormat": "felhasználónév:token",
|
||||
"includePrereleases": "Tartalmazza az előzetes kiadásokat",
|
||||
@ -228,7 +228,7 @@
|
||||
"dontShowTrackOnlyWarnings": "Ne jelenítsen meg 'Csak nyomon követés' figyelmeztetést",
|
||||
"dontShowAPKOriginWarnings": "Ne jelenítsen meg az APK eredetére vonatkozó figyelmeztetéseket",
|
||||
"moveNonInstalledAppsToBottom": "Helyezze át a nem telepített appokat az App nézet aljára",
|
||||
"gitlabPATLabel": "GitLab Personal Access Token\n(Engedélyezi a Keresést and Better APK Discovery)",
|
||||
"gitlabPATLabel": "GitLab Personal Access Token\n(Engedélyezi a Keresést és jobb APK felfedezés)",
|
||||
"about": "Rólunk",
|
||||
"requiresCredentialsInSettings": "Ehhez további hitelesítő adatokra van szükség (a Beállításokban)",
|
||||
"checkOnStart": "Egyszer az indításkor",
|
||||
@ -236,9 +236,15 @@
|
||||
"removeOnExternalUninstall": "A külsőleg eltávolított appok auto. eltávolítása",
|
||||
"pickHighestVersionCode": "A legmagasabb verziószámú APK auto. kiválasztása",
|
||||
"checkUpdateOnDetailPage": "Frissítések keresése az app részleteit tartalmazó oldal megnyitásakor",
|
||||
"disablePageTransitions": "Disable page transition animations",
|
||||
"reversePageTransitions": "Reverse page transition animations",
|
||||
"minStarCount": "Minimum Star Count",
|
||||
"disablePageTransitions": "Lap áttűnési animációk tiltása",
|
||||
"reversePageTransitions": "Fordított lap áttűnési animációk",
|
||||
"minStarCount": "Minimális csillag szám",
|
||||
"addInfoBelow": "Adja hozzá ezt az infót alább.",
|
||||
"addInfoInSettings": "Adja hozzá ezt az infót a Beállításokban.",
|
||||
"githubSourceNote": "A GitHub értékelési korlátozása elkerülhető API-kulcs használatával.",
|
||||
"gitlabSourceNote": "Előfordulhat, hogy a GitLab APK kibontása nem működik API-kulcs nélkül.",
|
||||
"sortByFileNamesNotLinks": "Sort by file names instead of full links",
|
||||
"filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression",
|
||||
"removeAppQuestion": {
|
||||
"one": "Eltávolítja az alkalmazást?",
|
||||
"other": "Eltávolítja az alkalmazást?"
|
||||
|
@ -240,6 +240,12 @@
|
||||
"disablePageTransitions": "Disable page transition animations",
|
||||
"reversePageTransitions": "Reverse page transition animations",
|
||||
"minStarCount": "Minimum Star Count",
|
||||
"addInfoBelow": "Add this info below.",
|
||||
"addInfoInSettings": "Add this info in the Settings.",
|
||||
"githubSourceNote": "GitHub rate limiting can be avoided using an API key.",
|
||||
"gitlabSourceNote": "GitLab APK extraction may not work without an API key.",
|
||||
"sortByFileNamesNotLinks": "Sort by file names instead of full links",
|
||||
"filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression",
|
||||
"removeAppQuestion": {
|
||||
"one": "Rimuovere l'app?",
|
||||
"other": "Rimuovere le app?"
|
||||
|
@ -239,7 +239,13 @@
|
||||
"checkUpdateOnDetailPage": "アプリの詳細ページを開く際にアップデートを確認する",
|
||||
"disablePageTransitions": "ページ遷移アニメーションを無効化する",
|
||||
"reversePageTransitions": "ページ遷移アニメーションを反転する",
|
||||
"minStarCount": "Minimum Star Count",
|
||||
"minStarCount": "最小スター数",
|
||||
"addInfoBelow": "下部でこの情報を追加してください。",
|
||||
"addInfoInSettings": "設定でこの情報を追加してください。",
|
||||
"githubSourceNote": "GitHubのレート制限はAPIキーを使うことで回避できます。",
|
||||
"gitlabSourceNote": "GitLabのAPK抽出はAPIキーがないと動作しない場合があります。",
|
||||
"sortByFileNamesNotLinks": "Sort by file names instead of full links",
|
||||
"filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression",
|
||||
"removeAppQuestion": {
|
||||
"one": "アプリを削除しますか?",
|
||||
"other": "アプリを削除しますか?"
|
||||
|
@ -243,7 +243,13 @@
|
||||
"checkUpdateOnDetailPage": "Sprawdzaj aktualizacje podczas otwierania strony szczegółów aplikacji",
|
||||
"disablePageTransitions": "Wyłącz animacje przejścia między stronami",
|
||||
"reversePageTransitions": "Odwróć animacje przejścia pomiędzy stronami",
|
||||
"minStarCount": "Minimum Star Count",
|
||||
"minStarCount": "Minimalna ilość gwiazdek",
|
||||
"addInfoBelow": "Dodaj tę informację poniżej.",
|
||||
"addInfoInSettings": "Dodaj tę informację w Ustawieniach.",
|
||||
"githubSourceNote": "Limit żądań GitHub można ominąć za pomocą klucza API.",
|
||||
"gitlabSourceNote": "Pozyskiwanie pliku APK z GitLab może nie działać bez klucza API.",
|
||||
"sortByFileNamesNotLinks": "Sort by file names instead of full links",
|
||||
"filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression",
|
||||
"removeAppQuestion": {
|
||||
"one": "Usunąć aplikację?",
|
||||
"other": "Usunąć aplikacje?"
|
||||
|
@ -239,7 +239,13 @@
|
||||
"checkUpdateOnDetailPage": "Проверять наличие обновлений при открытии страницы представления приложения",
|
||||
"disablePageTransitions": "Отключить анимацию перехода между страницами",
|
||||
"reversePageTransitions": "Реверс анимации перехода между страницами",
|
||||
"minStarCount": "Minimum Star Count",
|
||||
"minStarCount": "Минимальное количество звёзд",
|
||||
"addInfoBelow": "Добавьте эту информацию ниже.",
|
||||
"addInfoInSettings": "Добавьте эту информацию в Настройки.",
|
||||
"githubSourceNote": "Лимит запросов GitHub можно обойти, используя ключ API.",
|
||||
"gitlabSourceNote": "Извлечение APK из GitLab может не работать без ключа API.",
|
||||
"sortByFileNamesNotLinks": "Sort by file names instead of full links",
|
||||
"filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression",
|
||||
"removeAppQuestion": {
|
||||
"one": "Удалить приложение?",
|
||||
"other": "Удалить приложения?"
|
||||
|
@ -107,7 +107,7 @@
|
||||
"searchX": "搜索 {}",
|
||||
"noResults": "无结果",
|
||||
"importX": "导入 {}",
|
||||
"importedAppsIdDisclaimer": "导入的应用可能错误地显示为“未安装”。\n请通过 Obtainium 重新安装这些应用来解决此问题。",
|
||||
"importedAppsIdDisclaimer": "导入的应用可能会错误地显示为“未安装”状态。\n请通过 Obtainium 重新安装这些应用来解决此问题。",
|
||||
"importErrors": "导入错误",
|
||||
"importedXOfYApps": "已导入 {} 中的 {} 个应用。",
|
||||
"followingURLsHadErrors": "下列 URL 存在错误:",
|
||||
@ -229,17 +229,23 @@
|
||||
"dontShowTrackOnlyWarnings": "不显示“仅追踪”模式警告",
|
||||
"dontShowAPKOriginWarnings": "不显示 APK 文件来源警告",
|
||||
"moveNonInstalledAppsToBottom": "将未安装应用置底",
|
||||
"gitlabPATLabel": "GitLab 个人访问令牌\n(用于搜索应用 and Better APK Discovery)",
|
||||
"gitlabPATLabel": "GitLab 个人访问令牌\n(启用搜索功能并增强 APK 发现)",
|
||||
"about": "相关文档",
|
||||
"requiresCredentialsInSettings": "此功能需要额外的凭据(在“设置”中添加)",
|
||||
"checkOnStart": "启动时进行一次检查",
|
||||
"tryInferAppIdFromCode": "尝试从源代码推断应用 ID",
|
||||
"removeOnExternalUninstall": "Automatically remove externally uninstalled Apps",
|
||||
"pickHighestVersionCode": "Auto-select highest version code APK",
|
||||
"checkUpdateOnDetailPage": "Check for updates on opening an App detail page",
|
||||
"disablePageTransitions": "Disable page transition animations",
|
||||
"reversePageTransitions": "Reverse page transition animations",
|
||||
"minStarCount": "Minimum Star Count",
|
||||
"removeOnExternalUninstall": "自动删除已卸载的外部应用",
|
||||
"pickHighestVersionCode": "自动选择版本号最高的 APK 文件",
|
||||
"checkUpdateOnDetailPage": "打开应用详情页时检查更新",
|
||||
"disablePageTransitions": "禁用页面过渡动画效果",
|
||||
"reversePageTransitions": "反转页面过渡动画效果",
|
||||
"minStarCount": "最小星标数",
|
||||
"addInfoBelow": "在下方添加此凭据。",
|
||||
"addInfoInSettings": "在“设置”中添加此凭据。",
|
||||
"githubSourceNote": "使用访问令牌可避免触发 GitHub 的 API 请求限制。",
|
||||
"gitlabSourceNote": "未使用访问令牌时可能无法从 GitLab 获取 APK 文件。",
|
||||
"sortByFileNamesNotLinks": "Sort by file names instead of full links",
|
||||
"filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression",
|
||||
"removeAppQuestion": {
|
||||
"one": "是否删除应用?",
|
||||
"other": "是否删除应用?"
|
||||
|
@ -1,6 +1,4 @@
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:obtainium/app_sources/github.dart';
|
||||
import 'package:obtainium/components/generated_form.dart';
|
||||
import 'package:obtainium/custom_errors.dart';
|
||||
import 'package:obtainium/providers/source_provider.dart';
|
||||
|
||||
@ -9,28 +7,8 @@ class Codeberg extends AppSource {
|
||||
Codeberg() {
|
||||
host = 'codeberg.org';
|
||||
|
||||
additionalSourceSpecificSettingFormItems = [];
|
||||
|
||||
additionalSourceAppSpecificSettingFormItems = [
|
||||
[
|
||||
GeneratedFormSwitch('includePrereleases',
|
||||
label: tr('includePrereleases'), defaultValue: false)
|
||||
],
|
||||
[
|
||||
GeneratedFormSwitch('fallbackToOlderReleases',
|
||||
label: tr('fallbackToOlderReleases'), defaultValue: true)
|
||||
],
|
||||
[
|
||||
GeneratedFormTextField('filterReleaseTitlesByRegEx',
|
||||
label: tr('filterReleaseTitlesByRegEx'),
|
||||
required: false,
|
||||
additionalValidators: [
|
||||
(value) {
|
||||
return regExValidator(value);
|
||||
}
|
||||
])
|
||||
]
|
||||
];
|
||||
additionalSourceAppSpecificSettingFormItems =
|
||||
gh.additionalSourceAppSpecificSettingFormItems;
|
||||
|
||||
canSearch = true;
|
||||
searchQuerySettingFormItems = gh.searchQuerySettingFormItems;
|
||||
|
@ -16,7 +16,7 @@ class GitHub extends AppSource {
|
||||
host = 'github.com';
|
||||
appIdInferIsOptional = true;
|
||||
|
||||
additionalSourceSpecificSettingFormItems = [
|
||||
sourceConfigSettingFormItems = [
|
||||
GeneratedFormTextField('github-creds',
|
||||
label: tr('githubPATLabel'),
|
||||
password: true,
|
||||
@ -75,6 +75,16 @@ class GitHub extends AppSource {
|
||||
return regExValidator(value);
|
||||
}
|
||||
])
|
||||
],
|
||||
[
|
||||
GeneratedFormTextField('filterReleaseNotesByRegEx',
|
||||
label: tr('filterReleaseNotesByRegEx'),
|
||||
required: false,
|
||||
additionalValidators: [
|
||||
(value) {
|
||||
return regExValidator(value);
|
||||
}
|
||||
])
|
||||
]
|
||||
];
|
||||
|
||||
@ -107,7 +117,7 @@ class GitHub extends AppSource {
|
||||
for (var path in possibleBuildGradleLocations) {
|
||||
try {
|
||||
var res = await sourceRequest(
|
||||
'${await convertStandardUrlToAPIUrl(standardUrl)}/contents/$path');
|
||||
'${await convertStandardUrlToAPIUrl(standardUrl, additionalSettings)}/contents/$path');
|
||||
if (res.statusCode == 200) {
|
||||
try {
|
||||
var body = jsonDecode(res.body);
|
||||
@ -155,19 +165,30 @@ class GitHub extends AppSource {
|
||||
return url.substring(0, match.end);
|
||||
}
|
||||
|
||||
Future<String> getCredentialPrefixIfAny() async {
|
||||
Future<String> getCredentialPrefixIfAny(
|
||||
Map<String, dynamic> additionalSettings) async {
|
||||
SettingsProvider settingsProvider = SettingsProvider();
|
||||
await settingsProvider.initializeSettings();
|
||||
String? creds = settingsProvider
|
||||
.getSettingString(additionalSourceSpecificSettingFormItems[0].key);
|
||||
var sourceConfig =
|
||||
await getSourceConfigValues(additionalSettings, settingsProvider);
|
||||
String? creds = sourceConfig['github-creds'];
|
||||
return creds != null && creds.isNotEmpty ? '$creds@' : '';
|
||||
}
|
||||
|
||||
Future<String> getAPIHost() async =>
|
||||
'https://${await getCredentialPrefixIfAny()}api.$host';
|
||||
@override
|
||||
Future<String?> getSourceNote() async {
|
||||
if (!hostChanged && (await getCredentialPrefixIfAny({})).isEmpty) {
|
||||
return '${tr('githubSourceNote')} ${hostChanged ? tr('addInfoBelow') : tr('addInfoInSettings')}';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<String> convertStandardUrlToAPIUrl(String standardUrl) async =>
|
||||
'${await getAPIHost()}/repos${standardUrl.substring('https://$host'.length)}';
|
||||
Future<String> getAPIHost(Map<String, dynamic> additionalSettings) async =>
|
||||
'https://${await getCredentialPrefixIfAny(additionalSettings)}api.$host';
|
||||
|
||||
Future<String> convertStandardUrlToAPIUrl(
|
||||
String standardUrl, Map<String, dynamic> additionalSettings) async =>
|
||||
'${await getAPIHost(additionalSettings)}/repos${standardUrl.substring('https://$host'.length)}';
|
||||
|
||||
@override
|
||||
String? changeLogPageFromStandardUrl(String standardUrl) =>
|
||||
@ -185,6 +206,12 @@ class GitHub extends AppSource {
|
||||
true
|
||||
? additionalSettings['filterReleaseTitlesByRegEx']
|
||||
: null;
|
||||
String? regexNotesFilter =
|
||||
(additionalSettings['filterReleaseNotesByRegEx'] as String?)
|
||||
?.isNotEmpty ==
|
||||
true
|
||||
? additionalSettings['filterReleaseNotesByRegEx']
|
||||
: null;
|
||||
Response res = await sourceRequest(requestUrl);
|
||||
if (res.statusCode == 200) {
|
||||
var releases = jsonDecode(res.body) as List<dynamic>;
|
||||
@ -253,6 +280,11 @@ class GitHub extends AppSource {
|
||||
!RegExp(regexFilter).hasMatch(nameToFilter.trim())) {
|
||||
continue;
|
||||
}
|
||||
if (regexNotesFilter != null &&
|
||||
!RegExp(regexNotesFilter)
|
||||
.hasMatch(((releases[i]['body'] as String?) ?? '').trim())) {
|
||||
continue;
|
||||
}
|
||||
var apkUrls = getReleaseAPKUrls(releases[i]);
|
||||
if (apkUrls.isEmpty && additionalSettings['trackOnly'] != true) {
|
||||
continue;
|
||||
@ -311,7 +343,7 @@ class GitHub extends AppSource {
|
||||
) async {
|
||||
return await getLatestAPKDetailsCommon2(standardUrl, additionalSettings,
|
||||
(bool useTagUrl) async {
|
||||
return '${await convertStandardUrlToAPIUrl(standardUrl)}/${useTagUrl ? 'tags' : 'releases'}?per_page=100';
|
||||
return '${await convertStandardUrlToAPIUrl(standardUrl, additionalSettings)}/${useTagUrl ? 'tags' : 'releases'}?per_page=100';
|
||||
}, (Response res) {
|
||||
rateLimitErrorCheck(res);
|
||||
});
|
||||
@ -360,7 +392,7 @@ class GitHub extends AppSource {
|
||||
{Map<String, dynamic> querySettings = const {}}) async {
|
||||
return searchCommon(
|
||||
query,
|
||||
'${await getAPIHost()}/search/repositories?q=${Uri.encodeQueryComponent(query)}&per_page=100',
|
||||
'${await getAPIHost({})}/search/repositories?q=${Uri.encodeQueryComponent(query)}&per_page=100',
|
||||
'items', onHttpErrorCode: (Response res) {
|
||||
rateLimitErrorCheck(res);
|
||||
}, querySettings: querySettings);
|
||||
|
@ -16,7 +16,7 @@ class GitLab extends AppSource {
|
||||
host = 'gitlab.com';
|
||||
canSearch = true;
|
||||
|
||||
additionalSourceSpecificSettingFormItems = [
|
||||
sourceConfigSettingFormItems = [
|
||||
GeneratedFormTextField('gitlab-creds',
|
||||
label: tr('gitlabPATLabel'),
|
||||
password: true,
|
||||
@ -60,18 +60,27 @@ class GitLab extends AppSource {
|
||||
return url.substring(0, match.end);
|
||||
}
|
||||
|
||||
Future<String?> getPATIfAny() async {
|
||||
Future<String?> getPATIfAny(Map<String, dynamic> additionalSettings) async {
|
||||
SettingsProvider settingsProvider = SettingsProvider();
|
||||
await settingsProvider.initializeSettings();
|
||||
String? creds = settingsProvider
|
||||
.getSettingString(additionalSourceSpecificSettingFormItems[0].key);
|
||||
var sourceConfig =
|
||||
await getSourceConfigValues(additionalSettings, settingsProvider);
|
||||
String? creds = sourceConfig['gitlab-creds'];
|
||||
return creds != null && creds.isNotEmpty ? creds : null;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String?> getSourceNote() async {
|
||||
if ((await getPATIfAny({})) == null) {
|
||||
return '${tr('gitlabSourceNote')} ${hostChanged ? tr('addInfoBelow') : tr('addInfoInSettings')}';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Map<String, List<String>>> search(String query,
|
||||
{Map<String, dynamic> querySettings = const {}}) async {
|
||||
String? PAT = await getPATIfAny();
|
||||
String? PAT = await getPATIfAny({});
|
||||
if (PAT == null) {
|
||||
throw CredsNeededError(name);
|
||||
}
|
||||
@ -103,7 +112,7 @@ class GitLab extends AppSource {
|
||||
) async {
|
||||
bool fallbackToOlderReleases =
|
||||
additionalSettings['fallbackToOlderReleases'] == true;
|
||||
String? PAT = await getPATIfAny();
|
||||
String? PAT = await getPATIfAny(hostChanged ? additionalSettings : {});
|
||||
Iterable<APKDetails> apkDetailsList = [];
|
||||
if (PAT != null) {
|
||||
var names = GitHub().getAppNames(standardUrl);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:html/parser.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:obtainium/components/generated_form.dart';
|
||||
import 'package:obtainium/custom_errors.dart';
|
||||
import 'package:obtainium/providers/source_provider.dart';
|
||||
|
||||
@ -85,6 +86,15 @@ bool _isNumeric(String s) {
|
||||
}
|
||||
|
||||
class HTML extends AppSource {
|
||||
HTML() {
|
||||
additionalSourceAppSpecificSettingFormItems = [
|
||||
[
|
||||
GeneratedFormSwitch('sortByFileNamesNotLinks',
|
||||
label: tr('sortByFileNamesNotLinks'))
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
// TODO: implement requestHeaders choice, hardcoded for now
|
||||
Map<String, String>? get requestHeaders => {
|
||||
@ -111,7 +121,9 @@ class HTML extends AppSource {
|
||||
.where((element) =>
|
||||
Uri.parse(element).path.toLowerCase().endsWith('.apk'))
|
||||
.toList();
|
||||
links.sort((a, b) => compareAlphaNumeric(a, b));
|
||||
links.sort((a, b) => additionalSettings['sortByFileNamesNotLinks'] == true
|
||||
? compareAlphaNumeric(a.split('/').last, b.split('/').last)
|
||||
: compareAlphaNumeric(a, b));
|
||||
if (additionalSettings['apkFilterRegEx'] != null) {
|
||||
var reg = RegExp(additionalSettings['apkFilterRegEx']);
|
||||
links = links.where((element) => reg.hasMatch(element)).toList();
|
||||
|
@ -38,16 +38,14 @@ class VLC extends AppSource {
|
||||
}
|
||||
String? targetUrl = 'https://$dwUrlBase/$version/';
|
||||
Response res2 = await sourceRequest(targetUrl);
|
||||
String mirrorDwBase =
|
||||
'https://plug-mirror.rcac.purdue.edu/vlc/vlc-android/$version/';
|
||||
List<String> apkUrls = [];
|
||||
if (res2.statusCode == 200) {
|
||||
apkUrls = parse(res2.body)
|
||||
.querySelectorAll('a')
|
||||
.map((e) => e.attributes['href'])
|
||||
.map((e) => e.attributes['href']?.split('/').last)
|
||||
.where((h) =>
|
||||
h != null && h.isNotEmpty && h.toLowerCase().endsWith('.apk'))
|
||||
.map((e) => mirrorDwBase + e!)
|
||||
.map((e) => targetUrl + e!)
|
||||
.toList();
|
||||
} else {
|
||||
throw getObtainiumHttpError(res2);
|
||||
@ -59,4 +57,20 @@ class VLC extends AppSource {
|
||||
throw getObtainiumHttpError(res);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> apkUrlPrefetchModifier(
|
||||
String apkUrl, String standardUrl) async {
|
||||
Response res = await sourceRequest(apkUrl);
|
||||
if (res.statusCode == 200) {
|
||||
String? apkUrl =
|
||||
parse(res.body).querySelector('#alt_link')?.attributes['href'];
|
||||
if (apkUrl == null) {
|
||||
throw NoAPKError();
|
||||
}
|
||||
return apkUrl;
|
||||
} else {
|
||||
throw getObtainiumHttpError(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,8 @@ class GeneratedFormModal extends StatefulWidget {
|
||||
this.initValid = false,
|
||||
this.message = '',
|
||||
this.additionalWidgets = const [],
|
||||
this.singleNullReturnButton});
|
||||
this.singleNullReturnButton,
|
||||
this.primaryActionColour});
|
||||
|
||||
final String title;
|
||||
final String message;
|
||||
@ -19,6 +20,7 @@ class GeneratedFormModal extends StatefulWidget {
|
||||
final bool initValid;
|
||||
final List<Widget> additionalWidgets;
|
||||
final String? singleNullReturnButton;
|
||||
final Color? primaryActionColour;
|
||||
|
||||
@override
|
||||
State<GeneratedFormModal> createState() => _GeneratedFormModalState();
|
||||
@ -71,6 +73,10 @@ class _GeneratedFormModalState extends State<GeneratedFormModal> {
|
||||
: widget.singleNullReturnButton!)),
|
||||
widget.singleNullReturnButton == null
|
||||
? TextButton(
|
||||
style: widget.primaryActionColour == null
|
||||
? null
|
||||
: TextButton.styleFrom(
|
||||
foregroundColor: widget.primaryActionColour),
|
||||
onPressed: !valid
|
||||
? null
|
||||
: () {
|
||||
|
@ -3,6 +3,7 @@ import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:obtainium/custom_errors.dart';
|
||||
import 'package:obtainium/pages/home.dart';
|
||||
import 'package:obtainium/providers/apps_provider.dart';
|
||||
@ -21,7 +22,7 @@ import 'package:easy_localization/src/easy_localization_controller.dart';
|
||||
// ignore: implementation_imports
|
||||
import 'package:easy_localization/src/localization.dart';
|
||||
|
||||
const String currentVersion = '0.13.19';
|
||||
const String currentVersion = '0.13.23';
|
||||
const String currentReleaseTag =
|
||||
'v$currentVersion-beta'; // KEEP THIS IN SYNC WITH GITHUB RELEASES
|
||||
|
||||
@ -101,10 +102,15 @@ Future<void> bgUpdateCheck(int taskId, Map<String, dynamic>? params) async {
|
||||
await appsProvider.checkUpdates(
|
||||
ignoreAppsCheckedAfter: ignoreAfter, throwErrorsForRetry: true);
|
||||
} catch (e) {
|
||||
if (e is RateLimitError || e is SocketException) {
|
||||
if (e is RateLimitError || e is ClientException) {
|
||||
var remainingMinutes = e is RateLimitError ? e.remainingMinutes : 15;
|
||||
logs.add(plural('bgUpdateGotErrorRetryInMinutes', remainingMinutes,
|
||||
args: [e.toString(), remainingMinutes.toString()]));
|
||||
logs.add(
|
||||
plural('bgUpdateGotErrorRetryInMinutes', remainingMinutes, args: [
|
||||
e is ClientException
|
||||
? '${(e).message}, ${e.uri?.path}'
|
||||
: e.toString(),
|
||||
remainingMinutes.toString()
|
||||
]));
|
||||
AndroidAlarmManager.oneShot(Duration(minutes: remainingMinutes),
|
||||
Random().nextInt(pow(2, 31) as int), bgUpdateCheck, params: {
|
||||
'ignoreAfterMicroseconds': nextIgnoreAfter.microsecondsSinceEpoch
|
||||
|
@ -16,7 +16,7 @@ class GitHubStars implements MassAppUrlSource {
|
||||
Future<Map<String, List<String>>> getOnePageOfUserStarredUrlsWithDescriptions(
|
||||
String username, int page) async {
|
||||
Response res = await get(Uri.parse(
|
||||
'https://${await GitHub().getCredentialPrefixIfAny()}api.github.com/users/$username/starred?per_page=100&page=$page'));
|
||||
'https://${await GitHub().getCredentialPrefixIfAny({})}api.github.com/users/$username/starred?per_page=100&page=$page'));
|
||||
if (res.statusCode == 200) {
|
||||
Map<String, List<String>> urlsWithDescriptions = {};
|
||||
for (var e in (jsonDecode(res.body) as List<dynamic>)) {
|
||||
|
@ -41,6 +41,7 @@ class _AddAppPageState extends State<AddAppPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
AppsProvider appsProvider = context.read<AppsProvider>();
|
||||
SettingsProvider settingsProvider = context.watch<SettingsProvider>();
|
||||
|
||||
bool doingSomething = gettingAppInfo || searching;
|
||||
|
||||
@ -85,8 +86,7 @@ class _AddAppPageState extends State<AddAppPage> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> getTrackOnlyConfirmationIfNeeded(
|
||||
bool userPickedTrackOnly, SettingsProvider settingsProvider,
|
||||
Future<bool> getTrackOnlyConfirmationIfNeeded(bool userPickedTrackOnly,
|
||||
{bool ignoreHideSetting = false}) async {
|
||||
var useTrackOnly = userPickedTrackOnly || pickedSource!.enforceTrackOnly;
|
||||
if (useTrackOnly &&
|
||||
@ -138,11 +138,9 @@ class _AddAppPageState extends State<AddAppPage> {
|
||||
gettingAppInfo = true;
|
||||
});
|
||||
try {
|
||||
var settingsProvider = context.read<SettingsProvider>();
|
||||
var userPickedTrackOnly = additionalSettings['trackOnly'] == true;
|
||||
App? app;
|
||||
if ((await getTrackOnlyConfirmationIfNeeded(
|
||||
userPickedTrackOnly, settingsProvider)) &&
|
||||
if ((await getTrackOnlyConfirmationIfNeeded(userPickedTrackOnly)) &&
|
||||
(await getReleaseDateAsVersionConfirmationIfNeeded(
|
||||
userPickedTrackOnly))) {
|
||||
var trackOnly = pickedSource!.enforceTrackOnly || userPickedTrackOnly;
|
||||
@ -410,7 +408,13 @@ class _AddAppPageState extends State<AddAppPage> {
|
||||
),
|
||||
GeneratedForm(
|
||||
key: Key(pickedSource.runtimeType.toString()),
|
||||
items: pickedSource!.combinedAppSpecificSettingFormItems,
|
||||
items: [
|
||||
...pickedSource!.combinedAppSpecificSettingFormItems,
|
||||
...(pickedSourceOverride != null
|
||||
? pickedSource!.sourceConfigSettingFormItems
|
||||
.map((e) => [e])
|
||||
: [])
|
||||
],
|
||||
onValueChanges: (values, valid, isBuilding) {
|
||||
if (!isBuilding) {
|
||||
setState(() {
|
||||
@ -504,6 +508,18 @@ class _AddAppPageState extends State<AddAppPage> {
|
||||
HTML().runtimeType.toString()))
|
||||
getHTMLSourceOverrideDropdown(),
|
||||
if (shouldShowSearchBar()) getSearchBarRow(),
|
||||
if (pickedSource != null)
|
||||
FutureBuilder(
|
||||
builder: (ctx, val) {
|
||||
return val.data != null && val.data!.isNotEmpty
|
||||
? Text(
|
||||
val.data!,
|
||||
style:
|
||||
Theme.of(context).textTheme.bodySmall,
|
||||
)
|
||||
: const SizedBox();
|
||||
},
|
||||
future: pickedSource?.getSourceNote()),
|
||||
const SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
|
@ -431,8 +431,7 @@ class _AppPageState extends State<AppPage> {
|
||||
? getResetInstallStatusButton()
|
||||
: getInstallOrUpdateButton()),
|
||||
const SizedBox(width: 16.0),
|
||||
Expanded(
|
||||
child: TextButton(
|
||||
IconButton(
|
||||
onPressed: app?.downloadProgress != null
|
||||
? null
|
||||
: () {
|
||||
@ -445,13 +444,9 @@ class _AppPageState extends State<AppPage> {
|
||||
}
|
||||
});
|
||||
},
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor:
|
||||
Theme.of(context).colorScheme.error,
|
||||
surfaceTintColor:
|
||||
Theme.of(context).colorScheme.error),
|
||||
child: Text(tr('remove')),
|
||||
)),
|
||||
tooltip: tr('remove'),
|
||||
icon: const Icon(Icons.delete_outline),
|
||||
),
|
||||
])),
|
||||
if (app?.downloadProgress != null)
|
||||
Padding(
|
||||
|
@ -543,20 +543,19 @@ class AppsPageState extends State<AppsPage> {
|
||||
: FontWeight.normal)),
|
||||
trailing: listedApps[index].downloadProgress != null
|
||||
? SizedBox(
|
||||
width: 90,
|
||||
child: Text(
|
||||
listedApps[index].downloadProgress! >= 0
|
||||
? tr('percentProgress', args: [
|
||||
listedApps[index]
|
||||
.downloadProgress!
|
||||
.toInt()
|
||||
.toString()
|
||||
])
|
||||
: tr('pleaseWait'),
|
||||
textAlign: (listedApps[index].downloadProgress! >= 0)
|
||||
? TextAlign.start
|
||||
: TextAlign.end,
|
||||
))
|
||||
listedApps[index].downloadProgress! >= 0
|
||||
? tr('percentProgress', args: [
|
||||
listedApps[index]
|
||||
.downloadProgress!
|
||||
.toInt()
|
||||
.toString()
|
||||
])
|
||||
: tr('pleaseWait'),
|
||||
textAlign: (listedApps[index].downloadProgress! >= 0)
|
||||
? TextAlign.start
|
||||
: TextAlign.end,
|
||||
))
|
||||
: trailingRow,
|
||||
onTap: () {
|
||||
if (selectedAppIds.isNotEmpty) {
|
||||
|
@ -166,9 +166,9 @@ class _SettingsPageState extends State<SettingsPage> {
|
||||
});
|
||||
|
||||
var sourceSpecificFields = sourceProvider.sources.map((e) {
|
||||
if (e.additionalSourceSpecificSettingFormItems.isNotEmpty) {
|
||||
if (e.sourceConfigSettingFormItems.isNotEmpty) {
|
||||
return GeneratedForm(
|
||||
items: e.additionalSourceSpecificSettingFormItems.map((e) {
|
||||
items: e.sourceConfigSettingFormItems.map((e) {
|
||||
e.defaultValue = settingsProvider.getSettingString(e.key);
|
||||
return [e];
|
||||
}).toList(),
|
||||
@ -403,10 +403,13 @@ class _SettingsPageState extends State<SettingsPage> {
|
||||
Switch(
|
||||
value:
|
||||
settingsProvider.reversePageTransitions,
|
||||
onChanged: (value) {
|
||||
settingsProvider.reversePageTransitions =
|
||||
value;
|
||||
})
|
||||
onChanged: settingsProvider
|
||||
.disablePageTransitions
|
||||
? null
|
||||
: (value) {
|
||||
settingsProvider
|
||||
.reversePageTransitions = value;
|
||||
})
|
||||
],
|
||||
),
|
||||
height32,
|
||||
|
@ -144,6 +144,25 @@ class AppsProvider with ChangeNotifier {
|
||||
}();
|
||||
}
|
||||
|
||||
Future<File> downloadFileWithRetry(
|
||||
String url, String fileNameNoExt, Function? onProgress,
|
||||
{bool useExisting = true,
|
||||
Map<String, String>? headers,
|
||||
int retries = 3}) async {
|
||||
try {
|
||||
return await downloadFile(url, fileNameNoExt, onProgress,
|
||||
useExisting: useExisting, headers: headers);
|
||||
} catch (e) {
|
||||
if (retries > 0 && e is ClientException) {
|
||||
await Future.delayed(const Duration(seconds: 5));
|
||||
return await downloadFileWithRetry(url, fileNameNoExt, onProgress,
|
||||
useExisting: useExisting, headers: headers, retries: (retries - 1));
|
||||
} else {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<File> downloadFile(
|
||||
String url, String fileNameNoExt, Function? onProgress,
|
||||
{bool useExisting = true, Map<String, String>? headers}) async {
|
||||
@ -236,8 +255,9 @@ class AppsProvider with ChangeNotifier {
|
||||
notificationsProvider?.cancel(notif.id);
|
||||
int? prevProg;
|
||||
var fileNameNoExt = '${app.id}-${downloadUrl.hashCode}';
|
||||
var downloadedFile = await downloadFile(downloadUrl, fileNameNoExt,
|
||||
headers: source.requestHeaders, (double? progress) {
|
||||
var downloadedFile = await downloadFileWithRetry(
|
||||
downloadUrl, fileNameNoExt, headers: source.requestHeaders,
|
||||
(double? progress) {
|
||||
int? prog = progress?.ceil();
|
||||
if (apps[app.id] != null) {
|
||||
apps[app.id]!.downloadProgress = progress;
|
||||
@ -872,6 +892,7 @@ class AppsProvider with ChangeNotifier {
|
||||
context: context,
|
||||
builder: (BuildContext ctx) {
|
||||
return GeneratedFormModal(
|
||||
primaryActionColour: Theme.of(context).colorScheme.error,
|
||||
title: plural('removeAppQuestion', apps.length),
|
||||
items: !showUninstallOption
|
||||
? []
|
||||
|
@ -28,6 +28,7 @@ import 'package:obtainium/app_sources/vlc.dart';
|
||||
import 'package:obtainium/components/generated_form.dart';
|
||||
import 'package:obtainium/custom_errors.dart';
|
||||
import 'package:obtainium/mass_app_sources/githubstars.dart';
|
||||
import 'package:obtainium/providers/settings_provider.dart';
|
||||
|
||||
class AppNames {
|
||||
late String author;
|
||||
@ -424,12 +425,31 @@ abstract class AppSource {
|
||||
}
|
||||
|
||||
// Some Sources may have additional settings at the Source level (not specific to Apps) - these use SettingsProvider
|
||||
List<GeneratedFormItem> additionalSourceSpecificSettingFormItems = [];
|
||||
// If the source has been overridden, we expect the user to define one-time values as additional settings - don't use the stored values
|
||||
List<GeneratedFormItem> sourceConfigSettingFormItems = [];
|
||||
Future<Map<String, String>> getSourceConfigValues(
|
||||
Map<String, dynamic> additionalSettings,
|
||||
SettingsProvider settingsProvider) async {
|
||||
Map<String, String> results = {};
|
||||
for (var e in sourceConfigSettingFormItems) {
|
||||
var val = hostChanged
|
||||
? additionalSettings[e.key]
|
||||
: settingsProvider.getSettingString(e.key);
|
||||
if (val != null) {
|
||||
results[e.key] = val;
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
String? changeLogPageFromStandardUrl(String standardUrl) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<String?> getSourceNote() async {
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<String> apkUrlPrefetchModifier(
|
||||
String apkUrl, String standardUrl) async {
|
||||
return apkUrl;
|
||||
@ -449,8 +469,11 @@ abstract class AppSource {
|
||||
}
|
||||
|
||||
ObtainiumError getObtainiumHttpError(Response res) {
|
||||
return ObtainiumError(res.reasonPhrase ??
|
||||
tr('errorWithHttpStatusCode', args: [res.statusCode.toString()]));
|
||||
return ObtainiumError((res.reasonPhrase != null &&
|
||||
res.reasonPhrase != null &&
|
||||
res.reasonPhrase!.isNotEmpty)
|
||||
? res.reasonPhrase!
|
||||
: tr('errorWithHttpStatusCode', args: [res.statusCode.toString()]));
|
||||
}
|
||||
|
||||
abstract class MassAppUrlSource {
|
||||
|
64
pubspec.lock
64
pubspec.lock
@ -5,18 +5,18 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: android_alarm_manager_plus
|
||||
sha256: "80f963d47cb7ab0818144c7b0668aea4c038f9cb8626626e89a4ea77375defb7"
|
||||
sha256: c20d91a9096596f66274bf8172321c278f9cba8091638f80205fe66d31587fa5
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
version: "3.0.2"
|
||||
android_intent_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: android_intent_plus
|
||||
sha256: "2c87d8330ba5deef5fe20e77f4d178190b3b24531dce08368030ab4be40a9d4e"
|
||||
sha256: f72ae20bb37108694f442e7ae6acbd28b453ca62ce86842f6787b784355abfe6
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.1"
|
||||
version: "4.0.2"
|
||||
android_package_installer:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -158,10 +158,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: device_info_plus
|
||||
sha256: "2c35b6d1682b028e42d07b3aee4b98fa62996c10bc12cb651ec856a80d6a761b"
|
||||
sha256: "86add5ef97215562d2e090535b0a16f197902b10c369c558a100e74ea06e8659"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.0.2"
|
||||
version: "9.0.3"
|
||||
device_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -222,10 +222,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: file_picker
|
||||
sha256: b1729fc96627dd44012d0a901558177418818d6bd428df59dcfeb594e5f66432
|
||||
sha256: "21145c9c268d54b1f771d8380c195d2d6f655e0567dc1ca2f9c134c02c819e0a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.3.2"
|
||||
version: "5.3.3"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
@ -490,42 +490,42 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
sha256: "2cec049d282c7f13c594b4a73976b0b4f2d7a1838a6dd5aaf7bd9719196bee86"
|
||||
sha256: "5d44fc3314d969b84816b569070d7ace0f1dea04bd94a83f74c4829615d22ad8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.27"
|
||||
version: "2.1.0"
|
||||
path_provider_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_foundation
|
||||
sha256: "916731ccbdce44d545414dd9961f26ba5fbaa74bcbb55237d8e65a623a8c7297"
|
||||
sha256: "1b744d3d774e5a879bb76d6cd1ecee2ba2c6960c03b1020cd35212f6aa267ac5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.4"
|
||||
version: "2.3.0"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_linux
|
||||
sha256: ffbb8cc9ed2c9ec0e4b7a541e56fd79b138e8f47d2fb86815f15358a349b3b57
|
||||
sha256: ba2b77f0c52a33db09fc8caf85b12df691bf28d983e84cf87ff6d693cfa007b3
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.11"
|
||||
version: "2.2.0"
|
||||
path_provider_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_platform_interface
|
||||
sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec"
|
||||
sha256: bced5679c7df11190e1ddc35f3222c858f328fff85c3942e46e7f5589bf9eb84
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.6"
|
||||
version: "2.1.0"
|
||||
path_provider_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_windows
|
||||
sha256: "1cb68ba4cd3a795033de62ba1b7b4564dace301f952de6bfb3cd91b202b6ee96"
|
||||
sha256: ee0e0d164516b90ae1f970bdf29f726f1aa730d7cfc449ecc74c495378b705da
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.7"
|
||||
version: "2.2.0"
|
||||
permission_handler:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -610,18 +610,18 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: share_plus
|
||||
sha256: ed3fcea4f789ed95913328e629c0c53e69e80e08b6c24542f1b3576046c614e8
|
||||
sha256: "6cec740fa0943a826951223e76218df002804adb588235a8910dc3d6b0654e11"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.2"
|
||||
version: "7.1.0"
|
||||
share_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: share_plus_platform_interface
|
||||
sha256: "0c6e61471bd71b04a138b8b588fa388e66d8b005e6f2deda63371c5c505a0981"
|
||||
sha256: "357412af4178d8e11d14f41723f80f12caea54cf0d5cd29af9dcdab85d58aea7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.1"
|
||||
version: "3.3.0"
|
||||
shared_preferences:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -695,18 +695,18 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: sqflite
|
||||
sha256: b4d6710e1200e96845747e37338ea8a819a12b51689a3bcf31eff0003b37a0b9
|
||||
sha256: "591f1602816e9c31377d5f008c2d9ef7b8aca8941c3f89cc5fd9d84da0c38a9a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.8+4"
|
||||
version: "2.3.0"
|
||||
sqflite_common:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite_common
|
||||
sha256: "8f7603f3f8f126740bc55c4ca2d1027aab4b74a1267a3e31ce51fe40e3b65b8f"
|
||||
sha256: "1b92f368f44b0dee2425bb861cfa17b6f6cf3961f762ff6f941d20b33355660a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.5+1"
|
||||
version: "2.5.0"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -863,10 +863,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webview_flutter_android
|
||||
sha256: "8587d0b4991bd0f223f4b4957101c2c7449f905601571315f4967072498dd3fb"
|
||||
sha256: d936a09fbfd08cb78f7329e0bbacf6158fbdfe24ffc908b22444c07d295eb193
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.9.1"
|
||||
version: "3.9.2"
|
||||
webview_flutter_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -879,18 +879,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webview_flutter_wkwebview
|
||||
sha256: "3e36a8f564809cb7c257ff4278502b185e2191349df0ddee98837f91805c74b8"
|
||||
sha256: "5fa098f28b606f699e8ca52d9e4e11edbbfef65189f5f77ae92703ba5408fd25"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.7.1"
|
||||
version: "3.7.2"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
sha256: dfdf0136e0aa7a1b474ea133e67cb0154a0acd2599c4f3ada3b49d38d38793ee
|
||||
sha256: f2add6fa510d3ae152903412227bda57d0d5a8da61d2c39c1fb022c9429a41c0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.5"
|
||||
version: "5.0.6"
|
||||
win32_registry:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -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.13.19+183 # When changing this, update the tag in main() accordingly
|
||||
version: 0.13.23+187 # When changing this, update the tag in main() accordingly
|
||||
|
||||
environment:
|
||||
sdk: '>=2.18.2 <3.0.0'
|
||||
|
Reference in New Issue
Block a user