From 19b4b1acc9b4cc9c832a7ce417a90b1a902d83ad Mon Sep 17 00:00:00 2001 From: SputNikPlop <100245448+SputNikPlop@users.noreply.github.com> Date: Fri, 2 May 2025 12:18:14 -0700 Subject: [PATCH 1/3] feat: add realtimekit service --- lib/screens/settings/third_party.dart | 107 +++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 1 deletion(-) diff --git a/lib/screens/settings/third_party.dart b/lib/screens/settings/third_party.dart index f3d17f6e..e695d6ee 100644 --- a/lib/screens/settings/third_party.dart +++ b/lib/screens/settings/third_party.dart @@ -80,7 +80,7 @@ class _RealtimeCashWidgetState extends State<_RealtimeCashWidget> { padding: const EdgeInsets.only(left: 88, right: 16), child: TextField( controller: TextEditingController()..text = snapshot.data ?? "", - readOnly: true, + readOnly: false, decoration: InputDecoration( hintText: "Wallet address", suffixIcon: IconButton( @@ -264,6 +264,109 @@ class _StreamElementsWidget extends StatelessWidget { } } +class _RealTimeKitWidget extends StatefulWidget { + @override + State<_RealTimeKitWidget> createState() => _RealTimeKitWidgetState(); +} + +class _RealTimeKitWidgetState extends State<_RealTimeKitWidget> { + var _scanController = MobileScannerController( + detectionSpeed: DetectionSpeed.noDuplicates, + ); + + String apiKey = ""; + + @override + Widget build(BuildContext context) { + return Column( + children: [ + ListTile( + leading: const Image(image: AssetImage('assets/realtimekit.png')), + title: const Text("Realtime Kit"), + subtitle: const Text("Control OBS remotely"), + onTap: () => apiKey.isNotEmpty + ? openUrl(Uri.parse(apiKey)) + : openUrl(Uri.parse("https://kit.rtirl.com/")), + ), + Padding( + padding: const EdgeInsets.only(left: 88, right: 16), + child: TextField( + controller: TextEditingController()..text = apiKey, + readOnly: false, + decoration: InputDecoration( + hintText: "API Key", + suffixIcon: IconButton( + icon: const Icon(Icons.qr_code_scanner), + onPressed: () { + final messenger = ScaffoldMessenger.of(context); + + showModalBottomSheet( + isScrollControlled: true, + context: context, + builder: (ctx) { + return Stack( + children: [ + MobileScanner( + errorBuilder: (context, error, child) { + return ScannerErrorWidget(error: error); + }, + controller: _scanController, + onDetect: (capture) { + final List barcodes = + capture.barcodes; + + if (barcodes.isEmpty) { + messenger.showSnackBar(SnackBar( + content: Text( + AppLocalizations.of(context)! + .invalidUrlErrorText))); + return; + } + + final barcode = barcodes.first; + + if (barcode.rawValue == null || + barcode.rawValue!.isEmpty) { + messenger.showSnackBar(SnackBar( + content: Text( + AppLocalizations.of(context)! + .invalidUrlErrorText))); + Navigator.pop(ctx); + return; + } + + setState(() { + apiKey = barcode.rawValue!; + }); + + Navigator.pop(ctx); + }, + ), + Positioned( + top: 50, + left: 0, + right: 0, + child: ScannerSettings( + scanController: _scanController, + )), + ], + ); + }, + ).then((value) { + _scanController.dispose(); + + _scanController = MobileScannerController( + detectionSpeed: DetectionSpeed.noDuplicates, + ); + }); + })), + keyboardType: TextInputType.url), + ), + ], + ); + } +} + class ThirdPartyScreen extends StatelessWidget { const ThirdPartyScreen({super.key}); @@ -282,6 +385,8 @@ class ThirdPartyScreen extends StatelessWidget { children: [ _RealtimeCashWidget(userId: userId), const Divider(), + _RealTimeKitWidget(), + const Divider(), _StreamlabsWidget(userId: userId), const Divider(), _StreamElementsWidget(userId: userId), From d5d8719334776ecc9011e4b68c375a244cbd0458 Mon Sep 17 00:00:00 2001 From: SputNikPlop <100245448+SputNikPlop@users.noreply.github.com> Date: Fri, 2 May 2025 12:22:35 -0700 Subject: [PATCH 2/3] fix: checkmark --- lib/screens/settings/third_party.dart | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/screens/settings/third_party.dart b/lib/screens/settings/third_party.dart index e695d6ee..796b4671 100644 --- a/lib/screens/settings/third_party.dart +++ b/lib/screens/settings/third_party.dart @@ -284,6 +284,16 @@ class _RealTimeKitWidgetState extends State<_RealTimeKitWidget> { leading: const Image(image: AssetImage('assets/realtimekit.png')), title: const Text("Realtime Kit"), subtitle: const Text("Control OBS remotely"), + trailing: SizedBox( + width: 24, + height: 24, + child: apiKey.isNotEmpty + ? const Icon( + Icons.check_circle, + color: Colors.green, + ) + : const Icon(Icons.help), + ), onTap: () => apiKey.isNotEmpty ? openUrl(Uri.parse(apiKey)) : openUrl(Uri.parse("https://kit.rtirl.com/")), From 5b55d02c9fab9c8945da115c90917bc4dd410840 Mon Sep 17 00:00:00 2001 From: SputNikPlop <100245448+SputNikPlop@users.noreply.github.com> Date: Fri, 2 May 2025 12:24:55 -0700 Subject: [PATCH 3/3] fix: bad spelling because of a space --- lib/screens/settings/third_party.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/screens/settings/third_party.dart b/lib/screens/settings/third_party.dart index 796b4671..ce32fe0d 100644 --- a/lib/screens/settings/third_party.dart +++ b/lib/screens/settings/third_party.dart @@ -282,7 +282,7 @@ class _RealTimeKitWidgetState extends State<_RealTimeKitWidget> { children: [ ListTile( leading: const Image(image: AssetImage('assets/realtimekit.png')), - title: const Text("Realtime Kit"), + title: const Text("RealtimeKit"), subtitle: const Text("Control OBS remotely"), trailing: SizedBox( width: 24,