diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/calculations/calculate_cell.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/calculations/calculate_cell.dart index c2ff295212..c39d5e68bc 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/calculations/calculate_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/calculations/calculate_cell.dart @@ -3,12 +3,14 @@ import 'package:flutter/material.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/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/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/remove_calculation_button.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/number_entities.pb.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; @@ -37,6 +39,8 @@ class _CalculateCellState extends State { @override Widget build(BuildContext context) { + final prefix = _prefixFromFieldType(widget.fieldInfo.fieldType); + return SizedBox( height: 35, width: widget.width, @@ -85,14 +89,16 @@ class _CalculateCellState extends State { }, child: widget.fieldInfo.fieldType == FieldType.Number ? widget.calculation != null - ? _showCalculateValue(context) + ? _showCalculateValue(context, prefix) : CalculationSelector(isSelected: isSelected) : const SizedBox.shrink(), ), ); } - Widget _showCalculateValue(BuildContext context) { + Widget _showCalculateValue(BuildContext context, String? prefix) { + prefix = prefix != null ? '$prefix ' : ''; + return FlowyButton( radius: BorderRadius.zero, hoverColor: AFThemeExtension.of(context).lightGreyHover, @@ -110,8 +116,9 @@ class _CalculateCellState extends State { const HSpace(8), Flexible( child: FlowyText( - _withoutTrailingZeros(widget.calculation!.value), + '$prefix${_withoutTrailingZeros(widget.calculation!.value)}', color: AFThemeExtension.of(context).textColor, + overflow: TextOverflow.ellipsis, ), ), ], @@ -134,4 +141,12 @@ class _CalculateCellState extends State { return value; } + + String? _prefixFromFieldType(FieldType fieldType) => switch (fieldType) { + FieldType.Number => + NumberTypeOptionPB.fromBuffer(widget.fieldInfo.field.typeOptionData) + .format + .iconSymbol(), + _ => null, + }; } diff --git a/frontend/appflowy_flutter/lib/plugins/database/tab_bar/tab_bar_view.dart b/frontend/appflowy_flutter/lib/plugins/database/tab_bar/tab_bar_view.dart index f4a74eee45..e44524e3dd 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/tab_bar/tab_bar_view.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/tab_bar/tab_bar_view.dart @@ -8,6 +8,7 @@ import 'package:appflowy/plugins/util.dart'; import 'package:appflowy/startup/plugin/plugin.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/widgets/favorite_button.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/view_title_bar.dart'; @@ -270,6 +271,8 @@ class DatabasePluginWidgetBuilder extends PluginWidgetBuilder { children: [ DatabaseShareButton(key: ValueKey(view.id), view: view), const HSpace(4), + ViewFavoriteButton(view: view), + const HSpace(4), MoreViewActions(view: view, isDocument: false), ], ), diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/share_button.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/share_button.dart index 76aae97580..d6c84e39fe 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/share_button.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/share_button.dart @@ -1,3 +1,5 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/database/application/share_bloc.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:flowy_infra/file_picker/file_picker_service.dart'; import 'package:flowy_infra_ui/widget/rounded_button.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class DatabaseShareButton extends StatelessWidget { @@ -101,13 +102,14 @@ class DatabaseShareActionListState extends State { actions: ShareAction.values .map((action) => ShareActionWrapper(action)) .toList(), - buildChild: (controller) { - return RoundedTextButton( + buildChild: (controller) => Listener( + onPointerDown: (_) => controller.show(), + child: RoundedTextButton( title: LocaleKeys.shareAction_buttonText.tr(), textColor: Theme.of(context).colorScheme.onPrimary, - onPressed: () => controller.show(), - ); - }, + onPressed: () {}, + ), + ), onSelected: (action, controller) async { switch (action.inner) { case ShareAction.csv: diff --git a/frontend/appflowy_flutter/lib/plugins/document/document.dart b/frontend/appflowy_flutter/lib/plugins/document/document.dart index 52b2a0e3e3..6a35fb29bc 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/document.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/document.dart @@ -6,12 +6,12 @@ import 'package:appflowy/generated/flowy_svgs.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/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/util.dart'; import 'package:appflowy/startup/plugin/plugin.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/widgets/favorite_button.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/view_title_bar.dart'; @@ -140,7 +140,7 @@ class DocumentPluginWidgetBuilder extends PluginWidgetBuilder children: [ DocumentShareButton(key: ValueKey(view.id), view: view), const HSpace(4), - DocumentFavoriteButton( + ViewFavoriteButton( key: ValueKey('favorite_button_${view.id}'), view: view, ), diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/share/share_button.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/share/share_button.dart index c5a81ab293..a5d1c40c40 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/share/share_button.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/share/share_button.dart @@ -1,3 +1,5 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/document/application/share_bloc.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:flowy_infra/file_picker/file_picker_service.dart'; import 'package:flowy_infra_ui/widget/rounded_button.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class DocumentShareButton extends StatelessWidget { @@ -108,13 +109,14 @@ class ShareActionListState extends State { actions: ShareAction.values .map((action) => ShareActionWrapper(action)) .toList(), - buildChild: (controller) { - return RoundedTextButton( + buildChild: (controller) => Listener( + onPointerDown: (_) => controller.show(), + child: RoundedTextButton( title: LocaleKeys.shareAction_buttonText.tr(), - onPressed: () => controller.show(), + onPressed: () {}, textColor: Theme.of(context).colorScheme.onPrimary, - ); - }, + ), + ), onSelected: (action, controller) async { switch (action.inner) { case ShareAction.markdown: diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/favorite/favorite_button.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/favorite_button.dart similarity index 50% rename from frontend/appflowy_flutter/lib/plugins/document/presentation/favorite/favorite_button.dart rename to frontend/appflowy_flutter/lib/workspace/presentation/widgets/favorite_button.dart index b82b68dee4..4c52e6c278 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/favorite/favorite_button.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/favorite_button.dart @@ -1,15 +1,17 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/flowy_svgs.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_backend/protobuf/flowy-folder/view.pb.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/widget/flowy_tooltip.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -class DocumentFavoriteButton extends StatelessWidget { - const DocumentFavoriteButton({ +class ViewFavoriteButton extends StatelessWidget { + const ViewFavoriteButton({ super.key, required this.view, }); @@ -21,34 +23,27 @@ class DocumentFavoriteButton extends StatelessWidget { return BlocBuilder( builder: (context, state) { final isFavorite = state.views.any((v) => v.id == view.id); - return _buildFavoriteButton(context, isFavorite); + return Listener( + onPointerDown: (_) => + context.read().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().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, - ), - ); - } } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/view_title_bar.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/view_title_bar.dart index 3f2c6cc168..aca18da74e 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/view_title_bar.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/view_title_bar.dart @@ -216,12 +216,13 @@ class _ViewTitleState extends State<_ViewTitle> { ); if (widget.behavior == _ViewTitleBehavior.uneditable) { - return FlowyButton( - useIntrinsicWidth: true, - onTap: () { - context.read().openPlugin(widget.view); - }, - text: child, + return Listener( + onPointerDown: (_) => context.read().openPlugin(widget.view), + child: FlowyButton( + useIntrinsicWidth: true, + onTap: () {}, + text: child, + ), ); } diff --git a/frontend/rust-lib/flowy-database2/src/services/calculations/controller.rs b/frontend/rust-lib/flowy-database2/src/services/calculations/controller.rs index 849a4f9deb..0c78e30755 100644 --- a/frontend/rust-lib/flowy-database2/src/services/calculations/controller.rs +++ b/frontend/rust-lib/flowy-database2/src/services/calculations/controller.rs @@ -1,7 +1,6 @@ use std::str::FromStr; use std::sync::Arc; -use collab::core::any_map::AnyMapExtension; use collab_database::fields::Field; use collab_database::rows::{Row, RowCell}; use flowy_error::FlowyResult; @@ -227,25 +226,18 @@ impl CalculationsController { async fn handle_row_changed(&self, row: Row) { let cells = row.cells.iter(); - let mut updates = vec![]; // Iterate each cell in the row for cell in cells { 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(_cell_value) = value { - 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; - - if let Some(update) = update { - updates.push(CalculationPB::from(&update)); - self.delegate.update_calculation(&self.view_id, update); - } + 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) -> Option { - let row_cells = self + let field_cells = self .delegate .get_cells_for_field(&self.view_id, &calculation.field_id) .await; 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 = self .calculations_service - .calculate(&field, calculation.calculation_type, row_cells); + .calculate(&field, calculation.calculation_type, field_cells); if value != calculation.value { return Some(calculation.with_value(value)); diff --git a/frontend/rust-lib/flowy-database2/src/services/calculations/service.rs b/frontend/rust-lib/flowy-database2/src/services/calculations/service.rs index 76abb05f92..ebe517e377 100644 --- a/frontend/rust-lib/flowy-database2/src/services/calculations/service.rs +++ b/frontend/rust-lib/flowy-database2/src/services/calculations/service.rs @@ -49,7 +49,7 @@ impl CalculationsService { if len > 0.0 { format!("{:.5}", sum / len) } else { - "0".to_owned() + String::new() } }