This commit is contained in:
problematicconsumer
2023-12-01 12:56:24 +03:30
parent 9c165e178b
commit ed614988a2
181 changed files with 3092 additions and 2341 deletions

View File

@@ -0,0 +1,12 @@
import 'package:hiddify/core/http_client/http_client_provider.dart';
import 'package:hiddify/features/app_update/data/app_update_repository.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'app_update_data_providers.g.dart';
@Riverpod(keepAlive: true)
AppUpdateRepository appUpdateRepository(
AppUpdateRepositoryRef ref,
) {
return AppUpdateRepositoryImpl(dio: ref.watch(httpClientProvider));
}

View File

@@ -0,0 +1,55 @@
import 'package:dio/dio.dart';
import 'package:fpdart/fpdart.dart';
import 'package:hiddify/core/model/constants.dart';
import 'package:hiddify/core/model/environment.dart';
import 'package:hiddify/core/utils/exception_handler.dart';
import 'package:hiddify/features/app_update/data/github_release_parser.dart';
import 'package:hiddify/features/app_update/model/app_update_failure.dart';
import 'package:hiddify/features/app_update/model/remote_version_entity.dart';
import 'package:hiddify/utils/utils.dart';
abstract interface class AppUpdateRepository {
TaskEither<AppUpdateFailure, RemoteVersionEntity> getLatestVersion({
bool includePreReleases = false,
Release release = Release.general,
});
}
class AppUpdateRepositoryImpl
with ExceptionHandler, InfraLogger
implements AppUpdateRepository {
AppUpdateRepositoryImpl({required this.dio});
final Dio dio;
@override
TaskEither<AppUpdateFailure, RemoteVersionEntity> getLatestVersion({
bool includePreReleases = false,
Release release = Release.general,
}) {
return exceptionHandler(
() async {
if (!release.allowCustomUpdateChecker) {
throw Exception("custom update checkers are not supported");
}
final response = await dio.get<List>(Constants.githubReleasesApiUrl);
if (response.statusCode != 200 || response.data == null) {
loggy.warning("failed to fetch latest version info");
return left(const AppUpdateFailure.unexpected());
}
final releases = response.data!.map(
(e) => GithubReleaseParser.parse(e as Map<String, dynamic>),
);
late RemoteVersionEntity latest;
if (includePreReleases) {
latest = releases.first;
} else {
latest = releases.firstWhere((e) => e.preRelease == false);
}
return right(latest);
},
AppUpdateFailure.unexpected,
);
}
}

View File

@@ -0,0 +1,36 @@
import 'package:dartx/dartx.dart';
import 'package:hiddify/core/model/environment.dart';
import 'package:hiddify/features/app_update/model/remote_version_entity.dart';
abstract class GithubReleaseParser {
static RemoteVersionEntity parse(Map<String, dynamic> json) {
final fullTag = json['tag_name'] as String;
final fullVersion = fullTag.removePrefix("v").split("-").first.split("+");
var version = fullVersion.first;
var buildNumber = fullVersion.elementAtOrElse(1, (index) => "");
var flavor = Environment.prod;
for (final env in Environment.values) {
final suffix = ".${env.name}";
if (version.endsWith(suffix)) {
version = version.removeSuffix(suffix);
flavor = env;
break;
} else if (buildNumber.endsWith(suffix)) {
buildNumber = buildNumber.removeSuffix(suffix);
flavor = env;
break;
}
}
final preRelease = json["prerelease"] as bool;
final publishedAt = DateTime.parse(json["published_at"] as String);
return RemoteVersionEntity(
version: version,
buildNumber: buildNumber,
releaseTag: fullTag,
preRelease: preRelease,
url: json["html_url"] as String,
publishedAt: publishedAt,
flavor: flavor,
);
}
}