diff --git a/lib/components/Home/Home.dart b/lib/components/Home/Home.dart index 6084448e..6030ed08 100644 --- a/lib/components/Home/Home.dart +++ b/lib/components/Home/Home.dart @@ -111,6 +111,10 @@ class Home extends HookConsumerWidget { }, [backgroundColor]); return Scaffold( + bottomNavigationBar: SpotubeNavigationBar( + selectedIndex: _selectedIndex.value, + onSelectedIndexChanged: _onSelectedIndexChanged, + ), body: Column( children: [ if (_selectedIndex.value != 3) @@ -178,10 +182,6 @@ class Home extends HookConsumerWidget { ), // player itself Player(), - SpotubeNavigationBar( - selectedIndex: _selectedIndex.value, - onSelectedIndexChanged: _onSelectedIndexChanged, - ), ], ), ); diff --git a/lib/components/Home/SpotubeNavigationBar.dart b/lib/components/Home/SpotubeNavigationBar.dart index 562e3b40..e7811257 100644 --- a/lib/components/Home/SpotubeNavigationBar.dart +++ b/lib/components/Home/SpotubeNavigationBar.dart @@ -1,6 +1,5 @@ import 'package:badges/badges.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotube/components/Home/Sidebar.dart'; import 'package:spotube/hooks/useBreakpoints.dart'; @@ -24,7 +23,7 @@ class SpotubeNavigationBar extends HookConsumerWidget { ); final breakpoint = useBreakpoints(); - if (breakpoint.isMoreThan(Breakpoints.sm)) return Container(); + if (breakpoint.isMoreThan(Breakpoints.sm)) return const SizedBox(); return NavigationBar( destinations: [ ...sidebarTileList.map( diff --git a/lib/components/Library/UserLocalTracks.dart b/lib/components/Library/UserLocalTracks.dart index 152b1a71..35d1198a 100644 --- a/lib/components/Library/UserLocalTracks.dart +++ b/lib/components/Library/UserLocalTracks.dart @@ -1,12 +1,10 @@ -import 'dart:convert'; import 'dart:io'; -import 'package:dart_tags/dart_tags.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:metadata_god/bridge_generated.dart'; +import 'package:metadata_god/metadata_god.dart'; import 'package:mime/mime.dart'; -import 'package:mp3_info/mp3_info.dart'; import 'package:path/path.dart'; import 'package:path_provider/path_provider.dart'; import 'package:spotify/spotify.dart'; @@ -18,14 +16,12 @@ import 'package:spotube/provider/Playback.dart'; import 'package:spotube/provider/UserPreferences.dart'; import 'package:spotube/utils/primitive_utils.dart'; import 'package:spotube/utils/type_conversion_utils.dart'; -import 'package:id3/id3.dart'; - -final tagProcessor = TagProcessor(); const supportedAudioTypes = [ "audio/webm", "audio/ogg", "audio/mpeg", + "audio/mp4", "audio/opus", "audio/wav", "audio/aac", @@ -56,69 +52,38 @@ final localTracksProvider = FutureProvider>((ref) async { }).map( (f) async { try { - final bytes = f.readAsBytes(); - final mp3Instance = MP3Instance(await bytes); + final metadata = await MetadataGod.getMetadata(f); - bool isParsed = false; - try { - isParsed = mp3Instance.parseTagsSync(); - } catch (e, stack) { - getLogger(MP3Instance).e("[parseTagsSync]", e, stack); - } - - final imageFile = isParsed - ? File(join( - (await getTemporaryDirectory()).path, - "spotube", - basenameWithoutExtension(f.path) + - imgMimeToExt[mp3Instance.metaTags["APIC"]?["mime"] ?? - "image/jpeg"]!, - )) - : null; - if (imageFile != null && - !await imageFile.exists() && - mp3Instance.metaTags["APIC"]?["base64"] != null) { + final imageFile = File(join( + (await getTemporaryDirectory()).path, + "spotube", + basenameWithoutExtension(f.path) + + imgMimeToExt[metadata?.picture?.mimeType ?? "image/jpeg"]!, + )); + if (!await imageFile.exists() && metadata?.picture != null) { await imageFile.create(recursive: true); await imageFile.writeAsBytes( - base64Decode( - mp3Instance.metaTags["APIC"]["base64"], - ), + metadata?.picture?.data ?? [], mode: FileMode.writeOnly, ); } - Duration duration; - try { - duration = MP3Processor.fromBytes(await bytes).duration; - } catch (e, stack) { - getLogger(MP3Processor).e("[Parsing Mp3]", e, stack); - duration = Duration.zero; - } - final metadata = await tagProcessor.getTagsFromByteArray(bytes); - return { - "metadata": metadata, - "file": f, - "art": imageFile?.path, - "duration": duration, - }; + return {"metadata": metadata, "file": f, "art": imageFile.path}; } catch (e, stack) { getLogger(FutureProvider).e("[Fetching metadata]", e, stack); - return { - "metadata": [], - "file": f, - "duration": Duration.zero, - }; + return {}; } }, ), - )); + )) + .where((e) => e.isNotEmpty) + .toList(); final tracks = filesWithMetadata .map( (fileWithMetadata) => TypeConversionUtils.localTrack_X_Track( - fileWithMetadata["metadata"] as List, + fileWithMetadata["metadata"] as Metadata, fileWithMetadata["file"] as File, - fileWithMetadata["duration"] as Duration, fileWithMetadata["art"] as String?, ), ) diff --git a/lib/components/Shared/DownloadTrackButton.dart b/lib/components/Shared/DownloadTrackButton.dart index 64b395f4..576ffe28 100644 --- a/lib/components/Shared/DownloadTrackButton.dart +++ b/lib/components/Shared/DownloadTrackButton.dart @@ -36,7 +36,7 @@ class DownloadTrackButton extends HookConsumerWidget { useEffect(() { (() async { outputFile.value = - File(path.join(preferences.downloadLocation, "$fileName.mp3")); + File(path.join(preferences.downloadLocation, "$fileName.m4a")); }()); return null; }, [fileName, track, preferences.downloadLocation]); diff --git a/lib/extensions/yt-video-from-cache-track.dart b/lib/extensions/yt-video-from-cache-track.dart index 1777d8cb..aee94dde 100644 --- a/lib/extensions/yt-video-from-cache-track.dart +++ b/lib/extensions/yt-video-from-cache-track.dart @@ -12,6 +12,7 @@ extension VideoFromCacheTrackExtension on Video { cacheTrack.uploadDate != null ? DateTime.tryParse(cacheTrack.uploadDate!) : null, + cacheTrack.uploadDate, cacheTrack.publishDate != null ? DateTime.tryParse(cacheTrack.publishDate!) : null, @@ -69,6 +70,7 @@ extension VideoToJson on Video { map["author"], ChannelId(map["channelId"]), DateTime.tryParse(map["uploadDate"]), + map["uploadDate"], DateTime.tryParse(map["publishDate"]), map["description"], parseDuration(map["duration"]), diff --git a/lib/models/Id3Tags.dart b/lib/models/Id3Tags.dart deleted file mode 100644 index c2d0f885..00000000 --- a/lib/models/Id3Tags.dart +++ /dev/null @@ -1,157 +0,0 @@ -import 'package:dart_tags/dart_tags.dart'; - -class Id3Tags { - Id3Tags({ - this.tsse, - this.title, - this.album, - this.tpe2, - this.comment, - this.tcop, - this.tdrc, - this.genre, - this.picture, - }); - - String? tsse; - String? title; - String? album; - String? tpe2; - Comment? comment; - String? tcop; - String? tdrc; - String? genre; - AttachedPicture? picture; - - factory Id3Tags.fromJson(Map json) => Id3Tags( - tsse: json["TSSE"], - title: json["title"], - album: json["album"], - tpe2: json["TPE2"], - comment: json["comment"]?["eng:"] is Comment - ? json["comment"]["eng:"] - : CommentJson.fromJson(Map.from( - json["comment"]?["eng:"] ?? {}, - )), - tcop: json["TCOP"], - tdrc: json["TDRC"], - genre: json["genre"], - picture: json["picture"]?["Cover (front)"] is AttachedPicture - ? json["picture"]["Cover (front)"] - : AttachedPictureJson.fromJson(Map.from( - json["picture"]?["Cover (front)"] ?? {}, - )), - ); - - factory Id3Tags.fromId3v1Tags(Id3v1Tags v1tags) => Id3Tags( - album: v1tags.album, - comment: Comment("", "", v1tags.comment ?? ""), - genre: v1tags.genre, - title: v1tags.title, - tcop: v1tags.year, - tdrc: v1tags.year, - tpe2: v1tags.artist, - ); - - Map toJson() => { - "TSSE": tsse, - "title": title, - "album": album, - "TPE2": tpe2, - "comment": comment, - "TCOP": tcop, - "TDRC": tdrc, - "genre": genre, - "picture": picture, - }; - - String? get artist => tpe2; - String? get year => tdrc; - - Map toAndroidJson(String artwork) { - return { - "title": title ?? "Unknown", - "artist": artist ?? "Unknown", - "album": album ?? "Unknown", - "genre": genre ?? "Unknown", - "artwork": artwork, - "year": year ?? "Unknown", - }; - } -} - -extension CommentJson on Comment { - static fromJson(Map json) => Comment( - json["lang"] ?? "", - json["description"] ?? "", - json["comment"] ?? "", - ); - - Map toJson() => { - "comment": comment, - "description": description, - "key": key, - "lang": lang, - }; -} - -extension AttachedPictureJson on AttachedPicture { - static fromJson(Map json) => AttachedPicture( - json["mime"] ?? "", - json["imageTypeCode"] ?? 0, - json["description"] ?? "", - List.from(json["imageData"] ?? []), - ); - - Map toJson() => { - "description": description, - "imageData": imageData, - "imageData64": imageData64, - "imageType": imageType, - "imageTypeCode": imageTypeCode, - "key": key, - "mime": mime, - }; -} - -class Id3v1Tags { - String? title; - String? artist; - String? album; - String? year; - String? comment; - String? track; - String? genre; - - Id3v1Tags({ - this.title, - this.artist, - this.album, - this.year, - this.comment, - this.track, - this.genre, - }); - - Id3v1Tags.fromJson(Map json) { - title = json['title']; - artist = json['artist']; - album = json['album']; - year = json['year']; - comment = json['comment']; - track = json['track']; - genre = json['genre']; - } - - Map toJson() { - return { - 'title': title, - 'artist': artist, - 'album': album, - 'year': year, - 'comment': comment, - 'track': track, - 'genre': genre, - }; - } -} diff --git a/lib/provider/Downloader.dart b/lib/provider/Downloader.dart index c8f4f238..f00e9c39 100644 --- a/lib/provider/Downloader.dart +++ b/lib/provider/Downloader.dart @@ -1,22 +1,19 @@ import 'dart:async'; -import 'dart:convert'; import 'dart:io'; -import 'package:dart_tags/dart_tags.dart'; -import 'package:flutter/widgets.dart'; +import 'package:flutter/widgets.dart' hide Image; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:http/http.dart'; +import 'package:metadata_god/bridge_generated.dart'; +import 'package:metadata_god/metadata_god.dart'; import 'package:queue/queue.dart'; import 'package:path/path.dart' as path; -import 'package:spotify/spotify.dart'; -import 'package:spotube/components/Library/UserLocalTracks.dart'; -import 'package:spotube/models/Id3Tags.dart'; +import 'package:spotify/spotify.dart' hide Image; import 'package:spotube/models/Logger.dart'; import 'package:spotube/models/SpotubeTrack.dart'; import 'package:spotube/provider/Playback.dart'; import 'package:spotube/provider/UserPreferences.dart'; import 'package:spotube/provider/YouTube.dart'; -import 'package:spotube/utils/platform.dart'; import 'package:spotube/utils/type_conversion_utils.dart'; import 'package:youtube_explode_dart/youtube_explode_dart.dart' hide Comment; @@ -63,7 +60,7 @@ class Downloader with ChangeNotifier { RegExp(r'[/\\?%*:|"<>]'), "", ); - final filename = '$cleanTitle.mp3'; + final filename = '$cleanTitle.m4a'; final file = File(path.join(downloadPath, filename)); try { logger.v("[addToQueue] Download starting for ${file.path}"); @@ -97,9 +94,9 @@ class Downloader with ChangeNotifier { "[addToQueue] Download of ${file.path} is done successfully", ); - // Tagging isn't supported in Android currently - if (kIsAndroid) return; - + logger.v( + "[addToQueue] Writing metadata to ${file.path}", + ); final imageUri = TypeConversionUtils.image_X_UrlString( track.album?.images ?? [], ); @@ -108,43 +105,30 @@ class Downloader with ChangeNotifier { imageUri, ), ); - final picture = AttachedPicture.base64( - response.headers["Content-Type"] ?? "image/jpeg", - 3, - track.name!, - base64Encode(response.bodyBytes), - ); - // write id3 metadata - final tag = Id3Tags( - album: track.album?.name, - picture: picture, - title: track.name, - genre: "Spotube", - tcop: track.ytTrack.uploadDate?.year.toString(), - tdrc: track.ytTrack.uploadDate?.year.toString(), - tpe2: TypeConversionUtils.artists_X_String( - track.artists ?? [], - ), - tsse: "", - comment: Comment( - "eng", - track.ytTrack.description, - track.ytTrack.title, + + await MetadataGod.writeMetadata( + file, + Metadata( + title: track.name, + artist: track.artists?.map((a) => a.name).join(", "), + album: track.album?.name, + albumArtist: track.artists?.map((a) => a.name).join(", "), + year: track.album?.releaseDate != null + ? int.tryParse(track.album!.releaseDate!) + : null, + trackNumber: track.trackNumber, + discNumber: track.discNumber, + durationMs: track.durationMs?.toDouble(), + fileSize: file.lengthSync(), + trackTotal: track.album?.tracks?.length, + picture: response.headers['content-type'] != null + ? Image( + data: response.bodyBytes, + mimeType: response.headers['content-type']!, + ) + : null, ), ); - - logger.v("[addToQueue] Writing metadata to ${file.path}"); - - final taggedMp3 = await tagProcessor.putTagsToByteArray( - file.readAsBytes(), - [ - Tag() - ..type = "ID3" - ..version = "2.4.0" - ..tags = tag.toJson() - ], - ); - await file.writeAsBytes(taggedMp3); logger.v( "[addToQueue] Writing metadata to ${file.path} is successful", ); diff --git a/lib/utils/type_conversion_utils.dart b/lib/utils/type_conversion_utils.dart index d887637a..67aad529 100644 --- a/lib/utils/type_conversion_utils.dart +++ b/lib/utils/type_conversion_utils.dart @@ -2,15 +2,13 @@ import 'dart:io'; -import 'package:dart_tags/dart_tags.dart'; import 'package:flutter/widgets.dart' hide Image; +import 'package:metadata_god/bridge_generated.dart' hide Image; import 'package:path/path.dart'; import 'package:spotube/components/Shared/LinkText.dart'; import 'package:spotify/spotify.dart'; -import 'package:spotube/models/Id3Tags.dart'; import 'package:spotube/models/SpotubeTrack.dart'; import 'package:spotube/utils/primitive_utils.dart'; -import 'package:collection/collection.dart'; import 'package:youtube_explode_dart/youtube_explode_dart.dart'; abstract class TypeConversionUtils { @@ -91,30 +89,23 @@ abstract class TypeConversionUtils { } static SpotubeTrack localTrack_X_Track( - List metadatas, + Metadata metadata, File file, - Duration duration, String? art, ) { - final v2Tags = - metadatas.firstWhereOrNull((s) => s.version == "2.4.0")?.tags; - final v1Tags = - metadatas.firstWhereOrNull((s) => s.version != "2.4.0")?.tags; - final metadata = v2Tags != null - ? Id3Tags.fromJson(v2Tags) - : Id3Tags.fromId3v1Tags(Id3v1Tags.fromJson(v1Tags ?? {})); final track = SpotubeTrack( Video( VideoId("dQw4w9WgXcQ"), basenameWithoutExtension(file.path), - metadata.tpe2 ?? "", + metadata.artist ?? "", ChannelId( "https://www.youtube.com/channel/UCuAXFkgsw1L7xaCfnd5JJOw", ), DateTime.now(), + "", DateTime.now(), "", - duration, + Duration(milliseconds: metadata.durationMs?.toInt() ?? 0), ThumbnailSet(metadata.title ?? ""), [], const Engagement(0, 0, 0), @@ -129,22 +120,23 @@ abstract class TypeConversionUtils { ..genres = [if (metadata.genre != null) metadata.genre!] ..artists = [ Artist() - ..name = metadata.tpe2 ?? "Spotube" - ..id = metadata.tpe2 ?? "Spotube" + ..name = metadata.albumArtist ?? "Spotube" + ..id = metadata.albumArtist ?? "Spotube" ..type = "artist", ] - ..id = metadata.album; + ..id = metadata.album + ..releaseDate = metadata.year?.toString(); track.artists = [ Artist() - ..name = metadata.tpe2 ?? "Spotube" - ..id = metadata.tpe2 ?? "Spotube" + ..name = metadata.artist ?? "Spotube" + ..id = metadata.artist ?? "Spotube" ]; track.id = metadata.title ?? basenameWithoutExtension(file.path); track.name = metadata.title ?? basenameWithoutExtension(file.path); track.type = "track"; track.uri = file.path; - track.durationMs = duration.inMilliseconds; + track.durationMs = metadata.durationMs?.toInt(); return track; } diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 01b8e0f7..bf0cd78b 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -8,6 +8,7 @@ #include #include +#include #include void fl_register_plugins(FlPluginRegistry* registry) { @@ -17,6 +18,9 @@ void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) bitsdojo_window_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "BitsdojoWindowPlugin"); bitsdojo_window_plugin_register_with_registrar(bitsdojo_window_linux_registrar); + g_autoptr(FlPluginRegistrar) metadata_god_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "MetadataGodPlugin"); + metadata_god_plugin_register_with_registrar(metadata_god_registrar); g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 9aebc645..0de3bf80 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -5,6 +5,7 @@ list(APPEND FLUTTER_PLUGIN_LIST audioplayers_linux bitsdojo_window_linux + metadata_god url_launcher_linux ) diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 3e375fb3..eb3904ca 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -9,6 +9,7 @@ import audio_service import audio_session import audioplayers_darwin import bitsdojo_window_macos +import metadata_god import package_info_plus_macos import path_provider_macos import shared_preferences_macos @@ -20,6 +21,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin")) AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin")) BitsdojoWindowPlugin.register(with: registry.registrar(forPlugin: "BitsdojoWindowPlugin")) + MetadataGodPlugin.register(with: registry.registrar(forPlugin: "MetadataGodPlugin")) FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) diff --git a/pubspec.lock b/pubspec.lock index a0dcd9c8..d7542368 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -78,48 +78,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.0.9" - app_package_parser: - dependency: transitive - description: - name: app_package_parser - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.7" - app_package_parser_apk: - dependency: transitive - description: - name: app_package_parser_apk - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.7" - app_package_parser_ipa: - dependency: transitive - description: - name: app_package_parser_ipa - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.7" - app_package_publisher: - dependency: transitive - description: - name: app_package_publisher - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.9" - app_package_publisher_fir: - dependency: transitive - description: - name: app_package_publisher_fir - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.9" - app_package_publisher_pgyer: - dependency: transitive - description: - name: app_package_publisher_pgyer - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.9" archive: dependency: transitive description: @@ -238,21 +196,21 @@ packages: name: bitsdojo_window url: "https://pub.dartlang.org" source: hosted - version: "0.1.2" + version: "0.1.4" bitsdojo_window_linux: dependency: transitive description: name: bitsdojo_window_linux url: "https://pub.dartlang.org" source: hosted - version: "0.1.2" + version: "0.1.3" bitsdojo_window_macos: dependency: transitive description: name: bitsdojo_window_macos url: "https://pub.dartlang.org" source: hosted - version: "0.1.2" + version: "0.1.3" bitsdojo_window_platform_interface: dependency: transitive description: @@ -266,7 +224,7 @@ packages: name: bitsdojo_window_windows url: "https://pub.dartlang.org" source: hosted - version: "0.1.2" + version: "0.1.4" boolean_selector: dependency: transitive description: @@ -386,20 +344,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.16.0" - colorize: - dependency: transitive - description: - name: colorize - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.0" - console_bars: - dependency: transitive - description: - name: console_bars - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" convert: dependency: transitive description: @@ -435,27 +379,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.2.3" - dart_tags: - dependency: "direct main" - description: - name: dart_tags - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.0" dbus: dependency: "direct main" description: name: dbus url: "https://pub.dartlang.org" source: hosted - version: "0.7.3" - dio: - dependency: transitive - description: - name: dio - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.6" + version: "0.7.8" dots_indicator: dependency: transitive description: @@ -483,7 +413,7 @@ packages: name: ffi url: "https://pub.dartlang.org" source: hosted - version: "1.2.1" + version: "2.0.1" file: dependency: transitive description: @@ -494,10 +424,12 @@ packages: file_picker: dependency: "direct main" description: - name: file_picker - url: "https://pub.dartlang.org" - source: hosted - version: "4.6.1" + path: "." + ref: HEAD + resolved-ref: f9133f6d5dbf33191fc9b58655aebfd15445045a + url: "https://github.com/KRTirtho/flutter_file_picker.git" + source: git + version: "5.0.1" fixnum: dependency: transitive description: @@ -524,13 +456,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.0.9" - flutter_app_publisher: - dependency: transitive - description: - name: flutter_app_publisher - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.9" flutter_blurhash: dependency: transitive description: @@ -551,7 +476,7 @@ packages: name: flutter_distributor url: "https://pub.dartlang.org" source: hosted - version: "0.0.9" + version: "0.0.2" flutter_hooks: dependency: "direct main" description: @@ -587,6 +512,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.4" + flutter_rust_bridge: + dependency: transitive + description: + name: flutter_rust_bridge + url: "https://pub.dartlang.org" + source: hosted + version: "1.42.0" flutter_test: dependency: "direct dev" description: flutter @@ -603,7 +535,7 @@ packages: name: freezed_annotation url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "2.1.0" frontend_server_client: dependency: transitive description: @@ -695,20 +627,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.0.1" - id3: - dependency: "direct main" - description: - name: id3 - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" image: dependency: transitive description: name: image url: "https://pub.dartlang.org" source: hosted - version: "3.1.3" + version: "3.2.0" infinite_scroll_pagination: dependency: transitive description: @@ -793,6 +718,15 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.0" + metadata_god: + dependency: "direct main" + description: + path: "." + ref: HEAD + resolved-ref: "65e3b973213ab8c7495506d13b8e047ecd9fca88" + url: "https://github.com/KRTirtho/metadata_god.git" + source: git + version: "0.0.1" mime: dependency: "direct main" description: @@ -800,13 +734,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.2" - mp3_info: - dependency: "direct main" - description: - name: mp3_info - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0" msix: dependency: "direct dev" description: @@ -841,7 +768,7 @@ packages: name: package_info_plus url: "https://pub.dartlang.org" source: hosted - version: "1.4.2" + version: "1.4.3+1" package_info_plus_linux: dependency: transitive description: @@ -876,7 +803,7 @@ packages: name: package_info_plus_windows url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "2.0.0" palette_generator: dependency: "direct main" description: @@ -884,13 +811,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.3.3" - parse_app_package: - dependency: transitive - description: - name: parse_app_package - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.7" path: dependency: "direct main" description: @@ -925,7 +845,7 @@ packages: name: path_provider_linux url: "https://pub.dartlang.org" source: hosted - version: "2.1.6" + version: "2.1.7" path_provider_macos: dependency: transitive description: @@ -946,7 +866,7 @@ packages: name: path_provider_windows url: "https://pub.dartlang.org" source: hosted - version: "2.0.6" + version: "2.1.3" pedantic: dependency: transitive description: @@ -1186,12 +1106,10 @@ packages: spotify: dependency: "direct main" description: - path: "." - ref: HEAD - resolved-ref: ea313e2d21c38157cd8255d248bcd7897bf51360 - url: "https://github.com/KRTirtho/spotify-dart.git" - source: git - version: "0.7.0" + name: spotify + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.0" sqflite: dependency: transitive description: @@ -1332,13 +1250,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.1" - utf_convert: - dependency: transitive - description: - name: utf_convert - url: "https://pub.dartlang.org" - source: hosted - version: "0.10.0+1" uuid: dependency: transitive description: @@ -1375,12 +1286,12 @@ packages: source: hosted version: "2.2.0" win32: - dependency: transitive + dependency: "direct overridden" description: name: win32 url: "https://pub.dartlang.org" source: hosted - version: "2.6.1" + version: "3.0.0" xdg_directories: dependency: transitive description: @@ -1394,7 +1305,7 @@ packages: name: xml url: "https://pub.dartlang.org" source: hosted - version: "5.4.1" + version: "6.1.0" yaml: dependency: transitive description: @@ -1408,7 +1319,7 @@ packages: name: youtube_explode_dart url: "https://pub.dartlang.org" source: hosted - version: "1.11.0" + version: "1.12.0" sdks: dart: ">=2.17.1 <3.0.0" flutter: ">=3.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 9ea0fc31..89f5ccc6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -37,11 +37,10 @@ dependencies: html: ^0.15.0 http: ^0.13.4 shared_preferences: ^2.0.11 - spotify: - git: https://github.com/KRTirtho/spotify-dart.git + spotify: ^0.8.0 url_launcher: ^6.0.17 youtube_explode_dart: ^1.10.8 - bitsdojo_window: ^0.1.2 + bitsdojo_window: 0.1.4 path: ^1.8.0 path_provider: ^2.0.8 collection: ^1.15.0 @@ -54,7 +53,7 @@ dependencies: permission_handler: ^9.2.0 marquee: ^2.2.1 scroll_to_index: ^2.1.1 - package_info_plus: ^1.4.2 + package_info_plus: ^1.4.3 version: ^2.0.0 audio_service: ^0.18.4 hookified_infinite_scroll_pagination: ^0.1.0 @@ -65,15 +64,23 @@ dependencies: audioplayers: ^1.0.1 introduction_screen: ^3.0.2 audio_session: ^0.1.9 - file_picker: ^4.6.1 + # This is temporary until the win32v3 update PR is merged and released + file_picker: + git: + url: https://github.com/KRTirtho/flutter_file_picker.git popover: ^0.2.6+3 queue: ^3.1.0+1 auto_size_text: ^3.0.0 badges: ^2.0.3 mime: ^1.0.2 - dart_tags: ^0.4.0 - id3: ^1.0.2 - mp3_info: ^0.2.0 + metadata_god: + git: + url: https://github.com/KRTirtho/metadata_god.git + +# Temporary before [package_info_plus_windows] is updated to support +# win32v3 +dependency_overrides: + win32: 3.0.0 dev_dependencies: flutter_test: diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 3e689c38..cf86bfe4 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -16,6 +17,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("AudioplayersWindowsPlugin")); BitsdojoWindowPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("BitsdojoWindowPlugin")); + MetadataGodPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("MetadataGodPluginCApi")); PermissionHandlerWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); UrlLauncherWindowsRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index c8e970a8..76747345 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -5,6 +5,7 @@ list(APPEND FLUTTER_PLUGIN_LIST audioplayers_windows bitsdojo_window_windows + metadata_god permission_handler_windows url_launcher_windows )