Merge pull request #1167 from AppFlowy-IO/fix/0053

Fix/0053
This commit is contained in:
Nathan.fooo 2022-09-27 10:57:28 +08:00 committed by GitHub
commit 9b78f35ffe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 103 additions and 41 deletions

View File

@ -68,9 +68,11 @@ class GridPluginDisplay extends PluginDisplay {
@override
Widget buildWidget(PluginContext context) {
notifier.isDeleted.addListener(() {
if (notifier.isDeleted.value) {
context.onDeleted(view);
}
notifier.isDeleted.value.fold(() => null, (deletedView) {
if (deletedView.hasIndex()) {
context.onDeleted(view, deletedView.index);
}
});
});
return BoardPage(key: ValueKey(view.id), view: view);

View File

@ -74,15 +74,26 @@ class DocumentPlugin extends Plugin<int> {
class DocumentPluginDisplay extends PluginDisplay with NavigationItem {
final ViewPluginNotifier notifier;
ViewPB get view => notifier.view;
int? deletedViewIndex;
DocumentPluginDisplay({required this.notifier, Key? key});
@override
Widget buildWidget(PluginContext context) => DocumentPage(
view: view,
onDeleted: () => context.onDeleted(view),
key: ValueKey(view.id),
);
Widget buildWidget(PluginContext context) {
notifier.isDeleted.addListener(() {
notifier.isDeleted.value.fold(() => null, (deletedView) {
if (deletedView.hasIndex()) {
deletedViewIndex = deletedView.index;
}
});
});
return DocumentPage(
view: view,
onDeleted: () => context.onDeleted(view, deletedViewIndex),
key: ValueKey(view.id),
);
}
@override
Widget get leftBarItem => ViewLeftBarItem(view: view);

View File

@ -11,7 +11,10 @@ class NumberFormatBloc extends Bloc<NumberFormatEvent, NumberFormatState> {
event.map(setFilter: (_SetFilter value) {
final List<NumberFormat> formats = List.from(NumberFormat.values);
if (value.filter.isNotEmpty) {
formats.retainWhere((element) => element.title().toLowerCase().contains(value.filter.toLowerCase()));
formats.retainWhere((element) => element
.title()
.toLowerCase()
.contains(value.filter.toLowerCase()));
}
emit(state.copyWith(formats: formats, filter: value.filter));
});
@ -91,7 +94,7 @@ extension NumberFormatExtension on NumberFormat {
case NumberFormat.Percent:
return "Percent";
case NumberFormat.PhilippinePeso:
return "Percent";
return "PhilippinePeso";
case NumberFormat.Pound:
return "Pound";
case NumberFormat.Rand:

View File

@ -70,9 +70,11 @@ class GridPluginDisplay extends PluginDisplay {
@override
Widget buildWidget(PluginContext context) {
notifier.isDeleted.addListener(() {
if (notifier.isDeleted.value) {
context.onDeleted(view);
}
notifier.isDeleted.value.fold(() => null, (deletedView) {
if (deletedView.hasIndex()) {
context.onDeleted(view, deletedView.index);
}
});
});
return GridPage(key: ValueKey(view.id), view: view);

View File

@ -1,15 +1,16 @@
import 'package:app_flowy/startup/plugin/plugin.dart';
import 'package:app_flowy/workspace/application/view/view_listener.dart';
import 'package:dartz/dartz.dart';
import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
import 'package:flutter/material.dart';
class ViewPluginNotifier extends PluginNotifier {
class ViewPluginNotifier extends PluginNotifier<Option<DeletedViewPB>> {
final ViewListener? _viewListener;
ViewPB view;
@override
final ValueNotifier<bool> isDeleted = ValueNotifier(false);
final ValueNotifier<Option<DeletedViewPB>> isDeleted = ValueNotifier(none());
@override
final ValueNotifier<int> isDisplayChanged = ValueNotifier(0);
@ -27,9 +28,7 @@ class ViewPluginNotifier extends PluginNotifier {
);
}, onViewMoveToTrash: (result) {
result.fold(
(deletedView) {
isDeleted.value = true;
},
(deletedView) => isDeleted.value = some(deletedView),
(err) => Log.error(err),
);
});

View File

@ -32,9 +32,9 @@ abstract class Plugin<T> {
}
}
abstract class PluginNotifier {
abstract class PluginNotifier<T> {
/// Notify if the plugin get deleted
ValueNotifier<bool> get isDeleted;
ValueNotifier<T> get isDeleted;
/// Notify if the [PluginDisplay]'s content was changed
ValueNotifier<int> get isDisplayChanged;
@ -67,7 +67,7 @@ abstract class PluginDisplay with NavigationItem {
class PluginContext {
// calls when widget of the plugin get deleted
final Function(ViewPB) onDeleted;
final Function(ViewPB, int?) onDeleted;
PluginContext({required this.onDeleted});
}

View File

@ -16,7 +16,7 @@ typedef UpdateViewNotifiedValue = Either<ViewPB, FlowyError>;
// Restore the view from trash
typedef RestoreViewNotifiedValue = Either<ViewPB, FlowyError>;
// Move the view to trash
typedef MoveToTrashNotifiedValue = Either<ViewIdPB, FlowyError>;
typedef MoveToTrashNotifiedValue = Either<DeletedViewPB, FlowyError>;
class ViewListener {
StreamSubscription<SubscribeObject>? _subscription;
@ -98,8 +98,8 @@ class ViewListener {
break;
case FolderNotification.ViewMoveToTrash:
result.fold(
(payload) =>
_moveToTrashNotifier.value = left(ViewIdPB.fromBuffer(payload)),
(payload) => _moveToTrashNotifier.value =
left(DeletedViewPB.fromBuffer(payload)),
(error) => _moveToTrashNotifier.value = right(error),
);
break;

View File

@ -251,14 +251,18 @@ class HomeScreenStackAdaptor extends HomeStackDelegate {
});
@override
void didDeleteStackWidget(ViewPB view) {
void didDeleteStackWidget(ViewPB view, int? index) {
final homeService = HomeService();
homeService.readApp(appId: view.appId).then((result) {
result.fold(
(appPB) {
final List<ViewPB> views = appPB.belongings.items;
if (views.isNotEmpty) {
final lastView = views.last;
var lastView = views.last;
if (index != null && index != 0 && views.length > index - 1) {
lastView = views[index - 1];
}
final plugin = makePlugin(
pluginType: lastView.pluginType,
data: lastView,

View File

@ -18,7 +18,7 @@ import 'home_layout.dart';
typedef NavigationCallback = void Function(String id);
abstract class HomeStackDelegate {
void didDeleteStackWidget(ViewPB view);
void didDeleteStackWidget(ViewPB view, int? index);
}
class HomeStack extends StatelessWidget {
@ -41,9 +41,11 @@ class HomeStack extends StatelessWidget {
child: Container(
color: theme.surface,
child: FocusTraversalGroup(
child: getIt<HomeStackManager>().stackWidget(onDeleted: (view) {
delegate.didDeleteStackWidget(view);
}),
child: getIt<HomeStackManager>().stackWidget(
onDeleted: (view, index) {
delegate.didDeleteStackWidget(view, index);
},
),
),
),
),
@ -168,7 +170,7 @@ class HomeStackManager {
);
}
Widget stackWidget({required Function(ViewPB) onDeleted}) {
Widget stackWidget({required Function(ViewPB, int?) onDeleted}) {
return MultiProvider(
providers: [ChangeNotifierProvider.value(value: _notifier)],
child: Consumer(builder: (ctx, HomeStackNotifier notifier, child) {

View File

@ -206,6 +206,15 @@ impl std::convert::From<&str> for ViewIdPB {
}
}
#[derive(Default, ProtoBuf, Clone, Debug)]
pub struct DeletedViewPB {
#[pb(index = 1)]
pub view_id: String,
#[pb(index = 2, one_of)]
pub index: Option<i32>,
}
impl std::ops::Deref for ViewIdPB {
type Target = str;

View File

@ -1,5 +1,5 @@
pub use crate::entities::view::ViewDataTypePB;
use crate::entities::{ViewInfoPB, ViewLayoutTypePB};
use crate::entities::{DeletedViewPB, ViewInfoPB, ViewLayoutTypePB};
use crate::manager::{ViewDataProcessor, ViewDataProcessorMap};
use crate::{
dart_notification::{send_dart_notification, FolderNotification},
@ -122,12 +122,12 @@ impl ViewController {
.await
}
#[tracing::instrument(level = "debug", skip(self, view_id), fields(view_id = %view_id.value), err)]
pub(crate) async fn read_view(&self, view_id: ViewIdPB) -> Result<ViewRevision, FlowyError> {
#[tracing::instrument(level = "debug", skip(self, view_id), err)]
pub(crate) async fn read_view(&self, view_id: &str) -> Result<ViewRevision, FlowyError> {
let view_rev = self
.persistence
.begin_transaction(|transaction| {
let view = transaction.read_view(&view_id.value)?;
let view = transaction.read_view(view_id)?;
let trash_ids = self.trash_controller.read_trash_ids(&transaction)?;
if trash_ids.contains(&view.id) {
return Err(FlowyError::record_not_found());
@ -135,7 +135,6 @@ impl ViewController {
Ok(view)
})
.await?;
let _ = self.read_view_on_server(view_id);
Ok(view_rev)
}
@ -201,9 +200,26 @@ impl ViewController {
let _ = KV::remove(LATEST_VIEW_ID);
}
}
let view_id_pb = ViewIdPB::from(view_id.as_str());
let deleted_view = self
.persistence
.begin_transaction(|transaction| {
let view = transaction.read_view(&view_id)?;
let views = read_belonging_views_on_local(&view.app_id, self.trash_controller.clone(), &transaction)?;
let index = views
.iter()
.position(|view| view.id == view_id)
.and_then(|index| Some(index as i32));
Ok(DeletedViewPB {
view_id: view_id.clone(),
index,
})
})
.await?;
send_dart_notification(&view_id, FolderNotification::ViewMoveToTrash)
.payload(view_id_pb)
.payload(deleted_view)
.send();
let processor = self.get_data_processor_from_view_id(&view_id).await?;

View File

@ -31,7 +31,7 @@ pub(crate) async fn read_view_handler(
controller: AppData<Arc<ViewController>>,
) -> DataResult<ViewPB, FlowyError> {
let view_id: ViewIdPB = data.into_inner();
let view_rev = controller.read_view(view_id.clone()).await?;
let view_rev = controller.read_view(&view_id.value).await?;
data_result(view_rev.into())
}

View File

@ -70,6 +70,15 @@ define_currency_set!(
symbol: "RUB",
symbol_first: false,
},
PERCENT : {
code: "",
exponent: 2,
locale: EnIn,
minor_units: 1,
name: "percent",
symbol: "%",
symbol_first: false,
},
USD : {
code: "USD",
exponent: 2,
@ -435,7 +444,7 @@ impl NumberFormat {
NumberFormat::Leu => number_currency::RON,
NumberFormat::ArgentinePeso => number_currency::ARS,
NumberFormat::UruguayanPeso => number_currency::UYU,
NumberFormat::Percent => number_currency::USD,
NumberFormat::Percent => number_currency::PERCENT,
}
}

View File

@ -93,6 +93,11 @@ mod tests {
assert_number(&type_option, "€0.5", "€0,5", &field_type, &field_rev);
assert_number(&type_option, "€1844", "€1.844", &field_type, &field_rev);
}
NumberFormat::Percent => {
assert_number(&type_option, "1", "1%", &field_type, &field_rev);
assert_number(&type_option, "10.1", "10.1%", &field_type, &field_rev);
assert_number(&type_option, "100", "100%", &field_type, &field_rev);
}
_ => {}
}
}

View File

@ -77,7 +77,7 @@ impl NumberTypeOptionPB {
pub(crate) fn format_cell_data(&self, s: &str) -> FlowyResult<NumberCellData> {
match self.format {
NumberFormat::Num | NumberFormat::Percent => match Decimal::from_str(s) {
NumberFormat::Num => match Decimal::from_str(s) {
Ok(value, ..) => Ok(NumberCellData::from_decimal(value)),
Err(_) => Ok(NumberCellData::new()),
},