mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-12-05 23:19:42 +00:00
feat: implement webview api for plugin usage
This commit is contained in:
parent
fca0551032
commit
fe83f50286
@ -45,7 +45,6 @@ import 'package:spotube/services/kv_store/encrypted_kv_store.dart';
|
|||||||
import 'package:spotube/services/kv_store/kv_store.dart';
|
import 'package:spotube/services/kv_store/kv_store.dart';
|
||||||
import 'package:spotube/services/logger/logger.dart';
|
import 'package:spotube/services/logger/logger.dart';
|
||||||
import 'package:spotube/services/wm_tools/wm_tools.dart';
|
import 'package:spotube/services/wm_tools/wm_tools.dart';
|
||||||
import 'package:spotube/src/plugin_api/webview/webview_binding.dart';
|
|
||||||
import 'package:spotube/src/rust/api/plugin/models/core.dart';
|
import 'package:spotube/src/rust/api/plugin/models/core.dart';
|
||||||
import 'package:spotube/src/rust/api/plugin/plugin.dart';
|
import 'package:spotube/src/rust/api/plugin/plugin.dart';
|
||||||
import 'package:spotube/src/rust/frb_generated.dart';
|
import 'package:spotube/src/rust/frb_generated.dart';
|
||||||
@ -99,44 +98,6 @@ Future<void> main(List<String> rawArgs) async {
|
|||||||
await KVStoreService.initialize();
|
await KVStoreService.initialize();
|
||||||
|
|
||||||
await RustLib.init();
|
await RustLib.init();
|
||||||
WebViewBinding.register();
|
|
||||||
|
|
||||||
final plugin = SpotubePlugin();
|
|
||||||
const pluginConfiguration = PluginConfiguration(
|
|
||||||
name: "Spotube Plugin",
|
|
||||||
description: "Spotube Plugin",
|
|
||||||
version: "1.0.0",
|
|
||||||
author: "Spotube",
|
|
||||||
entryPoint: "Plugin",
|
|
||||||
pluginApiVersion: "2.0.0",
|
|
||||||
apis: [PluginApi.localstorage, PluginApi.webview],
|
|
||||||
abilities: [PluginAbility.metadata],
|
|
||||||
);
|
|
||||||
final pluginContext = plugin.createContext(
|
|
||||||
pluginScript: """
|
|
||||||
class AuthEndpoint {
|
|
||||||
}
|
|
||||||
class CoreEndpoint {
|
|
||||||
async checkUpdate() {
|
|
||||||
const webview = await Webview.create("https://spotube.krtirtho.dev");
|
|
||||||
webview.events.on("url_change", (url) => {
|
|
||||||
console.log("url_change: ", url);
|
|
||||||
})
|
|
||||||
await webview.open();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
class Plugin {
|
|
||||||
constructor() {
|
|
||||||
this.auth = new AuthEndpoint();
|
|
||||||
this.core = new CoreEndpoint();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
""",
|
|
||||||
pluginConfig: pluginConfiguration,
|
|
||||||
);
|
|
||||||
|
|
||||||
await plugin.core
|
|
||||||
.checkUpdate(mpscTx: pluginContext, pluginConfig: pluginConfiguration);
|
|
||||||
|
|
||||||
if (kIsDesktop) {
|
if (kIsDesktop) {
|
||||||
await windowManager.setPreventClose(true);
|
await windowManager.setPreventClose(true);
|
||||||
@ -217,6 +178,58 @@ class Spotube extends HookConsumerWidget {
|
|||||||
HomeWidget.registerInteractivityCallback(glanceBackgroundCallback);
|
HomeWidget.registerInteractivityCallback(glanceBackgroundCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
start() async {
|
||||||
|
final server = await ref.read(serverProvider.future);
|
||||||
|
|
||||||
|
final plugin = SpotubePlugin();
|
||||||
|
const pluginConfiguration = PluginConfiguration(
|
||||||
|
name: "Spotube Plugin",
|
||||||
|
description: "Spotube Plugin",
|
||||||
|
version: "1.0.0",
|
||||||
|
author: "Spotube",
|
||||||
|
entryPoint: "Plugin",
|
||||||
|
pluginApiVersion: "2.0.0",
|
||||||
|
apis: [PluginApi.localstorage, PluginApi.webview],
|
||||||
|
abilities: [PluginAbility.metadata],
|
||||||
|
);
|
||||||
|
final pluginContext = plugin.createContext(
|
||||||
|
serverEndpointUrl:
|
||||||
|
"http://${server.server.address.host}:${server.port}",
|
||||||
|
serverSecret: ref.read(serverRandomSecretProvider),
|
||||||
|
pluginScript: """
|
||||||
|
class AuthEndpoint {
|
||||||
|
}
|
||||||
|
class CoreEndpoint {
|
||||||
|
async checkUpdate() {
|
||||||
|
console.log(globalThis);
|
||||||
|
const webview = await WebView.create("https://spotube.krtirtho.dev");
|
||||||
|
webview.onUrlChange((url) => {
|
||||||
|
console.log("url_request: ", url);
|
||||||
|
if (url.includes("/about")) {
|
||||||
|
webview.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
await webview.open();
|
||||||
|
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 5000));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class Plugin {
|
||||||
|
constructor() {
|
||||||
|
this.auth = new AuthEndpoint();
|
||||||
|
this.core = new CoreEndpoint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
pluginConfig: pluginConfiguration,
|
||||||
|
);
|
||||||
|
|
||||||
|
await plugin.core.checkUpdate(
|
||||||
|
mpscTx: pluginContext, pluginConfig: pluginConfiguration);
|
||||||
|
}
|
||||||
|
|
||||||
|
start();
|
||||||
|
|
||||||
return () {
|
return () {
|
||||||
/// For enabling hot reload for audio player
|
/// For enabling hot reload for audio player
|
||||||
if (!kDebugMode) return;
|
if (!kDebugMode) return;
|
||||||
|
|||||||
@ -3,10 +3,23 @@ import 'package:shelf/shelf.dart';
|
|||||||
import 'package:shelf_router/shelf_router.dart';
|
import 'package:shelf_router/shelf_router.dart';
|
||||||
import 'package:spotube/provider/server/routes/connect.dart';
|
import 'package:spotube/provider/server/routes/connect.dart';
|
||||||
import 'package:spotube/provider/server/routes/playback.dart';
|
import 'package:spotube/provider/server/routes/playback.dart';
|
||||||
|
import 'package:spotube/provider/server/routes/plugin_apis/webview.dart';
|
||||||
|
|
||||||
|
Handler pluginApiAuthMiddleware(Handler handler) {
|
||||||
|
return (Request request) {
|
||||||
|
final apiKey = request.headers['X-Plugin-Secret'] ??
|
||||||
|
request.url.queryParameters['secret'];
|
||||||
|
if (apiKey == null || apiKey != request.context['plugin_api_secret']) {
|
||||||
|
return Response.forbidden('Forbidden');
|
||||||
|
}
|
||||||
|
return handler(request);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
final serverRouterProvider = Provider((ref) {
|
final serverRouterProvider = Provider((ref) {
|
||||||
final playbackRoutes = ref.watch(serverPlaybackRoutesProvider);
|
final playbackRoutes = ref.watch(serverPlaybackRoutesProvider);
|
||||||
final connectRoutes = ref.watch(serverConnectRoutesProvider);
|
final connectRoutes = ref.watch(serverConnectRoutesProvider);
|
||||||
|
final webviewRoutes = ref.watch(serverWebviewRoutesProvider);
|
||||||
|
|
||||||
final router = Router();
|
final router = Router();
|
||||||
|
|
||||||
@ -19,7 +32,32 @@ final serverRouterProvider = Provider((ref) {
|
|||||||
router.get("/playback/previous", playbackRoutes.previousTrack);
|
router.get("/playback/previous", playbackRoutes.previousTrack);
|
||||||
router.get("/playback/next", playbackRoutes.nextTrack);
|
router.get("/playback/next", playbackRoutes.nextTrack);
|
||||||
|
|
||||||
|
router.post(
|
||||||
|
"/plugin-api/webview/create",
|
||||||
|
pluginApiAuthMiddleware(webviewRoutes.postCreateWebview),
|
||||||
|
);
|
||||||
|
router.get(
|
||||||
|
"/plugin-api/webview/<uid>/on-url-request",
|
||||||
|
pluginApiAuthMiddleware(webviewRoutes.getOnUrlRequestStream),
|
||||||
|
);
|
||||||
|
router.post(
|
||||||
|
"/plugin-api/webview/open",
|
||||||
|
pluginApiAuthMiddleware(webviewRoutes.postOpenWebview),
|
||||||
|
);
|
||||||
|
router.post(
|
||||||
|
"/plugin-api/webview/close",
|
||||||
|
pluginApiAuthMiddleware(webviewRoutes.postCloseWebview),
|
||||||
|
);
|
||||||
|
router.post(
|
||||||
|
"/plugin-api/webview/cookies",
|
||||||
|
pluginApiAuthMiddleware(webviewRoutes.postGetWebviewCookies),
|
||||||
|
);
|
||||||
|
|
||||||
router.all("/ws", connectRoutes.websocket);
|
router.all("/ws", connectRoutes.websocket);
|
||||||
|
|
||||||
|
ref.onDispose(() {
|
||||||
|
webviewRoutes.dispose();
|
||||||
|
});
|
||||||
|
|
||||||
return router;
|
return router;
|
||||||
});
|
});
|
||||||
|
|||||||
134
lib/provider/server/routes/plugin_apis/webview.dart
Normal file
134
lib/provider/server/routes/plugin_apis/webview.dart
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:shadcn_flutter/shadcn_flutter.dart';
|
||||||
|
import 'package:shelf/shelf.dart';
|
||||||
|
import 'package:shelf_router/shelf_router.dart';
|
||||||
|
import 'package:spotube/src/plugin_api/webview/webview.dart';
|
||||||
|
import 'package:async/async.dart';
|
||||||
|
|
||||||
|
class ServerWebviewRoutes {
|
||||||
|
final Map<String, Webview> _webviews = {};
|
||||||
|
|
||||||
|
Future<Response> postCreateWebview(Request request) async {
|
||||||
|
final payload = jsonDecode(await request.readAsString());
|
||||||
|
final uri = Uri.parse(payload['url'] as String);
|
||||||
|
|
||||||
|
final webview = Webview(uri: uri.toString());
|
||||||
|
_webviews[webview.uid] = webview;
|
||||||
|
return Response.ok(
|
||||||
|
jsonEncode({'uid': webview.uid}),
|
||||||
|
encoding: utf8,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Response> getOnUrlRequestStream(Request request) async {
|
||||||
|
final uid = request.params["uid"];
|
||||||
|
|
||||||
|
final webview = _webviews[uid];
|
||||||
|
if (webview == null) {
|
||||||
|
return Response.notFound('Webview with uid $uid not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a stream that merges URL events with keepalive pings
|
||||||
|
final controller = StreamController<List<int>>();
|
||||||
|
|
||||||
|
// Send keepalive comment every 15 seconds to prevent connection timeout
|
||||||
|
final keepaliveTimer = Stream.periodic(
|
||||||
|
const Duration(seconds: 15),
|
||||||
|
(_) => utf8.encode(": keepalive\n\n"),
|
||||||
|
);
|
||||||
|
|
||||||
|
final urlStream = webview.onUrlRequestStream.map((url) {
|
||||||
|
return utf8.encode("event: url-request\n"
|
||||||
|
"data: ${jsonEncode({'url': url})}\n\n");
|
||||||
|
});
|
||||||
|
|
||||||
|
// Merge both streams
|
||||||
|
final subscription = StreamGroup.merge([keepaliveTimer, urlStream]).listen(
|
||||||
|
(data) {
|
||||||
|
if (!controller.isClosed) {
|
||||||
|
controller.add(data);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onDone: () {
|
||||||
|
controller.close();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// Clean up when client disconnects
|
||||||
|
controller.onCancel = () {
|
||||||
|
debugPrint('Webview $uid client disconnected');
|
||||||
|
subscription.cancel();
|
||||||
|
};
|
||||||
|
|
||||||
|
return Response.ok(
|
||||||
|
controller.stream,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/event-stream',
|
||||||
|
'Cache-Control': 'no-cache',
|
||||||
|
'Connection': 'keep-alive',
|
||||||
|
'X-Accel-Buffering': 'no', // Disable buffering for nginx
|
||||||
|
},
|
||||||
|
encoding: utf8,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Response> postOpenWebview(Request request) async {
|
||||||
|
final body = jsonDecode(await request.readAsString());
|
||||||
|
final uid = body['uid'] as String;
|
||||||
|
|
||||||
|
final webview = _webviews[uid];
|
||||||
|
if (webview == null) {
|
||||||
|
return Response.notFound('Webview with uid $uid not found');
|
||||||
|
}
|
||||||
|
await webview.open();
|
||||||
|
return Response.ok(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Response> postCloseWebview(Request request) async {
|
||||||
|
final body = jsonDecode(await request.readAsString());
|
||||||
|
final uid = body['uid'] as String;
|
||||||
|
|
||||||
|
final webview = _webviews[uid];
|
||||||
|
if (webview == null) {
|
||||||
|
return Response.notFound('Webview with uid $uid not found');
|
||||||
|
}
|
||||||
|
await webview.close();
|
||||||
|
|
||||||
|
_webviews.remove(uid);
|
||||||
|
return Response.ok(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Response> postGetWebviewCookies(Request request) async {
|
||||||
|
final body = jsonDecode(await request.readAsString());
|
||||||
|
final uid = body['uid'] as String;
|
||||||
|
final url = body['url'] as String;
|
||||||
|
|
||||||
|
final webview = _webviews[uid];
|
||||||
|
if (webview == null) {
|
||||||
|
return Response.notFound('Webview with uid $uid not found');
|
||||||
|
}
|
||||||
|
final cookies = await webview.getCookies(url);
|
||||||
|
return Response.ok(
|
||||||
|
jsonEncode(cookies),
|
||||||
|
encoding: utf8,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> dispose() async {
|
||||||
|
for (final webview in _webviews.values) {
|
||||||
|
await webview.close();
|
||||||
|
}
|
||||||
|
_webviews.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final serverWebviewRoutesProvider = Provider((ref) => ServerWebviewRoutes());
|
||||||
@ -1,7 +1,9 @@
|
|||||||
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:shelf/shelf.dart';
|
||||||
import 'package:shelf/shelf_io.dart';
|
import 'package:shelf/shelf_io.dart';
|
||||||
import 'package:spotube/provider/server/pipeline.dart';
|
import 'package:spotube/provider/server/pipeline.dart';
|
||||||
import 'package:spotube/provider/server/router.dart';
|
import 'package:spotube/provider/server/router.dart';
|
||||||
@ -9,8 +11,16 @@ import 'package:spotube/provider/user_preferences/user_preferences_provider.dart
|
|||||||
import 'package:spotube/services/audio_player/audio_player.dart';
|
import 'package:spotube/services/audio_player/audio_player.dart';
|
||||||
import 'package:spotube/services/logger/logger.dart';
|
import 'package:spotube/services/logger/logger.dart';
|
||||||
|
|
||||||
|
final serverRandomSecretProvider = Provider<String>(
|
||||||
|
(ref) {
|
||||||
|
final random = Random.secure();
|
||||||
|
final values = List<int>.generate(16, (i) => random.nextInt(256));
|
||||||
|
return base64Url.encode(values);
|
||||||
|
},
|
||||||
|
);
|
||||||
final serverProvider = FutureProvider(
|
final serverProvider = FutureProvider(
|
||||||
(ref) async {
|
(ref) async {
|
||||||
|
final randomSecret = ref.watch(serverRandomSecretProvider);
|
||||||
final enabledRemoteConnect = ref.watch(
|
final enabledRemoteConnect = ref.watch(
|
||||||
userPreferencesProvider.select((value) => value.enableConnect),
|
userPreferencesProvider.select((value) => value.enableConnect),
|
||||||
);
|
);
|
||||||
@ -31,8 +41,21 @@ final serverProvider = FutureProvider(
|
|||||||
SpotubeMedia.serverPort = connectPort;
|
SpotubeMedia.serverPort = connectPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final handler = pipeline.addMiddleware(logRequests()).addMiddleware(
|
||||||
|
(innerHandler) {
|
||||||
|
return (request) {
|
||||||
|
final updatedRequest = request.change(
|
||||||
|
context: {
|
||||||
|
'plugin_api_secret': randomSecret,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return innerHandler(updatedRequest);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
).addHandler(router.call);
|
||||||
|
|
||||||
final server = await serve(
|
final server = await serve(
|
||||||
pipeline.addHandler(router.call),
|
handler,
|
||||||
enabledRemoteConnect
|
enabledRemoteConnect
|
||||||
? InternetAddress.anyIPv4
|
? InternetAddress.anyIPv4
|
||||||
: InternetAddress.loopbackIPv4,
|
: InternetAddress.loopbackIPv4,
|
||||||
|
|||||||
@ -22,7 +22,6 @@ class Webview {
|
|||||||
required this.uri,
|
required this.uri,
|
||||||
}) : _onUrlRequestStreamController = StreamController<String>.broadcast(),
|
}) : _onUrlRequestStreamController = StreamController<String>.broadcast(),
|
||||||
uid = const Uuid().v4();
|
uid = const Uuid().v4();
|
||||||
|
|
||||||
StreamController<String>? _onUrlRequestStreamController;
|
StreamController<String>? _onUrlRequestStreamController;
|
||||||
Stream<String> get onUrlRequestStream =>
|
Stream<String> get onUrlRequestStream =>
|
||||||
_onUrlRequestStreamController!.stream;
|
_onUrlRequestStreamController!.stream;
|
||||||
|
|||||||
@ -1,40 +0,0 @@
|
|||||||
import 'dart:async';
|
|
||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:spotube/services/logger/logger.dart';
|
|
||||||
import 'package:spotube/src/plugin_api/webview/webview.dart';
|
|
||||||
import 'package:spotube/src/rust/api/host_api/webview.dart';
|
|
||||||
|
|
||||||
class WebViewBinding {
|
|
||||||
static void register() async {
|
|
||||||
final subscriptions = <String, StreamSubscription>{};
|
|
||||||
|
|
||||||
await initializeWebviewCallbacks(
|
|
||||||
createWebview: (uri, sender) async {
|
|
||||||
final webview = Webview(uri: uri);
|
|
||||||
|
|
||||||
subscriptions[webview.uid] =
|
|
||||||
webview.onUrlRequestStream.listen((event) async {
|
|
||||||
try {
|
|
||||||
await sendWebviewEvents(tx: sender, event: event);
|
|
||||||
} catch (e, stack) {
|
|
||||||
AppLogger.reportError(e, stack);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return webview;
|
|
||||||
},
|
|
||||||
openWebview: (webview) async {
|
|
||||||
await (webview as Webview).open();
|
|
||||||
},
|
|
||||||
closeWebview: (webview) async {
|
|
||||||
subscriptions.remove((webview as Webview).uid);
|
|
||||||
await webview.close();
|
|
||||||
},
|
|
||||||
getCookies: (webview, url) async {
|
|
||||||
final cookies = await (webview as Webview).getCookies(url);
|
|
||||||
return jsonEncode(cookies);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
// This file is automatically generated, so please do not edit it.
|
|
||||||
// @generated by `flutter_rust_bridge`@ 2.11.1.
|
|
||||||
|
|
||||||
// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import
|
|
||||||
|
|
||||||
import '../../frb_generated.dart';
|
|
||||||
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
|
||||||
|
|
||||||
// These types are ignored because they are neither used by any `pub` functions nor (for structs and enums) marked `#[frb(unignore)]`: `DART_CLOSE_WEBVIEW`, `DART_CREATE_WEBVIEW`, `DART_GET_COOKIES`, `DART_OPEN_WEBVIEW`, `HostWebview`, `Webview`
|
|
||||||
// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `deref`, `deref`, `deref`, `deref`, `initialize`, `initialize`, `initialize`, `initialize`, `trace`
|
|
||||||
// These functions are ignored (category: IgnoreBecauseExplicitAttribute): `close`, `close`, `create`, `create`, `get_cookies`, `get_cookies`, `open`, `open`, `poll_url_change_event`
|
|
||||||
|
|
||||||
Future<void> initializeWebviewCallbacks(
|
|
||||||
{required FutureOr<Object> Function(String, BroadcastSenderString)
|
|
||||||
createWebview,
|
|
||||||
required FutureOr<void> Function(Object) openWebview,
|
|
||||||
required FutureOr<void> Function(Object) closeWebview,
|
|
||||||
required FutureOr<String> Function(Object, String) getCookies}) =>
|
|
||||||
RustLib.instance.api.crateApiHostApiWebviewInitializeWebviewCallbacks(
|
|
||||||
createWebview: createWebview,
|
|
||||||
openWebview: openWebview,
|
|
||||||
closeWebview: closeWebview,
|
|
||||||
getCookies: getCookies);
|
|
||||||
|
|
||||||
Future<void> sendWebviewEvents(
|
|
||||||
{required BroadcastSenderString tx, required String event}) =>
|
|
||||||
RustLib.instance.api
|
|
||||||
.crateApiHostApiWebviewSendWebviewEvents(tx: tx, event: event);
|
|
||||||
|
|
||||||
// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<BroadcastSender < String >>>
|
|
||||||
abstract class BroadcastSenderString implements RustOpaqueInterface {}
|
|
||||||
@ -12,7 +12,6 @@ import 'senders.dart';
|
|||||||
|
|
||||||
// These functions are ignored because they are not marked as `pub`: `create_context`, `js_executor_thread`
|
// These functions are ignored because they are not marked as `pub`: `create_context`, `js_executor_thread`
|
||||||
// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `clone`, `fmt`
|
// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `clone`, `fmt`
|
||||||
// These functions are ignored (category: IgnoreBecauseExplicitAttribute): `open_webview`
|
|
||||||
|
|
||||||
// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<OpaqueSender>>
|
// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<OpaqueSender>>
|
||||||
abstract class OpaqueSender implements RustOpaqueInterface {
|
abstract class OpaqueSender implements RustOpaqueInterface {
|
||||||
@ -69,7 +68,9 @@ abstract class SpotubePlugin implements RustOpaqueInterface {
|
|||||||
|
|
||||||
OpaqueSender createContext(
|
OpaqueSender createContext(
|
||||||
{required String pluginScript,
|
{required String pluginScript,
|
||||||
required PluginConfiguration pluginConfig});
|
required PluginConfiguration pluginConfig,
|
||||||
|
required String serverEndpointUrl,
|
||||||
|
required String serverSecret});
|
||||||
|
|
||||||
factory SpotubePlugin() =>
|
factory SpotubePlugin() =>
|
||||||
RustLib.instance.api.crateApiPluginPluginSpotubePluginNew();
|
RustLib.instance.api.crateApiPluginPluginSpotubePluginNew();
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
// ignore_for_file: unused_import, unused_element, unnecessary_import, duplicate_ignore, invalid_use_of_internal_member, annotate_overrides, non_constant_identifier_names, curly_braces_in_flow_control_structures, prefer_const_literals_to_create_immutables, unused_field
|
// ignore_for_file: unused_import, unused_element, unnecessary_import, duplicate_ignore, invalid_use_of_internal_member, annotate_overrides, non_constant_identifier_names, curly_braces_in_flow_control_structures, prefer_const_literals_to_create_immutables, unused_field
|
||||||
|
|
||||||
import 'api/host_api/webview.dart';
|
|
||||||
import 'api/plugin/commands.dart';
|
import 'api/plugin/commands.dart';
|
||||||
import 'api/plugin/models/album.dart';
|
import 'api/plugin/models/album.dart';
|
||||||
import 'api/plugin/models/artist.dart';
|
import 'api/plugin/models/artist.dart';
|
||||||
@ -86,7 +85,7 @@ class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
|
|||||||
String get codegenVersion => '2.11.1';
|
String get codegenVersion => '2.11.1';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get rustContentHash => 1149066488;
|
int get rustContentHash => 1716120288;
|
||||||
|
|
||||||
static const kDefaultExternalLibraryLoaderConfig =
|
static const kDefaultExternalLibraryLoaderConfig =
|
||||||
ExternalLibraryLoaderConfig(
|
ExternalLibraryLoaderConfig(
|
||||||
@ -174,19 +173,14 @@ abstract class RustLibApi extends BaseApi {
|
|||||||
OpaqueSender crateApiPluginPluginSpotubePluginCreateContext(
|
OpaqueSender crateApiPluginPluginSpotubePluginCreateContext(
|
||||||
{required SpotubePlugin that,
|
{required SpotubePlugin that,
|
||||||
required String pluginScript,
|
required String pluginScript,
|
||||||
required PluginConfiguration pluginConfig});
|
required PluginConfiguration pluginConfig,
|
||||||
|
required String serverEndpointUrl,
|
||||||
|
required String serverSecret});
|
||||||
|
|
||||||
SpotubePlugin crateApiPluginPluginSpotubePluginNew();
|
SpotubePlugin crateApiPluginPluginSpotubePluginNew();
|
||||||
|
|
||||||
Future<void> crateApiInitApp();
|
Future<void> crateApiInitApp();
|
||||||
|
|
||||||
Future<void> crateApiHostApiWebviewInitializeWebviewCallbacks(
|
|
||||||
{required FutureOr<Object> Function(String, BroadcastSenderString)
|
|
||||||
createWebview,
|
|
||||||
required FutureOr<void> Function(Object) openWebview,
|
|
||||||
required FutureOr<void> Function(Object) closeWebview,
|
|
||||||
required FutureOr<String> Function(Object, String) getCookies});
|
|
||||||
|
|
||||||
Future<SpotubeFullAlbumObject> crateApiPluginSendersPluginAlbumSenderGetAlbum(
|
Future<SpotubeFullAlbumObject> crateApiPluginSendersPluginAlbumSenderGetAlbum(
|
||||||
{required PluginAlbumSender that,
|
{required PluginAlbumSender that,
|
||||||
required OpaqueSender mpscTx,
|
required OpaqueSender mpscTx,
|
||||||
@ -463,9 +457,6 @@ abstract class RustLibApi extends BaseApi {
|
|||||||
int? offset,
|
int? offset,
|
||||||
int? limit});
|
int? limit});
|
||||||
|
|
||||||
Future<void> crateApiHostApiWebviewSendWebviewEvents(
|
|
||||||
{required BroadcastSenderString tx, required String event});
|
|
||||||
|
|
||||||
String
|
String
|
||||||
crateApiPluginModelsAudioSourceSpotubeAudioLosslessContainerQualityToStringFmt(
|
crateApiPluginModelsAudioSourceSpotubeAudioLosslessContainerQualityToStringFmt(
|
||||||
{required SpotubeAudioLosslessContainerQuality that});
|
{required SpotubeAudioLosslessContainerQuality that});
|
||||||
@ -478,15 +469,6 @@ abstract class RustLibApi extends BaseApi {
|
|||||||
crateApiPluginModelsAudioSourceSpotubeAudioSourceContainerPresetFileExtension(
|
crateApiPluginModelsAudioSourceSpotubeAudioSourceContainerPresetFileExtension(
|
||||||
{required SpotubeAudioSourceContainerPreset that});
|
{required SpotubeAudioSourceContainerPreset that});
|
||||||
|
|
||||||
RustArcIncrementStrongCountFnType
|
|
||||||
get rust_arc_increment_strong_count_BroadcastSenderString;
|
|
||||||
|
|
||||||
RustArcDecrementStrongCountFnType
|
|
||||||
get rust_arc_decrement_strong_count_BroadcastSenderString;
|
|
||||||
|
|
||||||
CrossPlatformFinalizerArg
|
|
||||||
get rust_arc_decrement_strong_count_BroadcastSenderStringPtr;
|
|
||||||
|
|
||||||
RustArcIncrementStrongCountFnType
|
RustArcIncrementStrongCountFnType
|
||||||
get rust_arc_increment_strong_count_OpaqueSender;
|
get rust_arc_increment_strong_count_OpaqueSender;
|
||||||
|
|
||||||
@ -1219,7 +1201,9 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
OpaqueSender crateApiPluginPluginSpotubePluginCreateContext(
|
OpaqueSender crateApiPluginPluginSpotubePluginCreateContext(
|
||||||
{required SpotubePlugin that,
|
{required SpotubePlugin that,
|
||||||
required String pluginScript,
|
required String pluginScript,
|
||||||
required PluginConfiguration pluginConfig}) {
|
required PluginConfiguration pluginConfig,
|
||||||
|
required String serverEndpointUrl,
|
||||||
|
required String serverSecret}) {
|
||||||
return handler.executeSync(SyncTask(
|
return handler.executeSync(SyncTask(
|
||||||
callFfi: () {
|
callFfi: () {
|
||||||
final serializer = SseSerializer(generalizedFrbRustBinding);
|
final serializer = SseSerializer(generalizedFrbRustBinding);
|
||||||
@ -1227,6 +1211,8 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
that, serializer);
|
that, serializer);
|
||||||
sse_encode_String(pluginScript, serializer);
|
sse_encode_String(pluginScript, serializer);
|
||||||
sse_encode_box_autoadd_plugin_configuration(pluginConfig, serializer);
|
sse_encode_box_autoadd_plugin_configuration(pluginConfig, serializer);
|
||||||
|
sse_encode_String(serverEndpointUrl, serializer);
|
||||||
|
sse_encode_String(serverSecret, serializer);
|
||||||
return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 25)!;
|
return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 25)!;
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
@ -1235,7 +1221,13 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
decodeErrorData: sse_decode_AnyhowException,
|
decodeErrorData: sse_decode_AnyhowException,
|
||||||
),
|
),
|
||||||
constMeta: kCrateApiPluginPluginSpotubePluginCreateContextConstMeta,
|
constMeta: kCrateApiPluginPluginSpotubePluginCreateContextConstMeta,
|
||||||
argValues: [that, pluginScript, pluginConfig],
|
argValues: [
|
||||||
|
that,
|
||||||
|
pluginScript,
|
||||||
|
pluginConfig,
|
||||||
|
serverEndpointUrl,
|
||||||
|
serverSecret
|
||||||
|
],
|
||||||
apiImpl: this,
|
apiImpl: this,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -1243,7 +1235,13 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
TaskConstMeta get kCrateApiPluginPluginSpotubePluginCreateContextConstMeta =>
|
TaskConstMeta get kCrateApiPluginPluginSpotubePluginCreateContextConstMeta =>
|
||||||
const TaskConstMeta(
|
const TaskConstMeta(
|
||||||
debugName: "SpotubePlugin_create_context",
|
debugName: "SpotubePlugin_create_context",
|
||||||
argNames: ["that", "pluginScript", "pluginConfig"],
|
argNames: [
|
||||||
|
"that",
|
||||||
|
"pluginScript",
|
||||||
|
"pluginConfig",
|
||||||
|
"serverEndpointUrl",
|
||||||
|
"serverSecret"
|
||||||
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -1293,49 +1291,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
argNames: [],
|
argNames: [],
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> crateApiHostApiWebviewInitializeWebviewCallbacks(
|
|
||||||
{required FutureOr<Object> Function(String, BroadcastSenderString)
|
|
||||||
createWebview,
|
|
||||||
required FutureOr<void> Function(Object) openWebview,
|
|
||||||
required FutureOr<void> Function(Object) closeWebview,
|
|
||||||
required FutureOr<String> Function(Object, String) getCookies}) {
|
|
||||||
return handler.executeNormal(NormalTask(
|
|
||||||
callFfi: (port_) {
|
|
||||||
final serializer = SseSerializer(generalizedFrbRustBinding);
|
|
||||||
sse_encode_DartFn_Inputs_String_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString_Output_DartOpaque_AnyhowException(
|
|
||||||
createWebview, serializer);
|
|
||||||
sse_encode_DartFn_Inputs_DartOpaque_Output_unit_AnyhowException(
|
|
||||||
openWebview, serializer);
|
|
||||||
sse_encode_DartFn_Inputs_DartOpaque_Output_unit_AnyhowException(
|
|
||||||
closeWebview, serializer);
|
|
||||||
sse_encode_DartFn_Inputs_DartOpaque_String_Output_String_AnyhowException(
|
|
||||||
getCookies, serializer);
|
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
|
||||||
funcId: 28, port: port_);
|
|
||||||
},
|
|
||||||
codec: SseCodec(
|
|
||||||
decodeSuccessData: sse_decode_unit,
|
|
||||||
decodeErrorData: sse_decode_AnyhowException,
|
|
||||||
),
|
|
||||||
constMeta: kCrateApiHostApiWebviewInitializeWebviewCallbacksConstMeta,
|
|
||||||
argValues: [createWebview, openWebview, closeWebview, getCookies],
|
|
||||||
apiImpl: this,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
TaskConstMeta
|
|
||||||
get kCrateApiHostApiWebviewInitializeWebviewCallbacksConstMeta =>
|
|
||||||
const TaskConstMeta(
|
|
||||||
debugName: "initialize_webview_callbacks",
|
|
||||||
argNames: [
|
|
||||||
"createWebview",
|
|
||||||
"openWebview",
|
|
||||||
"closeWebview",
|
|
||||||
"getCookies"
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<SpotubeFullAlbumObject> crateApiPluginSendersPluginAlbumSenderGetAlbum(
|
Future<SpotubeFullAlbumObject> crateApiPluginSendersPluginAlbumSenderGetAlbum(
|
||||||
{required PluginAlbumSender that,
|
{required PluginAlbumSender that,
|
||||||
@ -1349,7 +1304,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
mpscTx, serializer);
|
mpscTx, serializer);
|
||||||
sse_encode_String(id, serializer);
|
sse_encode_String(id, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 29, port: port_);
|
funcId: 28, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_spotube_full_album_object,
|
decodeSuccessData: sse_decode_spotube_full_album_object,
|
||||||
@ -1383,7 +1338,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
||||||
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 30, port: port_);
|
funcId: 29, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
||||||
@ -1414,7 +1369,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
mpscTx, serializer);
|
mpscTx, serializer);
|
||||||
sse_encode_list_String(ids, serializer);
|
sse_encode_list_String(ids, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 31, port: port_);
|
funcId: 30, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_unit,
|
decodeSuccessData: sse_decode_unit,
|
||||||
@ -1450,7 +1405,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
||||||
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 32, port: port_);
|
funcId: 31, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
||||||
@ -1481,7 +1436,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
mpscTx, serializer);
|
mpscTx, serializer);
|
||||||
sse_encode_list_String(ids, serializer);
|
sse_encode_list_String(ids, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 33, port: port_);
|
funcId: 32, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_unit,
|
decodeSuccessData: sse_decode_unit,
|
||||||
@ -1517,7 +1472,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
||||||
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 34, port: port_);
|
funcId: 33, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
||||||
@ -1549,7 +1504,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
mpscTx, serializer);
|
mpscTx, serializer);
|
||||||
sse_encode_String(id, serializer);
|
sse_encode_String(id, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 35, port: port_);
|
funcId: 34, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_spotube_full_artist_object,
|
decodeSuccessData: sse_decode_spotube_full_artist_object,
|
||||||
@ -1586,7 +1541,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
||||||
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 36, port: port_);
|
funcId: 35, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
||||||
@ -1617,7 +1572,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
mpscTx, serializer);
|
mpscTx, serializer);
|
||||||
sse_encode_list_String(ids, serializer);
|
sse_encode_list_String(ids, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 37, port: port_);
|
funcId: 36, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_unit,
|
decodeSuccessData: sse_decode_unit,
|
||||||
@ -1653,7 +1608,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
||||||
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 38, port: port_);
|
funcId: 37, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
||||||
@ -1685,7 +1640,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
mpscTx, serializer);
|
mpscTx, serializer);
|
||||||
sse_encode_list_String(ids, serializer);
|
sse_encode_list_String(ids, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 39, port: port_);
|
funcId: 38, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_unit,
|
decodeSuccessData: sse_decode_unit,
|
||||||
@ -1717,7 +1672,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
mpscTx, serializer);
|
mpscTx, serializer);
|
||||||
sse_encode_box_autoadd_spotube_track_object(track, serializer);
|
sse_encode_box_autoadd_spotube_track_object(track, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 40, port: port_);
|
funcId: 39, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_list_spotube_audio_source_match_object,
|
decodeSuccessData: sse_decode_list_spotube_audio_source_match_object,
|
||||||
@ -1751,7 +1706,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_box_autoadd_spotube_audio_source_match_object(
|
sse_encode_box_autoadd_spotube_audio_source_match_object(
|
||||||
matched, serializer);
|
matched, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 41, port: port_);
|
funcId: 40, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_list_spotube_audio_source_stream_object,
|
decodeSuccessData: sse_decode_list_spotube_audio_source_stream_object,
|
||||||
@ -1780,7 +1735,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
||||||
mpscTx, serializer);
|
mpscTx, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 42, port: port_);
|
funcId: 41, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_unit,
|
decodeSuccessData: sse_decode_unit,
|
||||||
@ -1809,7 +1764,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
||||||
mpscTx, serializer);
|
mpscTx, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 43, port: port_);
|
funcId: 42, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_bool,
|
decodeSuccessData: sse_decode_bool,
|
||||||
@ -1838,7 +1793,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
||||||
mpscTx, serializer);
|
mpscTx, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 44, port: port_);
|
funcId: 43, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_unit,
|
decodeSuccessData: sse_decode_unit,
|
||||||
@ -1874,7 +1829,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
||||||
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 45, port: port_);
|
funcId: 44, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
||||||
@ -1909,7 +1864,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
||||||
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 46, port: port_);
|
funcId: 45, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
||||||
@ -1935,7 +1890,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
final serializer = SseSerializer(generalizedFrbRustBinding);
|
final serializer = SseSerializer(generalizedFrbRustBinding);
|
||||||
sse_encode_box_autoadd_plugin_configuration(that, serializer);
|
sse_encode_box_autoadd_plugin_configuration(that, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 47, port: port_);
|
funcId: 46, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_String,
|
decodeSuccessData: sse_decode_String,
|
||||||
@ -1967,7 +1922,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
mpscTx, serializer);
|
mpscTx, serializer);
|
||||||
sse_encode_box_autoadd_plugin_configuration(pluginConfig, serializer);
|
sse_encode_box_autoadd_plugin_configuration(pluginConfig, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 48, port: port_);
|
funcId: 47, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_opt_box_autoadd_plugin_update_available,
|
decodeSuccessData: sse_decode_opt_box_autoadd_plugin_update_available,
|
||||||
@ -1999,7 +1954,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
mpscTx, serializer);
|
mpscTx, serializer);
|
||||||
sse_encode_box_autoadd_scrobble_details(details, serializer);
|
sse_encode_box_autoadd_scrobble_details(details, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 49, port: port_);
|
funcId: 48, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_unit,
|
decodeSuccessData: sse_decode_unit,
|
||||||
@ -2027,7 +1982,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
||||||
mpscTx, serializer);
|
mpscTx, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 50, port: port_);
|
funcId: 49, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_String,
|
decodeSuccessData: sse_decode_String,
|
||||||
@ -2062,7 +2017,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_list_String(trackIds, serializer);
|
sse_encode_list_String(trackIds, serializer);
|
||||||
sse_encode_opt_box_autoadd_u_32(position, serializer);
|
sse_encode_opt_box_autoadd_u_32(position, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 51, port: port_);
|
funcId: 50, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_unit,
|
decodeSuccessData: sse_decode_unit,
|
||||||
@ -2103,7 +2058,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_opt_box_autoadd_bool(public, serializer);
|
sse_encode_opt_box_autoadd_bool(public, serializer);
|
||||||
sse_encode_opt_box_autoadd_bool(collaborative, serializer);
|
sse_encode_opt_box_autoadd_bool(collaborative, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 52, port: port_);
|
funcId: 51, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData:
|
decodeSuccessData:
|
||||||
@ -2153,7 +2108,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
mpscTx, serializer);
|
mpscTx, serializer);
|
||||||
sse_encode_String(playlistId, serializer);
|
sse_encode_String(playlistId, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 53, port: port_);
|
funcId: 52, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_unit,
|
decodeSuccessData: sse_decode_unit,
|
||||||
@ -2187,7 +2142,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
mpscTx, serializer);
|
mpscTx, serializer);
|
||||||
sse_encode_String(id, serializer);
|
sse_encode_String(id, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 54, port: port_);
|
funcId: 53, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_spotube_full_playlist_object,
|
decodeSuccessData: sse_decode_spotube_full_playlist_object,
|
||||||
@ -2221,7 +2176,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_String(playlistId, serializer);
|
sse_encode_String(playlistId, serializer);
|
||||||
sse_encode_list_String(trackIds, serializer);
|
sse_encode_list_String(trackIds, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 55, port: port_);
|
funcId: 54, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_unit,
|
decodeSuccessData: sse_decode_unit,
|
||||||
@ -2254,7 +2209,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
mpscTx, serializer);
|
mpscTx, serializer);
|
||||||
sse_encode_String(playlistId, serializer);
|
sse_encode_String(playlistId, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 56, port: port_);
|
funcId: 55, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_unit,
|
decodeSuccessData: sse_decode_unit,
|
||||||
@ -2290,7 +2245,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
||||||
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 57, port: port_);
|
funcId: 56, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
||||||
@ -2321,7 +2276,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
mpscTx, serializer);
|
mpscTx, serializer);
|
||||||
sse_encode_String(playlistId, serializer);
|
sse_encode_String(playlistId, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 58, port: port_);
|
funcId: 57, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_unit,
|
decodeSuccessData: sse_decode_unit,
|
||||||
@ -2360,7 +2315,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_opt_box_autoadd_bool(public, serializer);
|
sse_encode_opt_box_autoadd_bool(public, serializer);
|
||||||
sse_encode_opt_box_autoadd_bool(collaborative, serializer);
|
sse_encode_opt_box_autoadd_bool(collaborative, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 59, port: port_);
|
funcId: 58, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_unit,
|
decodeSuccessData: sse_decode_unit,
|
||||||
@ -2414,7 +2369,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
||||||
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 60, port: port_);
|
funcId: 59, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
||||||
@ -2446,7 +2401,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
mpscTx, serializer);
|
mpscTx, serializer);
|
||||||
sse_encode_String(query, serializer);
|
sse_encode_String(query, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 61, port: port_);
|
funcId: 60, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_spotube_search_response_object,
|
decodeSuccessData: sse_decode_spotube_search_response_object,
|
||||||
@ -2482,7 +2437,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
||||||
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 62, port: port_);
|
funcId: 61, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
||||||
@ -2510,7 +2465,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
||||||
mpscTx, serializer);
|
mpscTx, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 63, port: port_);
|
funcId: 62, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_list_String,
|
decodeSuccessData: sse_decode_list_String,
|
||||||
@ -2546,7 +2501,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
||||||
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 64, port: port_);
|
funcId: 63, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
||||||
@ -2583,7 +2538,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
||||||
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 65, port: port_);
|
funcId: 64, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
||||||
@ -2614,7 +2569,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
mpscTx, serializer);
|
mpscTx, serializer);
|
||||||
sse_encode_String(id, serializer);
|
sse_encode_String(id, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 66, port: port_);
|
funcId: 65, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_spotube_track_object,
|
decodeSuccessData: sse_decode_spotube_track_object,
|
||||||
@ -2645,7 +2600,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
mpscTx, serializer);
|
mpscTx, serializer);
|
||||||
sse_encode_String(id, serializer);
|
sse_encode_String(id, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 67, port: port_);
|
funcId: 66, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_list_spotube_track_object,
|
decodeSuccessData: sse_decode_list_spotube_track_object,
|
||||||
@ -2676,7 +2631,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
mpscTx, serializer);
|
mpscTx, serializer);
|
||||||
sse_encode_list_String(ids, serializer);
|
sse_encode_list_String(ids, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 68, port: port_);
|
funcId: 67, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_unit,
|
decodeSuccessData: sse_decode_unit,
|
||||||
@ -2707,7 +2662,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
mpscTx, serializer);
|
mpscTx, serializer);
|
||||||
sse_encode_list_String(ids, serializer);
|
sse_encode_list_String(ids, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 69, port: port_);
|
funcId: 68, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_unit,
|
decodeSuccessData: sse_decode_unit,
|
||||||
@ -2735,7 +2690,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
||||||
mpscTx, serializer);
|
mpscTx, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 70, port: port_);
|
funcId: 69, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_spotube_user_object,
|
decodeSuccessData: sse_decode_spotube_user_object,
|
||||||
@ -2769,7 +2724,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
||||||
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 71, port: port_);
|
funcId: 70, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
||||||
@ -2804,7 +2759,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
||||||
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 72, port: port_);
|
funcId: 71, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
||||||
@ -2839,7 +2794,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
||||||
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 73, port: port_);
|
funcId: 72, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
||||||
@ -2874,7 +2829,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
sse_encode_opt_box_autoadd_u_32(offset, serializer);
|
||||||
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
sse_encode_opt_box_autoadd_u_32(limit, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 74, port: port_);
|
funcId: 73, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
decodeSuccessData: sse_decode_spotube_pagination_response_object,
|
||||||
@ -2893,34 +2848,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
argNames: ["that", "mpscTx", "offset", "limit"],
|
argNames: ["that", "mpscTx", "offset", "limit"],
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> crateApiHostApiWebviewSendWebviewEvents(
|
|
||||||
{required BroadcastSenderString tx, required String event}) {
|
|
||||||
return handler.executeNormal(NormalTask(
|
|
||||||
callFfi: (port_) {
|
|
||||||
final serializer = SseSerializer(generalizedFrbRustBinding);
|
|
||||||
sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString(
|
|
||||||
tx, serializer);
|
|
||||||
sse_encode_String(event, serializer);
|
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
|
||||||
funcId: 75, port: port_);
|
|
||||||
},
|
|
||||||
codec: SseCodec(
|
|
||||||
decodeSuccessData: sse_decode_unit,
|
|
||||||
decodeErrorData: sse_decode_AnyhowException,
|
|
||||||
),
|
|
||||||
constMeta: kCrateApiHostApiWebviewSendWebviewEventsConstMeta,
|
|
||||||
argValues: [tx, event],
|
|
||||||
apiImpl: this,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
TaskConstMeta get kCrateApiHostApiWebviewSendWebviewEventsConstMeta =>
|
|
||||||
const TaskConstMeta(
|
|
||||||
debugName: "send_webview_events",
|
|
||||||
argNames: ["tx", "event"],
|
|
||||||
);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String
|
String
|
||||||
crateApiPluginModelsAudioSourceSpotubeAudioLosslessContainerQualityToStringFmt(
|
crateApiPluginModelsAudioSourceSpotubeAudioLosslessContainerQualityToStringFmt(
|
||||||
@ -2930,7 +2857,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
final serializer = SseSerializer(generalizedFrbRustBinding);
|
final serializer = SseSerializer(generalizedFrbRustBinding);
|
||||||
sse_encode_box_autoadd_spotube_audio_lossless_container_quality(
|
sse_encode_box_autoadd_spotube_audio_lossless_container_quality(
|
||||||
that, serializer);
|
that, serializer);
|
||||||
return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 76)!;
|
return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 74)!;
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_String,
|
decodeSuccessData: sse_decode_String,
|
||||||
@ -2960,7 +2887,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_box_autoadd_spotube_audio_lossy_container_quality(
|
sse_encode_box_autoadd_spotube_audio_lossy_container_quality(
|
||||||
that, serializer);
|
that, serializer);
|
||||||
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
pdeCallFfi(generalizedFrbRustBinding, serializer,
|
||||||
funcId: 77, port: port_);
|
funcId: 75, port: port_);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_String,
|
decodeSuccessData: sse_decode_String,
|
||||||
@ -2989,7 +2916,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
final serializer = SseSerializer(generalizedFrbRustBinding);
|
final serializer = SseSerializer(generalizedFrbRustBinding);
|
||||||
sse_encode_box_autoadd_spotube_audio_source_container_preset(
|
sse_encode_box_autoadd_spotube_audio_source_container_preset(
|
||||||
that, serializer);
|
that, serializer);
|
||||||
return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 78)!;
|
return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 76)!;
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_String,
|
decodeSuccessData: sse_decode_String,
|
||||||
@ -3009,117 +2936,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
argNames: ["that"],
|
argNames: ["that"],
|
||||||
);
|
);
|
||||||
|
|
||||||
Future<void> Function(int, dynamic)
|
|
||||||
encode_DartFn_Inputs_DartOpaque_Output_unit_AnyhowException(
|
|
||||||
FutureOr<void> Function(Object) raw) {
|
|
||||||
return (callId, rawArg0) async {
|
|
||||||
final arg0 = dco_decode_DartOpaque(rawArg0);
|
|
||||||
|
|
||||||
Box<void>? rawOutput;
|
|
||||||
Box<AnyhowException>? rawError;
|
|
||||||
try {
|
|
||||||
rawOutput = Box(await raw(arg0));
|
|
||||||
} catch (e, s) {
|
|
||||||
rawError = Box(AnyhowException("$e\n\n$s"));
|
|
||||||
}
|
|
||||||
|
|
||||||
final serializer = SseSerializer(generalizedFrbRustBinding);
|
|
||||||
assert((rawOutput != null) ^ (rawError != null));
|
|
||||||
if (rawOutput != null) {
|
|
||||||
serializer.buffer.putUint8(0);
|
|
||||||
sse_encode_unit(rawOutput.value, serializer);
|
|
||||||
} else {
|
|
||||||
serializer.buffer.putUint8(1);
|
|
||||||
sse_encode_AnyhowException(rawError!.value, serializer);
|
|
||||||
}
|
|
||||||
final output = serializer.intoRaw();
|
|
||||||
|
|
||||||
generalizedFrbRustBinding.dartFnDeliverOutput(
|
|
||||||
callId: callId,
|
|
||||||
ptr: output.ptr,
|
|
||||||
rustVecLen: output.rustVecLen,
|
|
||||||
dataLen: output.dataLen);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> Function(int, dynamic, dynamic)
|
|
||||||
encode_DartFn_Inputs_DartOpaque_String_Output_String_AnyhowException(
|
|
||||||
FutureOr<String> Function(Object, String) raw) {
|
|
||||||
return (callId, rawArg0, rawArg1) async {
|
|
||||||
final arg0 = dco_decode_DartOpaque(rawArg0);
|
|
||||||
final arg1 = dco_decode_String(rawArg1);
|
|
||||||
|
|
||||||
Box<String>? rawOutput;
|
|
||||||
Box<AnyhowException>? rawError;
|
|
||||||
try {
|
|
||||||
rawOutput = Box(await raw(arg0, arg1));
|
|
||||||
} catch (e, s) {
|
|
||||||
rawError = Box(AnyhowException("$e\n\n$s"));
|
|
||||||
}
|
|
||||||
|
|
||||||
final serializer = SseSerializer(generalizedFrbRustBinding);
|
|
||||||
assert((rawOutput != null) ^ (rawError != null));
|
|
||||||
if (rawOutput != null) {
|
|
||||||
serializer.buffer.putUint8(0);
|
|
||||||
sse_encode_String(rawOutput.value, serializer);
|
|
||||||
} else {
|
|
||||||
serializer.buffer.putUint8(1);
|
|
||||||
sse_encode_AnyhowException(rawError!.value, serializer);
|
|
||||||
}
|
|
||||||
final output = serializer.intoRaw();
|
|
||||||
|
|
||||||
generalizedFrbRustBinding.dartFnDeliverOutput(
|
|
||||||
callId: callId,
|
|
||||||
ptr: output.ptr,
|
|
||||||
rustVecLen: output.rustVecLen,
|
|
||||||
dataLen: output.dataLen);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> Function(int, dynamic, dynamic)
|
|
||||||
encode_DartFn_Inputs_String_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString_Output_DartOpaque_AnyhowException(
|
|
||||||
FutureOr<Object> Function(String, BroadcastSenderString) raw) {
|
|
||||||
return (callId, rawArg0, rawArg1) async {
|
|
||||||
final arg0 = dco_decode_String(rawArg0);
|
|
||||||
final arg1 =
|
|
||||||
dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString(
|
|
||||||
rawArg1);
|
|
||||||
|
|
||||||
Box<Object>? rawOutput;
|
|
||||||
Box<AnyhowException>? rawError;
|
|
||||||
try {
|
|
||||||
rawOutput = Box(await raw(arg0, arg1));
|
|
||||||
} catch (e, s) {
|
|
||||||
rawError = Box(AnyhowException("$e\n\n$s"));
|
|
||||||
}
|
|
||||||
|
|
||||||
final serializer = SseSerializer(generalizedFrbRustBinding);
|
|
||||||
assert((rawOutput != null) ^ (rawError != null));
|
|
||||||
if (rawOutput != null) {
|
|
||||||
serializer.buffer.putUint8(0);
|
|
||||||
sse_encode_DartOpaque(rawOutput.value, serializer);
|
|
||||||
} else {
|
|
||||||
serializer.buffer.putUint8(1);
|
|
||||||
sse_encode_AnyhowException(rawError!.value, serializer);
|
|
||||||
}
|
|
||||||
final output = serializer.intoRaw();
|
|
||||||
|
|
||||||
generalizedFrbRustBinding.dartFnDeliverOutput(
|
|
||||||
callId: callId,
|
|
||||||
ptr: output.ptr,
|
|
||||||
rustVecLen: output.rustVecLen,
|
|
||||||
dataLen: output.dataLen);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
RustArcIncrementStrongCountFnType
|
|
||||||
get rust_arc_increment_strong_count_BroadcastSenderString => wire
|
|
||||||
.rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString;
|
|
||||||
|
|
||||||
RustArcDecrementStrongCountFnType
|
|
||||||
get rust_arc_decrement_strong_count_BroadcastSenderString => wire
|
|
||||||
.rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString;
|
|
||||||
|
|
||||||
RustArcIncrementStrongCountFnType
|
RustArcIncrementStrongCountFnType
|
||||||
get rust_arc_increment_strong_count_OpaqueSender => wire
|
get rust_arc_increment_strong_count_OpaqueSender => wire
|
||||||
.rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender;
|
.rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender;
|
||||||
@ -3158,14 +2974,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
return AnyhowException(raw as String);
|
return AnyhowException(raw as String);
|
||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
|
||||||
BroadcastSenderString
|
|
||||||
dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString(
|
|
||||||
dynamic raw) {
|
|
||||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
|
||||||
return BroadcastSenderStringImpl.frbInternalDcoDecode(raw as List<dynamic>);
|
|
||||||
}
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
OpaqueSender
|
OpaqueSender
|
||||||
dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
||||||
@ -3230,44 +3038,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
return SpotubePluginImpl.frbInternalDcoDecode(raw as List<dynamic>);
|
return SpotubePluginImpl.frbInternalDcoDecode(raw as List<dynamic>);
|
||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
|
||||||
FutureOr<void> Function(Object)
|
|
||||||
dco_decode_DartFn_Inputs_DartOpaque_Output_unit_AnyhowException(
|
|
||||||
dynamic raw) {
|
|
||||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
|
||||||
throw UnimplementedError('');
|
|
||||||
}
|
|
||||||
|
|
||||||
@protected
|
|
||||||
FutureOr<String> Function(Object, String)
|
|
||||||
dco_decode_DartFn_Inputs_DartOpaque_String_Output_String_AnyhowException(
|
|
||||||
dynamic raw) {
|
|
||||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
|
||||||
throw UnimplementedError('');
|
|
||||||
}
|
|
||||||
|
|
||||||
@protected
|
|
||||||
FutureOr<Object> Function(String, BroadcastSenderString)
|
|
||||||
dco_decode_DartFn_Inputs_String_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString_Output_DartOpaque_AnyhowException(
|
|
||||||
dynamic raw) {
|
|
||||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
|
||||||
throw UnimplementedError('');
|
|
||||||
}
|
|
||||||
|
|
||||||
@protected
|
|
||||||
Object dco_decode_DartOpaque(dynamic raw) {
|
|
||||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
|
||||||
return decodeDartOpaque(raw, generalizedFrbRustBinding);
|
|
||||||
}
|
|
||||||
|
|
||||||
@protected
|
|
||||||
BroadcastSenderString
|
|
||||||
dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString(
|
|
||||||
dynamic raw) {
|
|
||||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
|
||||||
return BroadcastSenderStringImpl.frbInternalDcoDecode(raw as List<dynamic>);
|
|
||||||
}
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
OpaqueSender
|
OpaqueSender
|
||||||
dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
||||||
@ -3551,12 +3321,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
return dcoDecodeI64(raw);
|
return dcoDecodeI64(raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
|
||||||
PlatformInt64 dco_decode_isize(dynamic raw) {
|
|
||||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
|
||||||
return dcoDecodeI64(raw);
|
|
||||||
}
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
List<String> dco_decode_list_String(dynamic raw) {
|
List<String> dco_decode_list_String(dynamic raw) {
|
||||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||||
@ -4362,15 +4126,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
return AnyhowException(inner);
|
return AnyhowException(inner);
|
||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
|
||||||
BroadcastSenderString
|
|
||||||
sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString(
|
|
||||||
SseDeserializer deserializer) {
|
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
|
||||||
return BroadcastSenderStringImpl.frbInternalSseDecode(
|
|
||||||
sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
|
|
||||||
}
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
OpaqueSender
|
OpaqueSender
|
||||||
sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
||||||
@ -4443,22 +4198,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
|
sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
|
||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
|
||||||
Object sse_decode_DartOpaque(SseDeserializer deserializer) {
|
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
|
||||||
var inner = sse_decode_isize(deserializer);
|
|
||||||
return decodeDartOpaque(inner, generalizedFrbRustBinding);
|
|
||||||
}
|
|
||||||
|
|
||||||
@protected
|
|
||||||
BroadcastSenderString
|
|
||||||
sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString(
|
|
||||||
SseDeserializer deserializer) {
|
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
|
||||||
return BroadcastSenderStringImpl.frbInternalSseDecode(
|
|
||||||
sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
|
|
||||||
}
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
OpaqueSender
|
OpaqueSender
|
||||||
sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
||||||
@ -4758,12 +4497,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
return deserializer.buffer.getPlatformInt64();
|
return deserializer.buffer.getPlatformInt64();
|
||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
|
||||||
PlatformInt64 sse_decode_isize(SseDeserializer deserializer) {
|
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
|
||||||
return deserializer.buffer.getPlatformInt64();
|
|
||||||
}
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
List<String> sse_decode_list_String(SseDeserializer deserializer) {
|
List<String> sse_decode_list_String(SseDeserializer deserializer) {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
@ -5761,16 +5494,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_String(self.message, serializer);
|
sse_encode_String(self.message, serializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
|
||||||
void
|
|
||||||
sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString(
|
|
||||||
BroadcastSenderString self, SseSerializer serializer) {
|
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
|
||||||
sse_encode_usize(
|
|
||||||
(self as BroadcastSenderStringImpl).frbInternalSseEncode(move: true),
|
|
||||||
serializer);
|
|
||||||
}
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void
|
void
|
||||||
sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
||||||
@ -5851,57 +5574,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
serializer);
|
serializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
|
||||||
void sse_encode_DartFn_Inputs_DartOpaque_Output_unit_AnyhowException(
|
|
||||||
FutureOr<void> Function(Object) self, SseSerializer serializer) {
|
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
|
||||||
sse_encode_DartOpaque(
|
|
||||||
encode_DartFn_Inputs_DartOpaque_Output_unit_AnyhowException(self),
|
|
||||||
serializer);
|
|
||||||
}
|
|
||||||
|
|
||||||
@protected
|
|
||||||
void sse_encode_DartFn_Inputs_DartOpaque_String_Output_String_AnyhowException(
|
|
||||||
FutureOr<String> Function(Object, String) self,
|
|
||||||
SseSerializer serializer) {
|
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
|
||||||
sse_encode_DartOpaque(
|
|
||||||
encode_DartFn_Inputs_DartOpaque_String_Output_String_AnyhowException(
|
|
||||||
self),
|
|
||||||
serializer);
|
|
||||||
}
|
|
||||||
|
|
||||||
@protected
|
|
||||||
void
|
|
||||||
sse_encode_DartFn_Inputs_String_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString_Output_DartOpaque_AnyhowException(
|
|
||||||
FutureOr<Object> Function(String, BroadcastSenderString) self,
|
|
||||||
SseSerializer serializer) {
|
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
|
||||||
sse_encode_DartOpaque(
|
|
||||||
encode_DartFn_Inputs_String_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString_Output_DartOpaque_AnyhowException(
|
|
||||||
self),
|
|
||||||
serializer);
|
|
||||||
}
|
|
||||||
|
|
||||||
@protected
|
|
||||||
void sse_encode_DartOpaque(Object self, SseSerializer serializer) {
|
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
|
||||||
sse_encode_isize(
|
|
||||||
PlatformPointerUtil.ptrToPlatformInt64(encodeDartOpaque(
|
|
||||||
self, portManager.dartHandlerPort, generalizedFrbRustBinding)),
|
|
||||||
serializer);
|
|
||||||
}
|
|
||||||
|
|
||||||
@protected
|
|
||||||
void
|
|
||||||
sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString(
|
|
||||||
BroadcastSenderString self, SseSerializer serializer) {
|
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
|
||||||
sse_encode_usize(
|
|
||||||
(self as BroadcastSenderStringImpl).frbInternalSseEncode(move: null),
|
|
||||||
serializer);
|
|
||||||
}
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void
|
void
|
||||||
sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
||||||
@ -6205,12 +5877,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
serializer.buffer.putPlatformInt64(self);
|
serializer.buffer.putPlatformInt64(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
|
||||||
void sse_encode_isize(PlatformInt64 self, SseSerializer serializer) {
|
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
|
||||||
serializer.buffer.putPlatformInt64(self);
|
|
||||||
}
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void sse_encode_list_String(List<String> self, SseSerializer serializer) {
|
void sse_encode_list_String(List<String> self, SseSerializer serializer) {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
@ -6976,28 +6642,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@sealed
|
|
||||||
class BroadcastSenderStringImpl extends RustOpaque
|
|
||||||
implements BroadcastSenderString {
|
|
||||||
// Not to be used by end users
|
|
||||||
BroadcastSenderStringImpl.frbInternalDcoDecode(List<dynamic> wire)
|
|
||||||
: super.frbInternalDcoDecode(wire, _kStaticData);
|
|
||||||
|
|
||||||
// Not to be used by end users
|
|
||||||
BroadcastSenderStringImpl.frbInternalSseDecode(
|
|
||||||
BigInt ptr, int externalSizeOnNative)
|
|
||||||
: super.frbInternalSseDecode(ptr, externalSizeOnNative, _kStaticData);
|
|
||||||
|
|
||||||
static final _kStaticData = RustArcStaticData(
|
|
||||||
rustArcIncrementStrongCount: RustLib
|
|
||||||
.instance.api.rust_arc_increment_strong_count_BroadcastSenderString,
|
|
||||||
rustArcDecrementStrongCount: RustLib
|
|
||||||
.instance.api.rust_arc_decrement_strong_count_BroadcastSenderString,
|
|
||||||
rustArcDecrementStrongCountPtr: RustLib
|
|
||||||
.instance.api.rust_arc_decrement_strong_count_BroadcastSenderStringPtr,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@sealed
|
@sealed
|
||||||
class OpaqueSenderImpl extends RustOpaque implements OpaqueSender {
|
class OpaqueSenderImpl extends RustOpaque implements OpaqueSender {
|
||||||
// Not to be used by end users
|
// Not to be used by end users
|
||||||
@ -7188,7 +6832,13 @@ class SpotubePluginImpl extends RustOpaque implements SpotubePlugin {
|
|||||||
|
|
||||||
OpaqueSender createContext(
|
OpaqueSender createContext(
|
||||||
{required String pluginScript,
|
{required String pluginScript,
|
||||||
required PluginConfiguration pluginConfig}) =>
|
required PluginConfiguration pluginConfig,
|
||||||
|
required String serverEndpointUrl,
|
||||||
|
required String serverSecret}) =>
|
||||||
RustLib.instance.api.crateApiPluginPluginSpotubePluginCreateContext(
|
RustLib.instance.api.crateApiPluginPluginSpotubePluginCreateContext(
|
||||||
that: this, pluginScript: pluginScript, pluginConfig: pluginConfig);
|
that: this,
|
||||||
|
pluginScript: pluginScript,
|
||||||
|
pluginConfig: pluginConfig,
|
||||||
|
serverEndpointUrl: serverEndpointUrl,
|
||||||
|
serverSecret: serverSecret);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
// ignore_for_file: unused_import, unused_element, unnecessary_import, duplicate_ignore, invalid_use_of_internal_member, annotate_overrides, non_constant_identifier_names, curly_braces_in_flow_control_structures, prefer_const_literals_to_create_immutables, unused_field
|
// ignore_for_file: unused_import, unused_element, unnecessary_import, duplicate_ignore, invalid_use_of_internal_member, annotate_overrides, non_constant_identifier_names, curly_braces_in_flow_control_structures, prefer_const_literals_to_create_immutables, unused_field
|
||||||
|
|
||||||
import 'api/host_api/webview.dart';
|
|
||||||
import 'api/plugin/commands.dart';
|
import 'api/plugin/commands.dart';
|
||||||
import 'api/plugin/models/album.dart';
|
import 'api/plugin/models/album.dart';
|
||||||
import 'api/plugin/models/artist.dart';
|
import 'api/plugin/models/artist.dart';
|
||||||
@ -34,10 +33,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
required super.portManager,
|
required super.portManager,
|
||||||
});
|
});
|
||||||
|
|
||||||
CrossPlatformFinalizerArg
|
|
||||||
get rust_arc_decrement_strong_count_BroadcastSenderStringPtr => wire
|
|
||||||
._rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderStringPtr;
|
|
||||||
|
|
||||||
CrossPlatformFinalizerArg
|
CrossPlatformFinalizerArg
|
||||||
get rust_arc_decrement_strong_count_OpaqueSenderPtr => wire
|
get rust_arc_decrement_strong_count_OpaqueSenderPtr => wire
|
||||||
._rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSenderPtr;
|
._rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSenderPtr;
|
||||||
@ -57,11 +52,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
AnyhowException dco_decode_AnyhowException(dynamic raw);
|
AnyhowException dco_decode_AnyhowException(dynamic raw);
|
||||||
|
|
||||||
@protected
|
|
||||||
BroadcastSenderString
|
|
||||||
dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString(
|
|
||||||
dynamic raw);
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
OpaqueSender
|
OpaqueSender
|
||||||
dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
||||||
@ -102,29 +92,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
dco_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerSpotubePlugin(
|
dco_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerSpotubePlugin(
|
||||||
dynamic raw);
|
dynamic raw);
|
||||||
|
|
||||||
@protected
|
|
||||||
FutureOr<void> Function(Object)
|
|
||||||
dco_decode_DartFn_Inputs_DartOpaque_Output_unit_AnyhowException(
|
|
||||||
dynamic raw);
|
|
||||||
|
|
||||||
@protected
|
|
||||||
FutureOr<String> Function(Object, String)
|
|
||||||
dco_decode_DartFn_Inputs_DartOpaque_String_Output_String_AnyhowException(
|
|
||||||
dynamic raw);
|
|
||||||
|
|
||||||
@protected
|
|
||||||
FutureOr<Object> Function(String, BroadcastSenderString)
|
|
||||||
dco_decode_DartFn_Inputs_String_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString_Output_DartOpaque_AnyhowException(
|
|
||||||
dynamic raw);
|
|
||||||
|
|
||||||
@protected
|
|
||||||
Object dco_decode_DartOpaque(dynamic raw);
|
|
||||||
|
|
||||||
@protected
|
|
||||||
BroadcastSenderString
|
|
||||||
dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString(
|
|
||||||
dynamic raw);
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
OpaqueSender
|
OpaqueSender
|
||||||
dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
||||||
@ -275,9 +242,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
PlatformInt64 dco_decode_i_64(dynamic raw);
|
PlatformInt64 dco_decode_i_64(dynamic raw);
|
||||||
|
|
||||||
@protected
|
|
||||||
PlatformInt64 dco_decode_isize(dynamic raw);
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
List<String> dco_decode_list_String(dynamic raw);
|
List<String> dco_decode_list_String(dynamic raw);
|
||||||
|
|
||||||
@ -521,11 +485,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
AnyhowException sse_decode_AnyhowException(SseDeserializer deserializer);
|
AnyhowException sse_decode_AnyhowException(SseDeserializer deserializer);
|
||||||
|
|
||||||
@protected
|
|
||||||
BroadcastSenderString
|
|
||||||
sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString(
|
|
||||||
SseDeserializer deserializer);
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
OpaqueSender
|
OpaqueSender
|
||||||
sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
||||||
@ -566,14 +525,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
sse_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerSpotubePlugin(
|
sse_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerSpotubePlugin(
|
||||||
SseDeserializer deserializer);
|
SseDeserializer deserializer);
|
||||||
|
|
||||||
@protected
|
|
||||||
Object sse_decode_DartOpaque(SseDeserializer deserializer);
|
|
||||||
|
|
||||||
@protected
|
|
||||||
BroadcastSenderString
|
|
||||||
sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString(
|
|
||||||
SseDeserializer deserializer);
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
OpaqueSender
|
OpaqueSender
|
||||||
sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
||||||
@ -740,9 +691,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
PlatformInt64 sse_decode_i_64(SseDeserializer deserializer);
|
PlatformInt64 sse_decode_i_64(SseDeserializer deserializer);
|
||||||
|
|
||||||
@protected
|
|
||||||
PlatformInt64 sse_decode_isize(SseDeserializer deserializer);
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
List<String> sse_decode_list_String(SseDeserializer deserializer);
|
List<String> sse_decode_list_String(SseDeserializer deserializer);
|
||||||
|
|
||||||
@ -1020,11 +968,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
void sse_encode_AnyhowException(
|
void sse_encode_AnyhowException(
|
||||||
AnyhowException self, SseSerializer serializer);
|
AnyhowException self, SseSerializer serializer);
|
||||||
|
|
||||||
@protected
|
|
||||||
void
|
|
||||||
sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString(
|
|
||||||
BroadcastSenderString self, SseSerializer serializer);
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void
|
void
|
||||||
sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
||||||
@ -1065,28 +1008,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerSpotubePlugin(
|
sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerSpotubePlugin(
|
||||||
SpotubePlugin self, SseSerializer serializer);
|
SpotubePlugin self, SseSerializer serializer);
|
||||||
|
|
||||||
@protected
|
|
||||||
void sse_encode_DartFn_Inputs_DartOpaque_Output_unit_AnyhowException(
|
|
||||||
FutureOr<void> Function(Object) self, SseSerializer serializer);
|
|
||||||
|
|
||||||
@protected
|
|
||||||
void sse_encode_DartFn_Inputs_DartOpaque_String_Output_String_AnyhowException(
|
|
||||||
FutureOr<String> Function(Object, String) self, SseSerializer serializer);
|
|
||||||
|
|
||||||
@protected
|
|
||||||
void
|
|
||||||
sse_encode_DartFn_Inputs_String_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString_Output_DartOpaque_AnyhowException(
|
|
||||||
FutureOr<Object> Function(String, BroadcastSenderString) self,
|
|
||||||
SseSerializer serializer);
|
|
||||||
|
|
||||||
@protected
|
|
||||||
void sse_encode_DartOpaque(Object self, SseSerializer serializer);
|
|
||||||
|
|
||||||
@protected
|
|
||||||
void
|
|
||||||
sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString(
|
|
||||||
BroadcastSenderString self, SseSerializer serializer);
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void
|
void
|
||||||
sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
||||||
@ -1249,9 +1170,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
void sse_encode_i_64(PlatformInt64 self, SseSerializer serializer);
|
void sse_encode_i_64(PlatformInt64 self, SseSerializer serializer);
|
||||||
|
|
||||||
@protected
|
|
||||||
void sse_encode_isize(PlatformInt64 self, SseSerializer serializer);
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void sse_encode_list_String(List<String> self, SseSerializer serializer);
|
void sse_encode_list_String(List<String> self, SseSerializer serializer);
|
||||||
|
|
||||||
@ -1538,38 +1456,6 @@ class RustLibWire implements BaseWire {
|
|||||||
RustLibWire(ffi.DynamicLibrary dynamicLibrary)
|
RustLibWire(ffi.DynamicLibrary dynamicLibrary)
|
||||||
: _lookup = dynamicLibrary.lookup;
|
: _lookup = dynamicLibrary.lookup;
|
||||||
|
|
||||||
void
|
|
||||||
rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString(
|
|
||||||
ffi.Pointer<ffi.Void> ptr,
|
|
||||||
) {
|
|
||||||
return _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString(
|
|
||||||
ptr,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
late final _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderStringPtr =
|
|
||||||
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>(
|
|
||||||
'frbgen_spotube_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString');
|
|
||||||
late final _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString =
|
|
||||||
_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderStringPtr
|
|
||||||
.asFunction<void Function(ffi.Pointer<ffi.Void>)>();
|
|
||||||
|
|
||||||
void
|
|
||||||
rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString(
|
|
||||||
ffi.Pointer<ffi.Void> ptr,
|
|
||||||
) {
|
|
||||||
return _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString(
|
|
||||||
ptr,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
late final _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderStringPtr =
|
|
||||||
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>(
|
|
||||||
'frbgen_spotube_rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString');
|
|
||||||
late final _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString =
|
|
||||||
_rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderStringPtr
|
|
||||||
.asFunction<void Function(ffi.Pointer<ffi.Void>)>();
|
|
||||||
|
|
||||||
void
|
void
|
||||||
rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
||||||
ffi.Pointer<ffi.Void> ptr,
|
ffi.Pointer<ffi.Void> ptr,
|
||||||
|
|||||||
718
rust/Cargo.lock
generated
718
rust/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -19,7 +19,8 @@ rquickjs = { version = "0", features = ["chrono", "futures", "macro", "classes",
|
|||||||
tokio = { version = "1.48.0", features = ["full"] }
|
tokio = { version = "1.48.0", features = ["full"] }
|
||||||
heck = "0.5.0"
|
heck = "0.5.0"
|
||||||
llrt_modules = { git = "https://github.com/awslabs/llrt.git", rev = "7d749dd18cf26a2e51119094c3b945975ae57bd4", features = ["abort", "buffer", "console", "crypto", "events", "exceptions", "fetch", "navigator", "url", "timers"] }
|
llrt_modules = { git = "https://github.com/awslabs/llrt.git", rev = "7d749dd18cf26a2e51119094c3b945975ae57bd4", features = ["abort", "buffer", "console", "crypto", "events", "exceptions", "fetch", "navigator", "url", "timers"] }
|
||||||
once_cell = "1.21.3"
|
eventsource-client = "0.15.1"
|
||||||
|
reqwest = { version = "0.12", features = ["json"] }
|
||||||
|
|
||||||
[patch."https://github.com/DelSkayn/rquickjs"]
|
[patch."https://github.com/DelSkayn/rquickjs"]
|
||||||
rquickjs = "0.10.0"
|
rquickjs = "0.10.0"
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
pub mod webview;
|
|
||||||
@ -1,191 +0,0 @@
|
|||||||
use anyhow::anyhow;
|
|
||||||
use flutter_rust_bridge::for_generated::lazy_static;
|
|
||||||
use flutter_rust_bridge::{frb, DartFnFuture, DartOpaque};
|
|
||||||
use llrt_modules::events::EventEmitter;
|
|
||||||
use rquickjs::function::This;
|
|
||||||
use rquickjs::{Class, Function, Object};
|
|
||||||
use std::sync::Mutex;
|
|
||||||
use tokio::sync::broadcast;
|
|
||||||
|
|
||||||
pub type BroadcastSender<T> = broadcast::Sender<T>;
|
|
||||||
pub type BroadcastReceiver<T> = broadcast::Receiver<T>;
|
|
||||||
|
|
||||||
lazy_static! {
|
|
||||||
static ref DART_CREATE_WEBVIEW: Mutex<
|
|
||||||
Option<
|
|
||||||
Box<
|
|
||||||
dyn Fn(String, BroadcastSender<String>) -> DartFnFuture<DartOpaque>
|
|
||||||
+ Send
|
|
||||||
+ 'static,
|
|
||||||
>,
|
|
||||||
>,
|
|
||||||
> = Mutex::new(None);
|
|
||||||
static ref DART_OPEN_WEBVIEW: Mutex<Option<Box<dyn Fn(DartOpaque) -> DartFnFuture<()> + Send + 'static>>> =
|
|
||||||
Mutex::new(None);
|
|
||||||
static ref DART_CLOSE_WEBVIEW: Mutex<Option<Box<dyn Fn(DartOpaque) -> DartFnFuture<()> + Send + 'static>>> =
|
|
||||||
Mutex::new(None);
|
|
||||||
static ref DART_GET_COOKIES: Mutex<Option<Box<dyn Fn(DartOpaque, String) -> DartFnFuture<String> + Send + 'static>>> =
|
|
||||||
Mutex::new(None);
|
|
||||||
}
|
|
||||||
pub async fn initialize_webview_callbacks(
|
|
||||||
create_webview: impl Fn(String, BroadcastSender<String>) -> DartFnFuture<DartOpaque>
|
|
||||||
+ Send
|
|
||||||
+ 'static,
|
|
||||||
open_webview: impl Fn(DartOpaque) -> DartFnFuture<()> + Send + 'static,
|
|
||||||
close_webview: impl Fn(DartOpaque) -> DartFnFuture<()> + Send + 'static,
|
|
||||||
get_cookies: impl Fn(DartOpaque, String) -> DartFnFuture<String> + Send + 'static,
|
|
||||||
) -> anyhow::Result<()> {
|
|
||||||
*DART_CREATE_WEBVIEW
|
|
||||||
.lock()
|
|
||||||
.map_err(|_| anyhow!("Mutex poisoned"))? = Some(Box::new(create_webview));
|
|
||||||
*DART_OPEN_WEBVIEW
|
|
||||||
.lock()
|
|
||||||
.map_err(|_| anyhow!("Mutex poisoned"))? = Some(Box::new(open_webview));
|
|
||||||
*DART_CLOSE_WEBVIEW
|
|
||||||
.lock()
|
|
||||||
.map_err(|_| anyhow!("Mutex poisoned"))? = Some(Box::new(close_webview));
|
|
||||||
*DART_GET_COOKIES
|
|
||||||
.lock()
|
|
||||||
.map_err(|_| anyhow!("Mutex poisoned"))? = Some(Box::new(get_cookies));
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn send_webview_events(tx: BroadcastSender<String>, event: String) -> anyhow::Result<()> {
|
|
||||||
tx.send(event)
|
|
||||||
.map_err(|_| anyhow!("Failed to send event"))?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[frb(ignore)]
|
|
||||||
pub struct HostWebview {
|
|
||||||
webview: DartOpaque,
|
|
||||||
events: BroadcastReceiver<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[frb(ignore)]
|
|
||||||
impl HostWebview {
|
|
||||||
pub async fn create(uri: String) -> anyhow::Result<Self> {
|
|
||||||
let (tx, rx) = broadcast::channel(100);
|
|
||||||
|
|
||||||
let s = DART_CREATE_WEBVIEW
|
|
||||||
.lock()
|
|
||||||
.map_err(|_| anyhow!("Mutex poisoned"))?;
|
|
||||||
if let Some(create_webview_fn) = s.as_ref() {
|
|
||||||
let s = create_webview_fn(uri, tx.clone()).await;
|
|
||||||
Ok(Self {
|
|
||||||
webview: s,
|
|
||||||
events: rx,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
Err(anyhow!("create_webview not implemented"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn open(&self) -> anyhow::Result<()> {
|
|
||||||
let s = DART_OPEN_WEBVIEW
|
|
||||||
.lock()
|
|
||||||
.map_err(|_| anyhow!("Mutex poisoned"))?;
|
|
||||||
if let Some(open_webview) = s.as_ref() {
|
|
||||||
open_webview(self.webview.clone()).await;
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(anyhow!("open_webview not implemented"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn close(&self) -> anyhow::Result<()> {
|
|
||||||
let s = DART_CLOSE_WEBVIEW
|
|
||||||
.lock()
|
|
||||||
.map_err(|_| anyhow!("Mutex poisoned"))?;
|
|
||||||
if let Some(close_webview) = s.as_ref() {
|
|
||||||
close_webview(self.webview.clone()).await;
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(anyhow!("close_webview not implemented"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_cookies(&self, url: String) -> anyhow::Result<String> {
|
|
||||||
let s = DART_GET_COOKIES
|
|
||||||
.lock()
|
|
||||||
.map_err(|_| anyhow!("Mutex poisoned"))?;
|
|
||||||
if let Some(get_cookies) = s.as_ref() {
|
|
||||||
let s = get_cookies(self.webview.clone(), url).await;
|
|
||||||
Ok(s)
|
|
||||||
} else {
|
|
||||||
Err(anyhow!("get_cookies not implemented"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[frb(ignore)]
|
|
||||||
#[rquickjs::class]
|
|
||||||
#[derive(rquickjs::JsLifetime, rquickjs::class::Trace)]
|
|
||||||
pub struct Webview {
|
|
||||||
#[qjs(skip_trace)]
|
|
||||||
webview: HostWebview,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[frb(ignore)]
|
|
||||||
#[rquickjs::methods(rename_all = "camelCase")]
|
|
||||||
impl Webview {
|
|
||||||
#[qjs(static)]
|
|
||||||
pub async fn create(uri: String) -> rquickjs::Result<Self> {
|
|
||||||
let webview = HostWebview::create(uri)
|
|
||||||
.await
|
|
||||||
.map_err(|_| rquickjs::Error::Exception)?;
|
|
||||||
|
|
||||||
Ok(Self { webview })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn open(&mut self, this: This<Class<'_, Self>>) -> rquickjs::Result<()> {
|
|
||||||
let mut events = this.get::<_, Object>("events")?;
|
|
||||||
if events.is_null() || events.is_undefined() {
|
|
||||||
this.set("events", EventEmitter::new())?;
|
|
||||||
events = this.get::<_, Object>("events")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let emit = events.clone().get::<_, Function>("emit")?;
|
|
||||||
let mut rx = self.webview.events.resubscribe();
|
|
||||||
|
|
||||||
this.ctx().spawn(async move {
|
|
||||||
while let Ok(event) = rx.recv().await {
|
|
||||||
if let Err(e) = emit.call::<_, ()>(("url_change", event)) {
|
|
||||||
eprintln!("Failed to emit event: {:?}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
self.webview
|
|
||||||
.open()
|
|
||||||
.await
|
|
||||||
.map_err(|_| rquickjs::Error::Exception)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn close(&self) -> rquickjs::Result<()> {
|
|
||||||
self.webview
|
|
||||||
.close()
|
|
||||||
.await
|
|
||||||
.map_err(|_| rquickjs::Error::Exception)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_cookies(&self, url: String) -> rquickjs::Result<String> {
|
|
||||||
self.webview
|
|
||||||
.get_cookies(url)
|
|
||||||
.await
|
|
||||||
.map_err(|_| rquickjs::Error::Exception)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn poll_url_change_event(&mut self) -> rquickjs::Result<String> {
|
|
||||||
let event = self
|
|
||||||
.webview
|
|
||||||
.events
|
|
||||||
.recv()
|
|
||||||
.await
|
|
||||||
.map_err(|_| rquickjs::Error::Exception)?;
|
|
||||||
Ok(event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,5 +1,4 @@
|
|||||||
pub mod plugin;
|
pub mod plugin;
|
||||||
pub mod host_api;
|
|
||||||
|
|
||||||
#[flutter_rust_bridge::frb(init)]
|
#[flutter_rust_bridge::frb(init)]
|
||||||
pub fn init_app() {
|
pub fn init_app() {
|
||||||
|
|||||||
@ -11,34 +11,31 @@ use crate::api::plugin::senders::{
|
|||||||
PluginTrackSender, PluginUserSender,
|
PluginTrackSender, PluginUserSender,
|
||||||
};
|
};
|
||||||
use crate::frb_generated::StreamSink;
|
use crate::frb_generated::StreamSink;
|
||||||
|
use crate::internal::apis::webview;
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use flutter_rust_bridge::{frb, Rust2DartSendError};
|
use flutter_rust_bridge::{frb, Rust2DartSendError};
|
||||||
use llrt_modules::module_builder::ModuleBuilder;
|
use llrt_modules::module_builder::ModuleBuilder;
|
||||||
use llrt_modules::{
|
use llrt_modules::{
|
||||||
abort, buffer, console, crypto, events, exceptions, fetch, navigator, timers, url, util,
|
abort, buffer, console, crypto, events, exceptions, fetch, navigator, timers, url, util,
|
||||||
};
|
};
|
||||||
use rquickjs::prelude::{Async, Func};
|
use rquickjs::prelude::Func;
|
||||||
use rquickjs::{async_with, AsyncContext, AsyncRuntime, Class, Error, Object};
|
use rquickjs::{async_with, AsyncContext, AsyncRuntime, CatchResultExt, Error, Object};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use tokio::sync::mpsc::{Receiver, Sender};
|
use tokio::sync::mpsc::{Receiver, Sender};
|
||||||
use tokio::task;
|
use tokio::task;
|
||||||
use tokio::task::LocalSet;
|
use tokio::task::LocalSet;
|
||||||
use crate::api::host_api::webview::{HostWebview, Webview};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct OpaqueSender {
|
pub struct OpaqueSender {
|
||||||
pub sender: Sender<PluginCommand>,
|
pub sender: Sender<PluginCommand>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[frb(ignore)]
|
// #[frb(ignore)]
|
||||||
pub async fn open_webview(uri: String){
|
async fn create_context(
|
||||||
let webview = HostWebview::create(uri).await.unwrap();
|
server_endpoint_url: String,
|
||||||
webview.open().await.unwrap();
|
server_secret: String,
|
||||||
}
|
) -> anyhow::Result<(AsyncContext, AsyncRuntime)> {
|
||||||
|
|
||||||
#[frb(ignore)]
|
|
||||||
async fn create_context() -> anyhow::Result<(AsyncContext, AsyncRuntime)> {
|
|
||||||
let runtime = AsyncRuntime::new().expect("Unable to create async runtime");
|
let runtime = AsyncRuntime::new().expect("Unable to create async runtime");
|
||||||
|
|
||||||
let mut module_builder = ModuleBuilder::new();
|
let mut module_builder = ModuleBuilder::new();
|
||||||
@ -66,15 +63,9 @@ async fn create_context() -> anyhow::Result<(AsyncContext, AsyncRuntime)> {
|
|||||||
.expect("Unable to create async context");
|
.expect("Unable to create async context");
|
||||||
|
|
||||||
async_with!(context => |ctx| {
|
async_with!(context => |ctx| {
|
||||||
global_attachment.attach(&ctx)?;
|
global_attachment.attach(&ctx).catch(&ctx).map_err(|e| anyhow!("Failed to attach global modules: {}", e))?;
|
||||||
let global = ctx.globals();
|
webview::init(&ctx, server_endpoint_url, server_secret).catch(&ctx).map_err(|e| anyhow!("Failed to initialize WebView API: {}", e))?;
|
||||||
Class::<Webview>::define(&global)?;
|
anyhow::Ok(())
|
||||||
|
|
||||||
|
|
||||||
let globals = ctx.globals();
|
|
||||||
globals.set("openWebview", Func::new(Async(open_webview)))?;
|
|
||||||
|
|
||||||
Ok::<(), Error>(())
|
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.map_err(|e| anyhow!("Failed to register globals: {}", e))?;
|
.map_err(|e| anyhow!("Failed to register globals: {}", e))?;
|
||||||
@ -98,7 +89,9 @@ async fn js_executor_thread(
|
|||||||
let result = match command {
|
let result = match command {
|
||||||
PluginCommand::Artist(commands) => execute_artists(commands, &context).await,
|
PluginCommand::Artist(commands) => execute_artists(commands, &context).await,
|
||||||
PluginCommand::Album(commands) => execute_albums(commands, &context).await,
|
PluginCommand::Album(commands) => execute_albums(commands, &context).await,
|
||||||
PluginCommand::AudioSource(commands) => execute_audio_source(commands, &context).await,
|
PluginCommand::AudioSource(commands) => {
|
||||||
|
execute_audio_source(commands, &context).await
|
||||||
|
}
|
||||||
PluginCommand::Auth(commands) => execute_auth(commands, &context).await,
|
PluginCommand::Auth(commands) => execute_auth(commands, &context).await,
|
||||||
PluginCommand::Browse(commands) => execute_browse(commands, &context).await,
|
PluginCommand::Browse(commands) => execute_browse(commands, &context).await,
|
||||||
PluginCommand::Core(commands) => execute_core(commands, &context).await,
|
PluginCommand::Core(commands) => execute_core(commands, &context).await,
|
||||||
@ -162,11 +155,13 @@ impl SpotubePlugin {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[frb(sync)]
|
// #[frb(sync)]
|
||||||
pub fn create_context(
|
pub fn create_context(
|
||||||
&self,
|
&self,
|
||||||
plugin_script: String,
|
plugin_script: String,
|
||||||
plugin_config: PluginConfiguration,
|
plugin_config: PluginConfiguration,
|
||||||
|
server_endpoint_url: String,
|
||||||
|
server_secret: String,
|
||||||
) -> anyhow::Result<OpaqueSender> {
|
) -> anyhow::Result<OpaqueSender> {
|
||||||
let (command_tx, mut command_rx) = mpsc::channel(32);
|
let (command_tx, mut command_rx) = mpsc::channel(32);
|
||||||
let sender = self.event_tx.clone();
|
let sender = self.event_tx.clone();
|
||||||
@ -177,7 +172,10 @@ impl SpotubePlugin {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let local = LocalSet::new();
|
let local = LocalSet::new();
|
||||||
if let Err(e) = local.block_on(&rt, async {
|
if let Err(e) = local.block_on(&rt, async {
|
||||||
let (ctx, _) = create_context().await?;
|
let (ctx, _) = create_context(
|
||||||
|
server_endpoint_url,
|
||||||
|
server_secret,
|
||||||
|
).await?;
|
||||||
|
|
||||||
let injection = format!(
|
let injection = format!(
|
||||||
"globalThis.pluginInstance = new {}();",
|
"globalThis.pluginInstance = new {}();",
|
||||||
@ -185,7 +183,10 @@ impl SpotubePlugin {
|
|||||||
);
|
);
|
||||||
let script = format!("{}\n{}", plugin_script, injection);
|
let script = format!("{}\n{}", plugin_script, injection);
|
||||||
|
|
||||||
ctx.with(|cx| cx.eval::<(), _>(script.as_str())).await?;
|
async_with!(ctx => |cx| {
|
||||||
|
cx.eval::<(), _>(script.as_str())
|
||||||
|
.catch(&cx).map_err(|e| anyhow!("Failed to evaluate supplied plugin script: {}", e))
|
||||||
|
}).await?;
|
||||||
|
|
||||||
async_with!(ctx => |ctx|{
|
async_with!(ctx => |ctx|{
|
||||||
let globals = ctx.globals();
|
let globals = ctx.globals();
|
||||||
|
|||||||
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
// Section: imports
|
// Section: imports
|
||||||
|
|
||||||
use crate::api::host_api::webview::*;
|
|
||||||
use crate::api::plugin::commands::*;
|
use crate::api::plugin::commands::*;
|
||||||
use crate::api::plugin::plugin::*;
|
use crate::api::plugin::plugin::*;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
@ -43,7 +42,7 @@ flutter_rust_bridge::frb_generated_boilerplate!(
|
|||||||
default_rust_auto_opaque = RustAutoOpaqueMoi,
|
default_rust_auto_opaque = RustAutoOpaqueMoi,
|
||||||
);
|
);
|
||||||
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.11.1";
|
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.11.1";
|
||||||
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 1149066488;
|
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 1716120288;
|
||||||
|
|
||||||
// Section: executor
|
// Section: executor
|
||||||
|
|
||||||
@ -1282,6 +1281,8 @@ fn wire__crate__api__plugin__plugin__SpotubePlugin_create_context_impl(
|
|||||||
<crate::api::plugin::models::core::PluginConfiguration>::sse_decode(
|
<crate::api::plugin::models::core::PluginConfiguration>::sse_decode(
|
||||||
&mut deserializer,
|
&mut deserializer,
|
||||||
);
|
);
|
||||||
|
let api_server_endpoint_url = <String>::sse_decode(&mut deserializer);
|
||||||
|
let api_server_secret = <String>::sse_decode(&mut deserializer);
|
||||||
deserializer.end();
|
deserializer.end();
|
||||||
transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>(
|
transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>(
|
||||||
(move || {
|
(move || {
|
||||||
@ -1303,6 +1304,8 @@ fn wire__crate__api__plugin__plugin__SpotubePlugin_create_context_impl(
|
|||||||
&*api_that_guard,
|
&*api_that_guard,
|
||||||
api_plugin_script,
|
api_plugin_script,
|
||||||
api_plugin_config,
|
api_plugin_config,
|
||||||
|
api_server_endpoint_url,
|
||||||
|
api_server_secret,
|
||||||
)?;
|
)?;
|
||||||
Ok(output_ok)
|
Ok(output_ok)
|
||||||
})(),
|
})(),
|
||||||
@ -1374,24 +1377,6 @@ fn wire__crate__api__init_app_impl(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
fn wire__crate__api__host_api__webview__initialize_webview_callbacks_impl(
|
|
||||||
port_: flutter_rust_bridge::for_generated::MessagePort,
|
|
||||||
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
|
|
||||||
rust_vec_len_: i32,
|
|
||||||
data_len_: i32,
|
|
||||||
) {
|
|
||||||
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::SseCodec,_,_,_>(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "initialize_webview_callbacks", port: Some(port_), mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal }, move || {
|
|
||||||
let message = unsafe { flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_, rust_vec_len_, data_len_) };
|
|
||||||
let mut deserializer = flutter_rust_bridge::for_generated::SseDeserializer::new(message);
|
|
||||||
let api_create_webview = decode_DartFn_Inputs_String_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString_Output_DartOpaque_AnyhowException(<flutter_rust_bridge::DartOpaque>::sse_decode(&mut deserializer));
|
|
||||||
let api_open_webview = decode_DartFn_Inputs_DartOpaque_Output_unit_AnyhowException(<flutter_rust_bridge::DartOpaque>::sse_decode(&mut deserializer));
|
|
||||||
let api_close_webview = decode_DartFn_Inputs_DartOpaque_Output_unit_AnyhowException(<flutter_rust_bridge::DartOpaque>::sse_decode(&mut deserializer));
|
|
||||||
let api_get_cookies = decode_DartFn_Inputs_DartOpaque_String_Output_String_AnyhowException(<flutter_rust_bridge::DartOpaque>::sse_decode(&mut deserializer));deserializer.end(); move |context| async move {
|
|
||||||
transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>((move || async move {
|
|
||||||
let output_ok = crate::api::host_api::webview::initialize_webview_callbacks(api_create_webview, api_open_webview, api_close_webview, api_get_cookies).await?; Ok(output_ok)
|
|
||||||
})().await)
|
|
||||||
} })
|
|
||||||
}
|
|
||||||
fn wire__crate__api__plugin__senders__plugin_album_sender_get_album_impl(
|
fn wire__crate__api__plugin__senders__plugin_album_sender_get_album_impl(
|
||||||
port_: flutter_rust_bridge::for_generated::MessagePort,
|
port_: flutter_rust_bridge::for_generated::MessagePort,
|
||||||
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
|
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
|
||||||
@ -4401,45 +4386,6 @@ fn wire__crate__api__plugin__senders__plugin_user_sender_saved_tracks_impl(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
fn wire__crate__api__host_api__webview__send_webview_events_impl(
|
|
||||||
port_: flutter_rust_bridge::for_generated::MessagePort,
|
|
||||||
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
|
|
||||||
rust_vec_len_: i32,
|
|
||||||
data_len_: i32,
|
|
||||||
) {
|
|
||||||
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::SseCodec, _, _, _>(
|
|
||||||
flutter_rust_bridge::for_generated::TaskInfo {
|
|
||||||
debug_name: "send_webview_events",
|
|
||||||
port: Some(port_),
|
|
||||||
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
|
|
||||||
},
|
|
||||||
move || {
|
|
||||||
let message = unsafe {
|
|
||||||
flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(
|
|
||||||
ptr_,
|
|
||||||
rust_vec_len_,
|
|
||||||
data_len_,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
let mut deserializer =
|
|
||||||
flutter_rust_bridge::for_generated::SseDeserializer::new(message);
|
|
||||||
let api_tx = <BroadcastSender<String>>::sse_decode(&mut deserializer);
|
|
||||||
let api_event = <String>::sse_decode(&mut deserializer);
|
|
||||||
deserializer.end();
|
|
||||||
move |context| async move {
|
|
||||||
transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>(
|
|
||||||
(move || async move {
|
|
||||||
let output_ok =
|
|
||||||
crate::api::host_api::webview::send_webview_events(api_tx, api_event)
|
|
||||||
.await?;
|
|
||||||
Ok(output_ok)
|
|
||||||
})()
|
|
||||||
.await,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
fn wire__crate__api__plugin__models__audio_source__spotube_audio_lossless_container_quality_to_string_fmt_impl(
|
fn wire__crate__api__plugin__models__audio_source__spotube_audio_lossless_container_quality_to_string_fmt_impl(
|
||||||
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
|
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
|
||||||
rust_vec_len_: i32,
|
rust_vec_len_: i32,
|
||||||
@ -4484,129 +4430,6 @@ fn wire__crate__api__plugin__models__audio_source__spotube_audio_source_containe
|
|||||||
|
|
||||||
// Section: related_funcs
|
// Section: related_funcs
|
||||||
|
|
||||||
fn decode_DartFn_Inputs_DartOpaque_Output_unit_AnyhowException(
|
|
||||||
dart_opaque: flutter_rust_bridge::DartOpaque,
|
|
||||||
) -> impl Fn(flutter_rust_bridge::DartOpaque) -> flutter_rust_bridge::DartFnFuture<()> {
|
|
||||||
use flutter_rust_bridge::IntoDart;
|
|
||||||
|
|
||||||
async fn body(
|
|
||||||
dart_opaque: flutter_rust_bridge::DartOpaque,
|
|
||||||
arg0: flutter_rust_bridge::DartOpaque,
|
|
||||||
) -> () {
|
|
||||||
let args = vec![arg0.into_into_dart().into_dart()];
|
|
||||||
let message = FLUTTER_RUST_BRIDGE_HANDLER
|
|
||||||
.dart_fn_invoke(dart_opaque, args)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
let mut deserializer = flutter_rust_bridge::for_generated::SseDeserializer::new(message);
|
|
||||||
let action = deserializer.cursor.read_u8().unwrap();
|
|
||||||
let ans = match action {
|
|
||||||
0 => std::result::Result::Ok(<()>::sse_decode(&mut deserializer)),
|
|
||||||
1 => std::result::Result::Err(
|
|
||||||
<flutter_rust_bridge::for_generated::anyhow::Error>::sse_decode(&mut deserializer),
|
|
||||||
),
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
deserializer.end();
|
|
||||||
let ans = ans.expect("Dart throws exception but Rust side assume it is not failable");
|
|
||||||
ans
|
|
||||||
}
|
|
||||||
|
|
||||||
move |arg0: flutter_rust_bridge::DartOpaque| {
|
|
||||||
flutter_rust_bridge::for_generated::convert_into_dart_fn_future(body(
|
|
||||||
dart_opaque.clone(),
|
|
||||||
arg0,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn decode_DartFn_Inputs_DartOpaque_String_Output_String_AnyhowException(
|
|
||||||
dart_opaque: flutter_rust_bridge::DartOpaque,
|
|
||||||
) -> impl Fn(flutter_rust_bridge::DartOpaque, String) -> flutter_rust_bridge::DartFnFuture<String> {
|
|
||||||
use flutter_rust_bridge::IntoDart;
|
|
||||||
|
|
||||||
async fn body(
|
|
||||||
dart_opaque: flutter_rust_bridge::DartOpaque,
|
|
||||||
arg0: flutter_rust_bridge::DartOpaque,
|
|
||||||
arg1: String,
|
|
||||||
) -> String {
|
|
||||||
let args = vec![
|
|
||||||
arg0.into_into_dart().into_dart(),
|
|
||||||
arg1.into_into_dart().into_dart(),
|
|
||||||
];
|
|
||||||
let message = FLUTTER_RUST_BRIDGE_HANDLER
|
|
||||||
.dart_fn_invoke(dart_opaque, args)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
let mut deserializer = flutter_rust_bridge::for_generated::SseDeserializer::new(message);
|
|
||||||
let action = deserializer.cursor.read_u8().unwrap();
|
|
||||||
let ans = match action {
|
|
||||||
0 => std::result::Result::Ok(<String>::sse_decode(&mut deserializer)),
|
|
||||||
1 => std::result::Result::Err(
|
|
||||||
<flutter_rust_bridge::for_generated::anyhow::Error>::sse_decode(&mut deserializer),
|
|
||||||
),
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
deserializer.end();
|
|
||||||
let ans = ans.expect("Dart throws exception but Rust side assume it is not failable");
|
|
||||||
ans
|
|
||||||
}
|
|
||||||
|
|
||||||
move |arg0: flutter_rust_bridge::DartOpaque, arg1: String| {
|
|
||||||
flutter_rust_bridge::for_generated::convert_into_dart_fn_future(body(
|
|
||||||
dart_opaque.clone(),
|
|
||||||
arg0,
|
|
||||||
arg1,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn decode_DartFn_Inputs_String_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString_Output_DartOpaque_AnyhowException(
|
|
||||||
dart_opaque: flutter_rust_bridge::DartOpaque,
|
|
||||||
) -> impl Fn(
|
|
||||||
String,
|
|
||||||
BroadcastSender<String>,
|
|
||||||
) -> flutter_rust_bridge::DartFnFuture<flutter_rust_bridge::DartOpaque> {
|
|
||||||
use flutter_rust_bridge::IntoDart;
|
|
||||||
|
|
||||||
async fn body(
|
|
||||||
dart_opaque: flutter_rust_bridge::DartOpaque,
|
|
||||||
arg0: String,
|
|
||||||
arg1: BroadcastSender<String>,
|
|
||||||
) -> flutter_rust_bridge::DartOpaque {
|
|
||||||
let args = vec![
|
|
||||||
arg0.into_into_dart().into_dart(),
|
|
||||||
arg1.into_into_dart().into_dart(),
|
|
||||||
];
|
|
||||||
let message = FLUTTER_RUST_BRIDGE_HANDLER
|
|
||||||
.dart_fn_invoke(dart_opaque, args)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
let mut deserializer = flutter_rust_bridge::for_generated::SseDeserializer::new(message);
|
|
||||||
let action = deserializer.cursor.read_u8().unwrap();
|
|
||||||
let ans = match action {
|
|
||||||
0 => std::result::Result::Ok(<flutter_rust_bridge::DartOpaque>::sse_decode(
|
|
||||||
&mut deserializer,
|
|
||||||
)),
|
|
||||||
1 => std::result::Result::Err(
|
|
||||||
<flutter_rust_bridge::for_generated::anyhow::Error>::sse_decode(&mut deserializer),
|
|
||||||
),
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
deserializer.end();
|
|
||||||
let ans = ans.expect("Dart throws exception but Rust side assume it is not failable");
|
|
||||||
ans
|
|
||||||
}
|
|
||||||
|
|
||||||
move |arg0: String, arg1: BroadcastSender<String>| {
|
|
||||||
flutter_rust_bridge::for_generated::convert_into_dart_fn_future(body(
|
|
||||||
dart_opaque.clone(),
|
|
||||||
arg0,
|
|
||||||
arg1,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
flutter_rust_bridge::frb_generated_moi_arc_impl_value!(
|
|
||||||
flutter_rust_bridge::for_generated::RustAutoOpaqueInner<BroadcastSender<String>>
|
|
||||||
);
|
|
||||||
flutter_rust_bridge::frb_generated_moi_arc_impl_value!(
|
flutter_rust_bridge::frb_generated_moi_arc_impl_value!(
|
||||||
flutter_rust_bridge::for_generated::RustAutoOpaqueInner<OpaqueSender>
|
flutter_rust_bridge::for_generated::RustAutoOpaqueInner<OpaqueSender>
|
||||||
);
|
);
|
||||||
@ -4630,16 +4453,6 @@ impl SseDecode for flutter_rust_bridge::for_generated::anyhow::Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SseDecode for BroadcastSender<String> {
|
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
|
||||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
|
||||||
let mut inner = <RustOpaqueMoi<
|
|
||||||
flutter_rust_bridge::for_generated::RustAutoOpaqueInner<BroadcastSender<String>>,
|
|
||||||
>>::sse_decode(deserializer);
|
|
||||||
return flutter_rust_bridge::for_generated::rust_auto_opaque_decode_owned(inner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SseDecode for OpaqueSender {
|
impl SseDecode for OpaqueSender {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
||||||
@ -4680,26 +4493,6 @@ impl SseDecode for SpotubePlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SseDecode for flutter_rust_bridge::DartOpaque {
|
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
|
||||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
|
||||||
let mut inner = <usize>::sse_decode(deserializer);
|
|
||||||
return unsafe { flutter_rust_bridge::for_generated::sse_decode_dart_opaque(inner) };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SseDecode
|
|
||||||
for RustOpaqueMoi<
|
|
||||||
flutter_rust_bridge::for_generated::RustAutoOpaqueInner<BroadcastSender<String>>,
|
|
||||||
>
|
|
||||||
{
|
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
|
||||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
|
||||||
let mut inner = <usize>::sse_decode(deserializer);
|
|
||||||
return decode_rust_opaque_moi(inner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SseDecode
|
impl SseDecode
|
||||||
for RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<OpaqueSender>>
|
for RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<OpaqueSender>>
|
||||||
{
|
{
|
||||||
@ -4815,13 +4608,6 @@ impl SseDecode for i64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SseDecode for isize {
|
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
|
||||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
|
||||||
deserializer.cursor.read_i64::<NativeEndian>().unwrap() as _
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SseDecode for Vec<String> {
|
impl SseDecode for Vec<String> {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
||||||
@ -5970,55 +5756,53 @@ fn pde_ffi_dispatcher_primary_impl(
|
|||||||
3 => wire__crate__api__plugin__plugin__SpotubePlugin_auth_state_impl(port, ptr, rust_vec_len, data_len),
|
3 => wire__crate__api__plugin__plugin__SpotubePlugin_auth_state_impl(port, ptr, rust_vec_len, data_len),
|
||||||
24 => wire__crate__api__plugin__plugin__SpotubePlugin_close_impl(port, ptr, rust_vec_len, data_len),
|
24 => wire__crate__api__plugin__plugin__SpotubePlugin_close_impl(port, ptr, rust_vec_len, data_len),
|
||||||
27 => wire__crate__api__init_app_impl(port, ptr, rust_vec_len, data_len),
|
27 => wire__crate__api__init_app_impl(port, ptr, rust_vec_len, data_len),
|
||||||
28 => wire__crate__api__host_api__webview__initialize_webview_callbacks_impl(port, ptr, rust_vec_len, data_len),
|
28 => wire__crate__api__plugin__senders__plugin_album_sender_get_album_impl(port, ptr, rust_vec_len, data_len),
|
||||||
29 => wire__crate__api__plugin__senders__plugin_album_sender_get_album_impl(port, ptr, rust_vec_len, data_len),
|
29 => wire__crate__api__plugin__senders__plugin_album_sender_releases_impl(port, ptr, rust_vec_len, data_len),
|
||||||
30 => wire__crate__api__plugin__senders__plugin_album_sender_releases_impl(port, ptr, rust_vec_len, data_len),
|
30 => wire__crate__api__plugin__senders__plugin_album_sender_save_impl(port, ptr, rust_vec_len, data_len),
|
||||||
31 => wire__crate__api__plugin__senders__plugin_album_sender_save_impl(port, ptr, rust_vec_len, data_len),
|
31 => wire__crate__api__plugin__senders__plugin_album_sender_tracks_impl(port, ptr, rust_vec_len, data_len),
|
||||||
32 => wire__crate__api__plugin__senders__plugin_album_sender_tracks_impl(port, ptr, rust_vec_len, data_len),
|
32 => wire__crate__api__plugin__senders__plugin_album_sender_unsave_impl(port, ptr, rust_vec_len, data_len),
|
||||||
33 => wire__crate__api__plugin__senders__plugin_album_sender_unsave_impl(port, ptr, rust_vec_len, data_len),
|
33 => wire__crate__api__plugin__senders__plugin_artist_sender_albums_impl(port, ptr, rust_vec_len, data_len),
|
||||||
34 => wire__crate__api__plugin__senders__plugin_artist_sender_albums_impl(port, ptr, rust_vec_len, data_len),
|
34 => wire__crate__api__plugin__senders__plugin_artist_sender_get_artist_impl(port, ptr, rust_vec_len, data_len),
|
||||||
35 => wire__crate__api__plugin__senders__plugin_artist_sender_get_artist_impl(port, ptr, rust_vec_len, data_len),
|
35 => wire__crate__api__plugin__senders__plugin_artist_sender_related_impl(port, ptr, rust_vec_len, data_len),
|
||||||
36 => wire__crate__api__plugin__senders__plugin_artist_sender_related_impl(port, ptr, rust_vec_len, data_len),
|
36 => wire__crate__api__plugin__senders__plugin_artist_sender_save_impl(port, ptr, rust_vec_len, data_len),
|
||||||
37 => wire__crate__api__plugin__senders__plugin_artist_sender_save_impl(port, ptr, rust_vec_len, data_len),
|
37 => wire__crate__api__plugin__senders__plugin_artist_sender_top_tracks_impl(port, ptr, rust_vec_len, data_len),
|
||||||
38 => wire__crate__api__plugin__senders__plugin_artist_sender_top_tracks_impl(port, ptr, rust_vec_len, data_len),
|
38 => wire__crate__api__plugin__senders__plugin_artist_sender_unsave_impl(port, ptr, rust_vec_len, data_len),
|
||||||
39 => wire__crate__api__plugin__senders__plugin_artist_sender_unsave_impl(port, ptr, rust_vec_len, data_len),
|
39 => wire__crate__api__plugin__senders__plugin_audio_source_sender_matches_impl(port, ptr, rust_vec_len, data_len),
|
||||||
40 => wire__crate__api__plugin__senders__plugin_audio_source_sender_matches_impl(port, ptr, rust_vec_len, data_len),
|
40 => wire__crate__api__plugin__senders__plugin_audio_source_sender_streams_impl(port, ptr, rust_vec_len, data_len),
|
||||||
41 => wire__crate__api__plugin__senders__plugin_audio_source_sender_streams_impl(port, ptr, rust_vec_len, data_len),
|
41 => wire__crate__api__plugin__senders__plugin_auth_sender_authenticate_impl(port, ptr, rust_vec_len, data_len),
|
||||||
42 => wire__crate__api__plugin__senders__plugin_auth_sender_authenticate_impl(port, ptr, rust_vec_len, data_len),
|
42 => wire__crate__api__plugin__senders__plugin_auth_sender_is_authenticated_impl(port, ptr, rust_vec_len, data_len),
|
||||||
43 => wire__crate__api__plugin__senders__plugin_auth_sender_is_authenticated_impl(port, ptr, rust_vec_len, data_len),
|
43 => wire__crate__api__plugin__senders__plugin_auth_sender_logout_impl(port, ptr, rust_vec_len, data_len),
|
||||||
44 => wire__crate__api__plugin__senders__plugin_auth_sender_logout_impl(port, ptr, rust_vec_len, data_len),
|
44 => wire__crate__api__plugin__senders__plugin_browse_sender_section_items_impl(port, ptr, rust_vec_len, data_len),
|
||||||
45 => wire__crate__api__plugin__senders__plugin_browse_sender_section_items_impl(port, ptr, rust_vec_len, data_len),
|
45 => wire__crate__api__plugin__senders__plugin_browse_sender_sections_impl(port, ptr, rust_vec_len, data_len),
|
||||||
46 => wire__crate__api__plugin__senders__plugin_browse_sender_sections_impl(port, ptr, rust_vec_len, data_len),
|
46 => wire__crate__api__plugin__models__core__plugin_configuration_slug_impl(port, ptr, rust_vec_len, data_len),
|
||||||
47 => wire__crate__api__plugin__models__core__plugin_configuration_slug_impl(port, ptr, rust_vec_len, data_len),
|
47 => wire__crate__api__plugin__senders__plugin_core_sender_check_update_impl(port, ptr, rust_vec_len, data_len),
|
||||||
48 => wire__crate__api__plugin__senders__plugin_core_sender_check_update_impl(port, ptr, rust_vec_len, data_len),
|
48 => wire__crate__api__plugin__senders__plugin_core_sender_scrobble_impl(port, ptr, rust_vec_len, data_len),
|
||||||
49 => wire__crate__api__plugin__senders__plugin_core_sender_scrobble_impl(port, ptr, rust_vec_len, data_len),
|
49 => wire__crate__api__plugin__senders__plugin_core_sender_support_impl(port, ptr, rust_vec_len, data_len),
|
||||||
50 => wire__crate__api__plugin__senders__plugin_core_sender_support_impl(port, ptr, rust_vec_len, data_len),
|
50 => wire__crate__api__plugin__senders__plugin_playlist_sender_add_tracks_impl(port, ptr, rust_vec_len, data_len),
|
||||||
51 => wire__crate__api__plugin__senders__plugin_playlist_sender_add_tracks_impl(port, ptr, rust_vec_len, data_len),
|
51 => wire__crate__api__plugin__senders__plugin_playlist_sender_create_playlist_impl(port, ptr, rust_vec_len, data_len),
|
||||||
52 => wire__crate__api__plugin__senders__plugin_playlist_sender_create_playlist_impl(port, ptr, rust_vec_len, data_len),
|
52 => wire__crate__api__plugin__senders__plugin_playlist_sender_delete_playlist_impl(port, ptr, rust_vec_len, data_len),
|
||||||
53 => wire__crate__api__plugin__senders__plugin_playlist_sender_delete_playlist_impl(port, ptr, rust_vec_len, data_len),
|
53 => wire__crate__api__plugin__senders__plugin_playlist_sender_get_playlist_impl(port, ptr, rust_vec_len, data_len),
|
||||||
54 => wire__crate__api__plugin__senders__plugin_playlist_sender_get_playlist_impl(port, ptr, rust_vec_len, data_len),
|
54 => wire__crate__api__plugin__senders__plugin_playlist_sender_remove_tracks_impl(port, ptr, rust_vec_len, data_len),
|
||||||
55 => wire__crate__api__plugin__senders__plugin_playlist_sender_remove_tracks_impl(port, ptr, rust_vec_len, data_len),
|
55 => wire__crate__api__plugin__senders__plugin_playlist_sender_save_impl(port, ptr, rust_vec_len, data_len),
|
||||||
56 => wire__crate__api__plugin__senders__plugin_playlist_sender_save_impl(port, ptr, rust_vec_len, data_len),
|
56 => wire__crate__api__plugin__senders__plugin_playlist_sender_tracks_impl(port, ptr, rust_vec_len, data_len),
|
||||||
57 => wire__crate__api__plugin__senders__plugin_playlist_sender_tracks_impl(port, ptr, rust_vec_len, data_len),
|
57 => wire__crate__api__plugin__senders__plugin_playlist_sender_unsave_impl(port, ptr, rust_vec_len, data_len),
|
||||||
58 => wire__crate__api__plugin__senders__plugin_playlist_sender_unsave_impl(port, ptr, rust_vec_len, data_len),
|
58 => wire__crate__api__plugin__senders__plugin_playlist_sender_update_playlist_impl(port, ptr, rust_vec_len, data_len),
|
||||||
59 => wire__crate__api__plugin__senders__plugin_playlist_sender_update_playlist_impl(port, ptr, rust_vec_len, data_len),
|
59 => wire__crate__api__plugin__senders__plugin_search_sender_albums_impl(port, ptr, rust_vec_len, data_len),
|
||||||
60 => wire__crate__api__plugin__senders__plugin_search_sender_albums_impl(port, ptr, rust_vec_len, data_len),
|
60 => wire__crate__api__plugin__senders__plugin_search_sender_all_impl(port, ptr, rust_vec_len, data_len),
|
||||||
61 => wire__crate__api__plugin__senders__plugin_search_sender_all_impl(port, ptr, rust_vec_len, data_len),
|
61 => wire__crate__api__plugin__senders__plugin_search_sender_artists_impl(port, ptr, rust_vec_len, data_len),
|
||||||
62 => wire__crate__api__plugin__senders__plugin_search_sender_artists_impl(port, ptr, rust_vec_len, data_len),
|
62 => wire__crate__api__plugin__senders__plugin_search_sender_chips_impl(port, ptr, rust_vec_len, data_len),
|
||||||
63 => wire__crate__api__plugin__senders__plugin_search_sender_chips_impl(port, ptr, rust_vec_len, data_len),
|
63 => wire__crate__api__plugin__senders__plugin_search_sender_playlists_impl(port, ptr, rust_vec_len, data_len),
|
||||||
64 => wire__crate__api__plugin__senders__plugin_search_sender_playlists_impl(port, ptr, rust_vec_len, data_len),
|
64 => wire__crate__api__plugin__senders__plugin_search_sender_tracks_impl(port, ptr, rust_vec_len, data_len),
|
||||||
65 => wire__crate__api__plugin__senders__plugin_search_sender_tracks_impl(port, ptr, rust_vec_len, data_len),
|
65 => wire__crate__api__plugin__senders__plugin_track_sender_get_track_impl(port, ptr, rust_vec_len, data_len),
|
||||||
66 => wire__crate__api__plugin__senders__plugin_track_sender_get_track_impl(port, ptr, rust_vec_len, data_len),
|
66 => wire__crate__api__plugin__senders__plugin_track_sender_radio_impl(port, ptr, rust_vec_len, data_len),
|
||||||
67 => wire__crate__api__plugin__senders__plugin_track_sender_radio_impl(port, ptr, rust_vec_len, data_len),
|
67 => wire__crate__api__plugin__senders__plugin_track_sender_save_impl(port, ptr, rust_vec_len, data_len),
|
||||||
68 => wire__crate__api__plugin__senders__plugin_track_sender_save_impl(port, ptr, rust_vec_len, data_len),
|
68 => wire__crate__api__plugin__senders__plugin_track_sender_unsave_impl(port, ptr, rust_vec_len, data_len),
|
||||||
69 => wire__crate__api__plugin__senders__plugin_track_sender_unsave_impl(port, ptr, rust_vec_len, data_len),
|
69 => wire__crate__api__plugin__senders__plugin_user_sender_me_impl(port, ptr, rust_vec_len, data_len),
|
||||||
70 => wire__crate__api__plugin__senders__plugin_user_sender_me_impl(port, ptr, rust_vec_len, data_len),
|
70 => wire__crate__api__plugin__senders__plugin_user_sender_saved_albums_impl(port, ptr, rust_vec_len, data_len),
|
||||||
71 => wire__crate__api__plugin__senders__plugin_user_sender_saved_albums_impl(port, ptr, rust_vec_len, data_len),
|
71 => wire__crate__api__plugin__senders__plugin_user_sender_saved_artists_impl(port, ptr, rust_vec_len, data_len),
|
||||||
72 => wire__crate__api__plugin__senders__plugin_user_sender_saved_artists_impl(port, ptr, rust_vec_len, data_len),
|
72 => wire__crate__api__plugin__senders__plugin_user_sender_saved_playlists_impl(port, ptr, rust_vec_len, data_len),
|
||||||
73 => wire__crate__api__plugin__senders__plugin_user_sender_saved_playlists_impl(port, ptr, rust_vec_len, data_len),
|
73 => wire__crate__api__plugin__senders__plugin_user_sender_saved_tracks_impl(port, ptr, rust_vec_len, data_len),
|
||||||
74 => wire__crate__api__plugin__senders__plugin_user_sender_saved_tracks_impl(port, ptr, rust_vec_len, data_len),
|
75 => wire__crate__api__plugin__models__audio_source__spotube_audio_lossy_container_quality_to_string_fmt_impl(port, ptr, rust_vec_len, data_len),
|
||||||
75 => wire__crate__api__host_api__webview__send_webview_events_impl(port, ptr, rust_vec_len, data_len),
|
|
||||||
77 => wire__crate__api__plugin__models__audio_source__spotube_audio_lossy_container_quality_to_string_fmt_impl(port, ptr, rust_vec_len, data_len),
|
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6055,34 +5839,14 @@ fn pde_ffi_dispatcher_sync_impl(
|
|||||||
23 => wire__crate__api__plugin__plugin__SpotubePlugin_auto_accessor_set_user_impl(ptr, rust_vec_len, data_len),
|
23 => wire__crate__api__plugin__plugin__SpotubePlugin_auto_accessor_set_user_impl(ptr, rust_vec_len, data_len),
|
||||||
25 => wire__crate__api__plugin__plugin__SpotubePlugin_create_context_impl(ptr, rust_vec_len, data_len),
|
25 => wire__crate__api__plugin__plugin__SpotubePlugin_create_context_impl(ptr, rust_vec_len, data_len),
|
||||||
26 => wire__crate__api__plugin__plugin__SpotubePlugin_new_impl(ptr, rust_vec_len, data_len),
|
26 => wire__crate__api__plugin__plugin__SpotubePlugin_new_impl(ptr, rust_vec_len, data_len),
|
||||||
76 => wire__crate__api__plugin__models__audio_source__spotube_audio_lossless_container_quality_to_string_fmt_impl(ptr, rust_vec_len, data_len),
|
74 => wire__crate__api__plugin__models__audio_source__spotube_audio_lossless_container_quality_to_string_fmt_impl(ptr, rust_vec_len, data_len),
|
||||||
78 => wire__crate__api__plugin__models__audio_source__spotube_audio_source_container_preset_file_extension_impl(ptr, rust_vec_len, data_len),
|
76 => wire__crate__api__plugin__models__audio_source__spotube_audio_source_container_preset_file_extension_impl(ptr, rust_vec_len, data_len),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Section: rust2dart
|
// Section: rust2dart
|
||||||
|
|
||||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
|
||||||
impl flutter_rust_bridge::IntoDart for FrbWrapper<BroadcastSender<String>> {
|
|
||||||
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
|
|
||||||
flutter_rust_bridge::for_generated::rust_auto_opaque_encode::<_, MoiArc<_>>(self.0)
|
|
||||||
.into_dart()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive
|
|
||||||
for FrbWrapper<BroadcastSender<String>>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
impl flutter_rust_bridge::IntoIntoDart<FrbWrapper<BroadcastSender<String>>>
|
|
||||||
for BroadcastSender<String>
|
|
||||||
{
|
|
||||||
fn into_into_dart(self) -> FrbWrapper<BroadcastSender<String>> {
|
|
||||||
self.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||||
impl flutter_rust_bridge::IntoDart for FrbWrapper<OpaqueSender> {
|
impl flutter_rust_bridge::IntoDart for FrbWrapper<OpaqueSender> {
|
||||||
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
|
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
|
||||||
@ -7134,18 +6898,6 @@ impl SseEncode for flutter_rust_bridge::for_generated::anyhow::Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SseEncode for BroadcastSender<String> {
|
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
|
||||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
|
||||||
<RustOpaqueMoi<
|
|
||||||
flutter_rust_bridge::for_generated::RustAutoOpaqueInner<BroadcastSender<String>>,
|
|
||||||
>>::sse_encode(
|
|
||||||
flutter_rust_bridge::for_generated::rust_auto_opaque_encode::<_, MoiArc<_>>(self),
|
|
||||||
serializer,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SseEncode for OpaqueSender {
|
impl SseEncode for OpaqueSender {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||||
@ -7179,26 +6931,6 @@ impl SseEncode for SpotubePlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SseEncode for flutter_rust_bridge::DartOpaque {
|
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
|
||||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
|
||||||
<usize>::sse_encode(self.encode(), serializer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SseEncode
|
|
||||||
for RustOpaqueMoi<
|
|
||||||
flutter_rust_bridge::for_generated::RustAutoOpaqueInner<BroadcastSender<String>>,
|
|
||||||
>
|
|
||||||
{
|
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
|
||||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
|
||||||
let (ptr, size) = self.sse_encode_raw();
|
|
||||||
<usize>::sse_encode(ptr, serializer);
|
|
||||||
<i32>::sse_encode(size, serializer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SseEncode
|
impl SseEncode
|
||||||
for RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<OpaqueSender>>
|
for RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<OpaqueSender>>
|
||||||
{
|
{
|
||||||
@ -7316,16 +7048,6 @@ impl SseEncode for i64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SseEncode for isize {
|
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
|
||||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
|
||||||
serializer
|
|
||||||
.cursor
|
|
||||||
.write_i64::<NativeEndian>(self as _)
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SseEncode for Vec<String> {
|
impl SseEncode for Vec<String> {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||||
@ -8164,7 +7886,6 @@ mod io {
|
|||||||
// Section: imports
|
// Section: imports
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::api::host_api::webview::*;
|
|
||||||
use crate::api::plugin::commands::*;
|
use crate::api::plugin::commands::*;
|
||||||
use crate::api::plugin::plugin::*;
|
use crate::api::plugin::plugin::*;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
@ -8180,20 +7901,6 @@ mod io {
|
|||||||
|
|
||||||
flutter_rust_bridge::frb_generated_boilerplate_io!();
|
flutter_rust_bridge::frb_generated_boilerplate_io!();
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
|
||||||
pub extern "C" fn frbgen_spotube_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString(
|
|
||||||
ptr: *const std::ffi::c_void,
|
|
||||||
) {
|
|
||||||
MoiArc::<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<BroadcastSender < String >>>::increment_strong_count(ptr as _);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
|
||||||
pub extern "C" fn frbgen_spotube_rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBroadcastSenderString(
|
|
||||||
ptr: *const std::ffi::c_void,
|
|
||||||
) {
|
|
||||||
MoiArc::<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<BroadcastSender < String >>>::decrement_strong_count(ptr as _);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
pub extern "C" fn frbgen_spotube_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
pub extern "C" fn frbgen_spotube_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOpaqueSender(
|
||||||
ptr: *const std::ffi::c_void,
|
ptr: *const std::ffi::c_void,
|
||||||
|
|||||||
167
rust/src/internal/apis/event_source.rs
Normal file
167
rust/src/internal/apis/event_source.rs
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
use eventsource_client::{ClientBuilder, Client, SSE};
|
||||||
|
use flutter_rust_bridge::for_generated::futures::StreamExt;
|
||||||
|
use rquickjs::function::Func;
|
||||||
|
use rquickjs::{CatchResultExt, Ctx, Error as JsError, Function, Object, Value};
|
||||||
|
use tokio::sync::mpsc;
|
||||||
|
|
||||||
|
fn connect_sse<'js>(ctx: Ctx<'js>, config: Object<'js>) -> rquickjs::Result<Object<'js>> {
|
||||||
|
let url: String = config.get("url")?;
|
||||||
|
let on_connecting: Function = config.get("onConnecting")?;
|
||||||
|
let on_open: Function = config.get("onOpen")?;
|
||||||
|
let on_message: Function = config.get("onMessage")?;
|
||||||
|
let on_error: Function = config.get("onError")?;
|
||||||
|
|
||||||
|
let (close_tx, mut close_rx) = mpsc::unbounded_channel::<()>();
|
||||||
|
|
||||||
|
if let Err(e) = on_connecting.call::<_, ()>(()).catch(&ctx) {
|
||||||
|
eprintln!("Error in onConnecting callback: {}", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spawn the SSE background task using Ctx::spawn
|
||||||
|
let _ = ctx.clone().spawn(async move {
|
||||||
|
let client = ClientBuilder::for_url(&url);
|
||||||
|
if let Err(err) = client {
|
||||||
|
eprintln!("Error in ClientBuilder::for_url: {}", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let client = client.unwrap().build();
|
||||||
|
|
||||||
|
// Notify "open"
|
||||||
|
if let Err(e) = on_open.call::<(), ()>(()) {
|
||||||
|
eprintln!("Error in onOpen callback: {}", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now listen to SSE events OR close signal
|
||||||
|
let mut stream = Box::pin(client.stream());
|
||||||
|
|
||||||
|
loop {
|
||||||
|
tokio::select! {
|
||||||
|
// Check for close signal first
|
||||||
|
_ = close_rx.recv() => {
|
||||||
|
// Close requested — drop stream and exit
|
||||||
|
drop(stream);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
event = stream.next() => {
|
||||||
|
match event {
|
||||||
|
Some(Ok(SSE::Event(msg))) => {
|
||||||
|
let data = msg.data.clone();
|
||||||
|
if let Err(e) = on_message.call::<_, ()>((data,)) {
|
||||||
|
eprintln!("Error in onMessage callback: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(Ok(SSE::Connected(details))) => {
|
||||||
|
println!("SSE Connected: {:?}", details);
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(Ok(SSE::Comment(comment))) => {
|
||||||
|
println!("SSE Comment: {}", comment);
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(Err(err)) => {
|
||||||
|
if let Err(e) = on_error.call::<_, ()>((err.to_string(),)) {
|
||||||
|
eprintln!("Error in onError callback: {}", e);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
None => {
|
||||||
|
println!("SSE Stream ended gracefully");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Create the close function that sends signal via channel
|
||||||
|
let close_fn = Function::new(ctx.clone(), move |_ctx: Ctx<'_>| {
|
||||||
|
// Send close signal — ignore errors if receiver is gone
|
||||||
|
let _ = close_tx.send(());
|
||||||
|
Ok::<(), JsError>(())
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// Return { close: () => void }
|
||||||
|
let result = Object::new(ctx)?;
|
||||||
|
result.set("close", close_fn)?;
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init(ctx: &Ctx) -> rquickjs::Result<()> {
|
||||||
|
let globals = ctx.globals();
|
||||||
|
|
||||||
|
globals.set("__connectSSE", Func::new(connect_sse))?;
|
||||||
|
|
||||||
|
ctx.eval::<Value, _>(
|
||||||
|
r#"
|
||||||
|
globalThis.EventSource = class EventSource {
|
||||||
|
#listeners = {};
|
||||||
|
|
||||||
|
constructor(url, options) {
|
||||||
|
this.url = url;
|
||||||
|
this.options = options;
|
||||||
|
|
||||||
|
this.close = __connectSSE({
|
||||||
|
url: this.url,
|
||||||
|
onConnecting: this.#onConnecting.bind(this),
|
||||||
|
onOpen: this.#onOpen.bind(this),
|
||||||
|
onMessage: this.#onMessage.bind(this),
|
||||||
|
onError: this.#onError.bind(this),
|
||||||
|
}).close;
|
||||||
|
}
|
||||||
|
|
||||||
|
#onMessage(data) {
|
||||||
|
console.log("Received message:", data);
|
||||||
|
if (this.onmessage) {
|
||||||
|
this.onmessage(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
const eventLines = data.split('\n');
|
||||||
|
|
||||||
|
if(eventLines.length === 0) return;
|
||||||
|
const eventNameChunks = eventLines[0].split("event:");
|
||||||
|
|
||||||
|
if(eventNameChunks.length === 0) return;
|
||||||
|
const eventName = eventNameChunks[1].trim();
|
||||||
|
|
||||||
|
if (!this.#listeners[eventName]) return;
|
||||||
|
const eventDataChunks = eventLines[1].split("data:");
|
||||||
|
|
||||||
|
if(eventDataChunks.length === 0) return;
|
||||||
|
const eventData = eventDataChunks[1].trim();
|
||||||
|
|
||||||
|
if (!eventData) return;
|
||||||
|
this.#listeners[eventName](eventData);
|
||||||
|
}
|
||||||
|
|
||||||
|
#onConnecting() {
|
||||||
|
this.readyState = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#onOpen() {
|
||||||
|
this.readyState = 1;
|
||||||
|
if (this.onopen) {
|
||||||
|
this.onopen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#onError(error) {
|
||||||
|
this.readyState = 2;
|
||||||
|
if (this.onerror) {
|
||||||
|
this.onerror(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addEventListener(event, callback) {
|
||||||
|
this.#listeners[event] ??= [];
|
||||||
|
this.#listeners[event].push(callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@ -1 +1,2 @@
|
|||||||
pub mod fetcher;
|
pub mod event_source;
|
||||||
|
pub mod webview;
|
||||||
|
|||||||
215
rust/src/internal/apis/webview.rs
Normal file
215
rust/src/internal/apis/webview.rs
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
use eventsource_client::{Client as EventSourceClient, ClientBuilder};
|
||||||
|
use flutter_rust_bridge::for_generated::futures::StreamExt;
|
||||||
|
use rquickjs::{class::Trace, Class, Ctx, Function, JsLifetime};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct WebViewURLRequest {
|
||||||
|
url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct WebViewUIDRequest {
|
||||||
|
uid: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct WebViewCookiesRequest {
|
||||||
|
url: String,
|
||||||
|
uid: String,
|
||||||
|
}
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct WebViewResponse {
|
||||||
|
uid: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Trace, JsLifetime)]
|
||||||
|
#[rquickjs::class]
|
||||||
|
pub struct WebView<'js> {
|
||||||
|
pub url: String,
|
||||||
|
pub uid: String,
|
||||||
|
#[qjs(skip_trace)]
|
||||||
|
endpoint_url: String,
|
||||||
|
#[qjs(skip_trace)]
|
||||||
|
secret: String,
|
||||||
|
#[qjs(skip_trace)]
|
||||||
|
callbacks: Vec<Function<'js>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rquickjs::methods]
|
||||||
|
impl<'js> WebView<'js> {
|
||||||
|
#[qjs(constructor)]
|
||||||
|
pub fn new(url: String, uid: String, endpoint_url: String, secret: String) -> Self {
|
||||||
|
Self {
|
||||||
|
url,
|
||||||
|
uid,
|
||||||
|
endpoint_url,
|
||||||
|
secret,
|
||||||
|
callbacks: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[qjs(static)]
|
||||||
|
pub async fn create(ctx: Ctx<'js>, url: String) -> rquickjs::Result<Class<'js, WebView<'js>>> {
|
||||||
|
let endpoint_url: String = ctx.globals().get("__webviewUrl").unwrap_or_default();
|
||||||
|
let secret: String = ctx.globals().get("__webviewSecret").unwrap_or_default();
|
||||||
|
|
||||||
|
let client = reqwest::Client::new();
|
||||||
|
let endpoint = format!("{}/plugin-api/webview/create", endpoint_url.clone());
|
||||||
|
|
||||||
|
let response = client
|
||||||
|
.post(&endpoint)
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.header("X-Plugin-Secret", &secret)
|
||||||
|
.json(&WebViewURLRequest { url: url.clone() })
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
rquickjs::Error::new_from_js_message("reqwest", "Error", &e.to_string())
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let data: WebViewResponse = response.json().await.map_err(|e| {
|
||||||
|
rquickjs::Error::new_from_js_message("reqwest", "Error", &e.to_string())
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let webview = WebView::new(url, data.uid, endpoint_url, secret);
|
||||||
|
|
||||||
|
Class::instance(ctx, webview)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn open(&self) -> rquickjs::Result<()> {
|
||||||
|
let client = reqwest::Client::new();
|
||||||
|
let endpoint = format!("{}/plugin-api/webview/open", self.endpoint_url);
|
||||||
|
|
||||||
|
client
|
||||||
|
.post(&endpoint)
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.header("X-Plugin-Secret", &self.secret)
|
||||||
|
.json(&WebViewUIDRequest {
|
||||||
|
uid: self.uid.clone(),
|
||||||
|
})
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
rquickjs::Error::new_from_js_message("reqwest", "Error", &e.to_string())
|
||||||
|
})?;
|
||||||
|
|
||||||
|
self.url_change_task().await;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn cookies(&self, ctx: Ctx<'js>) -> rquickjs::Result<rquickjs::Value<'js>> {
|
||||||
|
let client = reqwest::Client::new();
|
||||||
|
let endpoint = format!("{}/plugin-api/webview/cookies", self.endpoint_url);
|
||||||
|
|
||||||
|
let response = client
|
||||||
|
.post(&endpoint)
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.header("X-Plugin-Secret", &self.secret)
|
||||||
|
.json(&WebViewCookiesRequest {
|
||||||
|
url: self.url.clone(),
|
||||||
|
uid: self.uid.clone(),
|
||||||
|
})
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
rquickjs::Error::new_from_js_message("reqwest", "Error", &e.to_string())
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let data: serde_json::Value = response.json().await.map_err(|e| {
|
||||||
|
rquickjs::Error::new_from_js_message("reqwest", "Error", &e.to_string())
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let value = ctx.json_parse(data.to_string())?;
|
||||||
|
Ok(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn close(&self) -> rquickjs::Result<()> {
|
||||||
|
let client = reqwest::Client::new();
|
||||||
|
let endpoint = format!("{}/plugin-api/webview/close", self.endpoint_url);
|
||||||
|
|
||||||
|
client
|
||||||
|
.post(&endpoint)
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.header("X-Plugin-Secret", &self.secret)
|
||||||
|
.json(&WebViewUIDRequest {
|
||||||
|
uid: self.uid.clone(),
|
||||||
|
})
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
rquickjs::Error::new_from_js_message("reqwest", "Error", &e.to_string())
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[qjs(rename = "onUrlChange")]
|
||||||
|
pub fn on_url_change(&mut self, callback: Function<'js>) -> rquickjs::Result<()> {
|
||||||
|
self.callbacks.push(callback);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn url_change_task(&self) {
|
||||||
|
let endpoint = format!(
|
||||||
|
"{}/plugin-api/webview/{}/on-url-request",
|
||||||
|
self.endpoint_url, self.uid
|
||||||
|
);
|
||||||
|
|
||||||
|
let secret = self.secret.clone();
|
||||||
|
|
||||||
|
let mut backoff = 1u64;
|
||||||
|
const MAX_BACKOFF: u64 = 60;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let client = ClientBuilder::for_url(&endpoint)
|
||||||
|
.expect("Failed to create EventSourceClient")
|
||||||
|
.header("X-Plugin-Secret", &secret)
|
||||||
|
.expect("Failed to set header for EventSourceClient")
|
||||||
|
.build();
|
||||||
|
let mut stream = client.stream();
|
||||||
|
while let Some(event) = stream.next().await {
|
||||||
|
match event {
|
||||||
|
Ok(eventsource_client::SSE::Event(msg)) => {
|
||||||
|
if msg.event_type != "url-request" {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
backoff = 1;
|
||||||
|
if let Ok(data) = serde_json::from_str::<HashMap<String, String>>(&msg.data)
|
||||||
|
{
|
||||||
|
let url = data.get("url").cloned().unwrap_or_default();
|
||||||
|
for callback in self.callbacks.iter() {
|
||||||
|
if let Err(e) = callback.call::<_, ()>((url.clone(),)) {
|
||||||
|
eprintln!("Error in onUrlChange callback: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
eprintln!("Failed to parse event data: {}", msg.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("Error in EventSource stream: {}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eprintln!("EventSource disconnected. Reconnecting in {}s...", backoff);
|
||||||
|
tokio::time::sleep(tokio::time::Duration::from_secs(backoff)).await;
|
||||||
|
backoff = (backoff * 2).min(MAX_BACKOFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init(ctx: &Ctx, endpoint_url: String, secret: String) -> rquickjs::Result<()> {
|
||||||
|
// Store config in globals for access in static methods
|
||||||
|
ctx.globals().set("__webviewUrl", endpoint_url)?;
|
||||||
|
ctx.globals().set("__webviewSecret", secret)?;
|
||||||
|
|
||||||
|
// Register the WebView class
|
||||||
|
Class::<WebView>::define(&ctx.globals())?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@ -1,5 +1,4 @@
|
|||||||
pub mod album;
|
pub mod album;
|
||||||
pub mod apis;
|
|
||||||
pub mod artist;
|
pub mod artist;
|
||||||
pub mod audio_source;
|
pub mod audio_source;
|
||||||
pub mod browse;
|
pub mod browse;
|
||||||
@ -10,4 +9,5 @@ pub mod track;
|
|||||||
pub mod user;
|
pub mod user;
|
||||||
pub mod auth;
|
pub mod auth;
|
||||||
pub(crate) mod utils;
|
pub(crate) mod utils;
|
||||||
|
pub(crate) mod apis;
|
||||||
// Export Context
|
// Export Context
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
mod api;
|
mod api;
|
||||||
mod internal;
|
|
||||||
mod frb_generated;
|
mod frb_generated;
|
||||||
|
mod internal;
|
||||||
|
|
||||||
use rquickjs::function::{Async, Func};
|
use rquickjs::function::{Async, Func};
|
||||||
use rquickjs::{async_with, AsyncContext, AsyncRuntime, Function, Object, Promise};
|
use rquickjs::{async_with, AsyncContext, AsyncRuntime, Function, Object, Promise};
|
||||||
@ -100,7 +100,7 @@ async fn plugin() -> anyhow::Result<()> {
|
|||||||
repository: None,
|
repository: None,
|
||||||
version: "0.1.0".to_string(),
|
version: "0.1.0".to_string(),
|
||||||
};
|
};
|
||||||
let sender = plugin.create_context(PLUGIN_JS.to_string(), config.clone())?;
|
let sender = plugin.create_context(PLUGIN_JS.to_string(), config.clone(), "".to_string(), "".to_string())?;
|
||||||
let (r1, r2) = tokio::join!(
|
let (r1, r2) = tokio::join!(
|
||||||
plugin.core.check_update(&sender, config.clone()),
|
plugin.core.check_update(&sender, config.clone()),
|
||||||
plugin.core.check_update(&sender, config.clone())
|
plugin.core.check_update(&sender, config.clone())
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user