debug view && priority in listview
This commit is contained in:
parent
34925b6678
commit
f5813a5489
11
flutter/README.md
Normal file
11
flutter/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
### Links
|
||||
|
||||
|
||||
- https://pub.dev/packages/font_awesome_flutter
|
||||
- https://fontawesome.com/search
|
||||
|
||||
- https://docs.flutter.dev/ui/widgets
|
||||
- https://docs.flutter.dev/ui/widgets/material
|
||||
|
||||
|
||||
|
@ -1,37 +1,55 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:simplecloudnotifier/pages/debug/debug_main.dart';
|
||||
import 'package:simplecloudnotifier/state/app_theme.dart';
|
||||
|
||||
class SCNAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
const SCNAppBar({Key? key, this.title}) : super(key: key);
|
||||
const SCNAppBar({
|
||||
Key? key,
|
||||
required this.title,
|
||||
required this.showThemeSwitch,
|
||||
required this.showDebug,
|
||||
required this.showSearch,
|
||||
}) : super(key: key);
|
||||
|
||||
final String? title;
|
||||
final bool showThemeSwitch;
|
||||
final bool showDebug;
|
||||
final bool showSearch;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AppBar(
|
||||
title: Text(title ?? 'Simple Cloud Notifier 2.0'),
|
||||
actions: <Widget>[
|
||||
Consumer<AppTheme>(
|
||||
builder: (context, appTheme, child) => IconButton(
|
||||
icon: Icon(appTheme.darkMode ? FontAwesomeIcons.solidSun : FontAwesomeIcons.solidMoon),
|
||||
if (showThemeSwitch)
|
||||
Consumer<AppTheme>(
|
||||
builder: (context, appTheme, child) => IconButton(
|
||||
icon: Icon(appTheme.darkMode ? FontAwesomeIcons.solidSun : FontAwesomeIcons.solidMoon),
|
||||
tooltip: 'Debug',
|
||||
onPressed: () {
|
||||
appTheme.switchDarkMode();
|
||||
},
|
||||
),
|
||||
),
|
||||
if (!showThemeSwitch) SizedBox.square(dimension: 40),
|
||||
if (showDebug)
|
||||
IconButton(
|
||||
icon: const Icon(FontAwesomeIcons.solidSpiderBlackWidow),
|
||||
tooltip: 'Debug',
|
||||
onPressed: () {
|
||||
appTheme.switchDarkMode();
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) => DebugMainPage()));
|
||||
},
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(FontAwesomeIcons.solidSpiderBlackWidow),
|
||||
tooltip: 'Debug',
|
||||
onPressed: () {},
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(FontAwesomeIcons.solidMagnifyingGlass),
|
||||
tooltip: 'Search',
|
||||
onPressed: () {},
|
||||
),
|
||||
if (!showDebug) SizedBox.square(dimension: 40),
|
||||
if (showSearch)
|
||||
IconButton(
|
||||
icon: const Icon(FontAwesomeIcons.solidMagnifyingGlass),
|
||||
tooltip: 'Search',
|
||||
onPressed: () {},
|
||||
),
|
||||
if (!showSearch) SizedBox.square(dimension: 40),
|
||||
],
|
||||
backgroundColor: Theme.of(context).secondaryHeaderColor,
|
||||
);
|
||||
|
@ -2,16 +2,29 @@ import 'package:flutter/material.dart';
|
||||
import 'package:simplecloudnotifier/components/layout/app_bar.dart';
|
||||
|
||||
class SCNScaffold extends StatelessWidget {
|
||||
const SCNScaffold({Key? key, required this.child, this.title}) : super(key: key);
|
||||
const SCNScaffold({
|
||||
Key? key,
|
||||
required this.child,
|
||||
this.title,
|
||||
this.showThemeSwitch = true,
|
||||
this.showDebug = true,
|
||||
this.showSearch = true,
|
||||
}) : super(key: key);
|
||||
|
||||
final Widget child;
|
||||
final String? title;
|
||||
final bool showThemeSwitch;
|
||||
final bool showDebug;
|
||||
final bool showSearch;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: SCNAppBar(
|
||||
title: title,
|
||||
showThemeSwitch: showThemeSwitch,
|
||||
showDebug: showDebug,
|
||||
showSearch: showSearch,
|
||||
),
|
||||
body: child,
|
||||
);
|
||||
|
@ -42,7 +42,12 @@ class _SCNNavLayoutState extends State<SCNNavLayout> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: SCNAppBar(),
|
||||
appBar: SCNAppBar(
|
||||
title: null,
|
||||
showDebug: true,
|
||||
showSearch: _selectedIndex == 0 || _selectedIndex == 1,
|
||||
showThemeSwitch: true,
|
||||
),
|
||||
body: _subPages.elementAt(_selectedIndex),
|
||||
bottomNavigationBar: _buildNavBar(context),
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
|
||||
|
126
flutter/lib/pages/debug/debug_colors.dart
Normal file
126
flutter/lib/pages/debug/debug_colors.dart
Normal file
@ -0,0 +1,126 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class DebugColorsPage extends StatefulWidget {
|
||||
@override
|
||||
_DebugColorsPageState createState() => _DebugColorsPageState();
|
||||
}
|
||||
|
||||
class _DebugColorsPageState extends State<DebugColorsPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: listColors(context),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> listColors(BuildContext context) {
|
||||
return [
|
||||
buildCol("primaryColor", Theme.of(context).primaryColor),
|
||||
buildCol("primaryColorDark", Theme.of(context).primaryColorDark),
|
||||
buildCol("primaryColorLight", Theme.of(context).primaryColorLight),
|
||||
buildCol("secondaryHeaderColor", Theme.of(context).secondaryHeaderColor),
|
||||
buildCol("disabledColor", Theme.of(context).disabledColor),
|
||||
buildCol("splashColor", Theme.of(context).splashColor),
|
||||
Divider(),
|
||||
buildCol("canvasColor", Theme.of(context).canvasColor),
|
||||
buildCol("cardColor", Theme.of(context).cardColor),
|
||||
buildCol("dialogBackgroundColor", Theme.of(context).dialogBackgroundColor),
|
||||
buildCol("dividerColor", Theme.of(context).dividerColor),
|
||||
buildCol("focusColor", Theme.of(context).focusColor),
|
||||
buildCol("highlightColor", Theme.of(context).highlightColor),
|
||||
buildCol("hintColor", Theme.of(context).hintColor),
|
||||
buildCol("hoverColor", Theme.of(context).hoverColor),
|
||||
buildCol("indicatorColor", Theme.of(context).indicatorColor),
|
||||
buildCol("scaffoldBackgroundColor", Theme.of(context).scaffoldBackgroundColor),
|
||||
buildCol("shadowColor", Theme.of(context).shadowColor),
|
||||
buildCol("unselectedWidgetColor", Theme.of(context).unselectedWidgetColor),
|
||||
Divider(),
|
||||
buildCol("colorScheme.primary", Theme.of(context).colorScheme.primary),
|
||||
buildCol("colorScheme.onPrimary", Theme.of(context).colorScheme.onPrimary),
|
||||
buildCol("colorScheme.primaryContainer", Theme.of(context).colorScheme.primaryContainer),
|
||||
buildCol("colorScheme.onPrimaryContainer", Theme.of(context).colorScheme.onPrimaryContainer),
|
||||
buildCol("colorScheme.inversePrimary", Theme.of(context).colorScheme.inversePrimary),
|
||||
buildCol("colorScheme.secondary", Theme.of(context).colorScheme.secondary),
|
||||
buildCol("colorScheme.onSecondary", Theme.of(context).colorScheme.onSecondary),
|
||||
buildCol("colorScheme.secondaryContainer", Theme.of(context).colorScheme.secondaryContainer),
|
||||
buildCol("colorScheme.onSecondaryContainer", Theme.of(context).colorScheme.onSecondaryContainer),
|
||||
buildCol("colorScheme.tertiary", Theme.of(context).colorScheme.tertiary),
|
||||
buildCol("colorScheme.onTertiary", Theme.of(context).colorScheme.onTertiary),
|
||||
buildCol("colorScheme.tertiaryContainer", Theme.of(context).colorScheme.tertiaryContainer),
|
||||
buildCol("colorScheme.onTertiaryContainer", Theme.of(context).colorScheme.onTertiaryContainer),
|
||||
buildCol("colorScheme.surface", Theme.of(context).colorScheme.surface),
|
||||
buildCol("colorScheme.onSurface", Theme.of(context).colorScheme.onSurface),
|
||||
buildCol("colorScheme.surfaceTint", Theme.of(context).colorScheme.surfaceTint),
|
||||
buildCol("colorScheme.surfaceVariant", Theme.of(context).colorScheme.surfaceVariant),
|
||||
buildCol("colorScheme.inverseSurface", Theme.of(context).colorScheme.inverseSurface),
|
||||
buildCol("colorScheme.onInverseSurface", Theme.of(context).colorScheme.onInverseSurface),
|
||||
buildCol("colorScheme.background", Theme.of(context).colorScheme.background),
|
||||
buildCol("colorScheme.onBackground", Theme.of(context).colorScheme.onBackground),
|
||||
buildCol("colorScheme.error", Theme.of(context).colorScheme.error),
|
||||
buildCol("colorScheme.onError", Theme.of(context).colorScheme.onError),
|
||||
buildCol("colorScheme.errorContainer", Theme.of(context).colorScheme.errorContainer),
|
||||
buildCol("colorScheme.onErrorContainer", Theme.of(context).colorScheme.onErrorContainer),
|
||||
buildCol("colorScheme.outline", Theme.of(context).colorScheme.outline),
|
||||
buildCol("colorScheme.outlineVariant", Theme.of(context).colorScheme.outlineVariant),
|
||||
buildCol("colorScheme.shadow", Theme.of(context).colorScheme.shadow),
|
||||
buildCol("colorScheme.scrim", Theme.of(context).colorScheme.scrim),
|
||||
Divider(),
|
||||
buildCol("primaryTextTheme.bodyLarge.backgroundColor", Theme.of(context).primaryTextTheme.bodyLarge?.backgroundColor),
|
||||
buildCol("primaryTextTheme.bodyLarge.color", Theme.of(context).primaryTextTheme.bodyLarge?.color),
|
||||
buildCol("primaryTextTheme.displayLarge.backgroundColor", Theme.of(context).primaryTextTheme.displayLarge?.backgroundColor),
|
||||
buildCol("primaryTextTheme.displayLarge.color", Theme.of(context).primaryTextTheme.displayLarge?.color),
|
||||
buildCol("primaryTextTheme.headlineLarge.backgroundColor", Theme.of(context).primaryTextTheme.headlineLarge?.backgroundColor),
|
||||
buildCol("primaryTextTheme.headlineLarge.color", Theme.of(context).primaryTextTheme.headlineLarge?.color),
|
||||
buildCol("primaryTextTheme.labelLarge.backgroundColor", Theme.of(context).primaryTextTheme.labelLarge?.backgroundColor),
|
||||
buildCol("primaryTextTheme.labelLarge.color", Theme.of(context).primaryTextTheme.labelLarge?.color),
|
||||
buildCol("primaryTextTheme.titleLarge.backgroundColor", Theme.of(context).primaryTextTheme.titleLarge?.backgroundColor),
|
||||
buildCol("primaryTextTheme.titleLarge.color", Theme.of(context).primaryTextTheme.titleLarge?.color),
|
||||
buildCol("textTheme.bodyLarge.backgroundColor", Theme.of(context).textTheme.bodyLarge?.backgroundColor),
|
||||
buildCol("textTheme.bodyLarge.color", Theme.of(context).textTheme.bodyLarge?.color),
|
||||
buildCol("textTheme.displayLarge.backgroundColor", Theme.of(context).textTheme.displayLarge?.backgroundColor),
|
||||
buildCol("textTheme.displayLarge.color", Theme.of(context).textTheme.displayLarge?.color),
|
||||
buildCol("textTheme.headlineLarge.backgroundColor", Theme.of(context).textTheme.headlineLarge?.backgroundColor),
|
||||
buildCol("textTheme.headlineLarge.color", Theme.of(context).textTheme.headlineLarge?.color),
|
||||
buildCol("textTheme.labelLarge.backgroundColor", Theme.of(context).textTheme.labelLarge?.backgroundColor),
|
||||
buildCol("textTheme.labelLarge.color", Theme.of(context).textTheme.labelLarge?.color),
|
||||
buildCol("textTheme.titleLarge.backgroundColor", Theme.of(context).textTheme.titleLarge?.backgroundColor),
|
||||
buildCol("textTheme.titleLarge.color", Theme.of(context).textTheme.titleLarge?.color),
|
||||
Divider(),
|
||||
buildCol("iconTheme.color", Theme.of(context).iconTheme.color),
|
||||
buildCol("primaryIconTheme.color", Theme.of(context).primaryIconTheme.color),
|
||||
buildCol("appBarTheme.foregroundColor", Theme.of(context).appBarTheme.foregroundColor),
|
||||
buildCol("appBarTheme.backgroundColor", Theme.of(context).appBarTheme.backgroundColor),
|
||||
buildCol("badgeTheme.textColor", Theme.of(context).badgeTheme.textColor),
|
||||
buildCol("badgeTheme.backgroundColor", Theme.of(context).badgeTheme.backgroundColor),
|
||||
buildCol("bannerTheme.backgroundColor", Theme.of(context).bannerTheme.backgroundColor),
|
||||
buildCol("bottomAppBarTheme.color", Theme.of(context).bottomAppBarTheme.color),
|
||||
buildCol("buttonTheme.colorScheme.background", Theme.of(context).buttonTheme.colorScheme?.background),
|
||||
buildCol("buttonTheme.colorScheme.primary", Theme.of(context).buttonTheme.colorScheme?.primary),
|
||||
buildCol("buttonTheme.colorScheme.secondary", Theme.of(context).buttonTheme.colorScheme?.secondary),
|
||||
buildCol("cardTheme.color", Theme.of(context).cardTheme.color),
|
||||
];
|
||||
}
|
||||
|
||||
Widget buildCol(String key, Color? value) {
|
||||
return Row(
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.all(4),
|
||||
child: Container(
|
||||
width: 20,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Colors.black),
|
||||
color: value ?? Color.fromARGB(0, 0, 0, 0),
|
||||
),
|
||||
height: 20,
|
||||
),
|
||||
),
|
||||
Expanded(child: Text(key))
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
64
flutter/lib/pages/debug/debug_main.dart
Normal file
64
flutter/lib/pages/debug/debug_main.dart
Normal file
@ -0,0 +1,64 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:simplecloudnotifier/components/layout/scaffold.dart';
|
||||
import 'package:simplecloudnotifier/pages/debug/debug_colors.dart';
|
||||
import 'package:simplecloudnotifier/pages/debug/debug_persistence.dart';
|
||||
import 'package:simplecloudnotifier/pages/debug/debug_requests.dart';
|
||||
|
||||
class DebugMainPage extends StatefulWidget {
|
||||
@override
|
||||
_DebugMainPageState createState() => _DebugMainPageState();
|
||||
}
|
||||
|
||||
enum DebugMainPageSubPage { colors, requests, persistence }
|
||||
|
||||
class _DebugMainPageState extends State<DebugMainPage> {
|
||||
final Map<DebugMainPageSubPage, Widget> _subpages = {
|
||||
DebugMainPageSubPage.colors: DebugColorsPage(),
|
||||
DebugMainPageSubPage.requests: DebugRequestsPage(),
|
||||
DebugMainPageSubPage.persistence: DebugPersistencePage(),
|
||||
};
|
||||
|
||||
DebugMainPageSubPage _subPage = DebugMainPageSubPage.colors;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SCNScaffold(
|
||||
title: 'Debug',
|
||||
showSearch: false,
|
||||
showDebug: false,
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
buildSegButton(context),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: _subpages[_subPage]!,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildSegButton(BuildContext context) {
|
||||
return SegmentedButton<DebugMainPageSubPage>(
|
||||
showSelectedIcon: false,
|
||||
segments: const <ButtonSegment<DebugMainPageSubPage>>[
|
||||
ButtonSegment<DebugMainPageSubPage>(value: DebugMainPageSubPage.colors, label: Text('Theme')),
|
||||
ButtonSegment<DebugMainPageSubPage>(value: DebugMainPageSubPage.requests, label: Text('Requests')),
|
||||
ButtonSegment<DebugMainPageSubPage>(value: DebugMainPageSubPage.persistence, label: Text('Persistence')),
|
||||
],
|
||||
selected: <DebugMainPageSubPage>{_subPage},
|
||||
onSelectionChanged: (Set<DebugMainPageSubPage> v) {
|
||||
setState(() {
|
||||
_subPage = v.first;
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
13
flutter/lib/pages/debug/debug_persistence.dart
Normal file
13
flutter/lib/pages/debug/debug_persistence.dart
Normal file
@ -0,0 +1,13 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class DebugPersistencePage extends StatefulWidget {
|
||||
@override
|
||||
_DebugPersistencePageState createState() => _DebugPersistencePageState();
|
||||
}
|
||||
|
||||
class _DebugPersistencePageState extends State<DebugPersistencePage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(/* Add your UI components here */);
|
||||
}
|
||||
}
|
13
flutter/lib/pages/debug/debug_requests.dart
Normal file
13
flutter/lib/pages/debug/debug_requests.dart
Normal file
@ -0,0 +1,13 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class DebugRequestsPage extends StatefulWidget {
|
||||
@override
|
||||
_DebugRequestsPageState createState() => _DebugRequestsPageState();
|
||||
}
|
||||
|
||||
class _DebugRequestsPageState extends State<DebugRequestsPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(/* Add your UI components here */);
|
||||
}
|
||||
}
|
@ -76,10 +76,7 @@ class _MessageListPageState extends State<MessageListPage> {
|
||||
message: item,
|
||||
allChannels: _channels ?? {},
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) => MessageViewPage(messageID: item.messageID)),
|
||||
);
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) => MessageViewPage(message: item)));
|
||||
},
|
||||
),
|
||||
),
|
||||
|
@ -1,13 +1,14 @@
|
||||
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:intl/intl.dart';
|
||||
|
||||
class MessageListItem extends StatelessWidget {
|
||||
static final _dateFormat = DateFormat('yyyy-MM-dd kk:mm');
|
||||
static final _lineCount = 3;
|
||||
static final _lineCount = 3; //TODO setting
|
||||
|
||||
const MessageListItem({
|
||||
required this.message,
|
||||
@ -23,107 +24,125 @@ class MessageListItem extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (showChannel(message)) {
|
||||
return Card.filled(
|
||||
margin: EdgeInsets.fromLTRB(0, 4, 0, 4),
|
||||
shape: BeveledRectangleBorder(borderRadius: BorderRadius.circular(0)),
|
||||
//clipBehavior: Clip.hardEdge, // nto needed, because our borderRadius is 0 anyway
|
||||
child: InkWell(
|
||||
splashColor: Theme.of(context).primaryColor.withAlpha(30),
|
||||
onTap: onPressed,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.fromLTRB(4, 0, 4, 0),
|
||||
margin: const EdgeInsets.fromLTRB(0, 0, 4, 0),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).hintColor,
|
||||
borderRadius: BorderRadius.all(Radius.circular(4)),
|
||||
),
|
||||
child: Text(
|
||||
resolveChannelName(message),
|
||||
style: TextStyle(fontWeight: FontWeight.bold, color: Theme.of(context).cardColor, fontSize: 12),
|
||||
overflow: TextOverflow.clip,
|
||||
maxLines: 1,
|
||||
),
|
||||
),
|
||||
Expanded(child: SizedBox()),
|
||||
Text(
|
||||
_dateFormat.format(DateTime.parse(message.timestamp).toLocal()),
|
||||
style: const TextStyle(fontWeight: FontWeight.normal, fontSize: 11),
|
||||
overflow: TextOverflow.clip,
|
||||
maxLines: 1,
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
processTitle(message.title),
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 3,
|
||||
),
|
||||
Text(
|
||||
processContent(message.content),
|
||||
style: TextStyle(color: Theme.of(context).textTheme.bodyLarge?.color?.withAlpha(160)),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: _lineCount,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
return buildWithChannel(context);
|
||||
} else {
|
||||
return Card.filled(
|
||||
margin: EdgeInsets.fromLTRB(0, 4, 0, 4),
|
||||
shape: BeveledRectangleBorder(borderRadius: BorderRadius.circular(0)),
|
||||
//clipBehavior: Clip.hardEdge, // nto needed, because our borderRadius is 0 anyway
|
||||
child: InkWell(
|
||||
splashColor: Theme.of(context).primaryColor.withAlpha(30),
|
||||
onTap: onPressed,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
processTitle(message.title),
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 3,
|
||||
),
|
||||
return buildWithoutChannel(context);
|
||||
}
|
||||
}
|
||||
|
||||
Card buildWithoutChannel(BuildContext context) {
|
||||
return Card.filled(
|
||||
margin: EdgeInsets.fromLTRB(0, 4, 0, 4),
|
||||
shape: BeveledRectangleBorder(borderRadius: BorderRadius.circular(0)),
|
||||
color: (message.priority == 2) ? Theme.of(context).colorScheme.errorContainer : Theme.of(context).cardTheme.color,
|
||||
//clipBehavior: Clip.hardEdge, // nto needed, because our borderRadius is 0 anyway
|
||||
child: InkWell(
|
||||
splashColor: Theme.of(context).splashColor,
|
||||
onTap: onPressed,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (message.priority == 2) FaIcon(FontAwesomeIcons.solidTriangleExclamation, size: 16, color: Theme.of(context).colorScheme.error),
|
||||
if (message.priority == 2) SizedBox(width: 4),
|
||||
if (message.priority == 0) FaIcon(FontAwesomeIcons.solidDown, size: 16, color: Theme.of(context).colorScheme.primary),
|
||||
if (message.priority == 0) SizedBox(width: 4),
|
||||
Expanded(
|
||||
child: Text(
|
||||
processTitle(message.title),
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 3,
|
||||
),
|
||||
Text(
|
||||
_dateFormat.format(DateTime.parse(message.timestamp).toLocal()),
|
||||
style: const TextStyle(fontWeight: FontWeight.normal, fontSize: 11),
|
||||
),
|
||||
Text(
|
||||
_dateFormat.format(DateTime.parse(message.timestamp).toLocal()),
|
||||
style: const TextStyle(fontWeight: FontWeight.normal, fontSize: 11),
|
||||
overflow: TextOverflow.clip,
|
||||
maxLines: 1,
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
processContent(message.content),
|
||||
style: TextStyle(color: Theme.of(context).textTheme.bodyLarge?.color?.withAlpha(160)),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: _lineCount,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Card buildWithChannel(BuildContext context) {
|
||||
return Card.filled(
|
||||
margin: EdgeInsets.fromLTRB(0, 4, 0, 4),
|
||||
shape: BeveledRectangleBorder(borderRadius: BorderRadius.circular(0)),
|
||||
//clipBehavior: Clip.hardEdge, // nto needed, because our borderRadius is 0 anyway
|
||||
color: (message.priority == 2) ? Theme.of(context).colorScheme.errorContainer : Theme.of(context).cardTheme.color,
|
||||
child: InkWell(
|
||||
splashColor: Theme.of(context).splashColor,
|
||||
onTap: onPressed,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (message.priority == 2) FaIcon(FontAwesomeIcons.solidTriangleExclamation, size: 16, color: Theme.of(context).colorScheme.error),
|
||||
if (message.priority == 2) SizedBox(width: 4),
|
||||
if (message.priority == 0) FaIcon(FontAwesomeIcons.solidDown, size: 16, color: Theme.of(context).colorScheme.primary),
|
||||
if (message.priority == 0) SizedBox(width: 4),
|
||||
Container(
|
||||
padding: const EdgeInsets.fromLTRB(4, 0, 4, 0),
|
||||
margin: const EdgeInsets.fromLTRB(0, 0, 4, 0),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).hintColor,
|
||||
borderRadius: BorderRadius.all(Radius.circular(4)),
|
||||
),
|
||||
child: Text(
|
||||
resolveChannelName(message),
|
||||
style: TextStyle(fontWeight: FontWeight.bold, color: Theme.of(context).cardColor, fontSize: 12),
|
||||
overflow: TextOverflow.clip,
|
||||
maxLines: 1,
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
processContent(message.content),
|
||||
style: TextStyle(color: Theme.of(context).textTheme.bodyLarge?.color?.withAlpha(160)),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: _lineCount,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(child: SizedBox()),
|
||||
Text(
|
||||
_dateFormat.format(DateTime.parse(message.timestamp).toLocal()),
|
||||
style: const TextStyle(fontWeight: FontWeight.normal, fontSize: 11),
|
||||
overflow: TextOverflow.clip,
|
||||
maxLines: 1,
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
processTitle(message.title),
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 3,
|
||||
),
|
||||
Text(
|
||||
processContent(message.content),
|
||||
style: TextStyle(color: Theme.of(context).textTheme.bodyLarge?.color?.withAlpha(160)),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: _lineCount,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
processContent(String? v) {
|
||||
|
@ -6,9 +6,9 @@ import 'package:simplecloudnotifier/models/message.dart';
|
||||
import 'package:simplecloudnotifier/state/user_account.dart';
|
||||
|
||||
class MessageViewPage extends StatefulWidget {
|
||||
const MessageViewPage({super.key, required this.messageID});
|
||||
const MessageViewPage({super.key, required this.message});
|
||||
|
||||
final String messageID;
|
||||
final Message message; // Potentially trimmed
|
||||
|
||||
@override
|
||||
State<MessageViewPage> createState() => _MessageViewPageState();
|
||||
@ -26,7 +26,7 @@ class _MessageViewPageState extends State<MessageViewPage> {
|
||||
Future<Message> fetchMessage() async {
|
||||
final acc = Provider.of<UserAccount>(context, listen: false);
|
||||
|
||||
return await APIClient.getMessage(acc.auth!, widget.messageID);
|
||||
return await APIClient.getMessage(acc.auth!, widget.message.messageID);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -38,18 +38,32 @@ class _MessageViewPageState extends State<MessageViewPage> {
|
||||
Widget build(BuildContext context) {
|
||||
return SCNScaffold(
|
||||
title: 'Message',
|
||||
showSearch: false,
|
||||
child: FutureBuilder<Message>(
|
||||
future: futureMessage,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
return Center(child: Text(snapshot.data!.title));
|
||||
return buildMessageView(snapshot.data!, false);
|
||||
} else if (snapshot.hasError) {
|
||||
return Center(child: Text('${snapshot.error}')); //TODO nice error page
|
||||
} else if (!widget.message.trimmed) {
|
||||
return buildMessageView(widget.message, true);
|
||||
} else {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildMessageView(Message message, bool loading) {
|
||||
return Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Text(message.title),
|
||||
Text(message.content ?? ''),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -101,6 +101,14 @@ class _SendRootPageState extends State<SendRootPage> {
|
||||
data: url,
|
||||
version: QrVersions.auto,
|
||||
size: 400.0,
|
||||
eyeStyle: QrEyeStyle(
|
||||
eyeShape: QrEyeShape.square,
|
||||
color: Theme.of(context).textTheme.bodyLarge?.color,
|
||||
),
|
||||
dataModuleStyle: QrDataModuleStyle(
|
||||
dataModuleShape: QrDataModuleShape.square,
|
||||
color: Theme.of(context).textTheme.bodyLarge?.color,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -123,6 +131,14 @@ class _SendRootPageState extends State<SendRootPage> {
|
||||
data: url,
|
||||
version: QrVersions.auto,
|
||||
size: 400.0,
|
||||
eyeStyle: QrEyeStyle(
|
||||
eyeShape: QrEyeShape.square,
|
||||
color: Theme.of(context).textTheme.bodyLarge?.color,
|
||||
),
|
||||
dataModuleStyle: QrDataModuleStyle(
|
||||
dataModuleShape: QrDataModuleShape.square,
|
||||
color: Theme.of(context).textTheme.bodyLarge?.color,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user