From a43a3b441f9518488ecaf8ec26080e3106c62744 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Schw=C3=B6rer?= Date: Thu, 17 Apr 2025 22:19:04 +0200 Subject: [PATCH] add qr button to channel_list_extended --- flutter/lib/components/layout/scaffold.dart | 3 ++ flutter/lib/pages/account/account.dart | 41 ++++++++++++++----- .../channel_list/channel_list_extended.dart | 9 ++++ .../pages/keytoken_view/keytoken_view.dart | 4 +- 4 files changed, 44 insertions(+), 13 deletions(-) diff --git a/flutter/lib/components/layout/scaffold.dart b/flutter/lib/components/layout/scaffold.dart index aaf44fc..ddf9910 100644 --- a/flutter/lib/components/layout/scaffold.dart +++ b/flutter/lib/components/layout/scaffold.dart @@ -10,9 +10,11 @@ class SCNScaffold extends StatelessWidget { this.showSearch = true, this.showShare = false, this.onShare = null, + this.floatingActionButton = null, }) : super(key: key); final Widget child; + final Widget? floatingActionButton; final String? title; final bool showThemeSwitch; final bool showSearch; @@ -30,6 +32,7 @@ class SCNScaffold extends StatelessWidget { onShare: onShare ?? () {}, ), body: child, + floatingActionButton: floatingActionButton, ); } } diff --git a/flutter/lib/pages/account/account.dart b/flutter/lib/pages/account/account.dart index 8ebcbcf..d2d42bf 100644 --- a/flutter/lib/pages/account/account.dart +++ b/flutter/lib/pages/account/account.dart @@ -38,6 +38,7 @@ class _AccountRootPageState extends State { late ImmediateFuture? futureKeyCount; late ImmediateFuture? futureChannelAllCount; late ImmediateFuture? futureChannelSubscribedCount; + late ImmediateFuture? futureChannelOwnedCount; late ImmediateFuture? futureSenderNamesCount; late ImmediateFuture? futureUser; @@ -94,6 +95,7 @@ class _AccountRootPageState extends State { futureKeyCount = null; futureChannelAllCount = null; futureChannelSubscribedCount = null; + futureChannelOwnedCount = null; futureSenderNamesCount = null; if (userAcc.isAuth()) { @@ -109,6 +111,12 @@ class _AccountRootPageState extends State { return channels.length; }()); + futureChannelOwnedCount = ImmediateFuture.ofFuture(() async { + if (!userAcc.isAuth()) throw new Exception('not logged in'); + final channels = await APIClient.getChannelList(userAcc, ChannelSelector.owned); + return channels.length; + }()); + futureSubscriptionCount = ImmediateFuture.ofFuture(() async { if (!userAcc.isAuth()) throw new Exception('not logged in'); final subs = await APIClient.getSubscriptionList(userAcc); @@ -344,10 +352,10 @@ class _AccountRootPageState extends State { children: [ SizedBox(width: 80, child: Text("Channels", style: TextStyle(color: Theme.of(context).textTheme.bodyLarge?.color?.withAlpha(160)))), FutureBuilder( - future: futureChannelAllCount!.future, + future: futureChannelOwnedCount!.future, builder: (context, snapshot) { - if (futureChannelAllCount?.value != null) { - return Text('${futureChannelAllCount!.value}'); + if (futureChannelOwnedCount?.value != null) { + return Text('${futureChannelOwnedCount!.value}'); } else if (snapshot.connectionState == ConnectionState.done) { return Text('${snapshot.data}'); } else { @@ -383,17 +391,17 @@ class _AccountRootPageState extends State { List _buildCards(BuildContext context, User user) { return [ - _buildNumberCard(context, 'Subscriptions', futureSubscriptionCount, () {/*TODO*/}), - _buildNumberCard(context, 'Clients', futureClientCount, () { + _buildNumberCard(context, 'Subscription', 's', futureSubscriptionCount, () {/*TODO*/}), + _buildNumberCard(context, 'Client', 's', futureClientCount, () { Navi.push(context, () => ClientListPage()); }), - _buildNumberCard(context, 'Keys', futureKeyCount, () { + _buildNumberCard(context, 'Key', 's', futureKeyCount, () { Navi.push(context, () => KeyTokenListPage()); }), - _buildNumberCard(context, 'Channels', futureChannelSubscribedCount, () { + _buildNumberCard(context, 'Channel', 's', futureChannelAllCount, () { Navi.push(context, () => ChannelListExtendedPage()); }), - _buildNumberCard(context, 'Sender', futureSenderNamesCount, () { + _buildNumberCard(context, 'Sender', '', futureSenderNamesCount, () { Navi.push(context, () => SenderListPage()); }), UI.buttonCard( @@ -413,7 +421,7 @@ class _AccountRootPageState extends State { ]; } - Widget _buildNumberCard(BuildContext context, String txt, ImmediateFuture? future, void Function() action) { + Widget _buildNumberCard(BuildContext context, String txt, String pluralSuffix, ImmediateFuture? future, void Function() action) { return UI.buttonCard( context: context, margin: EdgeInsets.fromLTRB(0, 4, 0, 4), @@ -423,7 +431,7 @@ class _AccountRootPageState extends State { future: future?.future, builder: (context, snapshot) { if (future?.value != null) { - return Text('${future?.value}', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20)); + return Text('${future!.value}', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20)); } else if (snapshot.connectionState == ConnectionState.done) { return Text('${snapshot.data}', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20)); } else { @@ -432,7 +440,18 @@ class _AccountRootPageState extends State { }, ), const SizedBox(width: 12), - Text(txt, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20)), + FutureBuilder( + future: future?.future, + builder: (context, snapshot) { + if (future?.value != null) { + return Text('${txt}${((future!.value != 1) ? pluralSuffix : '')}', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20)); + } else if (snapshot.connectionState == ConnectionState.done) { + return Text('${txt}${((snapshot.data != 1) ? pluralSuffix : '')}', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20)); + } else { + return Text(txt, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20)); + } + }, + ), ], ), onTap: action, diff --git a/flutter/lib/pages/channel_list/channel_list_extended.dart b/flutter/lib/pages/channel_list/channel_list_extended.dart index 62fec47..694b459 100644 --- a/flutter/lib/pages/channel_list/channel_list_extended.dart +++ b/flutter/lib/pages/channel_list/channel_list_extended.dart @@ -1,9 +1,11 @@ import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; import 'package:provider/provider.dart'; import 'package:simplecloudnotifier/api/api_client.dart'; import 'package:simplecloudnotifier/components/layout/scaffold.dart'; import 'package:simplecloudnotifier/models/channel.dart'; +import 'package:simplecloudnotifier/pages/channel_scanner/channel_scanner.dart'; import 'package:simplecloudnotifier/state/app_bar_state.dart'; import 'package:simplecloudnotifier/state/application_log.dart'; import 'package:simplecloudnotifier/state/app_auth.dart'; @@ -142,6 +144,13 @@ class _ChannelListExtendedPageState extends State with ), ), ), + floatingActionButton: FloatingActionButton( + heroTag: 'fab_channel_list_qr', + onPressed: () { + Navi.push(context, () => ChannelScannerPage()); + }, + child: const Icon(FontAwesomeIcons.qrcode), + ), ); } diff --git a/flutter/lib/pages/keytoken_view/keytoken_view.dart b/flutter/lib/pages/keytoken_view/keytoken_view.dart index e37a6c4..9e15a1e 100644 --- a/flutter/lib/pages/keytoken_view/keytoken_view.dart +++ b/flutter/lib/pages/keytoken_view/keytoken_view.dart @@ -373,7 +373,7 @@ class _KeyTokenViewPageState extends State { context: context, icon: FontAwesomeIcons.solidSnake, title: 'Channels', - values: (keyToken.allChannels) ? ['All Channels'] : keyToken.channels, + values: (keyToken.allChannels) ? ['All Channels'] : keyToken.channels, //TODO show channel names iconActions: [(FontAwesomeIcons.penToSquare, _editChannels)], ); } else { @@ -381,7 +381,7 @@ class _KeyTokenViewPageState extends State { context: context, icon: FontAwesomeIcons.solidSnake, title: 'Channels', - values: (keyToken.allChannels) ? ['All Channels'] : keyToken.channels, + values: (keyToken.allChannels) ? ['All Channels'] : keyToken.channels, //TODO show channel names ); }