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/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<CalculateCell> {
@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<CalculateCell> {
},
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<CalculateCell> {
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<CalculateCell> {
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/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),
],
),

View File

@ -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<DatabaseShareActionList> {
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:

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/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,
),

View File

@ -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<ShareActionList> {
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:

View File

@ -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<FavoriteBloc, FavoriteState>(
builder: (context, state) {
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) {
return FlowyButton(
useIntrinsicWidth: true,
onTap: () {
context.read<TabsBloc>().openPlugin(widget.view);
},
text: child,
return Listener(
onPointerDown: (_) => context.read<TabsBloc>().openPlugin(widget.view),
child: FlowyButton(
useIntrinsicWidth: true,
onTap: () {},
text: child,
),
);
}

View File

@ -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<Calculation>) -> Option<Calculation> {
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));

View File

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