chore: Implement translation callbacks to flutter

This commit is contained in:
PartyDonut 2025-10-17 18:43:00 +02:00
parent e902e2034a
commit 29917bb59f
16 changed files with 681 additions and 43 deletions

View file

@ -1348,5 +1348,13 @@
"mediaTunnelingTitle": "Media tunneling",
"mediaTunnelingDesc": "Enable media tunneling for native player",
"clientSettingsUseSystemIMETitle": "Use system keyboard",
"clientSettingsUseSystemIMEDesc": "Use the built-in keyboard provided by your system"
"clientSettingsUseSystemIMEDesc": "Use the built-in keyboard provided by your system",
"nextUpInCount": "Next-up in {seconds}",
"@nextUpInCount": {
"placeholders": {
"seconds": {
"type": "int"
}
}
}
}

View file

@ -0,0 +1,262 @@
// Autogenerated from Pigeon (v26.0.1), do not edit directly.
// See also: https://pub.dev/packages/pigeon
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers
import 'dart:async';
import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;
import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
import 'package:flutter/services.dart';
List<Object?> wrapResponse({Object? result, PlatformException? error, bool empty = false}) {
if (empty) {
return <Object?>[];
}
if (error == null) {
return <Object?>[result];
}
return <Object?>[error.code, error.message, error.details];
}
class _PigeonCodec extends StandardMessageCodec {
const _PigeonCodec();
@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is int) {
buffer.putUint8(4);
buffer.putInt64(value);
} else {
super.writeValue(buffer, value);
}
}
@override
Object? readValueOfType(int type, ReadBuffer buffer) {
switch (type) {
default:
return super.readValueOfType(type, buffer);
}
}
}
abstract class TranslationsPigeon {
static const MessageCodec<Object?> pigeonChannelCodec = _PigeonCodec();
String next();
String nextVideo();
String close();
String skip(String name);
String subtitles();
String off();
String chapters(int count);
String nextUpInSeconds(int seconds);
String endsAt(String time);
static void setUp(TranslationsPigeon? api, {BinaryMessenger? binaryMessenger, String messageChannelSuffix = '',}) {
messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : '';
{
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.nl_jknaapen_fladder.settings.TranslationsPigeon.next$messageChannelSuffix', pigeonChannelCodec,
binaryMessenger: binaryMessenger);
if (api == null) {
pigeonVar_channel.setMessageHandler(null);
} else {
pigeonVar_channel.setMessageHandler((Object? message) async {
try {
final String output = api.next();
return wrapResponse(result: output);
} on PlatformException catch (e) {
return wrapResponse(error: e);
} catch (e) {
return wrapResponse(error: PlatformException(code: 'error', message: e.toString()));
}
});
}
}
{
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.nl_jknaapen_fladder.settings.TranslationsPigeon.nextVideo$messageChannelSuffix', pigeonChannelCodec,
binaryMessenger: binaryMessenger);
if (api == null) {
pigeonVar_channel.setMessageHandler(null);
} else {
pigeonVar_channel.setMessageHandler((Object? message) async {
try {
final String output = api.nextVideo();
return wrapResponse(result: output);
} on PlatformException catch (e) {
return wrapResponse(error: e);
} catch (e) {
return wrapResponse(error: PlatformException(code: 'error', message: e.toString()));
}
});
}
}
{
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.nl_jknaapen_fladder.settings.TranslationsPigeon.close$messageChannelSuffix', pigeonChannelCodec,
binaryMessenger: binaryMessenger);
if (api == null) {
pigeonVar_channel.setMessageHandler(null);
} else {
pigeonVar_channel.setMessageHandler((Object? message) async {
try {
final String output = api.close();
return wrapResponse(result: output);
} on PlatformException catch (e) {
return wrapResponse(error: e);
} catch (e) {
return wrapResponse(error: PlatformException(code: 'error', message: e.toString()));
}
});
}
}
{
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.nl_jknaapen_fladder.settings.TranslationsPigeon.skip$messageChannelSuffix', pigeonChannelCodec,
binaryMessenger: binaryMessenger);
if (api == null) {
pigeonVar_channel.setMessageHandler(null);
} else {
pigeonVar_channel.setMessageHandler((Object? message) async {
assert(message != null,
'Argument for dev.flutter.pigeon.nl_jknaapen_fladder.settings.TranslationsPigeon.skip was null.');
final List<Object?> args = (message as List<Object?>?)!;
final String? arg_name = (args[0] as String?);
assert(arg_name != null,
'Argument for dev.flutter.pigeon.nl_jknaapen_fladder.settings.TranslationsPigeon.skip was null, expected non-null String.');
try {
final String output = api.skip(arg_name!);
return wrapResponse(result: output);
} on PlatformException catch (e) {
return wrapResponse(error: e);
} catch (e) {
return wrapResponse(error: PlatformException(code: 'error', message: e.toString()));
}
});
}
}
{
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.nl_jknaapen_fladder.settings.TranslationsPigeon.subtitles$messageChannelSuffix', pigeonChannelCodec,
binaryMessenger: binaryMessenger);
if (api == null) {
pigeonVar_channel.setMessageHandler(null);
} else {
pigeonVar_channel.setMessageHandler((Object? message) async {
try {
final String output = api.subtitles();
return wrapResponse(result: output);
} on PlatformException catch (e) {
return wrapResponse(error: e);
} catch (e) {
return wrapResponse(error: PlatformException(code: 'error', message: e.toString()));
}
});
}
}
{
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.nl_jknaapen_fladder.settings.TranslationsPigeon.off$messageChannelSuffix', pigeonChannelCodec,
binaryMessenger: binaryMessenger);
if (api == null) {
pigeonVar_channel.setMessageHandler(null);
} else {
pigeonVar_channel.setMessageHandler((Object? message) async {
try {
final String output = api.off();
return wrapResponse(result: output);
} on PlatformException catch (e) {
return wrapResponse(error: e);
} catch (e) {
return wrapResponse(error: PlatformException(code: 'error', message: e.toString()));
}
});
}
}
{
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.nl_jknaapen_fladder.settings.TranslationsPigeon.chapters$messageChannelSuffix', pigeonChannelCodec,
binaryMessenger: binaryMessenger);
if (api == null) {
pigeonVar_channel.setMessageHandler(null);
} else {
pigeonVar_channel.setMessageHandler((Object? message) async {
assert(message != null,
'Argument for dev.flutter.pigeon.nl_jknaapen_fladder.settings.TranslationsPigeon.chapters was null.');
final List<Object?> args = (message as List<Object?>?)!;
final int? arg_count = (args[0] as int?);
assert(arg_count != null,
'Argument for dev.flutter.pigeon.nl_jknaapen_fladder.settings.TranslationsPigeon.chapters was null, expected non-null int.');
try {
final String output = api.chapters(arg_count!);
return wrapResponse(result: output);
} on PlatformException catch (e) {
return wrapResponse(error: e);
} catch (e) {
return wrapResponse(error: PlatformException(code: 'error', message: e.toString()));
}
});
}
}
{
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.nl_jknaapen_fladder.settings.TranslationsPigeon.nextUpInSeconds$messageChannelSuffix', pigeonChannelCodec,
binaryMessenger: binaryMessenger);
if (api == null) {
pigeonVar_channel.setMessageHandler(null);
} else {
pigeonVar_channel.setMessageHandler((Object? message) async {
assert(message != null,
'Argument for dev.flutter.pigeon.nl_jknaapen_fladder.settings.TranslationsPigeon.nextUpInSeconds was null.');
final List<Object?> args = (message as List<Object?>?)!;
final int? arg_seconds = (args[0] as int?);
assert(arg_seconds != null,
'Argument for dev.flutter.pigeon.nl_jknaapen_fladder.settings.TranslationsPigeon.nextUpInSeconds was null, expected non-null int.');
try {
final String output = api.nextUpInSeconds(arg_seconds!);
return wrapResponse(result: output);
} on PlatformException catch (e) {
return wrapResponse(error: e);
} catch (e) {
return wrapResponse(error: PlatformException(code: 'error', message: e.toString()));
}
});
}
}
{
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.nl_jknaapen_fladder.settings.TranslationsPigeon.endsAt$messageChannelSuffix', pigeonChannelCodec,
binaryMessenger: binaryMessenger);
if (api == null) {
pigeonVar_channel.setMessageHandler(null);
} else {
pigeonVar_channel.setMessageHandler((Object? message) async {
assert(message != null,
'Argument for dev.flutter.pigeon.nl_jknaapen_fladder.settings.TranslationsPigeon.endsAt was null.');
final List<Object?> args = (message as List<Object?>?)!;
final String? arg_time = (args[0] as String?);
assert(arg_time != null,
'Argument for dev.flutter.pigeon.nl_jknaapen_fladder.settings.TranslationsPigeon.endsAt was null, expected non-null String.');
try {
final String output = api.endsAt(arg_time!);
return wrapResponse(result: output);
} on PlatformException catch (e) {
return wrapResponse(error: e);
} catch (e) {
return wrapResponse(error: PlatformException(code: 'error', message: e.toString()));
}
});
}
}
}
}

View file

@ -1,3 +1,5 @@
import 'dart:developer';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
@ -100,6 +102,7 @@ Future<void> _playVideo(
}
if (context.mounted) {
log("Finished refreshing");
await context.refreshData();
}

View file

@ -4,6 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:fladder/l10n/generated/app_localizations.dart';
import 'package:fladder/providers/sync/background_download_provider.dart';
import 'package:fladder/src/translations_pigeon.g.dart' as messenger;
///Only use for base translations, under normal circumstances ALWAYS use the widgets provided context
final localizationContextProvider = StateProvider<BuildContext?>((ref) => null);
@ -26,6 +27,7 @@ class LocalizationContextWrapper extends ConsumerStatefulWidget {
}
class _LocalizationContextWrapperState extends ConsumerState<LocalizationContextWrapper> {
_TranslationsMessgener? _messenger;
@override
void initState() {
super.initState();
@ -41,6 +43,11 @@ class _LocalizationContextWrapperState extends ConsumerState<LocalizationContext
}
void updateLanguageContext() {
if (_messenger == null) {
_messenger = _TranslationsMessgener(context: context);
messenger.TranslationsPigeon.setUp(_messenger);
}
WidgetsBinding.instance.addPostFrameCallback((value) {
ref.read(localizationContextProvider.notifier).update((cb) => context);
ref.read(backgroundDownloaderProvider.notifier).updateTranslations(context);
@ -58,3 +65,36 @@ extension LocaleDisplayCodeExtension on Locale {
: languageCode.toUpperCase();
}
}
class _TranslationsMessgener extends messenger.TranslationsPigeon {
_TranslationsMessgener({required this.context});
final BuildContext context;
@override
String chapters(int count) => context.localized.chapter(count);
@override
String close() => context.localized.close;
@override
String endsAt(String time) => context.localized.endsAt(DateTime.parse(time));
@override
String next() => context.localized.nextVideo;
@override
String nextUpInSeconds(int seconds) => context.localized.nextUpInCount(seconds);
@override
String nextVideo() => context.localized.nextVideo;
@override
String off() => context.localized.off;
@override
String skip(String name) => context.localized.skipButtonLabel(name);
@override
String subtitles() => context.localized.subtitles;
}

View file

@ -34,9 +34,9 @@ class NativePlayer extends BasePlayer implements VideoPlayerListenerCallback {
Future<void> loadVideo(String url, bool play) async => player.open(url, play);
@override
Future<void> open(BuildContext newContext) async {
Future<StartResult> open(BuildContext newContext) async {
nativeActivityStarted = true;
NativeVideoActivity().launchActivity();
return NativeVideoActivity().launchActivity();
}
@override