feat(debug): debug page for multiple UI elements

This commit is contained in:
Jagandeep Brar
2022-02-19 01:08:16 -05:00
parent 1229e5ee5b
commit 80c5d2118a
8 changed files with 270 additions and 16 deletions

View File

@@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:lunasea/core.dart';
enum _APPBAR_TYPE {
enum _AppBarType {
DEFAULT,
EMPTY,
DROPDOWN,
@@ -12,7 +12,7 @@ enum _APPBAR_TYPE {
class LunaAppBar extends StatefulWidget implements PreferredSizeWidget {
static const APPBAR_HEIGHT = kToolbarHeight;
final _APPBAR_TYPE type;
final _AppBarType type;
final String? title;
final List<Widget>? actions;
final PreferredSizeWidget? bottom;
@@ -76,7 +76,7 @@ class LunaAppBar extends StatefulWidget implements PreferredSizeWidget {
scrollControllers: scrollControllers,
hideLeading: hideLeading,
backgroundColor: backgroundColor,
type: _APPBAR_TYPE.DEFAULT,
type: _AppBarType.DEFAULT,
);
}
@@ -102,7 +102,7 @@ class LunaAppBar extends StatefulWidget implements PreferredSizeWidget {
height: height,
useDrawer: false,
backgroundColor: backgroundColor,
type: _APPBAR_TYPE.EMPTY,
type: _AppBarType.EMPTY,
);
}
@@ -137,7 +137,7 @@ class LunaAppBar extends StatefulWidget implements PreferredSizeWidget {
pageController: pageController,
scrollControllers: scrollControllers,
backgroundColor: backgroundColor,
type: _APPBAR_TYPE.DEFAULT,
type: _AppBarType.DEFAULT,
);
return LunaAppBar._internal(
title: title,
@@ -149,7 +149,7 @@ class LunaAppBar extends StatefulWidget implements PreferredSizeWidget {
pageController: pageController,
scrollControllers: scrollControllers,
backgroundColor: backgroundColor,
type: _APPBAR_TYPE.DROPDOWN,
type: _AppBarType.DROPDOWN,
);
}
@@ -196,13 +196,13 @@ class _State extends State<LunaAppBar> {
Widget build(BuildContext context) {
Widget child;
switch (widget.type) {
case _APPBAR_TYPE.DEFAULT:
case _AppBarType.DEFAULT:
child = _default(context);
break;
case _APPBAR_TYPE.EMPTY:
case _AppBarType.EMPTY:
child = _empty(context);
break;
case _APPBAR_TYPE.DROPDOWN:
case _AppBarType.DROPDOWN:
child = _dropdown(context);
break;
default:

View File

@@ -274,7 +274,7 @@ class LunaBlock extends StatelessWidget {
context: context,
title: _scrollableText(
child: LunaText.title(
text: title!,
text: title ?? LunaUI.TEXT_EMDASH,
color: titleColor,
overflow: TextOverflow.visible,
maxLines: 1,

View File

@@ -69,8 +69,10 @@ class SettingsRouter extends LunaModuleRouter {
SettingsConfigurationTautulliHeadersRouter().defineRoute(router);
// Configuration/Wake-on-LAN
SettingsConfigurationWakeOnLANRouter().defineRoute(router);
// Other
// Debug Menu
SettingsDebugMenuRouter().defineRoute(router);
SettingsSystemDebugMenuUIRouter().defineRoute(router);
// Other
SettingsDonationsRouter().defineRoute(router);
SettingsDonationsThankYouRouter().defineRoute(router);
SettingsNotificationsRouter().defineRoute(router);

View File

@@ -1 +1,2 @@
export 'debug_menu/pages.dart';
export 'debug_menu/route.dart';

View File

@@ -0,0 +1 @@
export 'pages/ui.dart';

View File

@@ -0,0 +1,243 @@
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:lunasea/core.dart';
import 'package:lunasea/modules/settings.dart';
import 'package:lunasea/modules/tautulli.dart';
class SettingsSystemDebugMenuUIRouter extends SettingsPageRouter {
SettingsSystemDebugMenuUIRouter() : super('/settings/debug_menu/ui');
@override
_Widget widget() => _Widget();
@override
void defineRoute(FluroRouter router) {
super.noParameterRouteDefinition(router);
}
}
class _Widget extends StatefulWidget {
@override
State<_Widget> createState() => _State();
}
class _State extends State<_Widget>
with LunaScrollControllerMixin, TickerProviderStateMixin {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
late AnimationController _iconController;
late AnimationController _hideController;
bool _isFabVisible = true;
bool _isFabPaused = false;
@override
void initState() {
super.initState();
_setupIconController();
_setupHideController();
}
@override
void dispose() {
_iconController.dispose();
_hideController.dispose();
scrollController.removeListener(scrollControllerListener);
super.dispose();
}
void scrollControllerListener() {
if (!scrollController.hasClients) return;
switch (scrollController.position.userScrollDirection) {
case ScrollDirection.forward:
if (!_isFabVisible) {
_hideController.forward();
_isFabVisible = true;
}
break;
case ScrollDirection.reverse:
if (_isFabVisible) {
_hideController.reverse();
_isFabVisible = false;
}
break;
case ScrollDirection.idle:
break;
}
}
void _setupIconController() {
_iconController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: LunaUI.ANIMATION_SPEED),
);
}
void _setupHideController() {
_hideController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: LunaUI.ANIMATION_SPEED),
);
_hideController.forward();
scrollController.addListener(scrollControllerListener);
}
Future<void> _toggle(BuildContext context) async {
HapticFeedback.lightImpact();
_isFabPaused ? _iconController.reverse() : _iconController.forward();
setState(() => _isFabPaused = !_isFabPaused);
}
@override
Widget build(BuildContext context) {
return LunaScaffold(
scaffoldKey: _scaffoldKey,
appBar: _appBar() as PreferredSizeWidget?,
body: _body(),
floatingActionButton: _floatingActionButton(),
);
}
Widget _appBar() {
return LunaAppBar(
title: 'settings.DebugMenu'.tr(),
scrollControllers: [scrollController],
);
}
Widget _floatingActionButton() {
return ScaleTransition(
scale: _hideController,
child: InkWell(
child: LunaFloatingActionButtonAnimated(
controller: _iconController,
icon: AnimatedIcons.pause_play,
onPressed: () => _toggle(context),
),
borderRadius: BorderRadius.circular(28.0),
),
);
}
Widget _body() {
return LunaListView(
controller: scrollController,
children: [
..._lunaBlock(),
..._tableContents(),
..._graphs(),
],
);
}
List<TextSpan> _generateBody(int l) =>
List.generate(l, (i) => TextSpan(text: 'Body ${i + 1}'));
List<LunaTableContent> _generateTableContent(int l) => List.generate(l,
(i) => LunaTableContent(title: 'Title ${i + 1}', body: 'Body ${i + 1}'));
List<Widget> _tableContents() {
return [
LunaExpandableListTile(
title: 'Expandable 1',
collapsedSubtitles: _generateBody(2),
expandedTableContent: _generateTableContent(4),
collapsedTrailing: const LunaIconButton(icon: LunaIcons.ARROW_RIGHT),
),
LunaTableCard(content: _generateTableContent(4)),
];
}
List<Widget> _lunaBlock() {
return [
LunaBlock(
title: 'Title 1',
body: _generateBody(1),
bodyLeadingIcons: const [LunaIcons.DOWNLOAD],
leading: const LunaIconButton(icon: LunaIcons.ARROW_RIGHT),
trailing: const LunaIconButton(icon: LunaIcons.ARROW_RIGHT),
),
LunaBlock(
disabled: true,
title: 'Title 1',
body: _generateBody(1),
bodyLeadingIcons: const [LunaIcons.DOWNLOAD],
leading: const LunaIconButton(icon: LunaIcons.ARROW_RIGHT),
trailing: const LunaIconButton(icon: LunaIcons.ARROW_RIGHT),
),
const LunaBlock(
skeletonEnabled: true,
skeletonPoster: true,
skeletonSubtitles: 2,
),
LunaBlock(
title: 'Title 1',
body: _generateBody(2),
posterPlaceholderIcon: LunaIcons.VIDEO_CAM,
posterUrl: TheMovieDB.getPosterURL('/qLX91FhHWCVrxDVsw0g2UD5c3Zk.jpg'),
backgroundUrl:
TheMovieDB.getPosterURL('/wR3ZbCWM55qbJBcIO7rHm0MB68j.jpg'),
onTap: () {},
),
];
}
List<Widget> _graphs() {
TautulliGraphData data = TautulliGraphData.fromJson(json.decode(
'{"categories":["2022-02-05","2022-02-06","2022-02-07","2022-02-08","2022-02-09","2022-02-10","2022-02-11","2022-02-12","2022-02-13","2022-02-14","2022-02-15","2022-02-16","2022-02-17","2022-02-18"],"series":[{"name":"Direct Play","data":[65,27,38,33,31,48,60,33,32,33,20,22,28,68]},{"name":"Direct Stream","data":[0,0,0,0,0,2,0,4,0,0,2,1,0,2]},{"name":"Transcode","data":[9,12,23,12,20,20,9,7,8,5,21,19,23,33]}]}',
));
return [
LunaCard(
context: context,
child: Column(
children: [
SizedBox(
height: TautulliGraphHelper.GRAPH_HEIGHT,
width: MediaQuery.of(context).size.width,
child: Padding(
child: LineChart(
LineChartData(
gridData: TautulliGraphHelper().gridData(),
titlesData: TautulliLineGraphHelper.titlesData(data),
borderData: TautulliGraphHelper().borderData(),
lineBarsData: TautulliLineGraphHelper.lineBarsData(data),
lineTouchData:
TautulliLineGraphHelper.lineTouchData(context, data),
),
),
padding: LunaUI.MARGIN_DEFAULT,
),
),
TautulliGraphHelper().createLegend(data.series!),
],
),
),
LunaCard(
context: context,
child: Column(
children: [
SizedBox(
height: TautulliGraphHelper.GRAPH_HEIGHT,
width: MediaQuery.of(context).size.width,
child: Padding(
child: BarChart(
BarChartData(
alignment: TautulliGraphHelper().chartAlignment(),
gridData: TautulliGraphHelper().gridData(),
titlesData: TautulliGraphHelper().titlesData(data),
borderData: TautulliGraphHelper().borderData(),
barGroups: TautulliBarGraphHelper.barGroups(context, data),
barTouchData:
TautulliBarGraphHelper.barTouchData(context, data),
),
),
padding: LunaUI.MARGIN_DEFAULT,
),
),
TautulliGraphHelper().createLegend(data.series!),
],
),
),
];
}
}

View File

@@ -3,7 +3,7 @@ import 'package:lunasea/core.dart';
import 'package:lunasea/modules/settings.dart';
class SettingsDebugMenuRouter extends SettingsPageRouter {
SettingsDebugMenuRouter() : super('/settings/debugmenu');
SettingsDebugMenuRouter() : super('/settings/debug_menu');
@override
Widget widget() => _Widget();
@@ -33,7 +33,7 @@ class _State extends State<_Widget> with LunaScrollControllerMixin {
PreferredSizeWidget _appBar() {
return LunaAppBar(
title: 'Debug Menu',
title: 'settings.DebugMenu'.tr(),
scrollControllers: [scrollController],
);
}
@@ -42,6 +42,13 @@ class _State extends State<_Widget> with LunaScrollControllerMixin {
return LunaListView(
controller: scrollController,
children: [
LunaBlock(
title: 'UI',
trailing: const LunaIconButton(icon: LunaIcons.ARROW_RIGHT),
onTap: () async =>
SettingsSystemDebugMenuUIRouter().navigateTo(context),
),
const LunaHeader(text: 'Boxes'),
LunaBlock(
title: 'Clear Alerts Box',
onTap: () async {

View File

@@ -687,7 +687,7 @@ packages:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.4"
version: "0.6.3"
json_annotation:
dependency: "direct main"
description:
@@ -841,7 +841,7 @@ packages:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.1"
version: "1.8.0"
path_provider:
dependency: "direct main"
description:
@@ -1492,5 +1492,5 @@ packages:
source: hosted
version: "3.1.0"
sdks:
dart: ">=2.16.0-100.0.dev <3.0.0"
dart: ">=2.15.1 <3.0.0"
flutter: ">=2.5.0"