channel list

This commit is contained in:
Mike Schwörer 2024-05-26 19:24:19 +02:00
parent f9dbbf4638
commit 6b7bf600f8
Signed by: Mikescher
GPG Key ID: D3C7172E0A70F8CF
4 changed files with 114 additions and 22 deletions

View File

@ -146,12 +146,16 @@ class APIClient {
);
}
static Future<(String, List<Message>)> getMessageList(KeyTokenAuth auth, String pageToken, int? pageSize) async {
static Future<(String, List<Message>)> getMessageList(KeyTokenAuth auth, String pageToken, {int? pageSize, List<String>? channelIDs}) async {
return await _request(
name: 'getMessageList',
method: 'GET',
relURL: 'messages',
query: {'next_page_token': pageToken, if (pageSize != null) 'page_size': pageSize.toString()},
query: {
'next_page_token': pageToken,
if (pageSize != null) 'page_size': pageSize.toString(),
if (channelIDs != null) 'channel_id': channelIDs.join(","),
},
fn: (json) => Message.fromPaginatedJsonArray(json, 'messages', 'next_page_token'),
auth: auth,
);

View File

@ -44,6 +44,8 @@ class _ChannelRootPageState extends State<ChannelRootPage> {
try {
final items = await APIClient.getChannelList(acc.auth!, ChannelSelector.all);
items.sort((a, b) => -1 * (a.timestampLastSent ?? '').compareTo(b.timestampLastSent ?? ''));
_pagingController.appendLastPage(items);
} catch (exc, trace) {
_pagingController.error = exc.toString();
@ -53,11 +55,17 @@ class _ChannelRootPageState extends State<ChannelRootPage> {
@override
Widget build(BuildContext context) {
return PagedListView<int, Channel>(
pagingController: _pagingController,
builderDelegate: PagedChildBuilderDelegate<Channel>(
itemBuilder: (context, item, index) => ChannelListItem(
channel: item,
return RefreshIndicator(
onRefresh: () => Future.sync(
() => _pagingController.refresh(),
),
child: PagedListView<int, Channel>(
pagingController: _pagingController,
builderDelegate: PagedChildBuilderDelegate<Channel>(
itemBuilder: (context, item, index) => ChannelListItem(
channel: item,
onPressed: () {/*TODO*/},
),
),
),
);

View File

@ -1,17 +1,92 @@
import 'package:flutter/material.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/message.dart';
import 'package:simplecloudnotifier/state/user_account.dart';
class ChannelListItem extends StatefulWidget {
static final _dateFormat = DateFormat('yyyy-MM-dd kk:mm');
class ChannelListItem extends StatelessWidget {
const ChannelListItem({
required this.channel,
required this.onPressed,
super.key,
});
final Channel channel;
final Null Function() onPressed;
@override
Widget build(BuildContext context) => ListTile(
leading: const SizedBox(width: 40, height: 40, child: const Placeholder()),
title: Text(channel.internalName),
);
State<ChannelListItem> createState() => _ChannelListItemState();
}
class _ChannelListItemState extends State<ChannelListItem> {
Message? lastMessage;
@override
void initState() {
super.initState();
final acc = Provider.of<UserAccount>(context, listen: false);
if (acc.auth != null) {
() async {
final (_, channelMessages) = await APIClient.getMessageList(acc.auth!, '@start', pageSize: 1, channelIDs: [widget.channel.channelID]);
setState(() {
lastMessage = channelMessages.firstOrNull;
});
}();
}
}
@override
Widget build(BuildContext context) {
//TODO subscription status
return Card.filled(
margin: EdgeInsets.fromLTRB(0, 4, 0, 4),
shape: BeveledRectangleBorder(borderRadius: BorderRadius.circular(0)),
color: Theme.of(context).cardTheme.color,
child: InkWell(
splashColor: Theme.of(context).splashColor,
onTap: widget.onPressed,
child: Padding(
padding: const EdgeInsets.all(8),
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),
),
],
),
SizedBox(height: 4),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: Text(
lastMessage?.title ?? '...',
style: TextStyle(color: Theme.of(context).textTheme.bodyLarge?.color?.withAlpha(160)),
),
),
Text(widget.channel.messagesSent.toString(), style: const TextStyle(fontSize: 14, fontWeight: FontWeight.bold)),
],
),
],
),
),
),
);
}
}

View File

@ -51,7 +51,7 @@ class _MessageListPageState extends State<MessageListPage> {
_channels = <String, ChannelWithSubscription>{for (var v in channels) v.channelID: v};
}
final (npt, newItems) = await APIClient.getMessageList(acc.auth!, thisPageToken, _pageSize);
final (npt, newItems) = await APIClient.getMessageList(acc.auth!, thisPageToken, pageSize: _pageSize);
if (npt == '@end') {
_pagingController.appendLastPage(newItems);
@ -68,15 +68,20 @@ class _MessageListPageState extends State<MessageListPage> {
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.fromLTRB(8, 4, 8, 4),
child: PagedListView<String, Message>(
pagingController: _pagingController,
builderDelegate: PagedChildBuilderDelegate<Message>(
itemBuilder: (context, item, index) => MessageListItem(
message: item,
allChannels: _channels ?? {},
onPressed: () {
Navigator.push(context, MaterialPageRoute<MessageViewPage>(builder: (context) => MessageViewPage(message: item)));
},
child: RefreshIndicator(
onRefresh: () => Future.sync(
() => _pagingController.refresh(),
),
child: PagedListView<String, Message>(
pagingController: _pagingController,
builderDelegate: PagedChildBuilderDelegate<Message>(
itemBuilder: (context, item, index) => MessageListItem(
message: item,
allChannels: _channels ?? {},
onPressed: () {
Navigator.push(context, MaterialPageRoute<MessageViewPage>(builder: (context) => MessageViewPage(message: item)));
},
),
),
),
),