Channel List/view WIP

This commit is contained in:
2024-06-25 12:00:34 +02:00
parent 7dad61dbbb
commit e2dbe8866d
7 changed files with 232 additions and 39 deletions

View File

@@ -3,10 +3,12 @@ import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'package:provider/provider.dart';
import 'package:simplecloudnotifier/api/api_client.dart';
import 'package:simplecloudnotifier/models/channel.dart';
import 'package:simplecloudnotifier/pages/channel_view/channel_view.dart';
import 'package:simplecloudnotifier/state/app_bar_state.dart';
import 'package:simplecloudnotifier/state/application_log.dart';
import 'package:simplecloudnotifier/state/app_auth.dart';
import 'package:simplecloudnotifier/pages/channel_list/channel_list_item.dart';
import 'package:simplecloudnotifier/utils/navi.dart';
class ChannelRootPage extends StatefulWidget {
const ChannelRootPage({super.key, required this.isVisiblePage});
@@ -18,7 +20,7 @@ class ChannelRootPage extends StatefulWidget {
}
class _ChannelRootPageState extends State<ChannelRootPage> {
final PagingController<int, Channel> _pagingController = PagingController.fromValue(PagingState(nextPageKey: null, itemList: [], error: null), firstPageKey: 0);
final PagingController<int, ChannelWithSubscription> _pagingController = PagingController.fromValue(PagingState(nextPageKey: null, itemList: [], error: null), firstPageKey: 0);
bool _isInitialized = false;
@@ -68,9 +70,9 @@ class _ChannelRootPageState extends State<ChannelRootPage> {
}
try {
final items = (await APIClient.getChannelList(acc, ChannelSelector.all)).map((p) => p.channel).toList();
final items = (await APIClient.getChannelList(acc, ChannelSelector.all)).toList();
items.sort((a, b) => -1 * (a.timestampLastSent ?? '').compareTo(b.timestampLastSent ?? ''));
items.sort((a, b) => -1 * (a.channel.timestampLastSent ?? '').compareTo(b.channel.timestampLastSent ?? ''));
_pagingController.value = PagingState(nextPageKey: null, itemList: items, error: null);
} catch (exc, trace) {
@@ -94,9 +96,9 @@ class _ChannelRootPageState extends State<ChannelRootPage> {
AppBarState().setLoadingIndeterminate(true);
final items = (await APIClient.getChannelList(acc, ChannelSelector.all)).map((p) => p.channel).toList();
final items = (await APIClient.getChannelList(acc, ChannelSelector.all)).toList();
items.sort((a, b) => -1 * (a.timestampLastSent ?? '').compareTo(b.timestampLastSent ?? ''));
items.sort((a, b) => -1 * (a.channel.timestampLastSent ?? '').compareTo(b.channel.timestampLastSent ?? ''));
_pagingController.value = PagingState(nextPageKey: null, itemList: items, error: null);
} catch (exc, trace) {
@@ -113,12 +115,15 @@ class _ChannelRootPageState extends State<ChannelRootPage> {
onRefresh: () => Future.sync(
() => _pagingController.refresh(),
),
child: PagedListView<int, Channel>(
child: PagedListView<int, ChannelWithSubscription>(
pagingController: _pagingController,
builderDelegate: PagedChildBuilderDelegate<Channel>(
builderDelegate: PagedChildBuilderDelegate<ChannelWithSubscription>(
itemBuilder: (context, item, index) => ChannelListItem(
channel: item,
onPressed: () {/*TODO*/},
channel: item.channel,
subscription: item.subscription,
onPressed: () {
Navi.push(context, () => ChannelViewPage(channel: item.channel, subscription: item.subscription));
},
),
),
),

View File

@@ -1,9 +1,11 @@
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:simplecloudnotifier/api/api_client.dart';
import 'package:simplecloudnotifier/models/channel.dart';
import 'package:simplecloudnotifier/models/scn_message.dart';
import 'package:simplecloudnotifier/models/subscription.dart';
import 'package:simplecloudnotifier/state/app_auth.dart';
class ChannelListItem extends StatefulWidget {
@@ -12,10 +14,12 @@ class ChannelListItem extends StatefulWidget {
const ChannelListItem({
required this.channel,
required this.onPressed,
required this.subscription,
super.key,
});
final Channel channel;
final Subscription? subscription;
final Null Function() onPressed;
@override
@@ -53,35 +57,43 @@ class _ChannelListItemState extends State<ChannelListItem> {
onTap: widget.onPressed,
child: Padding(
padding: const EdgeInsets.all(8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
child: Row(
children: [
Row(
children: [
Expanded(
child: Text(
widget.channel.displayName,
style: const TextStyle(fontWeight: FontWeight.bold),
_buildIcon(context),
SizedBox(width: 8),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Row(
children: [
Expanded(
child: Text(
widget.channel.displayName,
style: const TextStyle(fontWeight: FontWeight.bold),
),
),
Text(
(widget.channel.timestampLastSent == null) ? '' : ChannelListItem._dateFormat.format(DateTime.parse(widget.channel.timestampLastSent!).toLocal()),
style: const TextStyle(fontSize: 14),
),
],
),
),
Text(
(widget.channel.timestampLastSent == null) ? '' : ChannelListItem._dateFormat.format(DateTime.parse(widget.channel.timestampLastSent!).toLocal()),
style: const TextStyle(fontSize: 14),
),
],
),
SizedBox(height: 4),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: Text(
_preformatTitle(lastMessage),
style: TextStyle(color: Theme.of(context).textTheme.bodyLarge?.color?.withAlpha(160)),
SizedBox(height: 4),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: Text(
_preformatTitle(lastMessage),
style: TextStyle(color: Theme.of(context).textTheme.bodyLarge?.color?.withAlpha(160)),
),
),
Text(widget.channel.messagesSent.toString(), style: const TextStyle(fontSize: 14, fontWeight: FontWeight.bold)),
],
),
),
Text(widget.channel.messagesSent.toString(), style: const TextStyle(fontSize: 14, fontWeight: FontWeight.bold)),
],
],
),
),
],
),
@@ -94,4 +106,14 @@ class _ChannelListItemState extends State<ChannelListItem> {
if (message == null) return '...';
return message.title.replaceAll('\n', '').replaceAll('\r', '').replaceAll('\t', ' ');
}
Widget _buildIcon(BuildContext context) {
if (widget.subscription == null) {
return Icon(FontAwesomeIcons.solidSquareDashed, color: Theme.of(context).colorScheme.outline, size: 32); // not-subscribed
} else if (widget.subscription!.confirmed) {
return Icon(FontAwesomeIcons.solidSquareRss, color: Theme.of(context).colorScheme.onPrimaryContainer, size: 32); // subscribed
} else {
return Icon(FontAwesomeIcons.solidSquareEnvelope, color: Theme.of(context).colorScheme.tertiary, size: 32); // requested
}
}
}