mirror of
https://github.com/ImranR98/Obtainium.git
synced 2025-07-18 07:36:43 +02:00
Compare commits
11 Commits
v0.8.3-bet
...
v0.8.7-bet
Author | SHA1 | Date | |
---|---|---|---|
c4ba1e9dbc | |||
49862ad2a6 | |||
1b892f4e0d | |||
a4555f07f9 | |||
73fbdd84f0 | |||
a1518480db | |||
fd3ee02e52 | |||
609366675d | |||
fbff498ae1 | |||
bb4e470760 | |||
15183c3a95 |
@ -206,11 +206,11 @@
|
|||||||
"other": "Cleared {n} logs (before = {before}, after = {after})"
|
"other": "Cleared {n} logs (before = {before}, after = {after})"
|
||||||
},
|
},
|
||||||
"xAndNMoreUpdatesAvailable": {
|
"xAndNMoreUpdatesAvailable": {
|
||||||
"one": "{} and {} more app have updated.",
|
"one": "{} and 1 more app have updates.",
|
||||||
"other": "{} and {} more apps have updates."
|
"other": "{} and {} more apps have updates."
|
||||||
},
|
},
|
||||||
"xAndNMoreUpdatesInstalled": {
|
"xAndNMoreUpdatesInstalled": {
|
||||||
"one": "{} and {} more app were updated.",
|
"one": "{} and 1 more app were updated.",
|
||||||
"other": "{} and {} more apps were updated."
|
"other": "{} and {} more apps were updated."
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -16,20 +16,52 @@ import 'package:dynamic_color/dynamic_color.dart';
|
|||||||
import 'package:device_info_plus/device_info_plus.dart';
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
import 'package:android_alarm_manager_plus/android_alarm_manager_plus.dart';
|
import 'package:android_alarm_manager_plus/android_alarm_manager_plus.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
// ignore: implementation_imports
|
||||||
|
import 'package:easy_localization/src/easy_localization_controller.dart';
|
||||||
|
// ignore: implementation_imports
|
||||||
|
import 'package:easy_localization/src/localization.dart';
|
||||||
|
|
||||||
const String currentVersion = '0.8.3';
|
const String currentVersion = '0.8.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
|
||||||
|
|
||||||
const int bgUpdateCheckAlarmId = 666;
|
const int bgUpdateCheckAlarmId = 666;
|
||||||
|
|
||||||
|
const supportedLocales = [Locale('en')];
|
||||||
|
const fallbackLocale = Locale('en');
|
||||||
|
const localeDir = 'assets/translations';
|
||||||
|
|
||||||
|
Future<void> loadTranslations() async {
|
||||||
|
// See easy_localization/issues/210
|
||||||
|
await EasyLocalizationController.initEasyLocation();
|
||||||
|
final controller = EasyLocalizationController(
|
||||||
|
saveLocale: true,
|
||||||
|
fallbackLocale: fallbackLocale,
|
||||||
|
supportedLocales: supportedLocales,
|
||||||
|
assetLoader: const RootBundleAssetLoader(),
|
||||||
|
useOnlyLangCode: false,
|
||||||
|
useFallbackTranslations: true,
|
||||||
|
path: localeDir,
|
||||||
|
onLoadError: (FlutterError e) {
|
||||||
|
throw e;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
await controller.loadTranslations();
|
||||||
|
Localization.load(controller.locale,
|
||||||
|
translations: controller.translations,
|
||||||
|
fallbackTranslations: controller.fallbackTranslations);
|
||||||
|
}
|
||||||
|
|
||||||
@pragma('vm:entry-point')
|
@pragma('vm:entry-point')
|
||||||
Future<void> bgUpdateCheck(int taskId, Map<String, dynamic>? params) async {
|
Future<void> bgUpdateCheck(int taskId, Map<String, dynamic>? params) async {
|
||||||
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
await EasyLocalization.ensureInitialized();
|
||||||
|
|
||||||
|
await loadTranslations();
|
||||||
|
|
||||||
LogsProvider logs = LogsProvider();
|
LogsProvider logs = LogsProvider();
|
||||||
logs.add(tr('startedBgUpdateTask'));
|
logs.add(tr('startedBgUpdateTask'));
|
||||||
int? ignoreAfterMicroseconds = params?['ignoreAfterMicroseconds'];
|
int? ignoreAfterMicroseconds = params?['ignoreAfterMicroseconds'];
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
|
||||||
await EasyLocalization.ensureInitialized();
|
|
||||||
await AndroidAlarmManager.initialize();
|
await AndroidAlarmManager.initialize();
|
||||||
DateTime? ignoreAfter = ignoreAfterMicroseconds != null
|
DateTime? ignoreAfter = ignoreAfterMicroseconds != null
|
||||||
? DateTime.fromMicrosecondsSinceEpoch(ignoreAfterMicroseconds)
|
? DateTime.fromMicrosecondsSinceEpoch(ignoreAfterMicroseconds)
|
||||||
@ -116,9 +148,9 @@ void main() async {
|
|||||||
Provider(create: (context) => LogsProvider())
|
Provider(create: (context) => LogsProvider())
|
||||||
],
|
],
|
||||||
child: EasyLocalization(
|
child: EasyLocalization(
|
||||||
supportedLocales: const [Locale('en')],
|
supportedLocales: supportedLocales,
|
||||||
path: 'assets/translations',
|
path: localeDir,
|
||||||
fallbackLocale: const Locale('en'),
|
fallbackLocale: fallbackLocale,
|
||||||
child: const Obtainium()),
|
child: const Obtainium()),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -162,7 +194,6 @@ class _ObtainiumState extends State<Obtainium> {
|
|||||||
['true'],
|
['true'],
|
||||||
null,
|
null,
|
||||||
false,
|
false,
|
||||||
false,
|
|
||||||
false)
|
false)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -141,9 +141,7 @@ class _AppPageState extends State<AppPage> {
|
|||||||
children: [
|
children: [
|
||||||
if (app?.app.installedVersion != null &&
|
if (app?.app.installedVersion != null &&
|
||||||
app?.app.trackOnly == false &&
|
app?.app.trackOnly == false &&
|
||||||
app?.app.installedVersion !=
|
app?.app.installedVersion != app?.app.latestVersion)
|
||||||
app?.app.latestVersion &&
|
|
||||||
app?.app.enhancedVersionDetection != true)
|
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: app?.downloadProgress != null
|
onPressed: app?.downloadProgress != null
|
||||||
? null
|
? null
|
||||||
|
@ -253,7 +253,9 @@ class AppsPageState extends State<AppsPage> {
|
|||||||
fontWeight: sortedApps[index].app.pinned
|
fontWeight: sortedApps[index].app.pinned
|
||||||
? FontWeight.bold
|
? FontWeight.bold
|
||||||
: FontWeight.normal)),
|
: FontWeight.normal)),
|
||||||
trailing: sortedApps[index].downloadProgress != null
|
trailing: SingleChildScrollView(
|
||||||
|
reverse: true,
|
||||||
|
child: sortedApps[index].downloadProgress != null
|
||||||
? Text(tr('percentProgress', args: [
|
? Text(tr('percentProgress', args: [
|
||||||
sortedApps[index]
|
sortedApps[index]
|
||||||
.downloadProgress
|
.downloadProgress
|
||||||
@ -265,14 +267,13 @@ class AppsPageState extends State<AppsPage> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
SingleChildScrollView(
|
SizedBox(
|
||||||
child: SizedBox(
|
width: 100,
|
||||||
width: 80,
|
|
||||||
child: Text(
|
child: Text(
|
||||||
'${sortedApps[index].app.installedVersion ?? tr('notInstalled')}${sortedApps[index].app.trackOnly == true ? ' ${tr('estimateInBrackets')}' : ''}',
|
'${sortedApps[index].app.installedVersion ?? tr('notInstalled')}${sortedApps[index].app.trackOnly == true ? ' ${tr('estimateInBrackets')}' : ''}',
|
||||||
overflow: TextOverflow.fade,
|
overflow: TextOverflow.fade,
|
||||||
textAlign: TextAlign.end,
|
textAlign: TextAlign.end,
|
||||||
))),
|
)),
|
||||||
sortedApps[index].app.installedVersion != null &&
|
sortedApps[index].app.installedVersion != null &&
|
||||||
sortedApps[index].app.installedVersion !=
|
sortedApps[index].app.installedVersion !=
|
||||||
sortedApps[index].app.latestVersion
|
sortedApps[index].app.latestVersion
|
||||||
@ -294,7 +295,7 @@ class AppsPageState extends State<AppsPage> {
|
|||||||
))
|
))
|
||||||
: const SizedBox(),
|
: const SizedBox(),
|
||||||
],
|
],
|
||||||
)),
|
))),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (selectedApps.isNotEmpty) {
|
if (selectedApps.isNotEmpty) {
|
||||||
toggleAppSelected(sortedApps[index].app);
|
toggleAppSelected(sortedApps[index].app);
|
||||||
@ -526,8 +527,8 @@ class AppsPageState extends State<AppsPage> {
|
|||||||
.selectionClick();
|
.selectionClick();
|
||||||
appsProvider
|
appsProvider
|
||||||
.saveApps(selectedApps.map((a) {
|
.saveApps(selectedApps.map((a) {
|
||||||
if (a.installedVersion != null &&
|
if (a.installedVersion !=
|
||||||
!a.enhancedVersionDetection) {
|
null) {
|
||||||
a.installedVersion = a.latestVersion;
|
a.installedVersion = a.latestVersion;
|
||||||
}
|
}
|
||||||
return a;
|
return a;
|
||||||
|
@ -9,6 +9,7 @@ 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:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
import 'package:install_plugin_v2/install_plugin_v2.dart';
|
import 'package:install_plugin_v2/install_plugin_v2.dart';
|
||||||
import 'package:installed_apps/app_info.dart';
|
import 'package:installed_apps/app_info.dart';
|
||||||
import 'package:installed_apps/installed_apps.dart';
|
import 'package:installed_apps/installed_apps.dart';
|
||||||
@ -400,9 +401,9 @@ class AppsProvider with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the App says it is installed but installedInfo is null, set it to not installed
|
// If the App says it is installed but installedInfo is null, set it to not installed
|
||||||
// If the App says is is not installed but installedInfo exists, set it to the real installed version
|
// If the App says is is not installed but installedInfo exists, try to set it to installed as latest version...
|
||||||
// If the internal version does not match the real one, sync them if the App supports enhanced version detection
|
// ...if the latestVersion seems to match the version in installedInfo (not guaranteed)
|
||||||
// Enhanced version detection will be true if the version extracted from source matches the standard version format
|
// If that fails, just set it to the actual version string (all we can do at that point)
|
||||||
// Don't save changes, just return the object if changes were made (else null)
|
// Don't save changes, just return the object if changes were made (else null)
|
||||||
// If in a background isolate, return null straight away as the required plugin won't work anyways
|
// If in a background isolate, return null straight away as the required plugin won't work anyways
|
||||||
App? getCorrectedInstallStatusAppIfPossible(App app, AppInfo? installedInfo) {
|
App? getCorrectedInstallStatusAppIfPossible(App app, AppInfo? installedInfo) {
|
||||||
@ -415,21 +416,29 @@ class AppsProvider with ChangeNotifier {
|
|||||||
!app.trackOnly) {
|
!app.trackOnly) {
|
||||||
app.installedVersion = null;
|
app.installedVersion = null;
|
||||||
modded = true;
|
modded = true;
|
||||||
} else if (installedInfo != null && app.installedVersion == null) {
|
}
|
||||||
if (app.enhancedVersionDetection) {
|
if (installedInfo != null && app.installedVersion == null) {
|
||||||
app.installedVersion = installedInfo.versionName;
|
if (app.latestVersion.characters
|
||||||
} else {
|
.where((p0) => [
|
||||||
if (app.latestVersion.contains(installedInfo.versionName!)) {
|
// TODO: Won't work for other charsets
|
||||||
|
'0',
|
||||||
|
'1',
|
||||||
|
'2',
|
||||||
|
'3',
|
||||||
|
'4',
|
||||||
|
'5',
|
||||||
|
'6',
|
||||||
|
'7',
|
||||||
|
'8',
|
||||||
|
'9',
|
||||||
|
'.'
|
||||||
|
].contains(p0))
|
||||||
|
.join('') ==
|
||||||
|
installedInfo.versionName) {
|
||||||
app.installedVersion = app.latestVersion;
|
app.installedVersion = app.latestVersion;
|
||||||
} else {
|
} else {
|
||||||
app.installedVersion = installedInfo.versionName;
|
app.installedVersion = installedInfo.versionName;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
modded = true;
|
|
||||||
} else if (installedInfo?.versionName != app.installedVersion &&
|
|
||||||
app.enhancedVersionDetection &&
|
|
||||||
!app.trackOnly) {
|
|
||||||
app.installedVersion = installedInfo?.versionName;
|
|
||||||
modded = true;
|
modded = true;
|
||||||
}
|
}
|
||||||
return modded ? app : null;
|
return modded ? app : null;
|
||||||
|
@ -84,7 +84,7 @@ class DownloadNotification extends ObtainiumNotification {
|
|||||||
'APP_DOWNLOADING',
|
'APP_DOWNLOADING',
|
||||||
'Downloading App',
|
'Downloading App',
|
||||||
'Notifies the user of the progress in downloading an App',
|
'Notifies the user of the progress in downloading an App',
|
||||||
Importance.defaultImportance,
|
Importance.low,
|
||||||
onlyAlertOnce: true) {
|
onlyAlertOnce: true) {
|
||||||
message = tr('percentProgress', args: [progPercent.toString()]);
|
message = tr('percentProgress', args: [progPercent.toString()]);
|
||||||
}
|
}
|
||||||
|
@ -27,15 +27,9 @@ class AppNames {
|
|||||||
|
|
||||||
class APKDetails {
|
class APKDetails {
|
||||||
late String version;
|
late String version;
|
||||||
late String versionFromSource;
|
|
||||||
late bool isStandardVersion;
|
|
||||||
late List<String> apkUrls;
|
late List<String> apkUrls;
|
||||||
|
|
||||||
APKDetails(this.versionFromSource, this.apkUrls) {
|
APKDetails(this.version, this.apkUrls);
|
||||||
var temp = extractStandardVersionName(versionFromSource);
|
|
||||||
this.isStandardVersion = temp != null;
|
|
||||||
this.version = temp ?? versionFromSource;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class App {
|
class App {
|
||||||
@ -51,7 +45,6 @@ class App {
|
|||||||
late DateTime? lastUpdateCheck;
|
late DateTime? lastUpdateCheck;
|
||||||
bool pinned = false;
|
bool pinned = false;
|
||||||
bool trackOnly = false;
|
bool trackOnly = false;
|
||||||
bool enhancedVersionDetection = false;
|
|
||||||
App(
|
App(
|
||||||
this.id,
|
this.id,
|
||||||
this.url,
|
this.url,
|
||||||
@ -64,8 +57,7 @@ class App {
|
|||||||
this.additionalData,
|
this.additionalData,
|
||||||
this.lastUpdateCheck,
|
this.lastUpdateCheck,
|
||||||
this.pinned,
|
this.pinned,
|
||||||
this.trackOnly,
|
this.trackOnly);
|
||||||
this.enhancedVersionDetection);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
@ -94,8 +86,7 @@ class App {
|
|||||||
? null
|
? null
|
||||||
: DateTime.fromMicrosecondsSinceEpoch(json['lastUpdateCheck']),
|
: DateTime.fromMicrosecondsSinceEpoch(json['lastUpdateCheck']),
|
||||||
json['pinned'] ?? false,
|
json['pinned'] ?? false,
|
||||||
json['trackOnly'] ?? false,
|
json['trackOnly'] ?? false);
|
||||||
json['enhancedVersionDetection'] ?? false);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
'id': id,
|
'id': id,
|
||||||
@ -109,8 +100,7 @@ class App {
|
|||||||
'additionalData': jsonEncode(additionalData),
|
'additionalData': jsonEncode(additionalData),
|
||||||
'lastUpdateCheck': lastUpdateCheck?.microsecondsSinceEpoch,
|
'lastUpdateCheck': lastUpdateCheck?.microsecondsSinceEpoch,
|
||||||
'pinned': pinned,
|
'pinned': pinned,
|
||||||
'trackOnly': trackOnly,
|
'trackOnly': trackOnly
|
||||||
'enhancedVersionDetection': enhancedVersionDetection
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,13 +190,6 @@ ObtainiumError getObtainiumHttpError(Response res) {
|
|||||||
tr('errorWithHttpStatusCode', args: [res.statusCode.toString()]));
|
tr('errorWithHttpStatusCode', args: [res.statusCode.toString()]));
|
||||||
}
|
}
|
||||||
|
|
||||||
String? extractStandardVersionName(String version, {bool strict = false}) {
|
|
||||||
var match = RegExp(
|
|
||||||
'${strict ? '^' : ''}[0-9]+(\\.[0-9]+)+(-(alpha|beta|ocs)([0-9]+|\\+[0-9]+)?)?${strict ? '\$' : ''}')
|
|
||||||
.firstMatch(version);
|
|
||||||
return match != null ? version.substring(match.start, match.end) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class MassAppUrlSource {
|
abstract class MassAppUrlSource {
|
||||||
late String name;
|
late String name;
|
||||||
late List<String> requiredArgs;
|
late List<String> requiredArgs;
|
||||||
@ -285,12 +268,6 @@ class SourceProvider {
|
|||||||
if (apk.apkUrls.isEmpty && !trackOnly) {
|
if (apk.apkUrls.isEmpty && !trackOnly) {
|
||||||
throw NoAPKError();
|
throw NoAPKError();
|
||||||
}
|
}
|
||||||
bool enhancedVersionDetection = apk.isStandardVersion &&
|
|
||||||
installedVersion != null &&
|
|
||||||
extractStandardVersionName(installedVersion, strict: true) != null;
|
|
||||||
if (!enhancedVersionDetection) {
|
|
||||||
apk.version = apk.versionFromSource;
|
|
||||||
}
|
|
||||||
String apkVersion = apk.version.replaceAll('/', '-');
|
String apkVersion = apk.version.replaceAll('/', '-');
|
||||||
return App(
|
return App(
|
||||||
id ??
|
id ??
|
||||||
@ -308,8 +285,7 @@ class SourceProvider {
|
|||||||
additionalData,
|
additionalData,
|
||||||
DateTime.now(),
|
DateTime.now(),
|
||||||
pinned,
|
pinned,
|
||||||
trackOnly,
|
trackOnly);
|
||||||
enhancedVersionDetection);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns errors in [results, errors] instead of throwing them
|
// Returns errors in [results, errors] instead of throwing them
|
||||||
|
@ -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.8.3+66 # When changing this, update the tag in main() accordingly
|
version: 0.8.7+70 # 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