Initial commit

This commit is contained in:
admin1
2026-07-14 11:11:36 +08:00
commit 656499cf94
604 changed files with 119518 additions and 0 deletions
@@ -0,0 +1,108 @@
import 'dart:convert';
import 'package:dio/dio.dart';
import '../../contracts/app_update.dart';
import '../emby_api/emby_headers.dart';
const String kSmPlayerReleaseOwner = 'YOUR_GITHUB_OWNER';
const String kSmPlayerReleaseRepo = 'YOUR_GITHUB_REPO';
const String kSmPlayerManifestTag = '_manifests';
class GithubReleasesClient {
static Uri _platformManifestUri(String platformKey) => Uri.parse(
'https://github.com/$kSmPlayerReleaseOwner/$kSmPlayerReleaseRepo'
'/releases/download/$kSmPlayerManifestTag/latest-$platformKey.json',
);
final Dio _dio;
GithubReleasesClient({Dio? dio})
: _dio =
dio ??
Dio(
BaseOptions(
connectTimeout: const Duration(seconds: 8),
receiveTimeout: const Duration(seconds: 15),
responseType: ResponseType.json,
headers: {
'Accept': 'application/json',
'User-Agent': EmbyRequestHeaders.userAgent,
},
),
);
Future<AppUpdateInfo> fetchLatestRelease({
required String platformKey,
}) async {
final response = await _dio.get<dynamic>(
_platformManifestUri(platformKey).toString(),
);
final data = response.data;
final Map<String, dynamic> json;
if (data is Map<String, dynamic>) {
json = data;
} else if (data is String) {
final decoded = jsonDecode(data);
if (decoded is! Map<String, dynamic>) {
throw const FormatException('GitHub release JSON root is not a map');
}
json = decoded;
} else {
throw FormatException(
'GitHub release JSON has unexpected type: ${data.runtimeType}',
);
}
final platformAssets = <String, AppUpdateAsset>{};
final rawPlatforms = json['platforms'];
if (rawPlatforms is Map) {
rawPlatforms.forEach((key, value) {
if (value is Map<String, dynamic>) {
final asset = AppUpdateAsset.fromJson(value);
if (asset.name.isNotEmpty) {
platformAssets[key.toString()] = asset;
}
}
});
}
final assets = platformAssets.values.toList(growable: true);
final rawAssets = json['assets'];
if (rawAssets is List) {
assets.addAll(
rawAssets
.whereType<Map<String, dynamic>>()
.map(AppUpdateAsset.fromJson)
.where((asset) => asset.name.isNotEmpty),
);
}
final htmlUrl = _firstNonEmpty([
json['html_url'],
json['htmlUrl'],
json['downloadUrl'],
_latestReleasePageUrl,
]);
return AppUpdateInfo(
version: _firstNonEmpty([json['version'], json['tag_name']]),
releaseNotes: _firstNonEmpty([json['notes'], json['body']]),
htmlUrl: Uri.tryParse(htmlUrl) ?? Uri(),
assets: assets,
platformAssets: platformAssets,
);
}
static String get _latestReleasePageUrl =>
'https://github.com/$kSmPlayerReleaseOwner/$kSmPlayerReleaseRepo/releases/latest';
static String _firstNonEmpty(Iterable<Object?> values) {
return values
.map((value) => value?.toString().trim() ?? '')
.firstWhere((value) => value.isNotEmpty, orElse: () => '');
}
}