chore: add calendar_view package (#1690)

* chore: add calendar_view package

* chore: improve calendar navigator

* style: improve readability

* chore: localization and moving constants
This commit is contained in:
Richard Shiue 2023-01-13 21:35:20 +08:00 committed by GitHub
parent 9215f5188c
commit 707ea4c8c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 215 additions and 27 deletions

View File

@ -166,7 +166,7 @@
"dark": "Dark Mode",
"system": "Adapt to System"
},
"theme":"Theme"
"theme": "Theme"
},
"files": {
"defaultLocation": "Where your data is stored now",
@ -322,6 +322,12 @@
}
},
"calendar": {
"menuName": "Calendar"
"menuName": "Calendar",
"navigation": {
"today": "Today",
"jumpToday": "Jump to Today",
"previousMonth": "Previous Month",
"nextMonth": "Next Month"
}
}
}

View File

@ -7,6 +7,7 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:flutter/material.dart';
import '../util.dart';
import 'presentation/calendar_page.dart';
class CalendarPluginBuilder extends PluginBuilder {
@override
@ -79,33 +80,10 @@ class CalendarPluginDisplay extends PluginDisplay {
});
});
return BlankPage(key: ValueKey(view.id));
// return BoardPage(key: ValueKey(view.id), view: view);
return CalendarPage(key: ValueKey(view.id));
// return CalendarPage(key: ValueKey(view.id), view: view);
}
@override
List<NavigationItem> get navigationItems => [this];
}
// mark for removal
class BlankPage extends StatefulWidget {
const BlankPage({Key? key}) : super(key: key);
@override
State<BlankPage> createState() => _BlankPageState();
}
class _BlankPageState extends State<BlankPage> {
@override
Widget build(BuildContext context) {
return SizedBox.expand(
child: Container(
color: Theme.of(context).colorScheme.surface,
child: Padding(
padding: const EdgeInsets.all(10),
child: Container(),
),
),
);
}
}

View File

@ -0,0 +1,162 @@
import 'package:app_flowy/generated/locale_keys.g.dart';
import 'package:app_flowy/plugins/grid/presentation/layout/sizes.dart';
import 'package:calendar_view/calendar_view.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/image.dart';
import 'package:flowy_infra/size.dart';
import 'package:flowy_infra/theme_extension.dart';
import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flowy_infra_ui/style_widget/icon_button.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flutter/material.dart';
import 'package:styled_widget/styled_widget.dart';
import 'layout/sizes.dart';
import 'toolbar/calendar_toolbar.dart';
class CalendarPage extends StatelessWidget {
const CalendarPage({super.key});
@override
Widget build(BuildContext context) {
return const CalendarContent();
}
}
class CalendarContent extends StatefulWidget {
const CalendarContent({super.key});
@override
State<CalendarContent> createState() => _CalendarContentState();
}
class _CalendarContentState extends State<CalendarContent> {
late EventController _eventController;
GlobalKey<MonthViewState>? _calendarState;
@override
void initState() {
_eventController = EventController();
_calendarState = GlobalKey<MonthViewState>();
super.initState();
}
@override
Widget build(BuildContext context) {
return CalendarControllerProvider(
controller: _eventController,
child: Column(
children: [
// const _ToolbarBlocAdaptor(),
_toolbar(),
_buildCalendar(_eventController),
],
),
);
}
Widget _toolbar() {
return const CalendarToolbar();
}
Widget _buildCalendar(EventController eventController) {
return Expanded(
child: MonthView(
key: _calendarState,
controller: _eventController,
cellAspectRatio: 1.75,
borderColor: Theme.of(context).dividerColor,
headerBuilder: _headerNavigatorBuilder,
weekDayBuilder: _headerWeekDayBuilder,
cellBuilder: _calendarDayBuilder,
),
);
}
Widget _headerNavigatorBuilder(DateTime currentMonth) {
return Row(
children: [
FlowyText.medium(
DateFormat('MMMM y', context.locale.toLanguageTag())
.format(currentMonth),
),
const Spacer(),
FlowyIconButton(
width: CalendarSize.navigatorButtonWidth,
height: CalendarSize.navigatorButtonHeight,
icon: svgWidget('home/arrow_left'),
tooltipText: LocaleKeys.calendar_navigation_previousMonth.tr(),
hoverColor: AFThemeExtension.of(context).lightGreyHover,
onPressed: () => _calendarState?.currentState?.previousPage(),
),
FlowyTextButton(
LocaleKeys.calendar_navigation_today.tr(),
fillColor: Colors.transparent,
fontWeight: FontWeight.w500,
tooltip: LocaleKeys.calendar_navigation_jumpToday.tr(),
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 4),
hoverColor: AFThemeExtension.of(context).lightGreyHover,
onPressed: () =>
_calendarState?.currentState?.animateToMonth(DateTime.now()),
),
FlowyIconButton(
width: CalendarSize.navigatorButtonWidth,
height: CalendarSize.navigatorButtonHeight,
icon: svgWidget('home/arrow_right'),
tooltipText: LocaleKeys.calendar_navigation_nextMonth.tr(),
hoverColor: AFThemeExtension.of(context).lightGreyHover,
onPressed: () => _calendarState?.currentState?.nextPage(),
),
],
);
}
Widget _headerWeekDayBuilder(day) {
final symbols = DateFormat.EEEE(context.locale.toLanguageTag()).dateSymbols;
final weekDayString = symbols.WEEKDAYS[day];
return Center(
child: Padding(
padding: CalendarSize.daysOfWeekInsets,
child: FlowyText.medium(
weekDayString,
color: Theme.of(context).hintColor,
),
),
);
}
Widget _calendarDayBuilder(date, event, isToday, isInMonth) {
Color dayTextColor = Theme.of(context).colorScheme.onSurface;
Color cellBackgroundColor = Theme.of(context).colorScheme.surface;
String dayString = date.day == 1
? DateFormat('MMM d', context.locale.toLanguageTag()).format(date)
: date.day.toString();
if (isToday) {
dayTextColor = Theme.of(context).colorScheme.onPrimary;
}
if (!isInMonth) {
dayTextColor = Theme.of(context).disabledColor;
cellBackgroundColor = AFThemeExtension.of(context).lightGreyHover;
}
Widget day = Container(
decoration: BoxDecoration(
color: isToday ? Theme.of(context).colorScheme.primary : null,
borderRadius: Corners.s6Border,
),
padding: GridSize.typeOptionContentInsets,
child: FlowyText.medium(
dayString,
color: dayTextColor,
),
);
return Container(
color: cellBackgroundColor,
child: Align(
alignment: Alignment.topRight,
child: day.padding(all: 6.0),
),
);
}
}

View File

@ -0,0 +1,11 @@
import 'package:flutter/widgets.dart';
class CalendarSize {
static double scale = 1;
static double get scrollBarSize => 12 * scale;
static double get navigatorButtonWidth => 20 * scale;
static double get navigatorButtonHeight => 25 * scale;
static EdgeInsets get daysOfWeekInsets =>
EdgeInsets.symmetric(vertical: 10.0 * scale);
}

View File

@ -0,0 +1,23 @@
import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flutter/material.dart';
class CalendarToolbar extends StatelessWidget {
const CalendarToolbar({super.key});
@override
Widget build(BuildContext context) {
return SizedBox(
height: 40,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: const [
FlowyTextButton(
"Settings",
fillColor: Colors.transparent,
padding: EdgeInsets.symmetric(horizontal: 6, vertical: 2),
),
],
),
);
}
}

View File

@ -155,6 +155,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "8.3.2"
calendar_view:
dependency: "direct main"
description:
name: calendar_view
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
characters:
dependency: transitive
description:

View File

@ -93,6 +93,7 @@ dependencies:
percent_indicator: ^4.0.1
appflowy_editor_plugins:
path: packages/appflowy_editor_plugins
calendar_view: ^1.0.1
dev_dependencies:
flutter_lints: ^2.0.1