feat(Module): External modules support (#462)

* feat(Modules): Created definition for external modules
* feat(External Modules): Added database definitions, base route definition, added to exported config
* tweak(Settings): Updated help information message for external modules
* feat(Settings): Ability to add new external module
* feat(External Modules): Implemented external module list
* feat(Settings): Ability to modify and delete external modules
* feat(Settings): Add hints to external module host dialog
* chore(release): Updated CHANGELOG.md
This commit is contained in:
Jagandeep Brar
2021-05-06 02:42:37 -05:00
committed by GitHub
parent aa0ece1ce6
commit 5ab0628e6f
35 changed files with 889 additions and 29 deletions

View File

@@ -0,0 +1 @@
export 'core/router.dart';

View File

@@ -0,0 +1,44 @@
import 'package:fluro/fluro.dart';
import 'package:flutter/material.dart';
import 'package:lunasea/core.dart';
import 'package:lunasea/modules/external_modules.dart';
class ExternalModulesRouter extends LunaModuleRouter {
@override
void defineAllRoutes(FluroRouter router) {
ExternalModulesHomeRouter().defineRoute(router);
}
}
abstract class ExternalModulesPageRouter extends LunaPageRouter {
ExternalModulesPageRouter(String route) : super(route);
@override
void noParameterRouteDefinition(
FluroRouter router, {
bool homeRoute = false,
}) {
router.define(
fullRoute,
handler: Handler(
handlerFunc: (context, params) => widget(),
),
transitionType: LunaRouter.transitionType,
);
}
@override
void withParameterRouteDefinition(
FluroRouter router,
Widget Function(BuildContext, Map<String, List<String>>) handlerFunc, {
bool homeRoute = false,
}) {
router.define(
fullRoute,
handler: Handler(
handlerFunc: (context, params) => handlerFunc(context, params),
),
transitionType: LunaRouter.transitionType,
);
}
}

View File

@@ -0,0 +1 @@
export 'routes/external_modules.dart';

View File

@@ -0,0 +1,2 @@
export 'external_modules/route.dart';
export 'external_modules/widgets.dart';

View File

@@ -0,0 +1,72 @@
import 'package:flutter/material.dart';
import 'package:lunasea/core.dart';
import 'package:lunasea/modules/external_modules.dart';
class ExternalModulesHomeRouter extends ExternalModulesPageRouter {
ExternalModulesHomeRouter() : super('/externalmodules');
@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 {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return LunaScaffold(
scaffoldKey: _scaffoldKey,
appBar: _appBar(),
drawer: _drawer(),
body: _body(),
);
}
Widget _appBar() {
return LunaAppBar(
useDrawer: true,
title: LunaModule.EXTERNAL_MODULES.name,
scrollControllers: [scrollController],
);
}
Widget _drawer() => LunaDrawer(page: LunaModule.EXTERNAL_MODULES.key);
Widget _body() {
if ((Database.externalModulesBox.length ?? 0) == 0) {
return LunaMessage.moduleNotEnabled(
context: context,
module: LunaModule.EXTERNAL_MODULES.name,
);
}
return LunaListView(
controller: scrollController,
children: _list,
);
}
List get _list {
List<ExternalModulesModuleTile> list = List.generate(
Database.externalModulesBox.length,
(index) => ExternalModulesModuleTile(
module: Database.externalModulesBox.getAt(index),
),
);
list.sort(
(a, b) => a.module.displayName
.toLowerCase()
.compareTo(b.module.displayName.toLowerCase()),
);
return list;
}
}

View File

@@ -0,0 +1 @@
export 'widgets/module_tile.dart';

View File

@@ -0,0 +1,22 @@
import 'package:flutter/material.dart';
import 'package:lunasea/core.dart';
class ExternalModulesModuleTile extends StatelessWidget {
final ExternalModuleHiveObject module;
ExternalModulesModuleTile({
Key key,
@required this.module,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return LunaListTile(
context: context,
title: LunaText.title(text: module.displayName),
subtitle: LunaText.subtitle(text: module.host),
trailing: LunaIconButton(icon: Icons.arrow_forward_ios_rounded),
onTap: () async => module.host.lunaOpenGenericLink(),
);
}
}