diff --git a/lib/i18n/strings.g.dart b/lib/i18n/strings.g.dart index 0557400..feb4884 100644 --- a/lib/i18n/strings.g.dart +++ b/lib/i18n/strings.g.dart @@ -4,9 +4,9 @@ /// To regenerate, run: `dart run slang` /// /// Locales: 22 -/// Strings: 1650 (75 per locale) +/// Strings: 1653 (75 per locale) /// -/// Built on 2025-05-29 at 10:02 UTC +/// Built on 2025-05-29 at 11:29 UTC // coverage:ignore-file // ignore_for_file: type=lint, unused_import diff --git a/lib/i18n/strings_en.g.dart b/lib/i18n/strings_en.g.dart index 139a8b2..337b552 100644 --- a/lib/i18n/strings_en.g.dart +++ b/lib/i18n/strings_en.g.dart @@ -52,6 +52,8 @@ class Translations implements BaseTranslations { /// An anonymous user String get anon => 'Anon'; + String full_amount_sats({required num n}) => '${NumberFormat.decimalPattern('en').format(n)} sats'; + /// Number of viewers of the stream String viewers({required num n}) => (_root.$meta.cardinalResolver ?? PluralResolvers.cardinal('en'))(n, one: '1 viewer', @@ -290,6 +292,8 @@ class TranslationsSettingsWalletEn { String get disconnect_wallet => 'Disconnect Wallet'; String get connect_1tap => '1-Tap Connection'; String get paste => 'Paste URL'; + String get balance => 'Balance'; + String get name => 'Wallet'; late final TranslationsSettingsWalletErrorEn error = TranslationsSettingsWalletErrorEn.internal(_root); } @@ -381,6 +385,7 @@ extension on Translations { case 'most_zapped_streamers': return 'Most Zapped Streamers'; case 'no_user_found': return 'No user found'; case 'anon': return 'Anon'; + case 'full_amount_sats': return ({required num n}) => '${NumberFormat.decimalPattern('en').format(n)} sats'; case 'viewers': return ({required num n}) => (_root.$meta.cardinalResolver ?? PluralResolvers.cardinal('en'))(n, one: '1 viewer', other: '${NumberFormat.decimalPattern('en').format(n)} viewers', @@ -458,6 +463,8 @@ extension on Translations { case 'settings.wallet.disconnect_wallet': return 'Disconnect Wallet'; case 'settings.wallet.connect_1tap': return '1-Tap Connection'; case 'settings.wallet.paste': return 'Paste URL'; + case 'settings.wallet.balance': return 'Balance'; + case 'settings.wallet.name': return 'Wallet'; case 'settings.wallet.error.logged_out': return 'Cant connect wallet when logged out'; case 'settings.wallet.error.nwc_auth_event_not_found': return 'No wallet auth event found'; case 'login.username': return 'Username'; diff --git a/lib/i18n/translated/en.i18n.yaml b/lib/i18n/translated/en.i18n.yaml index 64a3a80..7292a7f 100644 --- a/lib/i18n/translated/en.i18n.yaml +++ b/lib/i18n/translated/en.i18n.yaml @@ -8,6 +8,7 @@ no_user_found: No user found "@no_user_found": description: No user found when searching anon: Anon +full_amount_sats: ${n:decimalPattern} sats viewers: one: 1 viewer other: ${n:decimalPattern} viewers @@ -122,6 +123,8 @@ settings: disconnect_wallet: Disconnect Wallet connect_1tap: 1-Tap Connection paste: Paste URL + balance: Balance + name: Wallet error: logged_out: Cant connect wallet when logged out nwc_auth_event_not_found: No wallet auth event found diff --git a/lib/login.dart b/lib/login.dart index a404883..16b5389 100644 --- a/lib/login.dart +++ b/lib/login.dart @@ -38,8 +38,16 @@ class WalletConfig { } } +class WalletInfo { + final String name; + final int balance; + + const WalletInfo({required this.name, required this.balance}); +} + abstract class SimpleWallet { Future payInvoice(String pr); + Future getInfo(); } class NWCWrapper extends SimpleWallet { @@ -60,6 +68,13 @@ class NWCWrapper extends SimpleWallet { return rsp.preimage!; } } + + @override + Future getInfo() async { + final info = await ndk.nwc.getInfo(_conn); + final balance = await ndk.nwc.getBalance(_conn); + return WalletInfo(name: info.alias, balance: balance.balanceSats); + } } class LoginAccount { diff --git a/lib/pages/settings_wallet.dart b/lib/pages/settings_wallet.dart index ca57c0d..435b4d8 100644 --- a/lib/pages/settings_wallet.dart +++ b/lib/pages/settings_wallet.dart @@ -87,7 +87,7 @@ class _Inner extends State with ProtocolListener { queryParameters: { "relay": nwcRelays, "name": "zap.stream", - "request_methods": "pay_invoice", + "request_methods": "pay_invoice get_info get_balance", "icon": "https://zap.stream/logo.png", "return_to": nwaHandlerUrl, }, @@ -174,13 +174,43 @@ class _Inner extends State with ProtocolListener { ], ); } else { - return BasicButton.text( - t.settings.wallet.disconnect_wallet, - onTap: (context) { - _setWallet(null); - if (context.mounted) { - context.pop(); - } + return FutureBuilder( + future: () async { + final wallet = await state!.getWallet(); + return await wallet?.getInfo(); + }(), + builder: (context, state) { + return Column( + spacing: 8, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Wallet: ${state.data?.name ?? ""}", + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24), + ), + Text.rich( + TextSpan( + style: TextStyle(fontWeight: FontWeight.w500), + children: [ + TextSpan(text: t.settings.wallet.balance), + TextSpan(text: ": "), + TextSpan( + text: t.full_amount_sats(n: state.data?.balance ?? 0), + ), + ], + ), + ), + BasicButton.text( + t.settings.wallet.disconnect_wallet, + onTap: (context) { + _setWallet(null); + if (context.mounted) { + context.pop(); + } + }, + ), + ], + ); }, ); }