spotube/lib/models/playback/track_sources.dart
Kingkor Roy Tirtho cdc64e4bb0 feat: Add repository and plugin API version fields to metadata plugins
- Updated database schema to include `repository` and `pluginApiVersion` columns in the `MetadataPluginsTable`.
- Modified `PluginConfiguration` model to include new fields for `repository` and `pluginApiVersion`.
- Enhanced JSON serialization and deserialization for the new fields in `PluginConfiguration`.
- Refactored `SettingsMetadataProviderPage` to display installed plugins with their repository information.
- Created new components `MetadataInstalledPluginItem` and `MetadataPluginRepositoryItem` for better UI representation of plugins.
- Updated plugin installation logic to handle new fields and display relevant information.
- Bumped `youtube_explode_dart` dependency version to `2.5.1`.
2025-07-18 15:55:28 +06:00

109 lines
3.2 KiB
Dart

import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:spotube/models/database/database.dart';
import 'package:spotube/models/metadata/metadata.dart';
import 'package:spotube/services/audio_player/audio_player.dart';
import 'package:spotube/services/sourced_track/enums.dart';
part 'track_sources.freezed.dart';
part 'track_sources.g.dart';
@freezed
class TrackSourceQuery with _$TrackSourceQuery {
TrackSourceQuery._();
factory TrackSourceQuery({
required String id,
required String title,
required List<String> artists,
required String album,
required int durationMs,
required String isrc,
required bool explicit,
}) = _TrackSourceQuery;
factory TrackSourceQuery.fromJson(Map<String, dynamic> json) =>
_$TrackSourceQueryFromJson(json);
factory TrackSourceQuery.fromTrack(SpotubeFullTrackObject track) {
return TrackSourceQuery(
id: track.id,
title: track.name,
artists: track.artists.map((e) => e.name).toList(),
album: track.album.name,
durationMs: track.durationMs,
isrc: track.isrc,
explicit: track.explicit,
);
}
/// Parses [SpotubeMedia]'s [uri] property to create a [TrackSourceQuery].
factory TrackSourceQuery.parseUri(String url) {
final uri = Uri.parse(url);
return TrackSourceQuery(
id: uri.pathSegments.last,
title: uri.queryParameters['title'] ?? '',
artists: uri.queryParameters['artists']?.split(',') ?? [],
album: uri.queryParameters['album'] ?? '',
durationMs: int.tryParse(uri.queryParameters['durationMs'] ?? '0') ?? 0,
isrc: uri.queryParameters['isrc'] ?? '',
explicit: uri.queryParameters['explicit']?.toLowerCase() == 'true',
);
}
String queryString() {
return toJson()
.entries
.map((e) =>
"${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value is List<String> ? e.value.join(",") : e.value.toString())}")
.join("&");
}
}
@freezed
class TrackSourceInfo with _$TrackSourceInfo {
factory TrackSourceInfo({
required String id,
required String title,
required String artists,
required String thumbnail,
required String pageUrl,
required int durationMs,
}) = _TrackSourceInfo;
factory TrackSourceInfo.fromJson(Map<String, dynamic> json) =>
_$TrackSourceInfoFromJson(json);
}
@freezed
class TrackSource with _$TrackSource {
factory TrackSource({
required String url,
required SourceQualities quality,
required SourceCodecs codec,
required String bitrate,
}) = _TrackSource;
factory TrackSource.fromJson(Map<String, dynamic> json) =>
_$TrackSourceFromJson(json);
}
@JsonSerializable()
class BasicSourcedTrack {
final TrackSourceQuery query;
final AudioSource source;
final TrackSourceInfo info;
final List<TrackSource> sources;
final List<TrackSourceInfo> siblings;
BasicSourcedTrack({
required this.query,
required this.source,
required this.info,
required this.sources,
this.siblings = const [],
});
factory BasicSourcedTrack.fromJson(Map<String, dynamic> json) =>
_$BasicSourcedTrackFromJson(json);
Map<String, dynamic> toJson() => _$BasicSourcedTrackToJson(this);
}