🔀 Merge database system from spotube
This commit is contained in:
		| @@ -8,6 +8,9 @@ abstract class PlatformInfo { | ||||
|  | ||||
|   static bool get isLinux => !kIsWeb && Platform.isLinux; | ||||
|  | ||||
|   static bool get isInFlatpak => | ||||
|       kIsWeb ? false : Platform.environment["FLATPAK_ID"] != null; | ||||
|  | ||||
|   static bool get isWindows => !kIsWeb && Platform.isWindows; | ||||
|  | ||||
|   static bool get isMacOS => !kIsWeb && Platform.isMacOS; | ||||
|   | ||||
							
								
								
									
										19
									
								
								lib/services/color.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								lib/services/color.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| import 'dart:ui'; | ||||
|  | ||||
| class RhythmColor extends Color { | ||||
|   final String name; | ||||
|  | ||||
|   const RhythmColor(super.color, {required this.name}); | ||||
|  | ||||
|   const RhythmColor.from(super.value, {required this.name}); | ||||
|  | ||||
|   factory RhythmColor.fromString(String string) { | ||||
|     final slices = string.split(':'); | ||||
|     return RhythmColor(int.parse(slices.last), name: slices.first); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   String toString() { | ||||
|     return '$name:$value'; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										80
									
								
								lib/services/database/database.dart
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										80
									
								
								lib/services/database/database.dart
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,80 @@ | ||||
| library database; | ||||
|  | ||||
| import 'dart:convert'; | ||||
| import 'dart:io'; | ||||
|  | ||||
| import 'package:drift/drift.dart'; | ||||
| import 'package:encrypt/encrypt.dart'; | ||||
| import 'package:path/path.dart'; | ||||
| import 'package:path_provider/path_provider.dart'; | ||||
| import 'package:rhythm_box/services/color.dart'; | ||||
| import 'package:rhythm_box/services/lyrics.dart'; | ||||
| import 'package:spotify/spotify.dart' hide Playlist; | ||||
| import 'package:rhythm_box/services/kv_store/encrypted_kv_store.dart'; | ||||
| import 'package:rhythm_box/services/kv_store/kv_store.dart'; | ||||
| import 'package:rhythm_box/services/sourced_track/enums.dart'; | ||||
| import 'package:flutter/material.dart' hide Table, Key, View; | ||||
| import 'package:drift/native.dart'; | ||||
| import 'package:sqlite3/sqlite3.dart'; | ||||
| import 'package:sqlite3_flutter_libs/sqlite3_flutter_libs.dart'; | ||||
|  | ||||
| part 'database.g.dart'; | ||||
|  | ||||
| part 'tables/authentication.dart'; | ||||
| part 'tables/blacklist.dart'; | ||||
| part 'tables/preferences.dart'; | ||||
| part 'tables/scrobbler.dart'; | ||||
| part 'tables/skip_segment.dart'; | ||||
| part 'tables/source_match.dart'; | ||||
| part 'tables/history.dart'; | ||||
| part 'tables/lyrics.dart'; | ||||
|  | ||||
| part 'typeconverters/color.dart'; | ||||
| part 'typeconverters/locale.dart'; | ||||
| part 'typeconverters/string_list.dart'; | ||||
| part 'typeconverters/encrypted_text.dart'; | ||||
| part 'typeconverters/map.dart'; | ||||
| part 'typeconverters/subtitle.dart'; | ||||
|  | ||||
| @DriftDatabase( | ||||
|   tables: [ | ||||
|     AuthenticationTable, | ||||
|     BlacklistTable, | ||||
|     PreferencesTable, | ||||
|     ScrobblerTable, | ||||
|     SkipSegmentTable, | ||||
|     SourceMatchTable, | ||||
|     HistoryTable, | ||||
|     LyricsTable, | ||||
|   ], | ||||
| ) | ||||
| class AppDatabase extends _$AppDatabase { | ||||
|   AppDatabase() : super(_openConnection()); | ||||
|  | ||||
|   @override | ||||
|   int get schemaVersion => 1; | ||||
| } | ||||
|  | ||||
| LazyDatabase _openConnection() { | ||||
|   // the LazyDatabase util lets us find the right location for the file async. | ||||
|   return LazyDatabase(() async { | ||||
|     // put the database file, called db.sqlite here, into the documents folder | ||||
|     // for your app. | ||||
|     final dbFolder = await getApplicationSupportDirectory(); | ||||
|     final file = File(join(dbFolder.path, 'db.sqlite')); | ||||
|  | ||||
|     // Also work around limitations on old Android versions | ||||
|     if (Platform.isAndroid) { | ||||
|       await applyWorkaroundToOpenSqlite3OnOldAndroidVersions(); | ||||
|     } | ||||
|  | ||||
|     // Make sqlite3 pick a more suitable location for temporary files - the | ||||
|     // one from the system may be inaccessible due to sandboxing. | ||||
|     final cacheBase = (await getTemporaryDirectory()).path; | ||||
|     // We can't access /tmp on Android, which sqlite3 would try by default. | ||||
|     // Explicitly tell it about the correct temporary directory. | ||||
|     sqlite3.tempDirectory = cacheBase; | ||||
|  | ||||
|     return NativeDatabase.createInBackground(file); | ||||
|   }); | ||||
| } | ||||
							
								
								
									
										4744
									
								
								lib/services/database/database.g.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4744
									
								
								lib/services/database/database.g.dart
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										8
									
								
								lib/services/database/tables/authentication.dart
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										8
									
								
								lib/services/database/tables/authentication.dart
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| part of '../database.dart'; | ||||
|  | ||||
| class AuthenticationTable extends Table { | ||||
|   IntColumn get id => integer().autoIncrement()(); | ||||
|   TextColumn get cookie => text().map(EncryptedTextConverter())(); | ||||
|   TextColumn get accessToken => text().map(EncryptedTextConverter())(); | ||||
|   DateTimeColumn get expiration => dateTime()(); | ||||
| } | ||||
							
								
								
									
										18
									
								
								lib/services/database/tables/blacklist.dart
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										18
									
								
								lib/services/database/tables/blacklist.dart
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| part of '../database.dart'; | ||||
|  | ||||
| enum BlacklistedType { | ||||
|   artist, | ||||
|   track; | ||||
| } | ||||
|  | ||||
| @TableIndex( | ||||
|   name: "unique_blacklist", | ||||
|   unique: true, | ||||
|   columns: {#elementType, #elementId}, | ||||
| ) | ||||
| class BlacklistTable extends Table { | ||||
|   IntColumn get id => integer().autoIncrement()(); | ||||
|   TextColumn get name => text()(); | ||||
|   TextColumn get elementType => textEnum<BlacklistedType>()(); | ||||
|   TextColumn get elementId => text()(); | ||||
| } | ||||
							
								
								
									
										25
									
								
								lib/services/database/tables/history.dart
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										25
									
								
								lib/services/database/tables/history.dart
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| part of '../database.dart'; | ||||
|  | ||||
| enum HistoryEntryType { | ||||
|   playlist, | ||||
|   album, | ||||
|   track, | ||||
| } | ||||
|  | ||||
| class HistoryTable extends Table { | ||||
|   IntColumn get id => integer().autoIncrement()(); | ||||
|   DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)(); | ||||
|   TextColumn get type => textEnum<HistoryEntryType>()(); | ||||
|   TextColumn get itemId => text()(); | ||||
|   TextColumn get data => | ||||
|       text().map(const MapTypeConverter<String, dynamic>())(); | ||||
| } | ||||
|  | ||||
| extension HistoryItemParseExtension on HistoryTableData { | ||||
|   PlaylistSimple? get playlist => | ||||
|       type == HistoryEntryType.playlist ? PlaylistSimple.fromJson(data) : null; | ||||
|   AlbumSimple? get album => | ||||
|       type == HistoryEntryType.album ? AlbumSimple.fromJson(data) : null; | ||||
|   Track? get track => | ||||
|       type == HistoryEntryType.track ? Track.fromJson(data) : null; | ||||
| } | ||||
							
								
								
									
										8
									
								
								lib/services/database/tables/lyrics.dart
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										8
									
								
								lib/services/database/tables/lyrics.dart
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| part of '../database.dart'; | ||||
|  | ||||
| class LyricsTable extends Table { | ||||
|   IntColumn get id => integer().autoIncrement()(); | ||||
|  | ||||
|   TextColumn get trackId => text()(); | ||||
|   TextColumn get data => text().map(SubtitleTypeConverter())(); | ||||
| } | ||||
							
								
								
									
										125
									
								
								lib/services/database/tables/preferences.dart
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										125
									
								
								lib/services/database/tables/preferences.dart
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,125 @@ | ||||
| part of '../database.dart'; | ||||
|  | ||||
| enum LayoutMode { | ||||
|   compact, | ||||
|   extended, | ||||
|   adaptive, | ||||
| } | ||||
|  | ||||
| enum CloseBehavior { | ||||
|   minimizeToTray, | ||||
|   close, | ||||
| } | ||||
|  | ||||
| enum AudioSource { | ||||
|   youtube, | ||||
|   piped, | ||||
|   jiosaavn; | ||||
|  | ||||
|   String get label => name[0].toUpperCase() + name.substring(1); | ||||
| } | ||||
|  | ||||
| enum MusicCodec { | ||||
|   m4a._('M4a (Best for downloaded music)'), | ||||
|   weba._("WebA (Best for streamed music)\nDoesn't support audio metadata"); | ||||
|  | ||||
|   final String label; | ||||
|   const MusicCodec._(this.label); | ||||
| } | ||||
|  | ||||
| enum SearchMode { | ||||
|   youtube._('YouTube'), | ||||
|   youtubeMusic._('YouTube Music'); | ||||
|  | ||||
|   final String label; | ||||
|  | ||||
|   const SearchMode._(this.label); | ||||
|  | ||||
|   factory SearchMode.fromString(String key) { | ||||
|     return SearchMode.values.firstWhere((e) => e.name == key); | ||||
|   } | ||||
| } | ||||
|  | ||||
| class PreferencesTable extends Table { | ||||
|   IntColumn get id => integer().autoIncrement()(); | ||||
|   TextColumn get audioQuality => textEnum<SourceQualities>() | ||||
|       .withDefault(Constant(SourceQualities.high.name))(); | ||||
|   BoolColumn get albumColorSync => | ||||
|       boolean().withDefault(const Constant(true))(); | ||||
|   BoolColumn get amoledDarkTheme => | ||||
|       boolean().withDefault(const Constant(false))(); | ||||
|   BoolColumn get checkUpdate => boolean().withDefault(const Constant(true))(); | ||||
|   BoolColumn get normalizeAudio => | ||||
|       boolean().withDefault(const Constant(false))(); | ||||
|   BoolColumn get showSystemTrayIcon => | ||||
|       boolean().withDefault(const Constant(false))(); | ||||
|   BoolColumn get systemTitleBar => | ||||
|       boolean().withDefault(const Constant(false))(); | ||||
|   BoolColumn get skipNonMusic => boolean().withDefault(const Constant(false))(); | ||||
|   TextColumn get closeBehavior => textEnum<CloseBehavior>() | ||||
|       .withDefault(Constant(CloseBehavior.close.name))(); | ||||
|   TextColumn get accentColorScheme => text() | ||||
|       .withDefault(const Constant('Blue:0xFF2196F3')) | ||||
|       .map(const RhythmColorConverter())(); | ||||
|   TextColumn get layoutMode => | ||||
|       textEnum<LayoutMode>().withDefault(Constant(LayoutMode.adaptive.name))(); | ||||
|   TextColumn get locale => text() | ||||
|       .withDefault( | ||||
|         const Constant('{"languageCode":"system","countryCode":"system"}'), | ||||
|       ) | ||||
|       .map(const LocaleConverter())(); | ||||
|   TextColumn get market => | ||||
|       textEnum<Market>().withDefault(Constant(Market.US.name))(); | ||||
|   TextColumn get searchMode => | ||||
|       textEnum<SearchMode>().withDefault(Constant(SearchMode.youtube.name))(); | ||||
|   TextColumn get downloadLocation => text().withDefault(const Constant(''))(); | ||||
|   TextColumn get localLibraryLocation => | ||||
|       text().withDefault(const Constant('')).map(const StringListConverter())(); | ||||
|   TextColumn get pipedInstance => | ||||
|       text().withDefault(const Constant('https://pipedapi.kavin.rocks'))(); | ||||
|   TextColumn get themeMode => | ||||
|       textEnum<ThemeMode>().withDefault(Constant(ThemeMode.system.name))(); | ||||
|   TextColumn get audioSource => | ||||
|       textEnum<AudioSource>().withDefault(Constant(AudioSource.youtube.name))(); | ||||
|   TextColumn get streamMusicCodec => | ||||
|       textEnum<SourceCodecs>().withDefault(Constant(SourceCodecs.weba.name))(); | ||||
|   TextColumn get downloadMusicCodec => | ||||
|       textEnum<SourceCodecs>().withDefault(Constant(SourceCodecs.m4a.name))(); | ||||
|   BoolColumn get discordPresence => | ||||
|       boolean().withDefault(const Constant(true))(); | ||||
|   BoolColumn get endlessPlayback => | ||||
|       boolean().withDefault(const Constant(true))(); | ||||
|   BoolColumn get enableConnect => | ||||
|       boolean().withDefault(const Constant(false))(); | ||||
|  | ||||
|   // Default values as PreferencesTableData | ||||
|   static PreferencesTableData defaults() { | ||||
|     return PreferencesTableData( | ||||
|       id: 0, | ||||
|       audioQuality: SourceQualities.high, | ||||
|       albumColorSync: true, | ||||
|       amoledDarkTheme: false, | ||||
|       checkUpdate: true, | ||||
|       normalizeAudio: false, | ||||
|       showSystemTrayIcon: false, | ||||
|       systemTitleBar: false, | ||||
|       skipNonMusic: false, | ||||
|       closeBehavior: CloseBehavior.close, | ||||
|       accentColorScheme: RhythmColor(Colors.blue.value, name: 'Blue'), | ||||
|       layoutMode: LayoutMode.adaptive, | ||||
|       locale: const Locale('system', 'system'), | ||||
|       market: Market.US, | ||||
|       searchMode: SearchMode.youtube, | ||||
|       downloadLocation: '', | ||||
|       localLibraryLocation: [], | ||||
|       pipedInstance: 'https://pipedapi.kavin.rocks', | ||||
|       themeMode: ThemeMode.system, | ||||
|       audioSource: AudioSource.youtube, | ||||
|       streamMusicCodec: SourceCodecs.weba, | ||||
|       downloadMusicCodec: SourceCodecs.m4a, | ||||
|       discordPresence: true, | ||||
|       endlessPlayback: true, | ||||
|       enableConnect: false, | ||||
|     ); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										8
									
								
								lib/services/database/tables/scrobbler.dart
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										8
									
								
								lib/services/database/tables/scrobbler.dart
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| part of '../database.dart'; | ||||
|  | ||||
| class ScrobblerTable extends Table { | ||||
|   IntColumn get id => integer().autoIncrement()(); | ||||
|   DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)(); | ||||
|   TextColumn get username => text()(); | ||||
|   TextColumn get passwordHash => text().map(EncryptedTextConverter())(); | ||||
| } | ||||
							
								
								
									
										9
									
								
								lib/services/database/tables/skip_segment.dart
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										9
									
								
								lib/services/database/tables/skip_segment.dart
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| part of '../database.dart'; | ||||
|  | ||||
| class SkipSegmentTable extends Table { | ||||
|   IntColumn get id => integer().autoIncrement()(); | ||||
|   IntColumn get start => integer()(); | ||||
|   IntColumn get end => integer()(); | ||||
|   TextColumn get trackId => text()(); | ||||
|   DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)(); | ||||
| } | ||||
							
								
								
									
										25
									
								
								lib/services/database/tables/source_match.dart
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										25
									
								
								lib/services/database/tables/source_match.dart
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| part of '../database.dart'; | ||||
|  | ||||
| enum SourceType { | ||||
|   youtube._("YouTube"), | ||||
|   youtubeMusic._("YouTube Music"), | ||||
|   jiosaavn._("JioSaavn"); | ||||
|  | ||||
|   final String label; | ||||
|  | ||||
|   const SourceType._(this.label); | ||||
| } | ||||
|  | ||||
| @TableIndex( | ||||
|   name: "uniq_track_match", | ||||
|   columns: {#trackId, #sourceId, #sourceType}, | ||||
|   unique: true, | ||||
| ) | ||||
| class SourceMatchTable extends Table { | ||||
|   IntColumn get id => integer().autoIncrement()(); | ||||
|   TextColumn get trackId => text()(); | ||||
|   TextColumn get sourceId => text()(); | ||||
|   TextColumn get sourceType => | ||||
|       textEnum<SourceType>().withDefault(Constant(SourceType.youtube.name))(); | ||||
|   DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)(); | ||||
| } | ||||
							
								
								
									
										29
									
								
								lib/services/database/typeconverters/color.dart
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										29
									
								
								lib/services/database/typeconverters/color.dart
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| part of '../database.dart'; | ||||
|  | ||||
| class ColorConverter extends TypeConverter<Color, int> { | ||||
|   const ColorConverter(); | ||||
|  | ||||
|   @override | ||||
|   Color fromSql(int fromDb) { | ||||
|     return Color(fromDb); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   int toSql(Color value) { | ||||
|     return value.value; | ||||
|   } | ||||
| } | ||||
|  | ||||
| class RhythmColorConverter extends TypeConverter<RhythmColor, String> { | ||||
|   const RhythmColorConverter(); | ||||
|  | ||||
|   @override | ||||
|   RhythmColor fromSql(String fromDb) { | ||||
|     return RhythmColor.fromString(fromDb); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   String toSql(RhythmColor value) { | ||||
|     return value.toString(); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										44
									
								
								lib/services/database/typeconverters/encrypted_text.dart
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										44
									
								
								lib/services/database/typeconverters/encrypted_text.dart
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| part of '../database.dart'; | ||||
|  | ||||
| class DecryptedText { | ||||
|   final String value; | ||||
|   const DecryptedText(this.value); | ||||
|  | ||||
|   static Encrypter? _encrypter; | ||||
|  | ||||
|   factory DecryptedText.decrypted(String value) { | ||||
|     _encrypter ??= Encrypter( | ||||
|       Salsa20( | ||||
|         Key.fromUtf8(EncryptedKvStoreService.encryptionKeySync), | ||||
|       ), | ||||
|     ); | ||||
|  | ||||
|     return DecryptedText( | ||||
|       _encrypter!.decrypt( | ||||
|         Encrypted.fromBase64(value), | ||||
|         iv: KVStoreService.ivKey, | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   String encrypt() { | ||||
|     _encrypter ??= Encrypter( | ||||
|       Salsa20( | ||||
|         Key.fromUtf8(EncryptedKvStoreService.encryptionKeySync), | ||||
|       ), | ||||
|     ); | ||||
|     return _encrypter!.encrypt(value, iv: KVStoreService.ivKey).base64; | ||||
|   } | ||||
| } | ||||
|  | ||||
| class EncryptedTextConverter extends TypeConverter<DecryptedText, String> { | ||||
|   @override | ||||
|   DecryptedText fromSql(String fromDb) { | ||||
|     return DecryptedText.decrypted(fromDb); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   String toSql(DecryptedText value) { | ||||
|     return value.encrypt(); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										19
									
								
								lib/services/database/typeconverters/locale.dart
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										19
									
								
								lib/services/database/typeconverters/locale.dart
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| part of '../database.dart'; | ||||
|  | ||||
| class LocaleConverter extends TypeConverter<Locale, String> { | ||||
|   const LocaleConverter(); | ||||
|  | ||||
|   @override | ||||
|   Locale fromSql(String fromDb) { | ||||
|     final rawMap = jsonDecode(fromDb) as Map<String, dynamic>; | ||||
|     return Locale(rawMap["languageCode"], rawMap["countryCode"]); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   String toSql(Locale value) { | ||||
|     return jsonEncode({ | ||||
|       "languageCode": value.languageCode, | ||||
|       "countryCode": value.countryCode, | ||||
|     }); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										15
									
								
								lib/services/database/typeconverters/map.dart
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										15
									
								
								lib/services/database/typeconverters/map.dart
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| part of '../database.dart'; | ||||
|  | ||||
| class MapTypeConverter<K, V> extends TypeConverter<Map<K, V>, String> { | ||||
|   const MapTypeConverter(); | ||||
|  | ||||
|   @override | ||||
|   fromSql(String fromDb) { | ||||
|     return json.decode(fromDb) as Map<K, V>; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   toSql(value) { | ||||
|     return json.encode(value); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										15
									
								
								lib/services/database/typeconverters/string_list.dart
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										15
									
								
								lib/services/database/typeconverters/string_list.dart
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| part of '../database.dart'; | ||||
|  | ||||
| class StringListConverter extends TypeConverter<List<String>, String> { | ||||
|   const StringListConverter(); | ||||
|  | ||||
|   @override | ||||
|   List<String> fromSql(String fromDb) { | ||||
|     return fromDb.split(",").where((e) => e.isNotEmpty).toList(); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   String toSql(List<String> value) { | ||||
|     return value.join(","); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										13
									
								
								lib/services/database/typeconverters/subtitle.dart
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										13
									
								
								lib/services/database/typeconverters/subtitle.dart
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| part of '../database.dart'; | ||||
|  | ||||
| class SubtitleTypeConverter extends TypeConverter<SubtitleSimple, String> { | ||||
|   @override | ||||
|   SubtitleSimple fromSql(String fromDb) { | ||||
|     return SubtitleSimple.fromJson(jsonDecode(fromDb)); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   String toSql(SubtitleSimple value) { | ||||
|     return jsonEncode(value.toJson()); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										61
									
								
								lib/services/kv_store/encrypted_kv_store.dart
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										61
									
								
								lib/services/kv_store/encrypted_kv_store.dart
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,61 @@ | ||||
| import 'package:flutter_secure_storage/flutter_secure_storage.dart'; | ||||
| import 'package:rhythm_box/platform.dart'; | ||||
| import 'package:rhythm_box/services/kv_store/kv_store.dart'; | ||||
| import 'package:uuid/uuid.dart'; | ||||
|  | ||||
| abstract class EncryptedKvStoreService { | ||||
|   static const _storage = FlutterSecureStorage( | ||||
|     aOptions: AndroidOptions( | ||||
|       encryptedSharedPreferences: true, | ||||
|     ), | ||||
|   ); | ||||
|  | ||||
|   static FlutterSecureStorage get storage => _storage; | ||||
|  | ||||
|   static String? _encryptionKeySync; | ||||
|  | ||||
|   static Future<void> initialize() async { | ||||
|     _encryptionKeySync = await encryptionKey; | ||||
|   } | ||||
|  | ||||
|   static String get encryptionKeySync => _encryptionKeySync!; | ||||
|  | ||||
|   static bool get isUnsupportedPlatform => | ||||
|       PlatformInfo.isMacOS || | ||||
|       PlatformInfo.isIOS || | ||||
|       (PlatformInfo.isLinux && !PlatformInfo.isInFlatpak); | ||||
|  | ||||
|   static Future<String> get encryptionKey async { | ||||
|     if (isUnsupportedPlatform) { | ||||
|       return KVStoreService.encryptionKey; | ||||
|     } | ||||
|     try { | ||||
|       final value = await _storage.read(key: 'encryption'); | ||||
|       final key = const Uuid().v4(); | ||||
|  | ||||
|       if (value == null) { | ||||
|         await setEncryptionKey(key); | ||||
|         return key; | ||||
|       } | ||||
|  | ||||
|       return value; | ||||
|     } catch (e) { | ||||
|       return KVStoreService.encryptionKey; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   static Future<void> setEncryptionKey(String key) async { | ||||
|     if (isUnsupportedPlatform) { | ||||
|       await KVStoreService.setEncryptionKey(key); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     try { | ||||
|       await _storage.write(key: 'encryption', value: key); | ||||
|     } catch (e) { | ||||
|       await KVStoreService.setEncryptionKey(key); | ||||
|     } finally { | ||||
|       _encryptionKeySync = key; | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										90
									
								
								lib/services/kv_store/kv_store.dart
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										90
									
								
								lib/services/kv_store/kv_store.dart
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,90 @@ | ||||
| import 'dart:convert'; | ||||
|  | ||||
| import 'package:encrypt/encrypt.dart'; | ||||
| import 'package:rhythm_box/services/wm_tools.dart'; | ||||
| import 'package:shared_preferences/shared_preferences.dart'; | ||||
| import 'package:uuid/uuid.dart'; | ||||
|  | ||||
| abstract class KVStoreService { | ||||
|   static SharedPreferences? _sharedPreferences; | ||||
|   static SharedPreferences get sharedPreferences => _sharedPreferences!; | ||||
|  | ||||
|   static Future<void> initialize() async { | ||||
|     _sharedPreferences = await SharedPreferences.getInstance(); | ||||
|   } | ||||
|  | ||||
|   static bool get doneGettingStarted => | ||||
|       sharedPreferences.getBool('doneGettingStarted') ?? false; | ||||
|   static Future<void> setDoneGettingStarted(bool value) async => | ||||
|       await sharedPreferences.setBool('doneGettingStarted', value); | ||||
|  | ||||
|   static bool get askedForBatteryOptimization => | ||||
|       sharedPreferences.getBool('askedForBatteryOptimization') ?? false; | ||||
|   static Future<void> setAskedForBatteryOptimization(bool value) async => | ||||
|       await sharedPreferences.setBool('askedForBatteryOptimization', value); | ||||
|  | ||||
|   static List<String> get recentSearches => | ||||
|       sharedPreferences.getStringList('recentSearches') ?? []; | ||||
|  | ||||
|   static Future<void> setRecentSearches(List<String> value) async => | ||||
|       await sharedPreferences.setStringList('recentSearches', value); | ||||
|  | ||||
|   static WindowSize? get windowSize { | ||||
|     final raw = sharedPreferences.getString('windowSize'); | ||||
|  | ||||
|     if (raw == null) { | ||||
|       return null; | ||||
|     } | ||||
|     return WindowSize.fromJson(jsonDecode(raw)); | ||||
|   } | ||||
|  | ||||
|   static Future<void> setWindowSize(WindowSize value) async => | ||||
|       await sharedPreferences.setString( | ||||
|         'windowSize', | ||||
|         jsonEncode( | ||||
|           value.toJson(), | ||||
|         ), | ||||
|       ); | ||||
|  | ||||
|   static String get encryptionKey { | ||||
|     final value = sharedPreferences.getString('encryption'); | ||||
|  | ||||
|     final key = const Uuid().v4(); | ||||
|     if (value == null) { | ||||
|       setEncryptionKey(key); | ||||
|       return key; | ||||
|     } | ||||
|  | ||||
|     return value; | ||||
|   } | ||||
|  | ||||
|   static Future<void> setEncryptionKey(String key) async { | ||||
|     await sharedPreferences.setString('encryption', key); | ||||
|   } | ||||
|  | ||||
|   static IV get ivKey { | ||||
|     final iv = sharedPreferences.getString('iv'); | ||||
|     final value = IV.fromSecureRandom(8); | ||||
|  | ||||
|     if (iv == null) { | ||||
|       setIVKey(value); | ||||
|  | ||||
|       return value; | ||||
|     } | ||||
|  | ||||
|     return IV.fromBase64(iv); | ||||
|   } | ||||
|  | ||||
|   static Future<void> setIVKey(IV iv) async { | ||||
|     await sharedPreferences.setString('iv', iv.base64); | ||||
|   } | ||||
|  | ||||
|   static double get volume => sharedPreferences.getDouble('volume') ?? 1.0; | ||||
|   static Future<void> setVolume(double value) async => | ||||
|       await sharedPreferences.setDouble('volume', value); | ||||
|  | ||||
|   static bool get hasMigratedToDrift => | ||||
|       sharedPreferences.getBool('hasMigratedToDrift') ?? false; | ||||
|   static Future<void> setHasMigratedToDrift(bool value) async => | ||||
|       await sharedPreferences.setBool('hasMigratedToDrift', value); | ||||
| } | ||||
							
								
								
									
										72
									
								
								lib/services/lyrics.dart
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										72
									
								
								lib/services/lyrics.dart
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,72 @@ | ||||
| import 'package:lrc/lrc.dart'; | ||||
|  | ||||
| class SubtitleSimple { | ||||
|   Uri uri; | ||||
|   String name; | ||||
|   List<LyricSlice> lyrics; | ||||
|   int rating; | ||||
|   String provider; | ||||
|  | ||||
|   SubtitleSimple({ | ||||
|     required this.uri, | ||||
|     required this.name, | ||||
|     required this.lyrics, | ||||
|     required this.rating, | ||||
|     required this.provider, | ||||
|   }); | ||||
|  | ||||
|   factory SubtitleSimple.fromJson(Map<String, dynamic> json) { | ||||
|     return SubtitleSimple( | ||||
|       uri: Uri.parse(json['uri'] as String), | ||||
|       name: json['name'] as String, | ||||
|       lyrics: (json['lyrics'] as List<dynamic>) | ||||
|           .map((e) => LyricSlice.fromJson(e as Map<String, dynamic>)) | ||||
|           .toList(), | ||||
|       rating: json['rating'] as int, | ||||
|       provider: json['provider'] as String? ?? 'unknown', | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   Map<String, dynamic> toJson() { | ||||
|     return { | ||||
|       'uri': uri.toString(), | ||||
|       'name': name, | ||||
|       'lyrics': lyrics.map((e) => e.toJson()).toList(), | ||||
|       'rating': rating, | ||||
|       'provider': provider, | ||||
|     }; | ||||
|   } | ||||
| } | ||||
|  | ||||
| class LyricSlice { | ||||
|   Duration time; | ||||
|   String text; | ||||
|  | ||||
|   LyricSlice({required this.time, required this.text}); | ||||
|  | ||||
|   factory LyricSlice.fromLrcLine(LrcLine line) { | ||||
|     return LyricSlice( | ||||
|       time: line.timestamp, | ||||
|       text: line.lyrics.trim(), | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   factory LyricSlice.fromJson(Map<String, dynamic> json) { | ||||
|     return LyricSlice( | ||||
|       time: Duration(milliseconds: json['time']), | ||||
|       text: json['text'] as String, | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   Map<String, dynamic> toJson() { | ||||
|     return { | ||||
|       'time': time.inMilliseconds, | ||||
|       'text': text, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   String toString() { | ||||
|     return 'LyricsSlice({time: $time, text: $text})'; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										3
									
								
								lib/services/song_link/song_link.g.dart
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										3
									
								
								lib/services/song_link/song_link.g.dart
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							| @@ -6,7 +6,8 @@ part of 'song_link.dart'; | ||||
| // JsonSerializableGenerator | ||||
| // ************************************************************************** | ||||
|  | ||||
| _$SongLinkImpl _$$SongLinkImplFromJson(Map json) => _$SongLinkImpl( | ||||
| _$SongLinkImpl _$$SongLinkImplFromJson(Map<String, dynamic> json) => | ||||
|     _$SongLinkImpl( | ||||
|       displayName: json['displayName'] as String, | ||||
|       linkId: json['linkId'] as String, | ||||
|       platform: json['platform'] as String, | ||||
|   | ||||
							
								
								
									
										4
									
								
								lib/services/sourced_track/models/source_info.g.dart
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										4
									
								
								lib/services/sourced_track/models/source_info.g.dart
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							| @@ -6,13 +6,13 @@ part of 'source_info.dart'; | ||||
| // JsonSerializableGenerator | ||||
| // ************************************************************************** | ||||
|  | ||||
| SourceInfo _$SourceInfoFromJson(Map json) => SourceInfo( | ||||
| SourceInfo _$SourceInfoFromJson(Map<String, dynamic> json) => SourceInfo( | ||||
|       id: json['id'] as String, | ||||
|       title: json['title'] as String, | ||||
|       artist: json['artist'] as String, | ||||
|       thumbnail: json['thumbnail'] as String, | ||||
|       pageUrl: json['pageUrl'] as String, | ||||
|       duration: Duration(microseconds: json['duration'] as int), | ||||
|       duration: Duration(microseconds: (json['duration'] as num).toInt()), | ||||
|       artistUrl: json['artistUrl'] as String, | ||||
|       album: json['album'] as String?, | ||||
|     ); | ||||
|   | ||||
							
								
								
									
										15
									
								
								lib/services/sourced_track/models/source_map.g.dart
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										15
									
								
								lib/services/sourced_track/models/source_map.g.dart
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							| @@ -6,7 +6,8 @@ part of 'source_map.dart'; | ||||
| // JsonSerializableGenerator | ||||
| // ************************************************************************** | ||||
|  | ||||
| SourceQualityMap _$SourceQualityMapFromJson(Map json) => SourceQualityMap( | ||||
| SourceQualityMap _$SourceQualityMapFromJson(Map<String, dynamic> json) => | ||||
|     SourceQualityMap( | ||||
|       high: json['high'] as String, | ||||
|       medium: json['medium'] as String, | ||||
|       low: json['low'] as String, | ||||
| @@ -19,18 +20,16 @@ Map<String, dynamic> _$SourceQualityMapToJson(SourceQualityMap instance) => | ||||
|       'low': instance.low, | ||||
|     }; | ||||
|  | ||||
| SourceMap _$SourceMapFromJson(Map json) => SourceMap( | ||||
| SourceMap _$SourceMapFromJson(Map<String, dynamic> json) => SourceMap( | ||||
|       weba: json['weba'] == null | ||||
|           ? null | ||||
|           : SourceQualityMap.fromJson( | ||||
|               Map<String, dynamic>.from(json['weba'] as Map)), | ||||
|           : SourceQualityMap.fromJson(json['weba'] as Map<String, dynamic>), | ||||
|       m4a: json['m4a'] == null | ||||
|           ? null | ||||
|           : SourceQualityMap.fromJson( | ||||
|               Map<String, dynamic>.from(json['m4a'] as Map)), | ||||
|           : SourceQualityMap.fromJson(json['m4a'] as Map<String, dynamic>), | ||||
|     ); | ||||
|  | ||||
| Map<String, dynamic> _$SourceMapToJson(SourceMap instance) => <String, dynamic>{ | ||||
|       'weba': instance.weba?.toJson(), | ||||
|       'm4a': instance.m4a?.toJson(), | ||||
|       'weba': instance.weba, | ||||
|       'm4a': instance.m4a, | ||||
|     }; | ||||
|   | ||||
							
								
								
									
										89
									
								
								lib/services/wm_tools.dart
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										89
									
								
								lib/services/wm_tools.dart
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,89 @@ | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:rhythm_box/platform.dart'; | ||||
| import 'package:rhythm_box/services/kv_store/kv_store.dart'; | ||||
| import 'package:window_manager/window_manager.dart'; | ||||
|  | ||||
| class WindowSize { | ||||
|   final double height; | ||||
|   final double width; | ||||
|   final bool maximized; | ||||
|  | ||||
|   WindowSize({ | ||||
|     required this.height, | ||||
|     required this.width, | ||||
|     required this.maximized, | ||||
|   }); | ||||
|  | ||||
|   factory WindowSize.fromJson(Map<String, dynamic> json) => WindowSize( | ||||
|         height: json['height'], | ||||
|         width: json['width'], | ||||
|         maximized: json['maximized'], | ||||
|       ); | ||||
|  | ||||
|   Map<String, dynamic> toJson() => { | ||||
|         'height': height, | ||||
|         'width': width, | ||||
|         'maximized': maximized, | ||||
|       }; | ||||
| } | ||||
|  | ||||
| class WindowManagerTools with WidgetsBindingObserver { | ||||
|   static WindowManagerTools? _instance; | ||||
|   static WindowManagerTools get instance => _instance!; | ||||
|  | ||||
|   WindowManagerTools._(); | ||||
|  | ||||
|   static Future<void> initialize() async { | ||||
|     await windowManager.ensureInitialized(); | ||||
|     _instance = WindowManagerTools._(); | ||||
|     WidgetsBinding.instance.addObserver(instance); | ||||
|  | ||||
|     await windowManager.waitUntilReadyToShow( | ||||
|       const WindowOptions( | ||||
|         title: 'RhythmBox', | ||||
|         backgroundColor: Colors.transparent, | ||||
|         minimumSize: Size(300, 700), | ||||
|         titleBarStyle: TitleBarStyle.hidden, | ||||
|         center: true, | ||||
|       ), | ||||
|       () async { | ||||
|         final savedSize = KVStoreService.windowSize; | ||||
|         await windowManager.setResizable(true); | ||||
|         if (savedSize?.maximized == true && | ||||
|             !(await windowManager.isMaximized())) { | ||||
|           await windowManager.maximize(); | ||||
|         } else if (savedSize != null) { | ||||
|           await windowManager.setSize(Size(savedSize.width, savedSize.height)); | ||||
|         } | ||||
|  | ||||
|         await windowManager.focus(); | ||||
|         await windowManager.show(); | ||||
|       }, | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   Size? _prevSize; | ||||
|  | ||||
|   @override | ||||
|   void didChangeMetrics() async { | ||||
|     super.didChangeMetrics(); | ||||
|     if (PlatformInfo.isMobile) return; | ||||
|     final size = await windowManager.getSize(); | ||||
|     final windowSameDimension = | ||||
|         _prevSize?.width == size.width && _prevSize?.height == size.height; | ||||
|  | ||||
|     if (windowSameDimension || _prevSize == null) { | ||||
|       _prevSize = size; | ||||
|       return; | ||||
|     } | ||||
|     final isMaximized = await windowManager.isMaximized(); | ||||
|     await KVStoreService.setWindowSize( | ||||
|       WindowSize( | ||||
|         height: size.height, | ||||
|         width: size.width, | ||||
|         maximized: isMaximized, | ||||
|       ), | ||||
|     ); | ||||
|     _prevSize = size; | ||||
|   } | ||||
| } | ||||
| @@ -6,10 +6,26 @@ | ||||
|  | ||||
| #include "generated_plugin_registrant.h" | ||||
|  | ||||
| #include <flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h> | ||||
| #include <media_kit_libs_linux/media_kit_libs_linux_plugin.h> | ||||
| #include <screen_retriever/screen_retriever_plugin.h> | ||||
| #include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h> | ||||
| #include <window_manager/window_manager_plugin.h> | ||||
|  | ||||
| void fl_register_plugins(FlPluginRegistry* registry) { | ||||
|   g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar = | ||||
|       fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin"); | ||||
|   flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar); | ||||
|   g_autoptr(FlPluginRegistrar) media_kit_libs_linux_registrar = | ||||
|       fl_plugin_registry_get_registrar_for_plugin(registry, "MediaKitLibsLinuxPlugin"); | ||||
|   media_kit_libs_linux_plugin_register_with_registrar(media_kit_libs_linux_registrar); | ||||
|   g_autoptr(FlPluginRegistrar) screen_retriever_registrar = | ||||
|       fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin"); | ||||
|   screen_retriever_plugin_register_with_registrar(screen_retriever_registrar); | ||||
|   g_autoptr(FlPluginRegistrar) sqlite3_flutter_libs_registrar = | ||||
|       fl_plugin_registry_get_registrar_for_plugin(registry, "Sqlite3FlutterLibsPlugin"); | ||||
|   sqlite3_flutter_libs_plugin_register_with_registrar(sqlite3_flutter_libs_registrar); | ||||
|   g_autoptr(FlPluginRegistrar) window_manager_registrar = | ||||
|       fl_plugin_registry_get_registrar_for_plugin(registry, "WindowManagerPlugin"); | ||||
|   window_manager_plugin_register_with_registrar(window_manager_registrar); | ||||
| } | ||||
|   | ||||
| @@ -3,7 +3,11 @@ | ||||
| # | ||||
|  | ||||
| list(APPEND FLUTTER_PLUGIN_LIST | ||||
|   flutter_secure_storage_linux | ||||
|   media_kit_libs_linux | ||||
|   screen_retriever | ||||
|   sqlite3_flutter_libs | ||||
|   window_manager | ||||
| ) | ||||
|  | ||||
| list(APPEND FLUTTER_FFI_PLUGIN_LIST | ||||
|   | ||||
| @@ -8,19 +8,27 @@ import Foundation | ||||
| import audio_service | ||||
| import audio_session | ||||
| import device_info_plus | ||||
| import flutter_secure_storage_macos | ||||
| import media_kit_libs_macos_audio | ||||
| import package_info_plus | ||||
| import path_provider_foundation | ||||
| import screen_retriever | ||||
| import shared_preferences_foundation | ||||
| import sqflite | ||||
| import sqlite3_flutter_libs | ||||
| import window_manager | ||||
|  | ||||
| func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { | ||||
|   AudioServicePlugin.register(with: registry.registrar(forPlugin: "AudioServicePlugin")) | ||||
|   AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin")) | ||||
|   DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) | ||||
|   FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin")) | ||||
|   MediaKitLibsMacosAudioPlugin.register(with: registry.registrar(forPlugin: "MediaKitLibsMacosAudioPlugin")) | ||||
|   FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) | ||||
|   PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) | ||||
|   ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin")) | ||||
|   SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) | ||||
|   SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) | ||||
|   Sqlite3FlutterLibsPlugin.register(with: registry.registrar(forPlugin: "Sqlite3FlutterLibsPlugin")) | ||||
|   WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin")) | ||||
| } | ||||
|   | ||||
							
								
								
									
										395
									
								
								pubspec.lock
									
									
									
									
									
								
							
							
						
						
									
										395
									
								
								pubspec.lock
									
									
									
									
									
								
							| @@ -1,6 +1,35 @@ | ||||
| # Generated by pub | ||||
| # See https://dart.dev/tools/pub/glossary#lockfile | ||||
| packages: | ||||
|   _fe_analyzer_shared: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: _fe_analyzer_shared | ||||
|       sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "72.0.0" | ||||
|   _macros: | ||||
|     dependency: transitive | ||||
|     description: dart | ||||
|     source: sdk | ||||
|     version: "0.3.2" | ||||
|   analyzer: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: analyzer | ||||
|       sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "6.7.0" | ||||
|   analyzer_plugin: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: analyzer_plugin | ||||
|       sha256: "9661b30b13a685efaee9f02e5d01ed9f2b423bd889d28a304d02d704aee69161" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "0.11.3" | ||||
|   archive: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -17,6 +46,14 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.5.0" | ||||
|   asn1lib: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: asn1lib | ||||
|       sha256: "58082b3f0dca697204dbab0ef9ff208bfaea7767ea771076af9a343488428dda" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.5.3" | ||||
|   async: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -65,6 +102,14 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.1.1" | ||||
|   build: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: build | ||||
|       sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.4.1" | ||||
|   build_cli_annotations: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -73,6 +118,62 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.1.0" | ||||
|   build_config: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: build_config | ||||
|       sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.1.1" | ||||
|   build_daemon: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: build_daemon | ||||
|       sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "4.0.2" | ||||
|   build_resolvers: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: build_resolvers | ||||
|       sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.4.2" | ||||
|   build_runner: | ||||
|     dependency: "direct dev" | ||||
|     description: | ||||
|       name: build_runner | ||||
|       sha256: dd09dd4e2b078992f42aac7f1a622f01882a8492fef08486b27ddde929c19f04 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.4.12" | ||||
|   build_runner_core: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: build_runner_core | ||||
|       sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "7.3.2" | ||||
|   built_collection: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: built_collection | ||||
|       sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "5.1.1" | ||||
|   built_value: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: built_value | ||||
|       sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "8.9.2" | ||||
|   cached_network_image: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
| @@ -105,6 +206,30 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.3.0" | ||||
|   charcode: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: charcode | ||||
|       sha256: fb98c0f6d12c920a02ee2d998da788bca066ca5f148492b7085ee23372b12306 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.3.1" | ||||
|   checked_yaml: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: checked_yaml | ||||
|       sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.0.3" | ||||
|   cli_util: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: cli_util | ||||
|       sha256: c05b7406fdabc7a49a3929d4af76bcaccbbffcbcdcf185b082e1ae07da323d19 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "0.4.1" | ||||
|   clock: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -113,6 +238,14 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.1.1" | ||||
|   code_builder: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: code_builder | ||||
|       sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "4.10.0" | ||||
|   collection: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
| @@ -153,6 +286,14 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.0.8" | ||||
|   dart_style: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: dart_style | ||||
|       sha256: "99e066ce75c89d6b29903d788a7bb9369cf754f7b24bf70bf4b6d6d6b26853b9" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.3.6" | ||||
|   device_info_plus: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
| @@ -193,6 +334,30 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.20.0" | ||||
|   drift_dev: | ||||
|     dependency: "direct dev" | ||||
|     description: | ||||
|       name: drift_dev | ||||
|       sha256: b9ec6159a731288e805a44225ccbebad507dd84d52ab71352c52584f13199d2d | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.20.1" | ||||
|   drift_flutter: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: drift_flutter | ||||
|       sha256: c670c947fe17ad149678a43fdbbfdb69321f0c83d315043e34e8ad2729e11f49 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "0.2.0" | ||||
|   encrypt: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: encrypt | ||||
|       sha256: "62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "5.0.3" | ||||
|   fake_async: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -262,6 +427,54 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.82.6" | ||||
|   flutter_secure_storage: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: flutter_secure_storage | ||||
|       sha256: "165164745e6afb5c0e3e3fcc72a012fb9e58496fb26ffb92cf22e16a821e85d0" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "9.2.2" | ||||
|   flutter_secure_storage_linux: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: flutter_secure_storage_linux | ||||
|       sha256: "4d91bfc23047422cbcd73ac684bc169859ee766482517c22172c86596bf1464b" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.2.1" | ||||
|   flutter_secure_storage_macos: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: flutter_secure_storage_macos | ||||
|       sha256: "1693ab11121a5f925bbea0be725abfcfbbcf36c1e29e571f84a0c0f436147a81" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "3.1.2" | ||||
|   flutter_secure_storage_platform_interface: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: flutter_secure_storage_platform_interface | ||||
|       sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.1.2" | ||||
|   flutter_secure_storage_web: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: flutter_secure_storage_web | ||||
|       sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.2.1" | ||||
|   flutter_secure_storage_windows: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: flutter_secure_storage_windows | ||||
|       sha256: b20b07cb5ed4ed74fc567b78a72936203f587eba460af1df11281c9326cd3709 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "3.1.2" | ||||
|   flutter_test: | ||||
|     dependency: "direct dev" | ||||
|     description: flutter | ||||
| @@ -288,6 +501,14 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.4.4" | ||||
|   frontend_server_client: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: frontend_server_client | ||||
|       sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "4.0.0" | ||||
|   gap: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
| @@ -304,6 +525,14 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "4.6.6" | ||||
|   glob: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: glob | ||||
|       sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.1.2" | ||||
|   go_router: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
| @@ -320,6 +549,14 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "6.2.1" | ||||
|   graphs: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: graphs | ||||
|       sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.3.2" | ||||
|   html: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
| @@ -344,6 +581,14 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.1.1" | ||||
|   http_multi_server: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: http_multi_server | ||||
|       sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "3.2.1" | ||||
|   http_parser: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -368,6 +613,14 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "0.19.0" | ||||
|   io: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: io | ||||
|       sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.0.4" | ||||
|   js: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -384,6 +637,14 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "4.9.0" | ||||
|   json_serializable: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: json_serializable | ||||
|       sha256: ea1432d167339ea9b5bb153f0571d0039607a873d6e04e0117af043f14a1fd4b | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "6.8.0" | ||||
|   leak_tracker: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -424,6 +685,22 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.2.0" | ||||
|   lrc: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: lrc | ||||
|       sha256: "5100362b5c8e97f4d3f03ff87efeb40e73a6dd780eca2cbde9312e0d44b8e5ba" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.0.2" | ||||
|   macros: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: macros | ||||
|       sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "0.1.2-main.4" | ||||
|   matcher: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -536,6 +813,14 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.1.0" | ||||
|   package_config: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: package_config | ||||
|       sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.1.0" | ||||
|   package_info_plus: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
| @@ -553,7 +838,7 @@ packages: | ||||
|     source: hosted | ||||
|     version: "3.0.1" | ||||
|   path: | ||||
|     dependency: transitive | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: path | ||||
|       sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" | ||||
| @@ -561,7 +846,7 @@ packages: | ||||
|     source: hosted | ||||
|     version: "1.9.0" | ||||
|   path_provider: | ||||
|     dependency: transitive | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: path_provider | ||||
|       sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378 | ||||
| @@ -640,6 +925,14 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.1.8" | ||||
|   pointycastle: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: pointycastle | ||||
|       sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "3.9.1" | ||||
|   pool: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -648,6 +941,22 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.5.1" | ||||
|   pub_semver: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: pub_semver | ||||
|       sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.1.4" | ||||
|   pubspec_parse: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: pubspec_parse | ||||
|       sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.3.0" | ||||
|   puppeteer: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -656,6 +965,14 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "3.13.0" | ||||
|   recase: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: recase | ||||
|       sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "4.1.0" | ||||
|   rxdart: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -672,6 +989,14 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.0.2" | ||||
|   screen_retriever: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: screen_retriever | ||||
|       sha256: "6ee02c8a1158e6dae7ca430da79436e3b1c9563c8cf02f524af997c201ac2b90" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "0.1.9" | ||||
|   shared_preferences: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
| @@ -781,6 +1106,22 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "0.1.3" | ||||
|   source_gen: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: source_gen | ||||
|       sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.5.0" | ||||
|   source_helper: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: source_helper | ||||
|       sha256: "6adebc0006c37dd63fe05bca0a929b99f06402fc95aa35bf36d67f5c06de01fd" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.3.4" | ||||
|   source_span: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -822,13 +1163,29 @@ packages: | ||||
|     source: hosted | ||||
|     version: "2.5.4+2" | ||||
|   sqlite3: | ||||
|     dependency: transitive | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: sqlite3 | ||||
|       sha256: "45f168ae2213201b54e09429ed0c593dc2c88c924a1488d6f9c523a255d567cb" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.4.6" | ||||
|   sqlite3_flutter_libs: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: sqlite3_flutter_libs | ||||
|       sha256: "62bbb4073edbcdf53f40c80775f33eea01d301b7b81417e5b3fb7395416258c1" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "0.5.24" | ||||
|   sqlparser: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: sqlparser | ||||
|       sha256: "3be52b4968fc2f098ba735863404756d2fe3ea0729cf006a5b5612618f74ca04" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "0.37.1" | ||||
|   stack_trace: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -845,6 +1202,14 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.1.2" | ||||
|   stream_transform: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: stream_transform | ||||
|       sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.1.0" | ||||
|   string_scanner: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -877,6 +1242,14 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "0.7.2" | ||||
|   timing: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: timing | ||||
|       sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.0.1" | ||||
|   tuple: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -933,6 +1306,14 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "14.2.4" | ||||
|   watcher: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: watcher | ||||
|       sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.1.0" | ||||
|   web: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -965,6 +1346,14 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.1.4" | ||||
|   window_manager: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: window_manager | ||||
|       sha256: ab8b2a7f97543d3db2b506c9d875e637149d48ee0c6a5cb5f5fd6e0dac463792 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "0.4.2" | ||||
|   xdg_directories: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|   | ||||
							
								
								
									
										12
									
								
								pubspec.yaml
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								pubspec.yaml
									
									
									
									
									
								
							| @@ -66,6 +66,16 @@ dependencies: | ||||
|   shelf_router: ^1.1.4 | ||||
|   dio: ^5.6.0 | ||||
|   json_annotation: ^4.9.0 | ||||
|   drift_flutter: ^0.2.0 | ||||
|   encrypt: ^5.0.3 | ||||
|   flutter_secure_storage: ^9.2.2 | ||||
|   window_manager: ^0.4.2 | ||||
|   lrc: ^1.0.2 | ||||
|   json_serializable: ^6.8.0 | ||||
|   path: ^1.9.0 | ||||
|   path_provider: ^2.1.4 | ||||
|   sqlite3: ^2.4.6 | ||||
|   sqlite3_flutter_libs: ^0.5.24 | ||||
|  | ||||
| dev_dependencies: | ||||
|   flutter_test: | ||||
| @@ -77,6 +87,8 @@ dev_dependencies: | ||||
|   # package. See that file for information about deactivating specific lint | ||||
|   # rules and activating additional ones. | ||||
|   flutter_lints: ^4.0.0 | ||||
|   drift_dev: ^2.20.1 | ||||
|   build_runner: ^2.4.12 | ||||
|  | ||||
| # For information on the generic Dart part of this file, see the | ||||
| # following page: https://dart.dev/tools/pub/pubspec | ||||
|   | ||||
| @@ -6,9 +6,21 @@ | ||||
|  | ||||
| #include "generated_plugin_registrant.h" | ||||
|  | ||||
| #include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h> | ||||
| #include <media_kit_libs_windows_audio/media_kit_libs_windows_audio_plugin_c_api.h> | ||||
| #include <screen_retriever/screen_retriever_plugin.h> | ||||
| #include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h> | ||||
| #include <window_manager/window_manager_plugin.h> | ||||
|  | ||||
| void RegisterPlugins(flutter::PluginRegistry* registry) { | ||||
|   FlutterSecureStorageWindowsPluginRegisterWithRegistrar( | ||||
|       registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin")); | ||||
|   MediaKitLibsWindowsAudioPluginCApiRegisterWithRegistrar( | ||||
|       registry->GetRegistrarForPlugin("MediaKitLibsWindowsAudioPluginCApi")); | ||||
|   ScreenRetrieverPluginRegisterWithRegistrar( | ||||
|       registry->GetRegistrarForPlugin("ScreenRetrieverPlugin")); | ||||
|   Sqlite3FlutterLibsPluginRegisterWithRegistrar( | ||||
|       registry->GetRegistrarForPlugin("Sqlite3FlutterLibsPlugin")); | ||||
|   WindowManagerPluginRegisterWithRegistrar( | ||||
|       registry->GetRegistrarForPlugin("WindowManagerPlugin")); | ||||
| } | ||||
|   | ||||
| @@ -3,7 +3,11 @@ | ||||
| # | ||||
|  | ||||
| list(APPEND FLUTTER_PLUGIN_LIST | ||||
|   flutter_secure_storage_windows | ||||
|   media_kit_libs_windows_audio | ||||
|   screen_retriever | ||||
|   sqlite3_flutter_libs | ||||
|   window_manager | ||||
| ) | ||||
|  | ||||
| list(APPEND FLUTTER_FFI_PLUGIN_LIST | ||||
|   | ||||
		Reference in New Issue
	
	Block a user