1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-11-25 22:39:22 +00:00

Start to build Forez main route

This commit is contained in:
Pierre HUBERT 2021-04-24 09:46:53 +02:00
parent 1de7e699d7
commit 229491cd79
6 changed files with 203 additions and 8 deletions

View File

@ -34,7 +34,7 @@ void main() {
appName: "#Forez", appName: "#Forez",
appQuickDescription: tr("Events organisation in Forez plain"), appQuickDescription: tr("Events organisation in Forez plain"),
toursEntriesBuilder: buildTour, toursEntriesBuilder: buildTour,
mainRouteBuilder: (c) => ForezRoute(), mainRouteBuilder: (c, k) => ForezRoute(key: k),
)); ));
HttpOverrides.global = new MyHttpOverride(); HttpOverrides.global = new MyHttpOverride();

View File

@ -2,6 +2,10 @@ import 'package:comunic/models/conversation.dart';
import 'package:comunic/ui/dialogs/alert_dialog.dart'; import 'package:comunic/ui/dialogs/alert_dialog.dart';
import 'package:comunic/ui/routes/main_route/main_route.dart'; import 'package:comunic/ui/routes/main_route/main_route.dart';
import 'package:comunic/ui/routes/main_route/page_info.dart'; import 'package:comunic/ui/routes/main_route/page_info.dart';
import 'package:comunic/ui/screens/conversations_list_screen.dart';
import 'package:comunic/ui/widgets/safe_state.dart';
import 'package:comunic/ui/widgets/status_widget.dart';
import 'package:comunic/ui/widgets/tab_transition_widget.dart';
import 'package:comunic/utils/intl_utils.dart'; import 'package:comunic/utils/intl_utils.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -24,9 +28,8 @@ class _MainRouteState extends MainController {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return StatusWidget(
color: Colors.blueAccent, child: (c) => SafeArea(
child: SafeArea(
// Avoid OS areas // Avoid OS areas
child: WillPopScope( child: WillPopScope(
onWillPop: willPop, onWillPop: willPop,
@ -52,14 +55,112 @@ class _MainRouteState extends MainController {
} }
} }
enum _PopupMenuItems { ACTION_SETTINGS, ACTION_SIGN_OUT }
class ForezRouteBody extends StatefulWidget { class ForezRouteBody extends StatefulWidget {
@override @override
_ForezRouteBodyState createState() => _ForezRouteBodyState(); _ForezRouteBodyState createState() => _ForezRouteBodyState();
} }
class _ForezRouteBodyState extends State<ForezRouteBody> { class _ForezRouteBodyState extends SafeState<ForezRouteBody> {
@override
void initState() {
super.initState();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Text("yolo"); return DefaultTabController(
length: _tabs.length,
child: Scaffold(
appBar: AppBar(
title: Text("#Forez"),
actions: <Widget>[_buildPopupMenuButton()],
bottom: TabBar(tabs: _tabs),
),
body: TabBarView(children: _tabsPages),
),
);
} }
Widget _buildPopupMenuButton() => PopupMenuButton<_PopupMenuItems>(
itemBuilder: (c) => [
PopupMenuItem(
child: Text(tr("Settings")),
value: _PopupMenuItems.ACTION_SETTINGS,
),
PopupMenuItem(
child: Text(tr("Sign out")),
value: _PopupMenuItems.ACTION_SIGN_OUT,
),
],
onSelected: _onMenuSelection,
);
void _onMenuSelection(_PopupMenuItems value) {
switch (value) {
case _PopupMenuItems.ACTION_SETTINGS:
MainController.of(context).openSettings();
break;
case _PopupMenuItems.ACTION_SIGN_OUT:
// TODO : handle logout
break;
}
}
final _list = <_Tab>[
// Presence tab
_Tab(
icon: Icons.calendar_today,
title: tr("Presence"),
widget: Text("Presence"),
),
// Conversations tab
_Tab(
icon: Icons.question_answer,
title: tr("Conversations"),
widget: ConversationsListScreen(),
isUnread: (c) => StatusWidgetState.of(c).unreadConversations > 0,
),
// Directory tab
_Tab(
icon: Icons.import_contacts,
title: tr("Directory"),
widget: Text("Directory"),
),
];
List<Tab> get _tabs => _list
.map((e) => Tab(
icon: Stack(
children: <Widget>[
Icon(e.icon),
e.isUnread?.call(context) ?? false
? Container(color: Colors.red, width: 10, height: 10)
: Container(width: 0)
],
),
text: e.title))
.toList();
List<Widget> get _tabsPages =>
_list.map((e) => TabTransitionWidget(e.widget)).toList();
}
class _Tab {
final IconData icon;
final String title;
final Widget widget;
final bool Function(BuildContext) isUnread;
const _Tab({
@required this.icon,
@required this.title,
@required this.widget,
this.isUnread,
}) : assert(icon != null),
assert(title != null),
assert(widget != null);
} }

View File

@ -28,7 +28,7 @@ class Config {
final TourEntriesBuilder toursEntriesBuilder; final TourEntriesBuilder toursEntriesBuilder;
// Custom main application route // Custom main application route
final Widget Function(BuildContext) mainRouteBuilder; final Widget Function(BuildContext, GlobalKey) mainRouteBuilder;
const Config({ const Config({
@required this.apiServerName, @required this.apiServerName,

View File

@ -108,7 +108,7 @@ class _InitializeWidgetState extends SafeState<InitializeWidget> {
if (_error || !WebSocketHelper.isConnected()) return _buildNonReadyWidget(); if (_error || !WebSocketHelper.isConnected()) return _buildNonReadyWidget();
if (config().mainRouteBuilder != null) if (config().mainRouteBuilder != null)
return config().mainRouteBuilder(context); return config().mainRouteBuilder(context, mainControllerKey);
return isTablet(context) return isTablet(context)
? TabletRoute(key: mainControllerKey) ? TabletRoute(key: mainControllerKey)

View File

@ -0,0 +1,62 @@
import 'package:comunic/helpers/events_helper.dart';
import 'package:comunic/helpers/notifications_helper.dart';
import 'package:comunic/ui/widgets/safe_state.dart';
import 'package:comunic/utils/log_utils.dart';
import 'package:flutter/material.dart';
/// Status widget
///
/// Store for its children information about the number of unread conversations
/// & the number of unread conversations
///
/// @author Pierre Hubert
class StatusWidget extends StatefulWidget {
final Widget Function(BuildContext) child;
const StatusWidget({
Key key,
@required this.child,
}) : assert(child != null),
super(key: key);
@override
StatusWidgetState createState() => StatusWidgetState();
}
class StatusWidgetState extends SafeState<StatusWidget> {
int unreadNotifications = 0;
int unreadConversations = 0;
Future<void> init() async {
try {
final res = await NotificationsHelper().countUnread();
unreadNotifications = res.notifications;
unreadConversations = res.conversations;
setState(() {});
} catch (e, s) {
logError(e, s);
print("Failed to initialize StatusWidget!");
}
}
@override
void initState() {
init();
super.initState();
listenChangeState<NewNumberNotifsEvent>(
(e) => unreadNotifications = e.newNum);
listenChangeState<NewNumberUnreadConversations>(
(e) => unreadConversations = e.newNum);
}
/// Find an ancestor of this object
static StatusWidgetState of(BuildContext c) =>
c.findAncestorStateOfType<StatusWidgetState>();
@override
Widget build(BuildContext context) => widget.child(context);
}

View File

@ -0,0 +1,32 @@
import 'package:flutter/material.dart';
class TabTransitionWidget extends StatefulWidget {
final Widget child;
const TabTransitionWidget(this.child, {Key key})
: assert(child != null),
super(key: key);
@override
_TabTransitionWidgetState createState() => _TabTransitionWidgetState();
}
class _TabTransitionWidgetState extends State<TabTransitionWidget> {
var _show = false;
@override
void initState() {
super.initState();
Future.delayed(Duration(microseconds: 10)).then((value) {
if (mounted) setState(() => _show = true);
});
}
@override
Widget build(BuildContext context) {
if (!_show)
return Center(child: CircularProgressIndicator());
else
return widget.child;
}
}