mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
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:
parent
609557c357
commit
c9dc24a13c
@ -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,
|
||||
};
|
||||
}
|
||||
|
@ -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),
|
||||
],
|
||||
),
|
||||
|
@ -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:
|
||||
|
@ -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,
|
||||
),
|
||||
|
@ -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:
|
||||
|
@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -49,7 +49,7 @@ impl CalculationsService {
|
||||
if len > 0.0 {
|
||||
format!("{:.5}", sum / len)
|
||||
} else {
|
||||
"0".to_owned()
|
||||
String::new()
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user