Notifications (android via local) work
This commit is contained in:
@@ -3,7 +3,7 @@ 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/models/scn_message.dart';
|
||||
import 'package:simplecloudnotifier/state/app_auth.dart';
|
||||
|
||||
class ChannelListItem extends StatefulWidget {
|
||||
@@ -23,7 +23,7 @@ class ChannelListItem extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _ChannelListItemState extends State<ChannelListItem> {
|
||||
Message? lastMessage;
|
||||
SCNMessage? lastMessage;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:simplecloudnotifier/utils/notifier.dart';
|
||||
import 'package:simplecloudnotifier/utils/toaster.dart';
|
||||
import 'package:simplecloudnotifier/utils/ui.dart';
|
||||
|
||||
@@ -52,6 +53,12 @@ class _DebugActionsPageState extends State<DebugActionsPage> {
|
||||
onPressed: _sendTokenToServer,
|
||||
text: 'Send FCM Token to Server',
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
UI.button(
|
||||
big: false,
|
||||
onPressed: () => Notifier.showLocalNotification('TEST_CHANNEL', "Test Channel", "Channel for testing", "Hello World", "Local Notification test", null),
|
||||
text: 'Show local notification',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@@ -30,7 +30,6 @@ class _DebugMainPageState extends State<DebugMainPage> {
|
||||
return SCNScaffold(
|
||||
title: 'Debug',
|
||||
showSearch: false,
|
||||
showDebug: false,
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
|
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:simplecloudnotifier/models/channel.dart';
|
||||
import 'package:simplecloudnotifier/models/message.dart';
|
||||
import 'package:simplecloudnotifier/models/scn_message.dart';
|
||||
import 'package:simplecloudnotifier/pages/debug/debug_persistence_hive.dart';
|
||||
import 'package:simplecloudnotifier/pages/debug/debug_persistence_sharedprefs.dart';
|
||||
import 'package:simplecloudnotifier/state/application_log.dart';
|
||||
@@ -36,7 +36,7 @@ class _DebugPersistencePageState extends State<DebugPersistencePage> {
|
||||
_buildSharedPrefCard(context),
|
||||
_buildHiveCard(context, () => Hive.box<SCNRequest>('scn-requests'), 'scn-requests'),
|
||||
_buildHiveCard(context, () => Hive.box<SCNLog>('scn-logs'), 'scn-logs'),
|
||||
_buildHiveCard(context, () => Hive.box<Message>('scn-message-cache'), 'scn-message-cache'),
|
||||
_buildHiveCard(context, () => Hive.box<SCNMessage>('scn-message-cache'), 'scn-message-cache'),
|
||||
_buildHiveCard(context, () => Hive.box<Channel>('scn-channel-cache'), 'scn-channel-cache'),
|
||||
_buildHiveCard(context, () => Hive.box<FBMessage>('scn-fb-messages'), 'scn-fb-messages'),
|
||||
],
|
||||
@@ -71,7 +71,7 @@ class _DebugPersistencePageState extends State<DebugPersistencePage> {
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
Navi.push(context, () => DebugHiveBoxPage(boxName: boxname, box: Hive.box<FBMessage>(boxname)));
|
||||
Navi.push(context, () => DebugHiveBoxPage(boxName: boxname, box: boxFunc()));
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
|
@@ -16,7 +16,6 @@ class DebugHiveBoxPage extends StatelessWidget {
|
||||
return SCNScaffold(
|
||||
title: 'Hive: ' + boxName,
|
||||
showSearch: false,
|
||||
showDebug: false,
|
||||
child: ListView.separated(
|
||||
itemCount: box.length,
|
||||
itemBuilder: (context, listIndex) {
|
||||
@@ -24,8 +23,9 @@ class DebugHiveBoxPage extends StatelessWidget {
|
||||
onTap: () {
|
||||
Navi.push(context, () => DebugHiveEntryPage(value: box.getAt(listIndex)!));
|
||||
},
|
||||
child: ListTile(
|
||||
title: Text(box.getAt(listIndex).toString(), style: TextStyle(fontWeight: FontWeight.bold)),
|
||||
child: Container(
|
||||
padding: EdgeInsets.fromLTRB(8, 4, 8, 4),
|
||||
child: Text(box.getAt(listIndex).toString(), style: TextStyle(fontWeight: FontWeight.bold, fontSize: 12)),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
@@ -13,11 +13,13 @@ class DebugHiveEntryPage extends StatelessWidget {
|
||||
return SCNScaffold(
|
||||
title: 'HiveEntry',
|
||||
showSearch: false,
|
||||
showDebug: false,
|
||||
child: ListView.separated(
|
||||
itemCount: fields.length,
|
||||
itemBuilder: (context, listIndex) {
|
||||
return ListTile(
|
||||
dense: true,
|
||||
contentPadding: EdgeInsets.fromLTRB(8, 0, 8, 0),
|
||||
visualDensity: VisualDensity(horizontal: 0, vertical: -4),
|
||||
title: Text(fields[listIndex].$1, style: TextStyle(fontWeight: FontWeight.bold)),
|
||||
subtitle: Text(fields[listIndex].$2, style: TextStyle(fontFamily: "monospace")),
|
||||
);
|
||||
|
@@ -13,7 +13,6 @@ class DebugSharedPrefPage extends StatelessWidget {
|
||||
return SCNScaffold(
|
||||
title: 'SharedPreferences',
|
||||
showSearch: false,
|
||||
showDebug: false,
|
||||
child: ListView.separated(
|
||||
itemCount: sharedPref.getKeys().length,
|
||||
itemBuilder: (context, listIndex) {
|
||||
|
@@ -16,7 +16,6 @@ class DebugRequestViewPage extends StatelessWidget {
|
||||
return SCNScaffold(
|
||||
title: 'Request',
|
||||
showSearch: false,
|
||||
showDebug: false,
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
|
@@ -4,8 +4,9 @@ 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/models/message.dart';
|
||||
import 'package:simplecloudnotifier/models/scn_message.dart';
|
||||
import 'package:simplecloudnotifier/pages/message_view/message_view.dart';
|
||||
import 'package:simplecloudnotifier/settings/app_settings.dart';
|
||||
import 'package:simplecloudnotifier/state/app_bar_state.dart';
|
||||
import 'package:simplecloudnotifier/state/application_log.dart';
|
||||
import 'package:simplecloudnotifier/state/app_auth.dart';
|
||||
@@ -25,11 +26,9 @@ class MessageListPage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _MessageListPageState extends State<MessageListPage> with RouteAware {
|
||||
static const _pageSize = 128;
|
||||
|
||||
late final AppLifecycleListener _lifecyleListener;
|
||||
|
||||
PagingController<String, Message> _pagingController = PagingController.fromValue(PagingState(nextPageKey: null, itemList: [], error: null), firstPageKey: '@start');
|
||||
PagingController<String, SCNMessage> _pagingController = PagingController.fromValue(PagingState(nextPageKey: null, itemList: [], error: null), firstPageKey: '@start');
|
||||
|
||||
Map<String, Channel>? _channels = null;
|
||||
|
||||
@@ -65,7 +64,7 @@ class _MessageListPageState extends State<MessageListPage> with RouteAware {
|
||||
ApplicationLog.debug('MessageListPage::_realInitState');
|
||||
|
||||
final chnCache = Hive.box<Channel>('scn-channel-cache');
|
||||
final msgCache = Hive.box<Message>('scn-message-cache');
|
||||
final msgCache = Hive.box<SCNMessage>('scn-message-cache');
|
||||
|
||||
if (chnCache.isNotEmpty && msgCache.isNotEmpty) {
|
||||
// ==== Use cache values - and refresh in background
|
||||
@@ -119,6 +118,7 @@ class _MessageListPageState extends State<MessageListPage> with RouteAware {
|
||||
|
||||
Future<void> _fetchPage(String thisPageToken) async {
|
||||
final acc = Provider.of<AppAuth>(context, listen: false);
|
||||
final cfg = Provider.of<AppSettings>(context, listen: false);
|
||||
|
||||
ApplicationLog.debug('Start MessageList::_pagingController::_fetchPage [ ${thisPageToken} ]');
|
||||
|
||||
@@ -135,7 +135,7 @@ class _MessageListPageState extends State<MessageListPage> with RouteAware {
|
||||
_setChannelCache(channels); // no await
|
||||
}
|
||||
|
||||
final (npt, newItems) = await APIClient.getMessageList(acc, thisPageToken, pageSize: _pageSize);
|
||||
final (npt, newItems) = await APIClient.getMessageList(acc, thisPageToken, pageSize: cfg.messagePageSize);
|
||||
|
||||
_addToMessageCache(newItems); // no await
|
||||
|
||||
@@ -154,6 +154,7 @@ class _MessageListPageState extends State<MessageListPage> with RouteAware {
|
||||
|
||||
Future<void> _backgroundRefresh(bool fullReplaceState) async {
|
||||
final acc = Provider.of<AppAuth>(context, listen: false);
|
||||
final cfg = Provider.of<AppSettings>(context, listen: false);
|
||||
|
||||
ApplicationLog.debug('Start background refresh of message list (fullReplaceState: $fullReplaceState)');
|
||||
|
||||
@@ -170,7 +171,7 @@ class _MessageListPageState extends State<MessageListPage> with RouteAware {
|
||||
_setChannelCache(channels); // no await
|
||||
}
|
||||
|
||||
final (npt, newItems) = await APIClient.getMessageList(acc, '@start', pageSize: _pageSize);
|
||||
final (npt, newItems) = await APIClient.getMessageList(acc, '@start', pageSize: cfg.messagePageSize);
|
||||
|
||||
_addToMessageCache(newItems); // no await
|
||||
|
||||
@@ -225,9 +226,9 @@ class _MessageListPageState extends State<MessageListPage> with RouteAware {
|
||||
onRefresh: () => Future.sync(
|
||||
() => _pagingController.refresh(),
|
||||
),
|
||||
child: PagedListView<String, Message>(
|
||||
child: PagedListView<String, SCNMessage>(
|
||||
pagingController: _pagingController,
|
||||
builderDelegate: PagedChildBuilderDelegate<Message>(
|
||||
builderDelegate: PagedChildBuilderDelegate<SCNMessage>(
|
||||
itemBuilder: (context, item, index) => MessageListItem(
|
||||
message: item,
|
||||
allChannels: _channels ?? {},
|
||||
@@ -249,20 +250,22 @@ class _MessageListPageState extends State<MessageListPage> with RouteAware {
|
||||
for (var chn in channels) await cache.put(chn.channel.channelID, chn.channel);
|
||||
}
|
||||
|
||||
Future<void> _addToMessageCache(List<Message> newItems) async {
|
||||
final cache = Hive.box<Message>('scn-message-cache');
|
||||
Future<void> _addToMessageCache(List<SCNMessage> newItems) async {
|
||||
final cfg = AppSettings();
|
||||
|
||||
final cache = Hive.box<SCNMessage>('scn-message-cache');
|
||||
|
||||
for (var msg in newItems) await cache.put(msg.messageID, msg);
|
||||
|
||||
// delete all but the newest 128 messages
|
||||
|
||||
if (cache.length < _pageSize) return;
|
||||
if (cache.length < cfg.messagePageSize) return;
|
||||
|
||||
final allValues = cache.values.toList();
|
||||
|
||||
allValues.sort((a, b) => -1 * a.timestamp.compareTo(b.timestamp));
|
||||
|
||||
for (var val in allValues.sublist(_pageSize)) {
|
||||
for (var val in allValues.sublist(cfg.messagePageSize)) {
|
||||
await cache.delete(val.messageID);
|
||||
}
|
||||
}
|
||||
|
@@ -3,7 +3,7 @@ import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:simplecloudnotifier/models/channel.dart';
|
||||
import 'package:simplecloudnotifier/models/message.dart';
|
||||
import 'package:simplecloudnotifier/models/scn_message.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:simplecloudnotifier/utils/ui.dart';
|
||||
|
||||
@@ -18,7 +18,7 @@ class MessageListItem extends StatelessWidget {
|
||||
super.key,
|
||||
});
|
||||
|
||||
final Message message;
|
||||
final SCNMessage message;
|
||||
final Map<String, Channel> allChannels;
|
||||
final Null Function() onPressed;
|
||||
|
||||
@@ -176,11 +176,11 @@ class MessageListItem extends StatelessWidget {
|
||||
return v;
|
||||
}
|
||||
|
||||
String resolveChannelName(Message message) {
|
||||
String resolveChannelName(SCNMessage message) {
|
||||
return allChannels[message.channelID]?.displayName ?? message.channelInternalName;
|
||||
}
|
||||
|
||||
bool showChannel(Message message) {
|
||||
bool showChannel(SCNMessage message) {
|
||||
return message.channelInternalName != 'main';
|
||||
}
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@ import 'package:simplecloudnotifier/api/api_client.dart';
|
||||
import 'package:simplecloudnotifier/components/layout/scaffold.dart';
|
||||
import 'package:simplecloudnotifier/models/channel.dart';
|
||||
import 'package:simplecloudnotifier/models/keytoken.dart';
|
||||
import 'package:simplecloudnotifier/models/message.dart';
|
||||
import 'package:simplecloudnotifier/models/scn_message.dart';
|
||||
import 'package:simplecloudnotifier/models/user.dart';
|
||||
import 'package:simplecloudnotifier/state/app_auth.dart';
|
||||
import 'package:simplecloudnotifier/state/app_bar_state.dart';
|
||||
@@ -18,15 +18,15 @@ import 'package:simplecloudnotifier/utils/ui.dart';
|
||||
class MessageViewPage extends StatefulWidget {
|
||||
const MessageViewPage({super.key, required this.message});
|
||||
|
||||
final Message message; // Potentially trimmed
|
||||
final SCNMessage message; // Potentially trimmed
|
||||
|
||||
@override
|
||||
State<MessageViewPage> createState() => _MessageViewPageState();
|
||||
}
|
||||
|
||||
class _MessageViewPageState extends State<MessageViewPage> {
|
||||
late Future<(Message, ChannelPreview, KeyTokenPreview, UserPreview)>? mainFuture;
|
||||
(Message, ChannelPreview, KeyTokenPreview, UserPreview)? mainFutureSnapshot = null;
|
||||
late Future<(SCNMessage, ChannelPreview, KeyTokenPreview, UserPreview)>? mainFuture;
|
||||
(SCNMessage, ChannelPreview, KeyTokenPreview, UserPreview)? mainFutureSnapshot = null;
|
||||
static final _dateFormat = DateFormat('yyyy-MM-dd kk:mm');
|
||||
|
||||
bool _monospaceMode = false;
|
||||
@@ -37,7 +37,7 @@ class _MessageViewPageState extends State<MessageViewPage> {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
Future<(Message, ChannelPreview, KeyTokenPreview, UserPreview)> fetchData() async {
|
||||
Future<(SCNMessage, ChannelPreview, KeyTokenPreview, UserPreview)> fetchData() async {
|
||||
try {
|
||||
await Future.delayed(const Duration(seconds: 0), () {}); // this is annoyingly important - otherwise we call setLoadingIndeterminate directly in initStat() and get an exception....
|
||||
|
||||
@@ -79,7 +79,7 @@ class _MessageViewPageState extends State<MessageViewPage> {
|
||||
showSearch: false,
|
||||
showShare: true,
|
||||
onShare: _share,
|
||||
child: FutureBuilder<(Message, ChannelPreview, KeyTokenPreview, UserPreview)>(
|
||||
child: FutureBuilder<(SCNMessage, ChannelPreview, KeyTokenPreview, UserPreview)>(
|
||||
future: mainFuture,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
@@ -118,7 +118,7 @@ class _MessageViewPageState extends State<MessageViewPage> {
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildMessageView(BuildContext context, Message message, ChannelPreview? channel, KeyTokenPreview? token, UserPreview? user) {
|
||||
Widget _buildMessageView(BuildContext context, SCNMessage message, ChannelPreview? channel, KeyTokenPreview? token, UserPreview? user) {
|
||||
final userAccUserID = context.select<AppAuth, String?>((v) => v.userID);
|
||||
|
||||
return SingleChildScrollView(
|
||||
@@ -144,11 +144,11 @@ class _MessageViewPageState extends State<MessageViewPage> {
|
||||
);
|
||||
}
|
||||
|
||||
String _resolveChannelName(ChannelPreview? channel, Message message) {
|
||||
String _resolveChannelName(ChannelPreview? channel, SCNMessage message) {
|
||||
return channel?.displayName ?? message.channelInternalName;
|
||||
}
|
||||
|
||||
List<Widget> _buildMessageHeader(BuildContext context, Message message, ChannelPreview? channel) {
|
||||
List<Widget> _buildMessageHeader(BuildContext context, SCNMessage message, ChannelPreview? channel) {
|
||||
return [
|
||||
Row(
|
||||
children: [
|
||||
@@ -167,7 +167,7 @@ class _MessageViewPageState extends State<MessageViewPage> {
|
||||
];
|
||||
}
|
||||
|
||||
List<Widget> _buildMessageContent(BuildContext context, Message message) {
|
||||
List<Widget> _buildMessageContent(BuildContext context, SCNMessage message) {
|
||||
return [
|
||||
Row(
|
||||
children: [
|
||||
@@ -249,7 +249,7 @@ class _MessageViewPageState extends State<MessageViewPage> {
|
||||
}
|
||||
}
|
||||
|
||||
String _preformatTitle(Message message) {
|
||||
String _preformatTitle(SCNMessage message) {
|
||||
return message.title.replaceAll('\n', '').replaceAll('\r', '').replaceAll('\t', ' ');
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user