fix: launch review 0.5.0 (#4735)

* fix: top bar buttons slow respond

* fix: fav button responsive

* fix: add favorite button to database views

* fix: add overflow to calculation

* fix: minor workaround for showing number format prefix

* fix: clear calculation on empty field cells

* fix: average calculation should not have def value

* fix: cargo fmt
This commit is contained in:
Mathias Mogensen 2024-02-25 21:32:44 +01:00 committed by GitHub
parent 609557c357
commit c9dc24a13c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 84 additions and 72 deletions

View File

@ -3,12 +3,14 @@ import 'package:flutter/material.dart';
import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/plugins/database/application/calculations/calculation_type_ext.dart'; import 'package:appflowy/plugins/database/application/calculations/calculation_type_ext.dart';
import 'package:appflowy/plugins/database/application/field/field_info.dart'; import 'package:appflowy/plugins/database/application/field/field_info.dart';
import 'package:appflowy/plugins/database/application/field/type_option/number_format_bloc.dart';
import 'package:appflowy/plugins/database/grid/application/calculations/calculations_bloc.dart'; import 'package:appflowy/plugins/database/grid/application/calculations/calculations_bloc.dart';
import 'package:appflowy/plugins/database/grid/presentation/widgets/calculations/calculation_selector.dart'; import 'package:appflowy/plugins/database/grid/presentation/widgets/calculations/calculation_selector.dart';
import 'package:appflowy/plugins/database/grid/presentation/widgets/calculations/calculation_type_item.dart'; import 'package:appflowy/plugins/database/grid/presentation/widgets/calculations/calculation_type_item.dart';
import 'package:appflowy/plugins/database/grid/presentation/widgets/calculations/remove_calculation_button.dart'; import 'package:appflowy/plugins/database/grid/presentation/widgets/calculations/remove_calculation_button.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/calculation_entities.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/calculation_entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/number_entities.pb.dart';
import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:appflowy_popover/appflowy_popover.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';
@ -37,6 +39,8 @@ class _CalculateCellState extends State<CalculateCell> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final prefix = _prefixFromFieldType(widget.fieldInfo.fieldType);
return SizedBox( return SizedBox(
height: 35, height: 35,
width: widget.width, width: widget.width,
@ -85,14 +89,16 @@ class _CalculateCellState extends State<CalculateCell> {
}, },
child: widget.fieldInfo.fieldType == FieldType.Number child: widget.fieldInfo.fieldType == FieldType.Number
? widget.calculation != null ? widget.calculation != null
? _showCalculateValue(context) ? _showCalculateValue(context, prefix)
: CalculationSelector(isSelected: isSelected) : CalculationSelector(isSelected: isSelected)
: const SizedBox.shrink(), : const SizedBox.shrink(),
), ),
); );
} }
Widget _showCalculateValue(BuildContext context) { Widget _showCalculateValue(BuildContext context, String? prefix) {
prefix = prefix != null ? '$prefix ' : '';
return FlowyButton( return FlowyButton(
radius: BorderRadius.zero, radius: BorderRadius.zero,
hoverColor: AFThemeExtension.of(context).lightGreyHover, hoverColor: AFThemeExtension.of(context).lightGreyHover,
@ -110,8 +116,9 @@ class _CalculateCellState extends State<CalculateCell> {
const HSpace(8), const HSpace(8),
Flexible( Flexible(
child: FlowyText( child: FlowyText(
_withoutTrailingZeros(widget.calculation!.value), '$prefix${_withoutTrailingZeros(widget.calculation!.value)}',
color: AFThemeExtension.of(context).textColor, color: AFThemeExtension.of(context).textColor,
overflow: TextOverflow.ellipsis,
), ),
), ),
], ],
@ -134,4 +141,12 @@ class _CalculateCellState extends State<CalculateCell> {
return value; return value;
} }
String? _prefixFromFieldType(FieldType fieldType) => switch (fieldType) {
FieldType.Number =>
NumberTypeOptionPB.fromBuffer(widget.fieldInfo.field.typeOptionData)
.format
.iconSymbol(),
_ => null,
};
} }

View File

@ -8,6 +8,7 @@ import 'package:appflowy/plugins/util.dart';
import 'package:appflowy/startup/plugin/plugin.dart'; import 'package:appflowy/startup/plugin/plugin.dart';
import 'package:appflowy/workspace/application/view_info/view_info_bloc.dart'; import 'package:appflowy/workspace/application/view_info/view_info_bloc.dart';
import 'package:appflowy/workspace/presentation/home/home_stack.dart'; import 'package:appflowy/workspace/presentation/home/home_stack.dart';
import 'package:appflowy/workspace/presentation/widgets/favorite_button.dart';
import 'package:appflowy/workspace/presentation/widgets/more_view_actions/more_view_actions.dart'; import 'package:appflowy/workspace/presentation/widgets/more_view_actions/more_view_actions.dart';
import 'package:appflowy/workspace/presentation/widgets/tab_bar_item.dart'; import 'package:appflowy/workspace/presentation/widgets/tab_bar_item.dart';
import 'package:appflowy/workspace/presentation/widgets/view_title_bar.dart'; import 'package:appflowy/workspace/presentation/widgets/view_title_bar.dart';
@ -270,6 +271,8 @@ class DatabasePluginWidgetBuilder extends PluginWidgetBuilder {
children: [ children: [
DatabaseShareButton(key: ValueKey(view.id), view: view), DatabaseShareButton(key: ValueKey(view.id), view: view),
const HSpace(4), const HSpace(4),
ViewFavoriteButton(view: view),
const HSpace(4),
MoreViewActions(view: view, isDocument: false), MoreViewActions(view: view, isDocument: false),
], ],
), ),

View File

@ -1,3 +1,5 @@
import 'package:flutter/material.dart';
import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/plugins/database/application/share_bloc.dart'; import 'package:appflowy/plugins/database/application/share_bloc.dart';
import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/startup/startup.dart';
@ -11,7 +13,6 @@ import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/file_picker/file_picker_service.dart'; import 'package:flowy_infra/file_picker/file_picker_service.dart';
import 'package:flowy_infra_ui/widget/rounded_button.dart'; import 'package:flowy_infra_ui/widget/rounded_button.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
class DatabaseShareButton extends StatelessWidget { class DatabaseShareButton extends StatelessWidget {
@ -101,13 +102,14 @@ class DatabaseShareActionListState extends State<DatabaseShareActionList> {
actions: ShareAction.values actions: ShareAction.values
.map((action) => ShareActionWrapper(action)) .map((action) => ShareActionWrapper(action))
.toList(), .toList(),
buildChild: (controller) { buildChild: (controller) => Listener(
return RoundedTextButton( onPointerDown: (_) => controller.show(),
child: RoundedTextButton(
title: LocaleKeys.shareAction_buttonText.tr(), title: LocaleKeys.shareAction_buttonText.tr(),
textColor: Theme.of(context).colorScheme.onPrimary, textColor: Theme.of(context).colorScheme.onPrimary,
onPressed: () => controller.show(), onPressed: () {},
); ),
}, ),
onSelected: (action, controller) async { onSelected: (action, controller) async {
switch (action.inner) { switch (action.inner) {
case ShareAction.csv: case ShareAction.csv:

View File

@ -6,12 +6,12 @@ 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/plugins/document/application/document_appearance_cubit.dart'; import 'package:appflowy/plugins/document/application/document_appearance_cubit.dart';
import 'package:appflowy/plugins/document/document_page.dart'; import 'package:appflowy/plugins/document/document_page.dart';
import 'package:appflowy/plugins/document/presentation/favorite/favorite_button.dart';
import 'package:appflowy/plugins/document/presentation/share/share_button.dart'; import 'package:appflowy/plugins/document/presentation/share/share_button.dart';
import 'package:appflowy/plugins/util.dart'; import 'package:appflowy/plugins/util.dart';
import 'package:appflowy/startup/plugin/plugin.dart'; import 'package:appflowy/startup/plugin/plugin.dart';
import 'package:appflowy/workspace/application/view_info/view_info_bloc.dart'; import 'package:appflowy/workspace/application/view_info/view_info_bloc.dart';
import 'package:appflowy/workspace/presentation/home/home_stack.dart'; import 'package:appflowy/workspace/presentation/home/home_stack.dart';
import 'package:appflowy/workspace/presentation/widgets/favorite_button.dart';
import 'package:appflowy/workspace/presentation/widgets/more_view_actions/more_view_actions.dart'; import 'package:appflowy/workspace/presentation/widgets/more_view_actions/more_view_actions.dart';
import 'package:appflowy/workspace/presentation/widgets/tab_bar_item.dart'; import 'package:appflowy/workspace/presentation/widgets/tab_bar_item.dart';
import 'package:appflowy/workspace/presentation/widgets/view_title_bar.dart'; import 'package:appflowy/workspace/presentation/widgets/view_title_bar.dart';
@ -140,7 +140,7 @@ class DocumentPluginWidgetBuilder extends PluginWidgetBuilder
children: [ children: [
DocumentShareButton(key: ValueKey(view.id), view: view), DocumentShareButton(key: ValueKey(view.id), view: view),
const HSpace(4), const HSpace(4),
DocumentFavoriteButton( ViewFavoriteButton(
key: ValueKey('favorite_button_${view.id}'), key: ValueKey('favorite_button_${view.id}'),
view: view, view: view,
), ),

View File

@ -1,3 +1,5 @@
import 'package:flutter/material.dart';
import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/plugins/document/application/share_bloc.dart'; import 'package:appflowy/plugins/document/application/share_bloc.dart';
import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/startup/startup.dart';
@ -12,7 +14,6 @@ import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/file_picker/file_picker_service.dart'; import 'package:flowy_infra/file_picker/file_picker_service.dart';
import 'package:flowy_infra_ui/widget/rounded_button.dart'; import 'package:flowy_infra_ui/widget/rounded_button.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
class DocumentShareButton extends StatelessWidget { class DocumentShareButton extends StatelessWidget {
@ -108,13 +109,14 @@ class ShareActionListState extends State<ShareActionList> {
actions: ShareAction.values actions: ShareAction.values
.map((action) => ShareActionWrapper(action)) .map((action) => ShareActionWrapper(action))
.toList(), .toList(),
buildChild: (controller) { buildChild: (controller) => Listener(
return RoundedTextButton( onPointerDown: (_) => controller.show(),
child: RoundedTextButton(
title: LocaleKeys.shareAction_buttonText.tr(), title: LocaleKeys.shareAction_buttonText.tr(),
onPressed: () => controller.show(), onPressed: () {},
textColor: Theme.of(context).colorScheme.onPrimary, textColor: Theme.of(context).colorScheme.onPrimary,
); ),
}, ),
onSelected: (action, controller) async { onSelected: (action, controller) async {
switch (action.inner) { switch (action.inner) {
case ShareAction.markdown: case ShareAction.markdown:

View File

@ -1,15 +1,17 @@
import 'package:flutter/material.dart';
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_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/theme_extension.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart';
import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
class DocumentFavoriteButton extends StatelessWidget { class ViewFavoriteButton extends StatelessWidget {
const DocumentFavoriteButton({ const ViewFavoriteButton({
super.key, super.key,
required this.view, required this.view,
}); });
@ -21,34 +23,27 @@ class DocumentFavoriteButton extends StatelessWidget {
return BlocBuilder<FavoriteBloc, FavoriteState>( return BlocBuilder<FavoriteBloc, FavoriteState>(
builder: (context, state) { builder: (context, state) {
final isFavorite = state.views.any((v) => v.id == view.id); final isFavorite = state.views.any((v) => v.id == view.id);
return _buildFavoriteButton(context, isFavorite); return Listener(
onPointerDown: (_) =>
context.read<FavoriteBloc>().add(FavoriteEvent.toggle(view)),
child: FlowyTooltip(
message: isFavorite
? LocaleKeys.button_removeFromFavorites.tr()
: LocaleKeys.button_addToFavorites.tr(),
child: FlowyHover(
resetHoverOnRebuild: false,
child: Padding(
padding: const EdgeInsets.all(6),
child: FlowySvg(
isFavorite ? FlowySvgs.favorite_s : FlowySvgs.unfavorite_s,
size: const Size(18, 18),
color: AFThemeExtension.of(context).warning,
),
),
),
),
);
}, },
); );
} }
Widget _buildFavoriteButton(BuildContext context, bool isFavorite) {
return FlowyTooltip(
message: isFavorite
? LocaleKeys.button_removeFromFavorites.tr()
: LocaleKeys.button_addToFavorites.tr(),
child: FlowyHover(
child: GestureDetector(
onTap: () =>
context.read<FavoriteBloc>().add(FavoriteEvent.toggle(view)),
child: _buildFavoriteIcon(context, isFavorite),
),
),
);
}
Widget _buildFavoriteIcon(BuildContext context, bool isFavorite) {
return Padding(
padding: const EdgeInsets.all(6),
child: FlowySvg(
isFavorite ? FlowySvgs.favorite_s : FlowySvgs.unfavorite_s,
size: const Size(18, 18),
color: Theme.of(context).iconTheme.color,
),
);
}
} }

View File

@ -216,12 +216,13 @@ class _ViewTitleState extends State<_ViewTitle> {
); );
if (widget.behavior == _ViewTitleBehavior.uneditable) { if (widget.behavior == _ViewTitleBehavior.uneditable) {
return FlowyButton( return Listener(
useIntrinsicWidth: true, onPointerDown: (_) => context.read<TabsBloc>().openPlugin(widget.view),
onTap: () { child: FlowyButton(
context.read<TabsBloc>().openPlugin(widget.view); useIntrinsicWidth: true,
}, onTap: () {},
text: child, text: child,
),
); );
} }

View File

@ -1,7 +1,6 @@
use std::str::FromStr; use std::str::FromStr;
use std::sync::Arc; use std::sync::Arc;
use collab::core::any_map::AnyMapExtension;
use collab_database::fields::Field; use collab_database::fields::Field;
use collab_database::rows::{Row, RowCell}; use collab_database::rows::{Row, RowCell};
use flowy_error::FlowyResult; use flowy_error::FlowyResult;
@ -227,25 +226,18 @@ impl CalculationsController {
async fn handle_row_changed(&self, row: Row) { async fn handle_row_changed(&self, row: Row) {
let cells = row.cells.iter(); let cells = row.cells.iter();
let mut updates = vec![]; let mut updates = vec![];
// Iterate each cell in the row // Iterate each cell in the row
for cell in cells { for cell in cells {
let field_id = cell.0; let field_id = cell.0;
let value = cell.1.value().get("data"); let calculation = self.delegate.get_calculation(&self.view_id, field_id).await;
if let Some(calculation) = calculation {
let update = self.get_updated_calculation(calculation.clone()).await;
// Only continue if there is a value in the cell if let Some(update) = update {
if let Some(_cell_value) = value { updates.push(CalculationPB::from(&update));
let calculation = self.delegate.get_calculation(&self.view_id, field_id).await; self.delegate.update_calculation(&self.view_id, update);
if let Some(calculation) = calculation {
let update = self.get_updated_calculation(calculation.clone()).await;
if let Some(update) = update {
updates.push(CalculationPB::from(&update));
self.delegate.update_calculation(&self.view_id, update);
}
} }
} }
} }
@ -262,17 +254,19 @@ impl CalculationsController {
} }
async fn get_updated_calculation(&self, calculation: Arc<Calculation>) -> Option<Calculation> { async fn get_updated_calculation(&self, calculation: Arc<Calculation>) -> Option<Calculation> {
let row_cells = self let field_cells = self
.delegate .delegate
.get_cells_for_field(&self.view_id, &calculation.field_id) .get_cells_for_field(&self.view_id, &calculation.field_id)
.await; .await;
let field = self.delegate.get_field(&calculation.field_id)?; let field = self.delegate.get_field(&calculation.field_id)?;
if !row_cells.is_empty() { if field_cells.is_empty() {
return Some(calculation.with_value(String::new()));
} else {
let value = let value =
self self
.calculations_service .calculations_service
.calculate(&field, calculation.calculation_type, row_cells); .calculate(&field, calculation.calculation_type, field_cells);
if value != calculation.value { if value != calculation.value {
return Some(calculation.with_value(value)); return Some(calculation.with_value(value));

View File

@ -49,7 +49,7 @@ impl CalculationsService {
if len > 0.0 { if len > 0.0 {
format!("{:.5}", sum / len) format!("{:.5}", sum / len)
} else { } else {
"0".to_owned() String::new()
} }
} }