mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-12-05 23:19:42 +00:00
feat: add default plugin loading capability
This commit is contained in:
parent
7c632c8f06
commit
fda2257119
Binary file not shown.
BIN
assets/plugins/spotube-plugin-youtube-audio/plugin.smplug
Normal file
BIN
assets/plugins/spotube-plugin-youtube-audio/plugin.smplug
Normal file
Binary file not shown.
@ -22,6 +22,7 @@ import 'package:drift/native.dart';
|
|||||||
import 'package:spotube/services/youtube_engine/newpipe_engine.dart';
|
import 'package:spotube/services/youtube_engine/newpipe_engine.dart';
|
||||||
import 'package:spotube/services/youtube_engine/youtube_explode_engine.dart';
|
import 'package:spotube/services/youtube_engine/youtube_explode_engine.dart';
|
||||||
import 'package:spotube/services/youtube_engine/yt_dlp_engine.dart';
|
import 'package:spotube/services/youtube_engine/yt_dlp_engine.dart';
|
||||||
|
import 'package:spotube/utils/platform.dart';
|
||||||
import 'package:sqlite3/sqlite3.dart';
|
import 'package:sqlite3/sqlite3.dart';
|
||||||
import 'package:sqlite3_flutter_libs/sqlite3_flutter_libs.dart';
|
import 'package:sqlite3_flutter_libs/sqlite3_flutter_libs.dart';
|
||||||
|
|
||||||
|
|||||||
@ -111,7 +111,9 @@ class PreferencesTable extends Table {
|
|||||||
localLibraryLocation: [],
|
localLibraryLocation: [],
|
||||||
themeMode: ThemeMode.system,
|
themeMode: ThemeMode.system,
|
||||||
audioSourceId: null,
|
audioSourceId: null,
|
||||||
youtubeClientEngine: YoutubeClientEngine.youtubeExplode,
|
youtubeClientEngine: kIsIOS
|
||||||
|
? YoutubeClientEngine.youtubeExplode
|
||||||
|
: YoutubeClientEngine.newPipe,
|
||||||
discordPresence: true,
|
discordPresence: true,
|
||||||
endlessPlayback: true,
|
endlessPlayback: true,
|
||||||
enableConnect: false,
|
enableConnect: false,
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import 'dart:io';
|
|||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:path/path.dart';
|
import 'package:path/path.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
@ -101,7 +102,11 @@ class MetadataPluginNotifier extends AsyncNotifier<MetadataPluginState> {
|
|||||||
|
|
||||||
final plugins = await database.pluginsTable.select().get();
|
final plugins = await database.pluginsTable.select().get();
|
||||||
|
|
||||||
return await toStatePlugins(plugins);
|
final pluginState = await toStatePlugins(plugins);
|
||||||
|
|
||||||
|
await _loadDefaultPlugins(pluginState);
|
||||||
|
|
||||||
|
return pluginState;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<MetadataPluginState> toStatePlugins(
|
Future<MetadataPluginState> toStatePlugins(
|
||||||
@ -171,6 +176,45 @@ class MetadataPluginNotifier extends AsyncNotifier<MetadataPluginState> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _loadDefaultPlugins(MetadataPluginState pluginState) async {
|
||||||
|
const plugins = [
|
||||||
|
"spotube-plugin-musicbrainz-listenbrainz",
|
||||||
|
"spotube-plugin-youtube-audio",
|
||||||
|
];
|
||||||
|
|
||||||
|
for (final plugin in plugins) {
|
||||||
|
final byteData = await rootBundle.load(
|
||||||
|
"assets/plugins/$plugin/plugin.smplug",
|
||||||
|
);
|
||||||
|
final pluginConfig =
|
||||||
|
await extractPluginArchive(byteData.buffer.asUint8List());
|
||||||
|
try {
|
||||||
|
await addPlugin(pluginConfig);
|
||||||
|
} on MetadataPluginException catch (e) {
|
||||||
|
if (e.errorCode == MetadataPluginErrorCode.duplicatePlugin &&
|
||||||
|
await isPluginUpdate(pluginConfig)) {
|
||||||
|
final oldConfig = pluginState.plugins
|
||||||
|
.firstWhereOrNull((p) => p.slug == pluginConfig.slug);
|
||||||
|
if (oldConfig == null) continue;
|
||||||
|
final isDefaultMetadata =
|
||||||
|
oldConfig == pluginState.defaultMetadataPluginConfig;
|
||||||
|
final isDefaultAudioSource =
|
||||||
|
oldConfig == pluginState.defaultAudioSourcePluginConfig;
|
||||||
|
|
||||||
|
await removePlugin(pluginConfig);
|
||||||
|
await addPlugin(pluginConfig);
|
||||||
|
|
||||||
|
if (isDefaultMetadata) {
|
||||||
|
await setDefaultMetadataPlugin(pluginConfig);
|
||||||
|
}
|
||||||
|
if (isDefaultAudioSource) {
|
||||||
|
await setDefaultAudioSourcePlugin(pluginConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Uri _getGithubReleasesUrl(String repoUrl) {
|
Uri _getGithubReleasesUrl(String repoUrl) {
|
||||||
final parsedUri = Uri.parse(repoUrl);
|
final parsedUri = Uri.parse(repoUrl);
|
||||||
final uri = parsedUri.replace(
|
final uri = parsedUri.replace(
|
||||||
@ -373,11 +417,19 @@ class MetadataPluginNotifier extends AsyncNotifier<MetadataPluginState> {
|
|||||||
repository: Value(plugin.repository),
|
repository: Value(plugin.repository),
|
||||||
// Setting the very first plugin as the default plugin
|
// Setting the very first plugin as the default plugin
|
||||||
selectedForMetadata: Value(
|
selectedForMetadata: Value(
|
||||||
(state.valueOrNull?.plugins.isEmpty ?? true) &&
|
(state.valueOrNull?.plugins
|
||||||
|
.where(
|
||||||
|
(d) => d.abilities.contains(PluginAbilities.metadata))
|
||||||
|
.isEmpty ??
|
||||||
|
true) &&
|
||||||
plugin.abilities.contains(PluginAbilities.metadata),
|
plugin.abilities.contains(PluginAbilities.metadata),
|
||||||
),
|
),
|
||||||
selectedForAudioSource: Value(
|
selectedForAudioSource: Value(
|
||||||
(state.valueOrNull?.plugins.isEmpty ?? true) &&
|
(state.valueOrNull?.plugins
|
||||||
|
.where((d) =>
|
||||||
|
d.abilities.contains(PluginAbilities.audioSource))
|
||||||
|
.isEmpty ??
|
||||||
|
true) &&
|
||||||
plugin.abilities.contains(PluginAbilities.audioSource),
|
plugin.abilities.contains(PluginAbilities.audioSource),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -420,6 +472,27 @@ class MetadataPluginNotifier extends AsyncNotifier<MetadataPluginState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool> isPluginUpdate(PluginConfiguration newPlugin) async {
|
||||||
|
final pluginRes = await (database.pluginsTable.select()
|
||||||
|
..where(
|
||||||
|
(tbl) =>
|
||||||
|
tbl.name.equals(newPlugin.name) &
|
||||||
|
tbl.author.equals(newPlugin.author),
|
||||||
|
)
|
||||||
|
..limit(1))
|
||||||
|
.get();
|
||||||
|
|
||||||
|
if (pluginRes.isEmpty) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final oldPlugin = pluginRes.first;
|
||||||
|
final oldPluginApiVersion = Version.parse(oldPlugin.pluginApiVersion);
|
||||||
|
final newPluginApiVersion = Version.parse(newPlugin.pluginApiVersion);
|
||||||
|
|
||||||
|
return newPluginApiVersion > oldPluginApiVersion;
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> updatePlugin(
|
Future<void> updatePlugin(
|
||||||
PluginConfiguration plugin,
|
PluginConfiguration plugin,
|
||||||
PluginUpdateAvailable update,
|
PluginUpdateAvailable update,
|
||||||
|
|||||||
@ -227,6 +227,8 @@ flutter:
|
|||||||
- assets/branding/spotube-logo.png
|
- assets/branding/spotube-logo.png
|
||||||
- assets/branding/spotube-logo-light.png
|
- assets/branding/spotube-logo-light.png
|
||||||
- assets/branding/spotube-logo.ico
|
- assets/branding/spotube-logo.ico
|
||||||
|
- assets/plugins/spotube-plugin-musicbrainz-listenbrainz/plugin.smplug
|
||||||
|
- assets/plugins/spotube-plugin-youtube-audio/plugin.smplug
|
||||||
- LICENSE
|
- LICENSE
|
||||||
- packages/flutter_undraw/assets/undraw/access_denied.svg
|
- packages/flutter_undraw/assets/undraw/access_denied.svg
|
||||||
- packages/flutter_undraw/assets/undraw/fixing_bugs.svg
|
- packages/flutter_undraw/assets/undraw/fixing_bugs.svg
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user