fix: mobile improvements for calendar (#4027)

This commit is contained in:
Mathias Mogensen
2023-11-28 03:13:22 +02:00
committed by GitHub
parent c659cf4ff2
commit bfa9233bd4
14 changed files with 92 additions and 130 deletions

View File

@ -1,8 +1,11 @@
import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/mobile/presentation/widgets/flowy_paginated_bottom_sheet.dart';
import 'package:appflowy/plugins/database_view/application/field/field_controller.dart'; import 'package:appflowy/plugins/database_view/application/field/field_controller.dart';
import 'package:appflowy/plugins/database_view/application/field/field_editor_bloc.dart'; import 'package:appflowy/plugins/database_view/application/field/field_editor_bloc.dart';
import 'package:appflowy/plugins/database_view/application/field/type_option/type_option_context.dart'; import 'package:appflowy/plugins/database_view/application/field/type_option/type_option_context.dart';
import 'package:appflowy/plugins/database_view/application/setting/property_bloc.dart';
import 'package:appflowy/plugins/database_view/widgets/setting/mobile_database_property_editor.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart';
@ -11,7 +14,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'bottom_sheet_action_widget.dart'; import 'bottom_sheet_action_widget.dart';
import 'bottom_sheet_database_field_header.dart';
import 'bottom_sheet_rename_widget.dart'; import 'bottom_sheet_rename_widget.dart';
/// The mobile bottom bar field editor is a two-deep menu. The type option /// The mobile bottom bar field editor is a two-deep menu. The type option
@ -67,30 +69,7 @@ class _MobileDBBottomSheetFieldEditorState
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider<FieldEditorBloc>.value( return BlocProvider<FieldEditorBloc>.value(
value: _fieldEditorBloc, value: _fieldEditorBloc,
child: Padding( child: _buildBody(),
padding: const EdgeInsets.fromLTRB(16, 16, 16, 32),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
_buildHeader(),
const VSpace(16),
_buildBody(),
],
),
),
);
}
Widget _buildHeader() {
return MobileDBFieldBottomSheetHeader(
showBackButton: viewMode == MobileDBBottomSheetViewMode.typeOption,
onBack: () {
if (viewMode == MobileDBBottomSheetViewMode.typeOption) {
setState(() {
viewMode = MobileDBBottomSheetViewMode.general;
});
}
},
); );
} }
@ -100,6 +79,22 @@ class _MobileDBBottomSheetFieldEditorState
onAction: (action) { onAction: (action) {
switch (action) { switch (action) {
case MobileDBBottomSheetGeneralAction.typeOption: case MobileDBBottomSheetGeneralAction.typeOption:
FlowyBottomSheetController.of(context)!.push(
SheetPage(
title: LocaleKeys.grid_field_editProperty.tr(),
body: MobileDatabasePropertyEditor(
padding: EdgeInsets.zero,
viewId: widget.viewId,
fieldInfo:
widget.fieldController.getField(widget.field.id)!,
fieldController: widget.fieldController,
bloc: DatabasePropertyBloc(
viewId: widget.viewId,
fieldController: widget.fieldController,
),
),
),
);
break; break;
case MobileDBBottomSheetGeneralAction.toggleVisibility: case MobileDBBottomSheetGeneralAction.toggleVisibility:
_fieldEditorBloc _fieldEditorBloc

View File

@ -1,52 +0,0 @@
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
class MobileDBFieldBottomSheetHeader extends StatelessWidget {
const MobileDBFieldBottomSheetHeader({
super.key,
required this.showBackButton,
required this.onBack,
});
final bool showBackButton;
final VoidCallback onBack;
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Row(
children: [
// back button
if (showBackButton)
InkWell(
onTap: onBack,
child: const Padding(
padding: EdgeInsets.symmetric(horizontal: 8.0),
child: Icon(
Icons.arrow_back_ios_new_rounded,
size: 24.0,
),
),
),
// field name
Expanded(
child: Text(
LocaleKeys.grid_field_editProperty.tr(),
style: theme.textTheme.labelSmall,
),
),
IconButton(
icon: Icon(
Icons.close,
color: theme.hintColor,
),
onPressed: () {
context.pop();
},
),
],
);
}
}

View File

@ -217,16 +217,16 @@ class MobileViewBottomSheetBody extends StatelessWidget {
: MobileViewBottomSheetBodyAction.addToFavorites, : MobileViewBottomSheetBodyAction.addToFavorites,
), ),
), ),
const VSpace(8),
// help center // Help Center
BottomSheetActionWidget( // const VSpace(8),
svg: FlowySvgs.m_help_center_m, // BottomSheetActionWidget(
text: LocaleKeys.button_helpCenter.tr(), // svg: FlowySvgs.m_help_center_m,
onTap: () => onAction( // text: LocaleKeys.button_helpCenter.tr(),
MobileViewBottomSheetBodyAction.helpCenter, // onTap: () => onAction(
), // MobileViewBottomSheetBodyAction.helpCenter,
), // ),
// ),
], ],
); );
} }

View File

@ -1,6 +1,8 @@
import 'package:appflowy/plugins/database_view/application/row/row_cache.dart'; import 'package:appflowy/plugins/database_view/application/row/row_cache.dart';
import 'package:appflowy/plugins/database_view/calendar/application/calendar_bloc.dart'; import 'package:appflowy/plugins/database_view/calendar/application/calendar_bloc.dart';
import 'package:appflowy/plugins/database_view/calendar/presentation/calendar_event_card.dart'; import 'package:appflowy/plugins/database_view/calendar/presentation/calendar_event_card.dart';
import 'package:calendar_view/calendar_view.dart';
import 'package:collection/collection.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -42,12 +44,17 @@ class _MobileCalendarEventsScreenState
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider.value( return BlocProvider<CalendarBloc>.value(
value: widget.calendarBloc, value: widget.calendarBloc,
child: BlocBuilder<CalendarBloc, CalendarState>( child: BlocBuilder<CalendarBloc, CalendarState>(
buildWhen: (p, c) => p.newEvent != c.newEvent, buildWhen: (p, c) =>
p.newEvent != c.newEvent &&
c.newEvent?.date.withoutTime == widget.date,
builder: (context, state) { builder: (context, state) {
if (state.newEvent?.event != null) { if (state.newEvent?.event != null &&
_events
.none((e) => e.eventId == state.newEvent!.event!.eventId) &&
state.newEvent!.date.withoutTime == widget.date) {
_events.add(state.newEvent!.event!); _events.add(state.newEvent!.event!);
} }
@ -71,17 +78,18 @@ class _MobileCalendarEventsScreenState
child: Column( child: Column(
children: [ children: [
const VSpace(10), const VSpace(10),
...widget.events.map((event) { ..._events.map((event) {
return ListTile( return EventCard(
dense: true, fieldController: widget.calendarBloc.fieldController,
title: EventCard( event: event,
fieldController: widget.calendarBloc.fieldController, viewId: widget.viewId,
event: event, rowCache: widget.rowCache,
viewId: widget.viewId, constraints: const BoxConstraints.expand(),
rowCache: widget.rowCache, autoEdit: false,
constraints: const BoxConstraints.expand(), isDraggable: false,
autoEdit: false, padding: const EdgeInsets.symmetric(
isDraggable: false, horizontal: 12,
vertical: 3,
), ),
); );
}), }),

View File

@ -185,8 +185,8 @@ class _EventIndicator extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Container( Container(
width: 6, width: 7,
height: 6, height: 7,
decoration: BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
color: Theme.of(context).hintColor, color: Theme.of(context).hintColor,
@ -303,8 +303,10 @@ class _DayBadge extends StatelessWidget {
dayTextColor = Theme.of(context).colorScheme.onPrimary; dayTextColor = Theme.of(context).colorScheme.onPrimary;
} }
final double size = PlatformExtension.isMobile ? 20 : 18;
return SizedBox( return SizedBox(
height: 18, height: size,
child: Row( child: Row(
mainAxisAlignment: PlatformExtension.isMobile mainAxisAlignment: PlatformExtension.isMobile
? MainAxisAlignment.center ? MainAxisAlignment.center
@ -322,12 +324,12 @@ class _DayBadge extends StatelessWidget {
color: isToday ? Theme.of(context).colorScheme.primary : null, color: isToday ? Theme.of(context).colorScheme.primary : null,
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
), ),
width: isToday ? 18 : null, width: isToday ? size : null,
height: isToday ? 18 : null, height: isToday ? size : null,
child: Center( child: Center(
child: FlowyText.medium( child: FlowyText.medium(
dayString, dayString,
fontSize: 11, fontSize: PlatformExtension.isMobile ? 12 : 11,
color: dayTextColor, color: dayTextColor,
), ),
), ),

View File

@ -34,6 +34,7 @@ class EventCard extends StatefulWidget {
required this.constraints, required this.constraints,
required this.autoEdit, required this.autoEdit,
this.isDraggable = true, this.isDraggable = true,
this.padding = EdgeInsets.zero,
}); });
final FieldController fieldController; final FieldController fieldController;
@ -43,6 +44,7 @@ class EventCard extends StatefulWidget {
final BoxConstraints constraints; final BoxConstraints constraints;
final bool autoEdit; final bool autoEdit;
final bool isDraggable; final bool isDraggable;
final EdgeInsets padding;
@override @override
State<EventCard> createState() => _EventCardState(); State<EventCard> createState() => _EventCardState();
@ -180,9 +182,12 @@ class _EventCardState extends State<EventCard> {
layoutSettings: settings, layoutSettings: settings,
); );
}, },
child: DecoratedBox( child: Padding(
decoration: decoration, padding: widget.padding,
child: card, child: DecoratedBox(
decoration: decoration,
child: card,
),
), ),
); );

View File

@ -194,10 +194,9 @@ class _CalendarPageState extends State<CalendarPage> {
behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false), behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false),
child: MonthView( child: MonthView(
key: _calendarState, key: _calendarState,
// TODO(Xazin): Border Color on Mobile
controller: _eventController, controller: _eventController,
width: constraints.maxWidth, width: constraints.maxWidth,
cellAspectRatio: PlatformExtension.isMobile ? 1 : 0.6, cellAspectRatio: PlatformExtension.isMobile ? 0.9 : 0.6,
startDay: _weekdayFromInt(firstDayOfWeek), startDay: _weekdayFromInt(firstDayOfWeek),
showBorder: false, showBorder: false,
headerBuilder: _headerNavigatorBuilder, headerBuilder: _headerNavigatorBuilder,

View File

@ -1,8 +1,10 @@
import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart'; import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet_database_field_editor.dart'; import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet_database_field_editor.dart';
import 'package:appflowy/mobile/presentation/widgets/flowy_paginated_bottom_sheet.dart';
import 'package:appflowy/plugins/database_view/application/field/field_info.dart'; import 'package:appflowy/plugins/database_view/application/field/field_info.dart';
import 'package:appflowy/plugins/database_view/grid/application/grid_bloc.dart'; import 'package:appflowy/plugins/database_view/grid/application/grid_bloc.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra/theme_extension.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart';
@ -42,12 +44,15 @@ class MobileFieldButton extends StatelessWidget {
), ),
child: TextButton( child: TextButton(
onLongPress: () { onLongPress: () {
showMobileBottomSheet( showPaginatedBottomSheet(
context: context, context,
builder: (context) => MobileDBBottomSheetFieldEditor( page: SheetPage(
viewId: viewId, title: LocaleKeys.grid_field_editProperty.tr(),
field: field.field, body: MobileDBBottomSheetFieldEditor(
fieldController: fieldController, viewId: viewId,
field: field.field,
fieldController: fieldController,
),
), ),
); );
}, },

View File

@ -190,7 +190,10 @@ extension DatabaseSettingActionExtension on DatabaseSettingAction {
layout.name, layout.name,
color: Theme.of(context).colorScheme.onSurface, color: Theme.of(context).colorScheme.onSurface,
), ),
const Icon(Icons.chevron_right), Icon(
Icons.chevron_right,
color: Theme.of(context).colorScheme.onSurface,
),
], ],
), ),
_ => null, _ => null,

View File

@ -23,12 +23,14 @@ class MobileDatabasePropertyEditor extends StatefulWidget {
required this.fieldInfo, required this.fieldInfo,
required this.fieldController, required this.fieldController,
required this.bloc, required this.bloc,
this.padding = const EdgeInsets.all(16),
}); });
final String viewId; final String viewId;
final FieldInfo fieldInfo; final FieldInfo fieldInfo;
final FieldController fieldController; final FieldController fieldController;
final DatabasePropertyBloc bloc; final DatabasePropertyBloc bloc;
final EdgeInsets padding;
@override @override
State<MobileDatabasePropertyEditor> createState() => State<MobileDatabasePropertyEditor> createState() =>
@ -67,7 +69,7 @@ class _MobileDatabasePropertyEditorState
context.read<FieldEditorBloc>().typeOptionController; context.read<FieldEditorBloc>().typeOptionController;
return Padding( return Padding(
padding: const EdgeInsets.all(16), padding: widget.padding,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [

View File

@ -196,6 +196,7 @@ class _MobileDatabasePropertyCellState
fieldInfo: widget.fieldInfo, fieldInfo: widget.fieldInfo,
fieldController: widget.fieldController, fieldController: widget.fieldController,
bloc: widget.bloc, bloc: widget.bloc,
padding: EdgeInsets.zero,
), ),
), ),
), ),

View File

@ -27,8 +27,7 @@ class ThemeUploadWidget extends StatefulWidget {
class _ThemeUploadWidgetState extends State<ThemeUploadWidget> { class _ThemeUploadWidgetState extends State<ThemeUploadWidget> {
void listen(BuildContext context, DynamicPluginState state) { void listen(BuildContext context, DynamicPluginState state) {
setState(() { setState(() {
state.when( state.whenOrNull(
uninitialized: () => null,
ready: (plugins) { ready: (plugins) {
child = child =
const UploadNewThemeWidget(key: Key('upload_new_theme_widget')); const UploadNewThemeWidget(key: Key('upload_new_theme_widget'));
@ -42,7 +41,7 @@ class _ThemeUploadWidgetState extends State<ThemeUploadWidget> {
key: Key('upload_theme_loading_widget'), key: Key('upload_theme_loading_widget'),
); );
}, },
compilationFailure: (path) { compilationFailure: () {
child = const ThemeUploadFailureWidget( child = const ThemeUploadFailureWidget(
key: Key('upload_theme_failure_widget'), key: Key('upload_theme_failure_widget'),
); );
@ -53,7 +52,6 @@ class _ThemeUploadWidgetState extends State<ThemeUploadWidget> {
.pop(const DynamicPluginState.compilationSuccess()); .pop(const DynamicPluginState.compilationSuccess());
} }
}, },
deletionFailure: (path) {},
); );
}); });
} }

View File

@ -38,9 +38,7 @@ class DynamicPluginBloc extends Bloc<DynamicPluginEvent, DynamicPluginState> {
} }
await FlowyPluginService.instance.addPlugin(plugin); await FlowyPluginService.instance.addPlugin(plugin);
} on PluginCompilationException { } on PluginCompilationException {
// TODO(a-wallen): Remove path from compilation failure return emit(const DynamicPluginState.compilationFailure());
emit(const DynamicPluginState.compilationFailure(path: ''));
return;
} }
emit(const DynamicPluginState.compilationSuccess()); emit(const DynamicPluginState.compilationSuccess());

View File

@ -11,9 +11,7 @@ class DynamicPluginState with _$DynamicPluginState {
required Iterable<FlowyDynamicPlugin> plugins, required Iterable<FlowyDynamicPlugin> plugins,
}) = Ready; }) = Ready;
const factory DynamicPluginState.processing() = _Processing; const factory DynamicPluginState.processing() = _Processing;
const factory DynamicPluginState.compilationFailure({ const factory DynamicPluginState.compilationFailure() = _CompilationFailure;
required String path,
}) = _CompilationFailure;
const factory DynamicPluginState.deletionFailure({ const factory DynamicPluginState.deletionFailure({
required String path, required String path,
}) = _DeletionFailure; }) = _DeletionFailure;