mirror of
https://github.com/ImranR98/Obtainium.git
synced 2025-07-18 15:39:40 +02:00
Compare commits
11 Commits
v0.13.3-be
...
v0.13.4-be
Author | SHA1 | Date | |
---|---|---|---|
|
ca1371260c | ||
|
03c2ce9a01 | ||
|
eda5fec37c | ||
|
e21c6297ff | ||
|
c6297ea449 | ||
|
e33cc00266 | ||
|
96c92c8df9 | ||
|
e256ada2dc | ||
|
eb0be196da | ||
|
1606ad3442 | ||
|
d212f13345 |
@@ -180,6 +180,7 @@
|
|||||||
"yesMarkUpdated": "Ja, als aktualisiert markieren",
|
"yesMarkUpdated": "Ja, als aktualisiert markieren",
|
||||||
"fdroid": "F-Droid Official",
|
"fdroid": "F-Droid Official",
|
||||||
"appIdOrName": "App ID oder Name",
|
"appIdOrName": "App ID oder Name",
|
||||||
|
"appId": "App ID",
|
||||||
"appWithIdOrNameNotFound": "Es wurde keine App mit dieser ID oder diesem Namen gefunden",
|
"appWithIdOrNameNotFound": "Es wurde keine App mit dieser ID oder diesem Namen gefunden",
|
||||||
"reposHaveMultipleApps": "Repos können mehrere Apps enthalten",
|
"reposHaveMultipleApps": "Repos können mehrere Apps enthalten",
|
||||||
"fdroidThirdPartyRepo": "F-Droid Third-Party Repo",
|
"fdroidThirdPartyRepo": "F-Droid Third-Party Repo",
|
||||||
|
@@ -180,6 +180,7 @@
|
|||||||
"yesMarkUpdated": "Yes, Mark as Updated",
|
"yesMarkUpdated": "Yes, Mark as Updated",
|
||||||
"fdroid": "F-Droid Official",
|
"fdroid": "F-Droid Official",
|
||||||
"appIdOrName": "App ID or Name",
|
"appIdOrName": "App ID or Name",
|
||||||
|
"appId": "App ID",
|
||||||
"appWithIdOrNameNotFound": "No App was found with that ID or Name",
|
"appWithIdOrNameNotFound": "No App was found with that ID or Name",
|
||||||
"reposHaveMultipleApps": "Repos may contain multiple Apps",
|
"reposHaveMultipleApps": "Repos may contain multiple Apps",
|
||||||
"fdroidThirdPartyRepo": "F-Droid Third-Party Repo",
|
"fdroidThirdPartyRepo": "F-Droid Third-Party Repo",
|
||||||
|
@@ -180,6 +180,7 @@
|
|||||||
"yesMarkUpdated": "Sí, Marcar como Actualizada",
|
"yesMarkUpdated": "Sí, Marcar como Actualizada",
|
||||||
"fdroid": "Repositorio oficial de F-Droid",
|
"fdroid": "Repositorio oficial de F-Droid",
|
||||||
"appIdOrName": "ID o Nombre de la Aplicación",
|
"appIdOrName": "ID o Nombre de la Aplicación",
|
||||||
|
"appId": "ID de la Aplicación",
|
||||||
"appWithIdOrNameNotFound": "No se han encontrado aplicaciones con esa ID o nombre",
|
"appWithIdOrNameNotFound": "No se han encontrado aplicaciones con esa ID o nombre",
|
||||||
"reposHaveMultipleApps": "Los repositorios pueden contener varias aplicaciones",
|
"reposHaveMultipleApps": "Los repositorios pueden contener varias aplicaciones",
|
||||||
"fdroidThirdPartyRepo": "Rpositorios de terceros de F-Droid",
|
"fdroidThirdPartyRepo": "Rpositorios de terceros de F-Droid",
|
||||||
|
@@ -180,6 +180,7 @@
|
|||||||
"yesMarkUpdated": "بله، علامت گذاری به عنوان به روز شده",
|
"yesMarkUpdated": "بله، علامت گذاری به عنوان به روز شده",
|
||||||
"fdroid": "F-Droid Official",
|
"fdroid": "F-Droid Official",
|
||||||
"appIdOrName": "شناسه یا نام برنامه",
|
"appIdOrName": "شناسه یا نام برنامه",
|
||||||
|
"appId": "App ID",
|
||||||
"appWithIdOrNameNotFound": "هیچ برنامه ای با آن شناسه یا نام یافت نشد",
|
"appWithIdOrNameNotFound": "هیچ برنامه ای با آن شناسه یا نام یافت نشد",
|
||||||
"reposHaveMultipleApps": "مخازن ممکن است شامل چندین برنامه باشد",
|
"reposHaveMultipleApps": "مخازن ممکن است شامل چندین برنامه باشد",
|
||||||
"fdroidThirdPartyRepo": "مخازن شخص ثالث F-Droid",
|
"fdroidThirdPartyRepo": "مخازن شخص ثالث F-Droid",
|
||||||
|
@@ -180,6 +180,7 @@
|
|||||||
"yesMarkUpdated": "Oui, marquer comme mis à jour",
|
"yesMarkUpdated": "Oui, marquer comme mis à jour",
|
||||||
"fdroid": "F-Droid Official",
|
"fdroid": "F-Droid Official",
|
||||||
"appIdOrName": "ID ou nom de l'application",
|
"appIdOrName": "ID ou nom de l'application",
|
||||||
|
"appId": "ID de l'application",
|
||||||
"appWithIdOrNameNotFound": "Aucune application n'a été trouvée avec cet identifiant ou ce nom",
|
"appWithIdOrNameNotFound": "Aucune application n'a été trouvée avec cet identifiant ou ce nom",
|
||||||
"reposHaveMultipleApps": "Les dépôts peuvent contenir plusieurs applications",
|
"reposHaveMultipleApps": "Les dépôts peuvent contenir plusieurs applications",
|
||||||
"fdroidThirdPartyRepo": "Dépôt tiers F-Droid",
|
"fdroidThirdPartyRepo": "Dépôt tiers F-Droid",
|
||||||
|
@@ -180,6 +180,7 @@
|
|||||||
"yesMarkUpdated": "Igen, megjelölés frissítettként",
|
"yesMarkUpdated": "Igen, megjelölés frissítettként",
|
||||||
"fdroid": "F-Droid Official",
|
"fdroid": "F-Droid Official",
|
||||||
"appIdOrName": "App ID vagy név",
|
"appIdOrName": "App ID vagy név",
|
||||||
|
"appId": "App ID",
|
||||||
"appWithIdOrNameNotFound": "Nem található app ezzel az azonosítóval vagy névvel",
|
"appWithIdOrNameNotFound": "Nem található app ezzel az azonosítóval vagy névvel",
|
||||||
"reposHaveMultipleApps": "A repók több alkalmazást is tartalmazhatnak",
|
"reposHaveMultipleApps": "A repók több alkalmazást is tartalmazhatnak",
|
||||||
"fdroidThirdPartyRepo": "F-Droid Harmadik-fél Repo",
|
"fdroidThirdPartyRepo": "F-Droid Harmadik-fél Repo",
|
||||||
|
@@ -180,6 +180,7 @@
|
|||||||
"yesMarkUpdated": "Sì, contrassegna come aggiornato",
|
"yesMarkUpdated": "Sì, contrassegna come aggiornato",
|
||||||
"fdroid": "F-Droid Official",
|
"fdroid": "F-Droid Official",
|
||||||
"appIdOrName": "ID o nome dell'App",
|
"appIdOrName": "ID o nome dell'App",
|
||||||
|
"appId": "ID dell'App",
|
||||||
"appWithIdOrNameNotFound": "Non è stata trovata alcuna App con quell'ID o nome",
|
"appWithIdOrNameNotFound": "Non è stata trovata alcuna App con quell'ID o nome",
|
||||||
"reposHaveMultipleApps": "I repository possono contenere più App",
|
"reposHaveMultipleApps": "I repository possono contenere più App",
|
||||||
"fdroidThirdPartyRepo": "Repository F-Droid di terze parti",
|
"fdroidThirdPartyRepo": "Repository F-Droid di terze parti",
|
||||||
|
@@ -180,6 +180,7 @@
|
|||||||
"yesMarkUpdated": "はい、アップデート済みとしてマークします",
|
"yesMarkUpdated": "はい、アップデート済みとしてマークします",
|
||||||
"fdroid": "F-Droid Official",
|
"fdroid": "F-Droid Official",
|
||||||
"appIdOrName": "アプリのIDまたは名前",
|
"appIdOrName": "アプリのIDまたは名前",
|
||||||
|
"appId": "App ID",
|
||||||
"appWithIdOrNameNotFound": "そのIDや名前を持つアプリは見つかりませんでした",
|
"appWithIdOrNameNotFound": "そのIDや名前を持つアプリは見つかりませんでした",
|
||||||
"reposHaveMultipleApps": "リポジトリには複数のアプリが含まれることがあります",
|
"reposHaveMultipleApps": "リポジトリには複数のアプリが含まれることがあります",
|
||||||
"fdroidThirdPartyRepo": "F-Droid サードパーティリポジトリ",
|
"fdroidThirdPartyRepo": "F-Droid サードパーティリポジトリ",
|
||||||
|
@@ -180,6 +180,7 @@
|
|||||||
"yesMarkUpdated": "是,标记为已更新",
|
"yesMarkUpdated": "是,标记为已更新",
|
||||||
"fdroid": "F-Droid 官方存储库",
|
"fdroid": "F-Droid 官方存储库",
|
||||||
"appIdOrName": "应用 ID 或名称",
|
"appIdOrName": "应用 ID 或名称",
|
||||||
|
"appId": "App ID",
|
||||||
"appWithIdOrNameNotFound": "未找到符合此 ID 或名称的应用",
|
"appWithIdOrNameNotFound": "未找到符合此 ID 或名称的应用",
|
||||||
"reposHaveMultipleApps": "存储库中可能包含多个应用",
|
"reposHaveMultipleApps": "存储库中可能包含多个应用",
|
||||||
"fdroidThirdPartyRepo": "F-Droid 第三方存储库",
|
"fdroidThirdPartyRepo": "F-Droid 第三方存储库",
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:html/parser.dart';
|
import 'package:html/parser.dart';
|
||||||
import 'package:http/http.dart';
|
|
||||||
import 'package:obtainium/custom_errors.dart';
|
import 'package:obtainium/custom_errors.dart';
|
||||||
import 'package:obtainium/providers/source_provider.dart';
|
import 'package:obtainium/providers/source_provider.dart';
|
||||||
|
|
||||||
@@ -85,7 +84,6 @@ class APKCombo extends AppSource {
|
|||||||
Map<String, dynamic> additionalSettings,
|
Map<String, dynamic> additionalSettings,
|
||||||
) async {
|
) async {
|
||||||
String appId = tryInferringAppId(standardUrl)!;
|
String appId = tryInferringAppId(standardUrl)!;
|
||||||
String host = Uri.parse(standardUrl).host;
|
|
||||||
var preres = await sourceRequest(standardUrl);
|
var preres = await sourceRequest(standardUrl);
|
||||||
if (preres.statusCode != 200) {
|
if (preres.statusCode != 200) {
|
||||||
throw getObtainiumHttpError(preres);
|
throw getObtainiumHttpError(preres);
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:html/parser.dart';
|
import 'package:html/parser.dart';
|
||||||
import 'package:http/http.dart';
|
|
||||||
import 'package:obtainium/custom_errors.dart';
|
import 'package:obtainium/custom_errors.dart';
|
||||||
import 'package:obtainium/providers/source_provider.dart';
|
import 'package:obtainium/providers/source_provider.dart';
|
||||||
|
|
||||||
|
@@ -1,6 +1,4 @@
|
|||||||
import 'dart:convert';
|
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:http/http.dart';
|
|
||||||
import 'package:obtainium/app_sources/github.dart';
|
import 'package:obtainium/app_sources/github.dart';
|
||||||
import 'package:obtainium/components/generated_form.dart';
|
import 'package:obtainium/components/generated_form.dart';
|
||||||
import 'package:obtainium/custom_errors.dart';
|
import 'package:obtainium/custom_errors.dart';
|
||||||
@@ -9,7 +7,6 @@ import 'package:obtainium/providers/source_provider.dart';
|
|||||||
class Codeberg extends AppSource {
|
class Codeberg extends AppSource {
|
||||||
Codeberg() {
|
Codeberg() {
|
||||||
host = 'codeberg.org';
|
host = 'codeberg.org';
|
||||||
overrideEligible = true;
|
|
||||||
|
|
||||||
additionalSourceSpecificSettingFormItems = [];
|
additionalSourceSpecificSettingFormItems = [];
|
||||||
|
|
||||||
@@ -58,10 +55,10 @@ class Codeberg extends AppSource {
|
|||||||
String standardUrl,
|
String standardUrl,
|
||||||
Map<String, dynamic> additionalSettings,
|
Map<String, dynamic> additionalSettings,
|
||||||
) async {
|
) async {
|
||||||
return gh.getLatestAPKDetailsCommon(
|
return await gh.getLatestAPKDetailsCommon2(standardUrl, additionalSettings,
|
||||||
'https://$host/api/v1/repos${standardUrl.substring('https://$host'.length)}/releases?per_page=100',
|
(bool useTagUrl) async {
|
||||||
standardUrl,
|
return 'https://$host/api/v1/repos${standardUrl.substring('https://$host'.length)}/${useTagUrl ? 'tags' : 'releases'}?per_page=100';
|
||||||
additionalSettings);
|
}, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
AppNames getAppNames(String standardUrl) {
|
AppNames getAppNames(String standardUrl) {
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:html/parser.dart';
|
import 'package:html/parser.dart';
|
||||||
import 'package:http/http.dart';
|
|
||||||
import 'package:obtainium/components/generated_form.dart';
|
import 'package:obtainium/components/generated_form.dart';
|
||||||
import 'package:obtainium/custom_errors.dart';
|
import 'package:obtainium/custom_errors.dart';
|
||||||
import 'package:obtainium/providers/source_provider.dart';
|
import 'package:obtainium/providers/source_provider.dart';
|
||||||
@@ -8,7 +7,6 @@ import 'package:obtainium/providers/source_provider.dart';
|
|||||||
class FDroidRepo extends AppSource {
|
class FDroidRepo extends AppSource {
|
||||||
FDroidRepo() {
|
FDroidRepo() {
|
||||||
name = tr('fdroidThirdPartyRepo');
|
name = tr('fdroidThirdPartyRepo');
|
||||||
overrideEligible = true;
|
|
||||||
|
|
||||||
additionalSourceAppSpecificSettingFormItems = [
|
additionalSourceAppSpecificSettingFormItems = [
|
||||||
[
|
[
|
||||||
|
@@ -13,7 +13,6 @@ import 'package:url_launcher/url_launcher_string.dart';
|
|||||||
class GitHub extends AppSource {
|
class GitHub extends AppSource {
|
||||||
GitHub() {
|
GitHub() {
|
||||||
host = 'github.com';
|
host = 'github.com';
|
||||||
overrideEligible = true;
|
|
||||||
|
|
||||||
additionalSourceSpecificSettingFormItems = [
|
additionalSourceSpecificSettingFormItems = [
|
||||||
GeneratedFormTextField('github-creds',
|
GeneratedFormTextField('github-creds',
|
||||||
@@ -143,15 +142,17 @@ class GitHub extends AppSource {
|
|||||||
} else if (b == null) {
|
} else if (b == null) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
var stdFormats = findStandardFormatsForVersion(a['tag_name'], true)
|
var nameA = a['tag_name'] ?? a['name'];
|
||||||
.intersection(findStandardFormatsForVersion(b['tag_name'], true));
|
var nameB = b['tag_name'] ?? b['name'];
|
||||||
|
var stdFormats = findStandardFormatsForVersion(nameA, true)
|
||||||
|
.intersection(findStandardFormatsForVersion(nameB, true));
|
||||||
if (stdFormats.isNotEmpty) {
|
if (stdFormats.isNotEmpty) {
|
||||||
var reg = RegExp(stdFormats.first);
|
var reg = RegExp(stdFormats.first);
|
||||||
var matchA = reg.firstMatch(a['tag_name']);
|
var matchA = reg.firstMatch(nameA);
|
||||||
var matchB = reg.firstMatch(b['tag_name']);
|
var matchB = reg.firstMatch(nameB);
|
||||||
return compareAlphaNumeric(
|
return compareAlphaNumeric(
|
||||||
(a['tag_name'] as String).substring(matchA!.start, matchA.end),
|
(nameA as String).substring(matchA!.start, matchA.end),
|
||||||
(b['tag_name'] as String).substring(matchB!.start, matchB.end));
|
(nameB as String).substring(matchB!.start, matchB.end));
|
||||||
} else {
|
} else {
|
||||||
return getReleaseDateFromRelease(a)!
|
return getReleaseDateFromRelease(a)!
|
||||||
.compareTo(getReleaseDateFromRelease(b)!);
|
.compareTo(getReleaseDateFromRelease(b)!);
|
||||||
@@ -191,7 +192,7 @@ class GitHub extends AppSource {
|
|||||||
if (targetRelease == null) {
|
if (targetRelease == null) {
|
||||||
throw NoReleasesError();
|
throw NoReleasesError();
|
||||||
}
|
}
|
||||||
String? version = targetRelease['tag_name'];
|
String? version = targetRelease['tag_name'] ?? targetRelease['name'];
|
||||||
DateTime? releaseDate = getReleaseDateFromRelease(targetRelease);
|
DateTime? releaseDate = getReleaseDateFromRelease(targetRelease);
|
||||||
if (version == null) {
|
if (version == null) {
|
||||||
throw NoVersionError();
|
throw NoVersionError();
|
||||||
@@ -211,15 +212,35 @@ class GitHub extends AppSource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getLatestAPKDetailsCommon2(
|
||||||
|
String standardUrl,
|
||||||
|
Map<String, dynamic> additionalSettings,
|
||||||
|
Future<String> Function(bool) reqUrlGenerator,
|
||||||
|
dynamic Function(Response)? onHttpErrorCode) async {
|
||||||
|
try {
|
||||||
|
return await getLatestAPKDetailsCommon(
|
||||||
|
await reqUrlGenerator(false), standardUrl, additionalSettings,
|
||||||
|
onHttpErrorCode: onHttpErrorCode);
|
||||||
|
} catch (err) {
|
||||||
|
if (err is NoReleasesError && additionalSettings['trackOnly'] == true) {
|
||||||
|
return await getLatestAPKDetailsCommon(
|
||||||
|
await reqUrlGenerator(true), standardUrl, additionalSettings,
|
||||||
|
onHttpErrorCode: onHttpErrorCode);
|
||||||
|
} else {
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<APKDetails> getLatestAPKDetails(
|
Future<APKDetails> getLatestAPKDetails(
|
||||||
String standardUrl,
|
String standardUrl,
|
||||||
Map<String, dynamic> additionalSettings,
|
Map<String, dynamic> additionalSettings,
|
||||||
) async {
|
) async {
|
||||||
return getLatestAPKDetailsCommon(
|
return await getLatestAPKDetailsCommon2(standardUrl, additionalSettings,
|
||||||
'https://${await getCredentialPrefixIfAny()}api.$host/repos${standardUrl.substring('https://$host'.length)}/releases?per_page=100',
|
(bool useTagUrl) async {
|
||||||
standardUrl,
|
return 'https://${await getCredentialPrefixIfAny()}api.$host/repos${standardUrl.substring('https://$host'.length)}/${useTagUrl ? 'tags' : 'releases'}?per_page=100';
|
||||||
additionalSettings, onHttpErrorCode: (Response res) {
|
}, (Response res) {
|
||||||
rateLimitErrorCheck(res);
|
rateLimitErrorCheck(res);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -14,7 +14,6 @@ import 'package:url_launcher/url_launcher_string.dart';
|
|||||||
class GitLab extends AppSource {
|
class GitLab extends AppSource {
|
||||||
GitLab() {
|
GitLab() {
|
||||||
host = 'gitlab.com';
|
host = 'gitlab.com';
|
||||||
overrideEligible = true;
|
|
||||||
canSearch = true;
|
canSearch = true;
|
||||||
|
|
||||||
additionalSourceSpecificSettingFormItems = [
|
additionalSourceSpecificSettingFormItems = [
|
||||||
@@ -83,12 +82,12 @@ class GitLab extends AppSource {
|
|||||||
}
|
}
|
||||||
var json = jsonDecode(res.body) as List<dynamic>;
|
var json = jsonDecode(res.body) as List<dynamic>;
|
||||||
Map<String, List<String>> results = {};
|
Map<String, List<String>> results = {};
|
||||||
json.forEach((element) {
|
for (var element in json) {
|
||||||
results['https://$host/${element['path_with_namespace']}'] = [
|
results['https://$host/${element['path_with_namespace']}'] = [
|
||||||
element['name_with_namespace'],
|
element['name_with_namespace'],
|
||||||
element['description'] ?? tr('noDescription')
|
element['description'] ?? tr('noDescription')
|
||||||
];
|
];
|
||||||
});
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -85,10 +85,6 @@ bool _isNumeric(String s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class HTML extends AppSource {
|
class HTML extends AppSource {
|
||||||
HTML() {
|
|
||||||
overrideEligible = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
// TODO: implement requestHeaders choice, hardcoded for now
|
// TODO: implement requestHeaders choice, hardcoded for now
|
||||||
Map<String, String>? get requestHeaders => {
|
Map<String, String>? get requestHeaders => {
|
||||||
|
@@ -1,4 +1,3 @@
|
|||||||
import 'package:http/http.dart';
|
|
||||||
import 'package:obtainium/app_sources/fdroid.dart';
|
import 'package:obtainium/app_sources/fdroid.dart';
|
||||||
import 'package:obtainium/custom_errors.dart';
|
import 'package:obtainium/custom_errors.dart';
|
||||||
import 'package:obtainium/providers/source_provider.dart';
|
import 'package:obtainium/providers/source_provider.dart';
|
||||||
|
@@ -6,11 +6,9 @@ import 'package:obtainium/providers/source_provider.dart';
|
|||||||
|
|
||||||
class Jenkins extends AppSource {
|
class Jenkins extends AppSource {
|
||||||
Jenkins() {
|
Jenkins() {
|
||||||
overrideEligible = true;
|
|
||||||
overrideVersionDetectionFormDefault('releaseDateAsVersion', true);
|
overrideVersionDetectionFormDefault('releaseDateAsVersion', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
String trimJobUrl(String url) {
|
String trimJobUrl(String url) {
|
||||||
RegExp standardUrlRegEx = RegExp('.*/job/[^/]+');
|
RegExp standardUrlRegEx = RegExp('.*/job/[^/]+');
|
||||||
RegExpMatch? match = standardUrlRegEx.firstMatch(url);
|
RegExpMatch? match = standardUrlRegEx.firstMatch(url);
|
||||||
|
@@ -6,7 +6,6 @@ import 'package:obtainium/providers/source_provider.dart';
|
|||||||
class SourceForge extends AppSource {
|
class SourceForge extends AppSource {
|
||||||
SourceForge() {
|
SourceForge() {
|
||||||
host = 'sourceforge.net';
|
host = 'sourceforge.net';
|
||||||
overrideEligible = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import 'package:html/parser.dart';
|
import 'package:html/parser.dart';
|
||||||
import 'package:http/http.dart';
|
import 'package:http/http.dart';
|
||||||
import 'package:obtainium/app_sources/github.dart';
|
|
||||||
import 'package:obtainium/app_sources/html.dart';
|
import 'package:obtainium/app_sources/html.dart';
|
||||||
import 'package:obtainium/custom_errors.dart';
|
import 'package:obtainium/custom_errors.dart';
|
||||||
import 'package:obtainium/providers/source_provider.dart';
|
import 'package:obtainium/providers/source_provider.dart';
|
||||||
@@ -10,7 +9,6 @@ import 'package:easy_localization/easy_localization.dart';
|
|||||||
class SourceHut extends AppSource {
|
class SourceHut extends AppSource {
|
||||||
SourceHut() {
|
SourceHut() {
|
||||||
host = 'git.sr.ht';
|
host = 'git.sr.ht';
|
||||||
overrideEligible = true;
|
|
||||||
|
|
||||||
additionalSourceAppSpecificSettingFormItems = [
|
additionalSourceAppSpecificSettingFormItems = [
|
||||||
[
|
[
|
||||||
@@ -58,11 +56,19 @@ class SourceHut extends AppSource {
|
|||||||
throw NoVersionError();
|
throw NoVersionError();
|
||||||
}
|
}
|
||||||
String? releaseDateString = entry.querySelector('pubDate')?.innerHtml;
|
String? releaseDateString = entry.querySelector('pubDate')?.innerHtml;
|
||||||
var link = entry.querySelector('link');
|
|
||||||
String releasePage = '$standardUrl/refs/$version';
|
String releasePage = '$standardUrl/refs/$version';
|
||||||
DateTime? releaseDate = releaseDateString != null
|
DateTime? releaseDate;
|
||||||
? DateFormat('EEE, dd MMM yyyy HH:mm:ss Z').parse(releaseDateString)
|
try {
|
||||||
: null;
|
releaseDate = releaseDateString != null
|
||||||
|
? DateFormat('E, dd MMM yyyy HH:mm:ss Z').parse(releaseDateString)
|
||||||
|
: null;
|
||||||
|
releaseDate = releaseDateString != null
|
||||||
|
? DateFormat('EEE, dd MMM yyyy HH:mm:ss Z')
|
||||||
|
.parse(releaseDateString)
|
||||||
|
: null;
|
||||||
|
} catch (e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
var res2 = await sourceRequest(releasePage);
|
var res2 = await sourceRequest(releasePage);
|
||||||
List<MapEntry<String, String>> apkUrls = [];
|
List<MapEntry<String, String>> apkUrls = [];
|
||||||
if (res2.statusCode == 200) {
|
if (res2.statusCode == 200) {
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import 'package:html/parser.dart';
|
import 'package:html/parser.dart';
|
||||||
import 'package:http/http.dart';
|
import 'package:http/http.dart';
|
||||||
import 'package:obtainium/app_sources/html.dart';
|
|
||||||
import 'package:obtainium/custom_errors.dart';
|
import 'package:obtainium/custom_errors.dart';
|
||||||
import 'package:obtainium/providers/source_provider.dart';
|
import 'package:obtainium/providers/source_provider.dart';
|
||||||
|
|
||||||
|
@@ -21,7 +21,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.13.3';
|
const String currentVersion = '0.13.4';
|
||||||
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
|
||||||
|
|
||||||
|
@@ -321,10 +321,8 @@ class _AddAppPageState extends State<AddAppPage> {
|
|||||||
'overrideSource',
|
'overrideSource',
|
||||||
defaultValue: HTML().runtimeType.toString(),
|
defaultValue: HTML().runtimeType.toString(),
|
||||||
[
|
[
|
||||||
...sourceProvider.sources
|
...sourceProvider.sources.map(
|
||||||
.where((s) => s.overrideEligible)
|
(s) => MapEntry(s.runtimeType.toString(), s.name))
|
||||||
.map((s) =>
|
|
||||||
MapEntry(s.runtimeType.toString(), s.name))
|
|
||||||
],
|
],
|
||||||
label: tr('overrideSource'))
|
label: tr('overrideSource'))
|
||||||
]
|
]
|
||||||
|
@@ -32,6 +32,7 @@ class _AppPageState extends State<AppPage> {
|
|||||||
getUpdate(String id) {
|
getUpdate(String id) {
|
||||||
appsProvider.checkUpdate(id).catchError((e) {
|
appsProvider.checkUpdate(id).catchError((e) {
|
||||||
showError(e, context);
|
showError(e, context);
|
||||||
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -61,8 +61,6 @@ class AppsPageState extends State<AppsPage> {
|
|||||||
var settingsProvider = context.watch<SettingsProvider>();
|
var settingsProvider = context.watch<SettingsProvider>();
|
||||||
var sourceProvider = SourceProvider();
|
var sourceProvider = SourceProvider();
|
||||||
var listedApps = appsProvider.getAppValues().toList();
|
var listedApps = appsProvider.getAppValues().toList();
|
||||||
var currentFilterIsUpdatesOnly =
|
|
||||||
filter.isIdenticalTo(updatesOnlyFilter, settingsProvider);
|
|
||||||
|
|
||||||
refresh() {
|
refresh() {
|
||||||
HapticFeedback.lightImpact();
|
HapticFeedback.lightImpact();
|
||||||
@@ -71,6 +69,7 @@ class AppsPageState extends State<AppsPage> {
|
|||||||
});
|
});
|
||||||
return appsProvider.checkUpdates().catchError((e) {
|
return appsProvider.checkUpdates().catchError((e) {
|
||||||
showError(e, context);
|
showError(e, context);
|
||||||
|
return <App>[];
|
||||||
}).whenComplete(() {
|
}).whenComplete(() {
|
||||||
setState(() {
|
setState(() {
|
||||||
refreshingSince = null;
|
refreshingSince = null;
|
||||||
@@ -128,6 +127,11 @@ class AppsPageState extends State<AppsPage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (filter.idFilter.isNotEmpty) {
|
||||||
|
if (!app.app.id.contains(filter.idFilter)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (filter.categoryFilter.isNotEmpty &&
|
if (filter.categoryFilter.isNotEmpty &&
|
||||||
filter.categoryFilter
|
filter.categoryFilter
|
||||||
.intersection(app.app.categories.toSet())
|
.intersection(app.app.categories.toSet())
|
||||||
@@ -379,6 +383,7 @@ class AppsPageState extends State<AppsPage> {
|
|||||||
[listedApps[appIndex].app.id],
|
[listedApps[appIndex].app.id],
|
||||||
globalNavigatorKey.currentContext).catchError((e) {
|
globalNavigatorKey.currentContext).catchError((e) {
|
||||||
showError(e, context);
|
showError(e, context);
|
||||||
|
return <String>[];
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
@@ -441,37 +446,35 @@ class AppsPageState extends State<AppsPage> {
|
|||||||
width: 10,
|
width: 10,
|
||||||
)
|
)
|
||||||
: const SizedBox.shrink(),
|
: const SizedBox.shrink(),
|
||||||
Column(
|
GestureDetector(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
onTap: showChangesFn,
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
child: Column(
|
||||||
children: [
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
Row(mainAxisSize: MainAxisSize.min, children: [
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
Container(
|
|
||||||
constraints: BoxConstraints(
|
|
||||||
maxWidth: MediaQuery.of(context).size.width / 4),
|
|
||||||
child: Text(
|
|
||||||
getVersionText(index),
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
textAlign: TextAlign.end,
|
|
||||||
)),
|
|
||||||
]),
|
|
||||||
Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
children: [
|
||||||
GestureDetector(
|
Row(mainAxisSize: MainAxisSize.min, children: [
|
||||||
onTap: showChangesFn,
|
Container(
|
||||||
child: Text(
|
constraints: BoxConstraints(
|
||||||
|
maxWidth: MediaQuery.of(context).size.width / 4),
|
||||||
|
child: Text(getVersionText(index),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
textAlign: TextAlign.end)),
|
||||||
|
]),
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
getChangesButtonString(index, showChangesFn != null),
|
getChangesButtonString(index, showChangesFn != null),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontStyle: FontStyle.italic,
|
fontStyle: FontStyle.italic,
|
||||||
decoration: showChangesFn != null
|
decoration: showChangesFn != null
|
||||||
? TextDecoration.underline
|
? TextDecoration.underline
|
||||||
: TextDecoration.none),
|
: TextDecoration.none),
|
||||||
))
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
))
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -540,15 +543,20 @@ class AppsPageState extends State<AppsPage> {
|
|||||||
: FontWeight.normal)),
|
: FontWeight.normal)),
|
||||||
trailing: listedApps[index].downloadProgress != null
|
trailing: listedApps[index].downloadProgress != null
|
||||||
? SizedBox(
|
? SizedBox(
|
||||||
width: 110,
|
width: 90,
|
||||||
child: Text(tr('percentProgress', args: [
|
child: Text(
|
||||||
listedApps[index].downloadProgress! >= 0
|
listedApps[index].downloadProgress! >= 0
|
||||||
? listedApps[index]
|
? tr('percentProgress', args: [
|
||||||
.downloadProgress!
|
listedApps[index]
|
||||||
.toInt()
|
.downloadProgress!
|
||||||
.toString()
|
.toInt()
|
||||||
: tr('pleaseWait')
|
.toString()
|
||||||
])))
|
])
|
||||||
|
: tr('pleaseWait'),
|
||||||
|
textAlign: (listedApps[index].downloadProgress! >= 0)
|
||||||
|
? TextAlign.start
|
||||||
|
: TextAlign.end,
|
||||||
|
))
|
||||||
: trailingRow,
|
: trailingRow,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (selectedAppIds.isNotEmpty) {
|
if (selectedAppIds.isNotEmpty) {
|
||||||
@@ -681,6 +689,7 @@ class AppsPageState extends State<AppsPage> {
|
|||||||
settingsProvider: settingsProvider)
|
settingsProvider: settingsProvider)
|
||||||
.catchError((e) {
|
.catchError((e) {
|
||||||
showError(e, context);
|
showError(e, context);
|
||||||
|
return <String>[];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -876,44 +885,41 @@ class AppsPageState extends State<AppsPage> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getMainBottomButtonsRow() {
|
getMainBottomButtons() {
|
||||||
return Row(
|
return [
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
IconButton(
|
||||||
children: [
|
|
||||||
IconButton(
|
|
||||||
visualDensity: VisualDensity.compact,
|
visualDensity: VisualDensity.compact,
|
||||||
onPressed: selectedAppIds.isEmpty
|
onPressed: getMassObtainFunction(),
|
||||||
? null
|
tooltip: selectedAppIds.isEmpty
|
||||||
: () {
|
? tr('installUpdateApps')
|
||||||
appsProvider.removeAppsWithModal(
|
: tr('installUpdateSelectedApps'),
|
||||||
context, selectedApps.toList());
|
icon: const Icon(
|
||||||
},
|
Icons.file_download_outlined,
|
||||||
tooltip: tr('removeSelectedApps'),
|
)),
|
||||||
icon: const Icon(Icons.delete_outline_outlined),
|
IconButton(
|
||||||
),
|
visualDensity: VisualDensity.compact,
|
||||||
IconButton(
|
onPressed: selectedAppIds.isEmpty
|
||||||
visualDensity: VisualDensity.compact,
|
? null
|
||||||
onPressed: getMassObtainFunction(),
|
: () {
|
||||||
tooltip: selectedAppIds.isEmpty
|
appsProvider.removeAppsWithModal(
|
||||||
? tr('installUpdateApps')
|
context, selectedApps.toList());
|
||||||
: tr('installUpdateSelectedApps'),
|
},
|
||||||
icon: const Icon(
|
tooltip: tr('removeSelectedApps'),
|
||||||
Icons.file_download_outlined,
|
icon: const Icon(Icons.delete_outline_outlined),
|
||||||
)),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
visualDensity: VisualDensity.compact,
|
visualDensity: VisualDensity.compact,
|
||||||
onPressed: selectedAppIds.isEmpty ? null : launchCategorizeDialog(),
|
onPressed: selectedAppIds.isEmpty ? null : launchCategorizeDialog(),
|
||||||
tooltip: tr('categorize'),
|
tooltip: tr('categorize'),
|
||||||
icon: const Icon(Icons.category_outlined),
|
icon: const Icon(Icons.category_outlined),
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
visualDensity: VisualDensity.compact,
|
visualDensity: VisualDensity.compact,
|
||||||
onPressed: selectedAppIds.isEmpty ? null : showMoreOptionsDialog,
|
onPressed: selectedAppIds.isEmpty ? null : showMoreOptionsDialog,
|
||||||
tooltip: tr('more'),
|
tooltip: tr('more'),
|
||||||
icon: const Icon(Icons.more_horiz),
|
icon: const Icon(Icons.more_horiz),
|
||||||
),
|
),
|
||||||
],
|
];
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
showFilterDialog() async {
|
showFilterDialog() async {
|
||||||
@@ -935,6 +941,12 @@ class AppsPageState extends State<AppsPage> {
|
|||||||
required: false,
|
required: false,
|
||||||
defaultValue: vals['author'])
|
defaultValue: vals['author'])
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
GeneratedFormTextField('appId',
|
||||||
|
label: tr('appId'),
|
||||||
|
required: false,
|
||||||
|
defaultValue: vals['appId'])
|
||||||
|
],
|
||||||
[
|
[
|
||||||
GeneratedFormSwitch('upToDateApps',
|
GeneratedFormSwitch('upToDateApps',
|
||||||
label: tr('upToDateApps'),
|
label: tr('upToDateApps'),
|
||||||
@@ -980,50 +992,33 @@ class AppsPageState extends State<AppsPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getFilterButtonsRow() {
|
getFilterButtonsRow() {
|
||||||
|
var isFilterOff = filter.isIdenticalTo(neutralFilter, settingsProvider);
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
getSelectAllButton(),
|
getSelectAllButton(),
|
||||||
|
IconButton(
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
style: const ButtonStyle(visualDensity: VisualDensity.compact),
|
||||||
|
tooltip: isFilterOff ? tr('filter') : tr('filterActive'),
|
||||||
|
onPressed: isFilterOff
|
||||||
|
? showFilterDialog
|
||||||
|
: () {
|
||||||
|
setState(() {
|
||||||
|
filter = AppsFilter();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
icon: Icon(isFilterOff
|
||||||
|
? Icons.filter_list_rounded
|
||||||
|
: Icons.filter_list_off_rounded)),
|
||||||
|
const SizedBox(
|
||||||
|
width: 10,
|
||||||
|
),
|
||||||
const VerticalDivider(),
|
const VerticalDivider(),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: SingleChildScrollView(
|
child: Row(
|
||||||
scrollDirection: Axis.horizontal,
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
child: getMainBottomButtonsRow())),
|
children: getMainBottomButtons(),
|
||||||
const VerticalDivider(),
|
)),
|
||||||
IconButton(
|
|
||||||
visualDensity: VisualDensity.compact,
|
|
||||||
onPressed: () {
|
|
||||||
setState(() {
|
|
||||||
if (currentFilterIsUpdatesOnly) {
|
|
||||||
filter = AppsFilter();
|
|
||||||
} else {
|
|
||||||
filter = updatesOnlyFilter;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
tooltip: currentFilterIsUpdatesOnly
|
|
||||||
? tr('removeOutdatedFilter')
|
|
||||||
: tr('showOutdatedOnly'),
|
|
||||||
icon: Icon(
|
|
||||||
currentFilterIsUpdatesOnly
|
|
||||||
? Icons.update_disabled_rounded
|
|
||||||
: Icons.update_rounded,
|
|
||||||
color: Theme.of(context).colorScheme.primary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
TextButton.icon(
|
|
||||||
style: const ButtonStyle(visualDensity: VisualDensity.compact),
|
|
||||||
label: Text(
|
|
||||||
filter.isIdenticalTo(neutralFilter, settingsProvider)
|
|
||||||
? tr('filter')
|
|
||||||
: tr('filterActive'),
|
|
||||||
style: TextStyle(
|
|
||||||
fontWeight:
|
|
||||||
filter.isIdenticalTo(neutralFilter, settingsProvider)
|
|
||||||
? FontWeight.normal
|
|
||||||
: FontWeight.bold),
|
|
||||||
),
|
|
||||||
onPressed: showFilterDialog,
|
|
||||||
icon: const Icon(Icons.filter_list_rounded))
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1066,6 +1061,7 @@ class AppsPageState extends State<AppsPage> {
|
|||||||
class AppsFilter {
|
class AppsFilter {
|
||||||
late String nameFilter;
|
late String nameFilter;
|
||||||
late String authorFilter;
|
late String authorFilter;
|
||||||
|
late String idFilter;
|
||||||
late bool includeUptodate;
|
late bool includeUptodate;
|
||||||
late bool includeNonInstalled;
|
late bool includeNonInstalled;
|
||||||
late Set<String> categoryFilter;
|
late Set<String> categoryFilter;
|
||||||
@@ -1074,6 +1070,7 @@ class AppsFilter {
|
|||||||
AppsFilter(
|
AppsFilter(
|
||||||
{this.nameFilter = '',
|
{this.nameFilter = '',
|
||||||
this.authorFilter = '',
|
this.authorFilter = '',
|
||||||
|
this.idFilter = '',
|
||||||
this.includeUptodate = true,
|
this.includeUptodate = true,
|
||||||
this.includeNonInstalled = true,
|
this.includeNonInstalled = true,
|
||||||
this.categoryFilter = const {},
|
this.categoryFilter = const {},
|
||||||
@@ -1083,6 +1080,7 @@ class AppsFilter {
|
|||||||
return {
|
return {
|
||||||
'appName': nameFilter,
|
'appName': nameFilter,
|
||||||
'author': authorFilter,
|
'author': authorFilter,
|
||||||
|
'appId': idFilter,
|
||||||
'upToDateApps': includeUptodate,
|
'upToDateApps': includeUptodate,
|
||||||
'nonInstalledApps': includeNonInstalled,
|
'nonInstalledApps': includeNonInstalled,
|
||||||
'sourceFilter': sourceFilter
|
'sourceFilter': sourceFilter
|
||||||
@@ -1092,6 +1090,7 @@ class AppsFilter {
|
|||||||
setFormValuesFromMap(Map<String, dynamic> values) {
|
setFormValuesFromMap(Map<String, dynamic> values) {
|
||||||
nameFilter = values['appName']!;
|
nameFilter = values['appName']!;
|
||||||
authorFilter = values['author']!;
|
authorFilter = values['author']!;
|
||||||
|
idFilter = values['appId']!;
|
||||||
includeUptodate = values['upToDateApps'];
|
includeUptodate = values['upToDateApps'];
|
||||||
includeNonInstalled = values['nonInstalledApps'];
|
includeNonInstalled = values['nonInstalledApps'];
|
||||||
sourceFilter = values['sourceFilter'];
|
sourceFilter = values['sourceFilter'];
|
||||||
@@ -1100,6 +1099,7 @@ class AppsFilter {
|
|||||||
bool isIdenticalTo(AppsFilter other, SettingsProvider settingsProvider) =>
|
bool isIdenticalTo(AppsFilter other, SettingsProvider settingsProvider) =>
|
||||||
authorFilter.trim() == other.authorFilter.trim() &&
|
authorFilter.trim() == other.authorFilter.trim() &&
|
||||||
nameFilter.trim() == other.nameFilter.trim() &&
|
nameFilter.trim() == other.nameFilter.trim() &&
|
||||||
|
idFilter.trim() == other.idFilter.trim() &&
|
||||||
includeUptodate == other.includeUptodate &&
|
includeUptodate == other.includeUptodate &&
|
||||||
includeNonInstalled == other.includeNonInstalled &&
|
includeNonInstalled == other.includeNonInstalled &&
|
||||||
settingsProvider.setEqual(categoryFilter, other.categoryFilter) &&
|
settingsProvider.setEqual(categoryFilter, other.categoryFilter) &&
|
||||||
|
@@ -323,8 +323,8 @@ class _ImportExportPageState extends State<ImportExportPage> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
if (importInProgress)
|
if (importInProgress)
|
||||||
Column(
|
const Column(
|
||||||
children: const [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 14,
|
height: 14,
|
||||||
),
|
),
|
||||||
|
@@ -7,7 +7,6 @@ import 'package:device_info_plus/device_info_plus.dart';
|
|||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:html/dom.dart';
|
import 'package:html/dom.dart';
|
||||||
import 'package:http/http.dart';
|
import 'package:http/http.dart';
|
||||||
import 'package:obtainium/app_sources/apkcombo.dart';
|
|
||||||
import 'package:obtainium/app_sources/apkmirror.dart';
|
import 'package:obtainium/app_sources/apkmirror.dart';
|
||||||
import 'package:obtainium/app_sources/apkpure.dart';
|
import 'package:obtainium/app_sources/apkpure.dart';
|
||||||
import 'package:obtainium/app_sources/codeberg.dart';
|
import 'package:obtainium/app_sources/codeberg.dart';
|
||||||
@@ -318,7 +317,6 @@ abstract class AppSource {
|
|||||||
late String name;
|
late String name;
|
||||||
bool enforceTrackOnly = false;
|
bool enforceTrackOnly = false;
|
||||||
bool changeLogIfAnyIsMarkDown = true;
|
bool changeLogIfAnyIsMarkDown = true;
|
||||||
bool overrideEligible = false;
|
|
||||||
|
|
||||||
AppSource() {
|
AppSource() {
|
||||||
name = runtimeType.toString();
|
name = runtimeType.toString();
|
||||||
|
@@ -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.13.3+167 # When changing this, update the tag in main() accordingly
|
version: 0.13.4+168 # When changing this, update the tag in main() accordingly
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=2.18.2 <3.0.0'
|
sdk: '>=2.18.2 <3.0.0'
|
||||||
|
Reference in New Issue
Block a user