mirror of
https://github.com/jagandeepbrar/lunasea.git
synced 2026-08-31 12:42:34 +00:00
feat(debug): debug page for multiple UI elements
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export 'debug_menu/pages.dart';
|
||||
export 'debug_menu/route.dart';
|
||||
|
||||
1
lib/modules/settings/routes/debug_menu/pages.dart
Normal file
1
lib/modules/settings/routes/debug_menu/pages.dart
Normal file
@@ -0,0 +1 @@
|
||||
export 'pages/ui.dart';
|
||||
243
lib/modules/settings/routes/debug_menu/pages/ui.dart
Normal file
243
lib/modules/settings/routes/debug_menu/pages/ui.dart
Normal 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!),
|
||||
],
|
||||
),
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user