add qr button to channel_list_extended

This commit is contained in:
Mike Schwörer 2025-04-17 22:19:04 +02:00
parent ab4b40ab75
commit a43a3b441f
Signed by: Mikescher
GPG Key ID: D3C7172E0A70F8CF
4 changed files with 44 additions and 13 deletions

View File

@ -10,9 +10,11 @@ class SCNScaffold extends StatelessWidget {
this.showSearch = true, this.showSearch = true,
this.showShare = false, this.showShare = false,
this.onShare = null, this.onShare = null,
this.floatingActionButton = null,
}) : super(key: key); }) : super(key: key);
final Widget child; final Widget child;
final Widget? floatingActionButton;
final String? title; final String? title;
final bool showThemeSwitch; final bool showThemeSwitch;
final bool showSearch; final bool showSearch;
@ -30,6 +32,7 @@ class SCNScaffold extends StatelessWidget {
onShare: onShare ?? () {}, onShare: onShare ?? () {},
), ),
body: child, body: child,
floatingActionButton: floatingActionButton,
); );
} }
} }

View File

@ -38,6 +38,7 @@ class _AccountRootPageState extends State<AccountRootPage> {
late ImmediateFuture<int>? futureKeyCount; late ImmediateFuture<int>? futureKeyCount;
late ImmediateFuture<int>? futureChannelAllCount; late ImmediateFuture<int>? futureChannelAllCount;
late ImmediateFuture<int>? futureChannelSubscribedCount; late ImmediateFuture<int>? futureChannelSubscribedCount;
late ImmediateFuture<int>? futureChannelOwnedCount;
late ImmediateFuture<int>? futureSenderNamesCount; late ImmediateFuture<int>? futureSenderNamesCount;
late ImmediateFuture<User>? futureUser; late ImmediateFuture<User>? futureUser;
@ -94,6 +95,7 @@ class _AccountRootPageState extends State<AccountRootPage> {
futureKeyCount = null; futureKeyCount = null;
futureChannelAllCount = null; futureChannelAllCount = null;
futureChannelSubscribedCount = null; futureChannelSubscribedCount = null;
futureChannelOwnedCount = null;
futureSenderNamesCount = null; futureSenderNamesCount = null;
if (userAcc.isAuth()) { if (userAcc.isAuth()) {
@ -109,6 +111,12 @@ class _AccountRootPageState extends State<AccountRootPage> {
return channels.length; 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 { futureSubscriptionCount = ImmediateFuture.ofFuture(() async {
if (!userAcc.isAuth()) throw new Exception('not logged in'); if (!userAcc.isAuth()) throw new Exception('not logged in');
final subs = await APIClient.getSubscriptionList(userAcc); final subs = await APIClient.getSubscriptionList(userAcc);
@ -344,10 +352,10 @@ class _AccountRootPageState extends State<AccountRootPage> {
children: [ children: [
SizedBox(width: 80, child: Text("Channels", style: TextStyle(color: Theme.of(context).textTheme.bodyLarge?.color?.withAlpha(160)))), SizedBox(width: 80, child: Text("Channels", style: TextStyle(color: Theme.of(context).textTheme.bodyLarge?.color?.withAlpha(160)))),
FutureBuilder( FutureBuilder(
future: futureChannelAllCount!.future, future: futureChannelOwnedCount!.future,
builder: (context, snapshot) { builder: (context, snapshot) {
if (futureChannelAllCount?.value != null) { if (futureChannelOwnedCount?.value != null) {
return Text('${futureChannelAllCount!.value}'); return Text('${futureChannelOwnedCount!.value}');
} else if (snapshot.connectionState == ConnectionState.done) { } else if (snapshot.connectionState == ConnectionState.done) {
return Text('${snapshot.data}'); return Text('${snapshot.data}');
} else { } else {
@ -383,17 +391,17 @@ class _AccountRootPageState extends State<AccountRootPage> {
List<Widget> _buildCards(BuildContext context, User user) { List<Widget> _buildCards(BuildContext context, User user) {
return [ return [
_buildNumberCard(context, 'Subscriptions', futureSubscriptionCount, () {/*TODO*/}), _buildNumberCard(context, 'Subscription', 's', futureSubscriptionCount, () {/*TODO*/}),
_buildNumberCard(context, 'Clients', futureClientCount, () { _buildNumberCard(context, 'Client', 's', futureClientCount, () {
Navi.push(context, () => ClientListPage()); Navi.push(context, () => ClientListPage());
}), }),
_buildNumberCard(context, 'Keys', futureKeyCount, () { _buildNumberCard(context, 'Key', 's', futureKeyCount, () {
Navi.push(context, () => KeyTokenListPage()); Navi.push(context, () => KeyTokenListPage());
}), }),
_buildNumberCard(context, 'Channels', futureChannelSubscribedCount, () { _buildNumberCard(context, 'Channel', 's', futureChannelAllCount, () {
Navi.push(context, () => ChannelListExtendedPage()); Navi.push(context, () => ChannelListExtendedPage());
}), }),
_buildNumberCard(context, 'Sender', futureSenderNamesCount, () { _buildNumberCard(context, 'Sender', '', futureSenderNamesCount, () {
Navi.push(context, () => SenderListPage()); Navi.push(context, () => SenderListPage());
}), }),
UI.buttonCard( UI.buttonCard(
@ -413,7 +421,7 @@ class _AccountRootPageState extends State<AccountRootPage> {
]; ];
} }
Widget _buildNumberCard(BuildContext context, String txt, ImmediateFuture<int>? future, void Function() action) { Widget _buildNumberCard(BuildContext context, String txt, String pluralSuffix, ImmediateFuture<int>? future, void Function() action) {
return UI.buttonCard( return UI.buttonCard(
context: context, context: context,
margin: EdgeInsets.fromLTRB(0, 4, 0, 4), margin: EdgeInsets.fromLTRB(0, 4, 0, 4),
@ -423,7 +431,7 @@ class _AccountRootPageState extends State<AccountRootPage> {
future: future?.future, future: future?.future,
builder: (context, snapshot) { builder: (context, snapshot) {
if (future?.value != null) { 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) { } else if (snapshot.connectionState == ConnectionState.done) {
return Text('${snapshot.data}', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20)); return Text('${snapshot.data}', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20));
} else { } else {
@ -432,7 +440,18 @@ class _AccountRootPageState extends State<AccountRootPage> {
}, },
), ),
const SizedBox(width: 12), 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, onTap: action,

View File

@ -1,9 +1,11 @@
import 'package:flutter/material.dart'; 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:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:simplecloudnotifier/api/api_client.dart'; import 'package:simplecloudnotifier/api/api_client.dart';
import 'package:simplecloudnotifier/components/layout/scaffold.dart'; import 'package:simplecloudnotifier/components/layout/scaffold.dart';
import 'package:simplecloudnotifier/models/channel.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/app_bar_state.dart';
import 'package:simplecloudnotifier/state/application_log.dart'; import 'package:simplecloudnotifier/state/application_log.dart';
import 'package:simplecloudnotifier/state/app_auth.dart'; import 'package:simplecloudnotifier/state/app_auth.dart';
@ -142,6 +144,13 @@ class _ChannelListExtendedPageState extends State<ChannelListExtendedPage> with
), ),
), ),
), ),
floatingActionButton: FloatingActionButton(
heroTag: 'fab_channel_list_qr',
onPressed: () {
Navi.push(context, () => ChannelScannerPage());
},
child: const Icon(FontAwesomeIcons.qrcode),
),
); );
} }

View File

@ -373,7 +373,7 @@ class _KeyTokenViewPageState extends State<KeyTokenViewPage> {
context: context, context: context,
icon: FontAwesomeIcons.solidSnake, icon: FontAwesomeIcons.solidSnake,
title: 'Channels', title: 'Channels',
values: (keyToken.allChannels) ? ['All Channels'] : keyToken.channels, values: (keyToken.allChannels) ? ['All Channels'] : keyToken.channels, //TODO show channel names
iconActions: [(FontAwesomeIcons.penToSquare, _editChannels)], iconActions: [(FontAwesomeIcons.penToSquare, _editChannels)],
); );
} else { } else {
@ -381,7 +381,7 @@ class _KeyTokenViewPageState extends State<KeyTokenViewPage> {
context: context, context: context,
icon: FontAwesomeIcons.solidSnake, icon: FontAwesomeIcons.solidSnake,
title: 'Channels', title: 'Channels',
values: (keyToken.allChannels) ? ['All Channels'] : keyToken.channels, values: (keyToken.allChannels) ? ['All Channels'] : keyToken.channels, //TODO show channel names
); );
} }