Skip to content

Commit

Permalink
fix: launch review 0.5.1 (#4855)
Browse files Browse the repository at this point in the history
* feat: floating calculations row

* fix: calculate cell overflow + tooltip

* fix: empty text cell should be counted as empty

* fix: empty text cell sohuld not be counted as not empty

* fix: conversion of some field types for calculations

* fix: tooltip + size of duplicate event button

* fix: minor view meta info changes

* fix: apply number format on word/char count

* fix: dart format

* fix: hide arrow for calc values

---------

Co-authored-by: Richard Shiue <[email protected]>
  • Loading branch information
Xazin and richardshiue authored Mar 11, 2024
1 parent 7afae69 commit c48001b
Show file tree
Hide file tree
Showing 12 changed files with 399 additions and 227 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:collection/collection.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class CalendarEventEditor extends StatelessWidget {
Expand Down Expand Up @@ -86,16 +87,22 @@ class EventEditorControls extends StatelessWidget {
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FlowyIconButton(
width: 20,
icon: const FlowySvg(FlowySvgs.m_duplicate_s),
iconColorOnHover: Theme.of(context).colorScheme.onSecondary,
onPressed: () => context.read<CalendarBloc>().add(
CalendarEvent.duplicateEvent(
rowController.viewId,
rowController.rowId,
FlowyTooltip(
message: LocaleKeys.calendar_duplicateEvent.tr(),
child: FlowyIconButton(
width: 20,
icon: const FlowySvg(
FlowySvgs.m_duplicate_s,
size: Size.square(17),
),
iconColorOnHover: Theme.of(context).colorScheme.onSecondary,
onPressed: () => context.read<CalendarBloc>().add(
CalendarEvent.duplicateEvent(
rowController.viewId,
rowController.rowId,
),
),
),
),
),
const HSpace(8.0),
FlowyIconButton(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@ extension AvailableCalculations on FieldType {
CalculationType.Count,
];

// These FieldTypes cannot be empty, no need to count empty/non-empty
if (![FieldType.Checkbox, FieldType.LastEditedTime, FieldType.CreatedTime]
.contains(this)) {
// These FieldTypes cannot be empty, or might hold secondary
// data causing them to be seen as not empty when in fact they
// are empty.
if (![
FieldType.URL,
FieldType.Checkbox,
FieldType.LastEditedTime,
FieldType.CreatedTime,
].contains(this)) {
calculationTypes.addAll([
CalculationType.CountEmpty,
CalculationType.CountNonEmpty,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:linked_scroll_controller/linked_scroll_controller.dart';

import '../../application/database_controller.dart';
import '../../application/row/row_cache.dart';
import '../../application/row/row_controller.dart';
import '../../tab_bar/tab_bar_view.dart';
import '../../widgets/row/row_detail.dart';
Expand Down Expand Up @@ -259,7 +258,7 @@ class _GridHeader extends StatelessWidget {
}
}

class _GridRows extends StatelessWidget {
class _GridRows extends StatefulWidget {
const _GridRows({
required this.viewId,
required this.scrollController,
Expand All @@ -268,31 +267,49 @@ class _GridRows extends StatelessWidget {
final String viewId;
final GridScrollController scrollController;

@override
State<_GridRows> createState() => _GridRowsState();
}

class _GridRowsState extends State<_GridRows> {
bool showFloatingCalculations = false;

@override
void initState() {
super.initState();
_evaluateFloatingCalculations();
}

void _evaluateFloatingCalculations() {
WidgetsBinding.instance.addPostFrameCallback((_) {
setState(() {
// maxScrollExtent is 0.0 if scrolling is not possible
showFloatingCalculations = widget
.scrollController.verticalController.position.maxScrollExtent >
0;
});
});
}

@override
Widget build(BuildContext context) {
return BlocBuilder<GridBloc, GridState>(
buildWhen: (previous, current) => previous.fields != current.fields,
builder: (context, state) {
return Flexible(
child: _WrapScrollView(
scrollController: scrollController,
scrollController: widget.scrollController,
contentWidth: GridLayout.headerWidth(state.fields),
child: BlocBuilder<GridBloc, GridState>(
buildWhen: (previous, current) => current.reason.maybeWhen(
reorderRows: () => true,
reorderSingleRow: (reorderRow, rowInfo) => true,
delete: (item) => true,
insert: (item) => true,
orElse: () => true,
),
child: BlocConsumer<GridBloc, GridState>(
listenWhen: (previous, current) =>
previous.rowCount != current.rowCount,
listener: (context, state) => _evaluateFloatingCalculations(),
builder: (context, state) {
final rowInfos = state.rowInfos;
final behavior = ScrollConfiguration.of(context).copyWith(
scrollbars: false,
);
return ScrollConfiguration(
behavior: behavior,
child: _renderList(context, state, rowInfos),
behavior: ScrollConfiguration.of(context).copyWith(
scrollbars: false,
),
child: _renderList(context, state),
);
},
),
Expand All @@ -305,42 +322,65 @@ class _GridRows extends StatelessWidget {
Widget _renderList(
BuildContext context,
GridState state,
List<RowInfo> rowInfos,
) {
final children = rowInfos.mapIndexed((index, rowInfo) {
final children = state.rowInfos.mapIndexed((index, rowInfo) {
return _renderRow(
context,
rowInfo.rowId,
isDraggable: state.reorderable,
index: index,
);
}).toList()
..add(const GridRowBottomBar(key: Key('grid_footer')))
..add(
..add(const GridRowBottomBar(key: Key('grid_footer')));

if (showFloatingCalculations) {
children.add(
const SizedBox(
key: Key('calculations_bottom_padding'),
height: 36,
),
);
} else {
children.add(
GridCalculationsRow(
key: const Key('grid_calculations'),
viewId: viewId,
viewId: widget.viewId,
),
);
}

return ReorderableListView.builder(
/// This is a workaround related to
/// https://github.com/flutter/flutter/issues/25652
cacheExtent: 5000,
scrollController: scrollController.verticalController,
buildDefaultDragHandles: false,
proxyDecorator: (child, index, animation) => Material(
color: Colors.white.withOpacity(.1),
child: Opacity(opacity: .5, child: child),
),
onReorder: (fromIndex, newIndex) {
final toIndex = newIndex > fromIndex ? newIndex - 1 : newIndex;
if (fromIndex != toIndex) {
context.read<GridBloc>().add(GridEvent.moveRow(fromIndex, toIndex));
}
},
itemCount: children.length,
itemBuilder: (context, index) => children[index],
children.add(const SizedBox(key: Key('footer_padding'), height: 10));

return Stack(
children: [
Positioned.fill(
child: ReorderableListView.builder(
/// This is a workaround related to
/// https://github.com/flutter/flutter/issues/25652
cacheExtent: 5000,
scrollController: widget.scrollController.verticalController,
physics: const ClampingScrollPhysics(),
buildDefaultDragHandles: false,
proxyDecorator: (child, index, animation) => Material(
color: Colors.white.withOpacity(.1),
child: Opacity(opacity: .5, child: child),
),
onReorder: (fromIndex, newIndex) {
final toIndex = newIndex > fromIndex ? newIndex - 1 : newIndex;
if (fromIndex != toIndex) {
context
.read<GridBloc>()
.add(GridEvent.moveRow(fromIndex, toIndex));
}
},
itemCount: children.length,
itemBuilder: (context, index) => children[index],
),
),
if (showFloatingCalculations) ...[
_PositionedCalculationsRow(viewId: widget.viewId),
],
],
);
}

Expand Down Expand Up @@ -378,21 +418,16 @@ class _GridRows extends StatelessWidget {
openDetailPage: (context, cellBuilder) {
FlowyOverlay.show(
context: context,
builder: (BuildContext context) {
return RowDetailPage(
rowController: rowController,
databaseController: databaseController,
);
},
builder: (_) => RowDetailPage(
rowController: rowController,
databaseController: databaseController,
),
);
},
);

if (animation != null) {
return SizeTransition(
sizeFactor: animation,
child: child,
);
return SizeTransition(sizeFactor: animation, child: child);
}

return child;
Expand All @@ -413,12 +448,14 @@ class _WrapScrollView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ScrollbarListStack(
includeInsets: false,
axis: Axis.vertical,
controller: scrollController.verticalController,
barSize: GridSize.scrollBarSize,
autoHideScrollbar: false,
child: StyledSingleChildScrollView(
autoHideScrollbar: false,
includeInsets: false,
controller: scrollController.horizontalController,
axis: Axis.horizontal,
child: SizedBox(
Expand All @@ -429,3 +466,49 @@ class _WrapScrollView extends StatelessWidget {
);
}
}

/// This Widget is used to show the Calculations Row at the bottom of the Grids ScrollView
/// when the ScrollView is scrollable.
///
class _PositionedCalculationsRow extends StatefulWidget {
const _PositionedCalculationsRow({
required this.viewId,
});

final String viewId;

@override
State<_PositionedCalculationsRow> createState() =>
_PositionedCalculationsRowState();
}

class _PositionedCalculationsRowState
extends State<_PositionedCalculationsRow> {
@override
Widget build(BuildContext context) {
return Positioned(
bottom: 0,
left: 0,
right: 0,
child: Container(
margin: EdgeInsets.only(left: GridSize.horizontalHeaderPadding),
padding: const EdgeInsets.only(bottom: 10),
decoration: BoxDecoration(
color: Theme.of(context).canvasColor,
border: Border(
top: BorderSide(color: Theme.of(context).dividerColor),
),
),
child: SizedBox(
height: 36,
width: double.infinity,
child: GridCalculationsRow(
key: const Key('floating_grid_calculations'),
viewId: widget.viewId,
includeDefaultInsets: false,
),
),
),
);
}
}
Loading

0 comments on commit c48001b

Please sign in to comment.