mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
Merge pull request #793 from AppFlowy-IO/feat/refactor_plugin_path
Refactor plugins path
This commit is contained in:
commit
aaee3003ce
@ -4,7 +4,7 @@ import 'package:flowy_infra_ui/style_widget/text.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||||
import 'package:app_flowy/plugin/plugin.dart';
|
import 'package:app_flowy/startup/plugin/plugin.dart';
|
||||||
|
|
||||||
class BlankPluginBuilder extends PluginBuilder {
|
class BlankPluginBuilder extends PluginBuilder {
|
||||||
@override
|
@override
|
||||||
@ -42,7 +42,8 @@ class BlankPagePlugin extends Plugin {
|
|||||||
|
|
||||||
class BlankPagePluginDisplay extends PluginDisplay with NavigationItem {
|
class BlankPagePluginDisplay extends PluginDisplay with NavigationItem {
|
||||||
@override
|
@override
|
||||||
Widget get leftBarItem => FlowyText.medium(LocaleKeys.blankPageTitle.tr(), fontSize: 12);
|
Widget get leftBarItem =>
|
||||||
|
FlowyText.medium(LocaleKeys.blankPageTitle.tr(), fontSize: 12);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget buildWidget() => const BlankPage();
|
Widget buildWidget() => const BlankPage();
|
@ -1,10 +1,10 @@
|
|||||||
import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
|
import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/widgets/left_bar_item.dart';
|
import 'package:app_flowy/workspace/presentation/widgets/left_bar_item.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
||||||
import 'package:app_flowy/plugin/plugin.dart';
|
import 'package:app_flowy/startup/plugin/plugin.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'src/board_page.dart';
|
import 'presentation/board_page.dart';
|
||||||
|
|
||||||
class BoardPluginBuilder implements PluginBuilder {
|
class BoardPluginBuilder implements PluginBuilder {
|
||||||
@override
|
@override
|
@ -1,7 +1,7 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:app_flowy/workspace/application/doc/doc_service.dart';
|
import 'package:app_flowy/plugins/trash/application/trash_service.dart';
|
||||||
import 'package:app_flowy/workspace/application/trash/trash_service.dart';
|
|
||||||
import 'package:app_flowy/workspace/application/view/view_listener.dart';
|
import 'package:app_flowy/workspace/application/view/view_listener.dart';
|
||||||
|
import 'package:app_flowy/plugins/doc/application/doc_service.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-folder/trash.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-folder/trash.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
||||||
@ -43,14 +43,17 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
|
|||||||
emit(state.copyWith(isDeleted: false));
|
emit(state.copyWith(isDeleted: false));
|
||||||
},
|
},
|
||||||
deletePermanently: (DeletePermanently value) async {
|
deletePermanently: (DeletePermanently value) async {
|
||||||
final result = await trashService.deleteViews([Tuple2(view.id, TrashType.TrashView)]);
|
final result = await trashService
|
||||||
|
.deleteViews([Tuple2(view.id, TrashType.TrashView)]);
|
||||||
|
|
||||||
final newState = result.fold((l) => state.copyWith(forceClose: true), (r) => state);
|
final newState = result.fold(
|
||||||
|
(l) => state.copyWith(forceClose: true), (r) => state);
|
||||||
emit(newState);
|
emit(newState);
|
||||||
},
|
},
|
||||||
restorePage: (RestorePage value) async {
|
restorePage: (RestorePage value) async {
|
||||||
final result = await trashService.putback(view.id);
|
final result = await trashService.putback(view.id);
|
||||||
final newState = result.fold((l) => state.copyWith(isDeleted: false), (r) => state);
|
final newState = result.fold(
|
||||||
|
(l) => state.copyWith(isDeleted: false), (r) => state);
|
||||||
emit(newState);
|
emit(newState);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -93,10 +96,12 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
|
|||||||
final documentDelta = document.toDelta();
|
final documentDelta = document.toDelta();
|
||||||
_composeDelta(delta, documentDelta);
|
_composeDelta(delta, documentDelta);
|
||||||
});
|
});
|
||||||
emit(state.copyWith(loadingState: DocumentLoadingState.finish(left(unit))));
|
emit(state.copyWith(
|
||||||
|
loadingState: DocumentLoadingState.finish(left(unit))));
|
||||||
},
|
},
|
||||||
(err) {
|
(err) {
|
||||||
emit(state.copyWith(loadingState: DocumentLoadingState.finish(right(err))));
|
emit(state.copyWith(
|
||||||
|
loadingState: DocumentLoadingState.finish(right(err))));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -156,5 +161,6 @@ class DocumentState with _$DocumentState {
|
|||||||
@freezed
|
@freezed
|
||||||
class DocumentLoadingState with _$DocumentLoadingState {
|
class DocumentLoadingState with _$DocumentLoadingState {
|
||||||
const factory DocumentLoadingState.loading() = _Loading;
|
const factory DocumentLoadingState.loading() = _Loading;
|
||||||
const factory DocumentLoadingState.finish(Either<Unit, FlowyError> successOrFail) = _Finish;
|
const factory DocumentLoadingState.finish(
|
||||||
|
Either<Unit, FlowyError> successOrFail) = _Finish;
|
||||||
}
|
}
|
@ -1,8 +1,8 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:app_flowy/startup/tasks/rust_sdk.dart';
|
import 'package:app_flowy/startup/tasks/rust_sdk.dart';
|
||||||
import 'package:app_flowy/workspace/application/doc/share_service.dart';
|
|
||||||
import 'package:app_flowy/workspace/application/markdown/delta_markdown.dart';
|
import 'package:app_flowy/workspace/application/markdown/delta_markdown.dart';
|
||||||
|
import 'package:app_flowy/plugins/doc/application/share_service.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-text-block/entities.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-text-block/entities.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||||
@ -14,13 +14,15 @@ part 'share_bloc.freezed.dart';
|
|||||||
class DocShareBloc extends Bloc<DocShareEvent, DocShareState> {
|
class DocShareBloc extends Bloc<DocShareEvent, DocShareState> {
|
||||||
ShareService service;
|
ShareService service;
|
||||||
ViewPB view;
|
ViewPB view;
|
||||||
DocShareBloc({required this.view, required this.service}) : super(const DocShareState.initial()) {
|
DocShareBloc({required this.view, required this.service})
|
||||||
|
: super(const DocShareState.initial()) {
|
||||||
on<DocShareEvent>((event, emit) async {
|
on<DocShareEvent>((event, emit) async {
|
||||||
await event.map(
|
await event.map(
|
||||||
shareMarkdown: (ShareMarkdown value) async {
|
shareMarkdown: (ShareMarkdown value) async {
|
||||||
await service.exportMarkdown(view.id).then((result) {
|
await service.exportMarkdown(view.id).then((result) {
|
||||||
result.fold(
|
result.fold(
|
||||||
(value) => emit(DocShareState.finish(left(_convertDeltaToMarkdown(value)))),
|
(value) => emit(
|
||||||
|
DocShareState.finish(left(_convertDeltaToMarkdown(value)))),
|
||||||
(error) => emit(DocShareState.finish(right(error))),
|
(error) => emit(DocShareState.finish(right(error))),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -73,5 +75,6 @@ class DocShareEvent with _$DocShareEvent {
|
|||||||
class DocShareState with _$DocShareState {
|
class DocShareState with _$DocShareState {
|
||||||
const factory DocShareState.initial() = _Initial;
|
const factory DocShareState.initial() = _Initial;
|
||||||
const factory DocShareState.loading() = _Loading;
|
const factory DocShareState.loading() = _Loading;
|
||||||
const factory DocShareState.finish(Either<ExportDataPB, FlowyError> successOrFail) = _Finish;
|
const factory DocShareState.finish(
|
||||||
|
Either<ExportDataPB, FlowyError> successOrFail) = _Finish;
|
||||||
}
|
}
|
@ -1,14 +1,14 @@
|
|||||||
library docuemnt_plugin;
|
library docuemnt_plugin;
|
||||||
|
|
||||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||||
import 'package:app_flowy/plugin/plugin.dart';
|
import 'package:app_flowy/startup/plugin/plugin.dart';
|
||||||
import 'package:app_flowy/startup/startup.dart';
|
import 'package:app_flowy/startup/startup.dart';
|
||||||
import 'package:app_flowy/workspace/application/appearance.dart';
|
import 'package:app_flowy/workspace/application/appearance.dart';
|
||||||
import 'package:app_flowy/workspace/application/doc/share_bloc.dart';
|
|
||||||
import 'package:app_flowy/workspace/application/view/view_listener.dart';
|
import 'package:app_flowy/workspace/application/view/view_listener.dart';
|
||||||
|
import 'package:app_flowy/plugins/doc/application/share_bloc.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
|
import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/home/toast.dart';
|
import 'package:app_flowy/workspace/presentation/home/toast.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/widgets/left_bar_item.dart';
|
import 'package:app_flowy/workspace/presentation/widgets/left_bar_item.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart';
|
import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/widgets/pop_up_action.dart';
|
import 'package:app_flowy/workspace/presentation/widgets/pop_up_action.dart';
|
||||||
import 'package:clipboard/clipboard.dart';
|
import 'package:clipboard/clipboard.dart';
|
||||||
@ -26,12 +26,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
import 'src/document_page.dart';
|
import 'document_page.dart';
|
||||||
|
|
||||||
export './src/document_page.dart';
|
|
||||||
export './src/widget/toolbar/history_button.dart';
|
|
||||||
export './src/widget/toolbar/tool_bar.dart';
|
|
||||||
export './src/widget/toolbar/toolbar_icon_button.dart';
|
|
||||||
|
|
||||||
class DocumentPluginBuilder extends PluginBuilder {
|
class DocumentPluginBuilder extends PluginBuilder {
|
||||||
@override
|
@override
|
||||||
@ -58,7 +53,9 @@ class DocumentPlugin implements Plugin {
|
|||||||
ViewListener? _listener;
|
ViewListener? _listener;
|
||||||
late PluginType _pluginType;
|
late PluginType _pluginType;
|
||||||
|
|
||||||
DocumentPlugin({required PluginType pluginType, required ViewPB view, Key? key}) : _view = view {
|
DocumentPlugin(
|
||||||
|
{required PluginType pluginType, required ViewPB view, Key? key})
|
||||||
|
: _view = view {
|
||||||
_pluginType = pluginType;
|
_pluginType = pluginType;
|
||||||
_listener = getIt<ViewListener>(param1: view);
|
_listener = getIt<ViewListener>(param1: view);
|
||||||
_listener?.start(onViewUpdated: (result) {
|
_listener?.start(onViewUpdated: (result) {
|
||||||
@ -112,7 +109,8 @@ class DocumentPluginDisplay extends PluginDisplay<int> with NavigationItem {
|
|||||||
|
|
||||||
class DocumentShareButton extends StatelessWidget {
|
class DocumentShareButton extends StatelessWidget {
|
||||||
final ViewPB view;
|
final ViewPB view;
|
||||||
DocumentShareButton({Key? key, required this.view}) : super(key: ValueKey(view.hashCode));
|
DocumentShareButton({Key? key, required this.view})
|
||||||
|
: super(key: ValueKey(view.hashCode));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -149,7 +147,8 @@ class DocumentShareButton extends StatelessWidget {
|
|||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
borderRadius: Corners.s6Border,
|
borderRadius: Corners.s6Border,
|
||||||
color: Colors.lightBlue,
|
color: Colors.lightBlue,
|
||||||
onPressed: () => _showActionList(context, Offset(-(buttonWidth / 2), 10)),
|
onPressed: () => _showActionList(
|
||||||
|
context, Offset(-(buttonWidth / 2), 10)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -165,7 +164,8 @@ class DocumentShareButton extends StatelessWidget {
|
|||||||
case ExportType.Link:
|
case ExportType.Link:
|
||||||
break;
|
break;
|
||||||
case ExportType.Markdown:
|
case ExportType.Markdown:
|
||||||
FlutterClipboard.copy(exportData.data).then((value) => Log.info('copied to clipboard'));
|
FlutterClipboard.copy(exportData.data)
|
||||||
|
.then((value) => Log.info('copied to clipboard'));
|
||||||
break;
|
break;
|
||||||
case ExportType.Text:
|
case ExportType.Text:
|
||||||
break;
|
break;
|
||||||
@ -179,11 +179,15 @@ class DocumentShareButton extends StatelessWidget {
|
|||||||
result.fold(() {}, (action) {
|
result.fold(() {}, (action) {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case ShareAction.markdown:
|
case ShareAction.markdown:
|
||||||
context.read<DocShareBloc>().add(const DocShareEvent.shareMarkdown());
|
context
|
||||||
showMessageToast('Exported to: ${LocaleKeys.notifications_export_path.tr()}');
|
.read<DocShareBloc>()
|
||||||
|
.add(const DocShareEvent.shareMarkdown());
|
||||||
|
showMessageToast(
|
||||||
|
'Exported to: ${LocaleKeys.notifications_export_path.tr()}');
|
||||||
break;
|
break;
|
||||||
case ShareAction.copyLink:
|
case ShareAction.copyLink:
|
||||||
FlowyAlertDialog(title: LocaleKeys.shareAction_workInProgress.tr()).show(context);
|
FlowyAlertDialog(title: LocaleKeys.shareAction_workInProgress.tr())
|
||||||
|
.show(context);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -198,7 +202,8 @@ class DocumentShareButton extends StatelessWidget {
|
|||||||
|
|
||||||
class ShareActions with ActionList<ShareActionWrapper>, FlowyOverlayDelegate {
|
class ShareActions with ActionList<ShareActionWrapper>, FlowyOverlayDelegate {
|
||||||
final Function(dartz.Option<ShareAction>) onSelected;
|
final Function(dartz.Option<ShareAction>) onSelected;
|
||||||
final _items = ShareAction.values.map((action) => ShareActionWrapper(action)).toList();
|
final _items =
|
||||||
|
ShareAction.values.map((action) => ShareActionWrapper(action)).toList();
|
||||||
|
|
||||||
ShareActions({required this.onSelected});
|
ShareActions({required this.onSelected});
|
||||||
|
|
||||||
@ -212,7 +217,8 @@ class ShareActions with ActionList<ShareActionWrapper>, FlowyOverlayDelegate {
|
|||||||
List<ShareActionWrapper> get items => _items;
|
List<ShareActionWrapper> get items => _items;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void Function(dartz.Option<ShareActionWrapper> p1) get selectCallback => (result) {
|
void Function(dartz.Option<ShareActionWrapper> p1) get selectCallback =>
|
||||||
|
(result) {
|
||||||
result.fold(
|
result.fold(
|
||||||
() => onSelected(dartz.none()),
|
() => onSelected(dartz.none()),
|
||||||
(wrapper) => onSelected(
|
(wrapper) => onSelected(
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:app_flowy/startup/startup.dart';
|
import 'package:app_flowy/startup/startup.dart';
|
||||||
import 'package:app_flowy/workspace/application/appearance.dart';
|
import 'package:app_flowy/workspace/application/appearance.dart';
|
||||||
import 'package:app_flowy/workspace/application/doc/doc_bloc.dart';
|
import 'package:app_flowy/plugins/doc/presentation/banner.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/doc/document.dart';
|
import 'package:app_flowy/plugins/doc/presentation/toolbar/tool_bar.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart';
|
import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart';
|
||||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||||
import 'package:flutter_quill/flutter_quill.dart' as quill;
|
import 'package:flutter_quill/flutter_quill.dart' as quill;
|
||||||
@ -10,8 +10,8 @@ import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import 'application/doc_bloc.dart';
|
||||||
import 'styles.dart';
|
import 'styles.dart';
|
||||||
import 'widget/banner.dart';
|
|
||||||
|
|
||||||
class DocumentPage extends StatefulWidget {
|
class DocumentPage extends StatefulWidget {
|
||||||
final ViewPB view;
|
final ViewPB view;
|
||||||
@ -29,7 +29,8 @@ class _DocumentPageState extends State<DocumentPage> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
documentBloc = getIt<DocumentBloc>(param1: super.widget.view)..add(const DocumentEvent.initial());
|
documentBloc = getIt<DocumentBloc>(param1: super.widget.view)
|
||||||
|
..add(const DocumentEvent.initial());
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,10 +40,12 @@ class _DocumentPageState extends State<DocumentPage> {
|
|||||||
providers: [
|
providers: [
|
||||||
BlocProvider<DocumentBloc>.value(value: documentBloc),
|
BlocProvider<DocumentBloc>.value(value: documentBloc),
|
||||||
],
|
],
|
||||||
child: BlocBuilder<DocumentBloc, DocumentState>(builder: (context, state) {
|
child:
|
||||||
|
BlocBuilder<DocumentBloc, DocumentState>(builder: (context, state) {
|
||||||
return state.loadingState.map(
|
return state.loadingState.map(
|
||||||
// loading: (_) => const FlowyProgressIndicator(),
|
// loading: (_) => const FlowyProgressIndicator(),
|
||||||
loading: (_) => SizedBox.expand(child: Container(color: Colors.transparent)),
|
loading: (_) =>
|
||||||
|
SizedBox.expand(child: Container(color: Colors.transparent)),
|
||||||
finish: (result) => result.successOrFail.fold(
|
finish: (result) => result.successOrFail.fold(
|
||||||
(_) {
|
(_) {
|
||||||
if (state.forceClose) {
|
if (state.forceClose) {
|
||||||
@ -90,8 +93,11 @@ class _DocumentPageState extends State<DocumentPage> {
|
|||||||
|
|
||||||
Widget _renderBanner(BuildContext context) {
|
Widget _renderBanner(BuildContext context) {
|
||||||
return DocumentBanner(
|
return DocumentBanner(
|
||||||
onRestore: () => context.read<DocumentBloc>().add(const DocumentEvent.restorePage()),
|
onRestore: () =>
|
||||||
onDelete: () => context.read<DocumentBloc>().add(const DocumentEvent.deletePermanently()),
|
context.read<DocumentBloc>().add(const DocumentEvent.restorePage()),
|
||||||
|
onDelete: () => context
|
||||||
|
.read<DocumentBloc>()
|
||||||
|
.add(const DocumentEvent.deletePermanently()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -1,11 +1,10 @@
|
|||||||
|
import 'package:app_flowy/plugins/doc/presentation/style_widgets.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_quill/flutter_quill.dart';
|
import 'package:flutter_quill/flutter_quill.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
|
|
||||||
import 'widget/style_widgets.dart';
|
|
||||||
|
|
||||||
DefaultStyles customStyles(BuildContext context) {
|
DefaultStyles customStyles(BuildContext context) {
|
||||||
const baseSpacing = Tuple2<double, double>(6, 0);
|
const baseSpacing = Tuple2<double, double>(6, 0);
|
||||||
|
|
||||||
@ -53,7 +52,8 @@ DefaultStyles customStyles(BuildContext context) {
|
|||||||
const Tuple2(8, 0),
|
const Tuple2(8, 0),
|
||||||
const Tuple2(0, 0),
|
const Tuple2(0, 0),
|
||||||
null),
|
null),
|
||||||
paragraph: DefaultTextBlockStyle(baseStyle, const Tuple2(10, 0), const Tuple2(0, 0), null),
|
paragraph: DefaultTextBlockStyle(
|
||||||
|
baseStyle, const Tuple2(10, 0), const Tuple2(0, 0), null),
|
||||||
bold: const TextStyle(fontWeight: FontWeight.bold),
|
bold: const TextStyle(fontWeight: FontWeight.bold),
|
||||||
italic: const TextStyle(fontStyle: FontStyle.italic),
|
italic: const TextStyle(fontStyle: FontStyle.italic),
|
||||||
small: const TextStyle(fontSize: 12, color: Colors.black45),
|
small: const TextStyle(fontSize: 12, color: Colors.black45),
|
||||||
@ -78,8 +78,8 @@ DefaultStyles customStyles(BuildContext context) {
|
|||||||
const Tuple2(0, 0),
|
const Tuple2(0, 0),
|
||||||
const Tuple2(0, 0),
|
const Tuple2(0, 0),
|
||||||
null),
|
null),
|
||||||
lists:
|
lists: DefaultListBlockStyle(baseStyle, baseSpacing, const Tuple2(0, 6),
|
||||||
DefaultListBlockStyle(baseStyle, baseSpacing, const Tuple2(0, 6), null, StyleWidgetBuilder.checkbox(theme)),
|
null, StyleWidgetBuilder.checkbox(theme)),
|
||||||
quote: DefaultTextBlockStyle(
|
quote: DefaultTextBlockStyle(
|
||||||
TextStyle(color: baseStyle.color!.withOpacity(0.6)),
|
TextStyle(color: baseStyle.color!.withOpacity(0.6)),
|
||||||
baseSpacing,
|
baseSpacing,
|
||||||
@ -102,9 +102,12 @@ DefaultStyles customStyles(BuildContext context) {
|
|||||||
color: Colors.grey.shade50,
|
color: Colors.grey.shade50,
|
||||||
borderRadius: BorderRadius.circular(2),
|
borderRadius: BorderRadius.circular(2),
|
||||||
)),
|
)),
|
||||||
indent: DefaultTextBlockStyle(baseStyle, baseSpacing, const Tuple2(0, 6), null),
|
indent: DefaultTextBlockStyle(
|
||||||
align: DefaultTextBlockStyle(baseStyle, const Tuple2(0, 0), const Tuple2(0, 0), null),
|
baseStyle, baseSpacing, const Tuple2(0, 6), null),
|
||||||
leading: DefaultTextBlockStyle(baseStyle, const Tuple2(0, 0), const Tuple2(0, 0), null),
|
align: DefaultTextBlockStyle(
|
||||||
|
baseStyle, const Tuple2(0, 0), const Tuple2(0, 0), null),
|
||||||
|
leading: DefaultTextBlockStyle(
|
||||||
|
baseStyle, const Tuple2(0, 0), const Tuple2(0, 0), null),
|
||||||
sizeSmall: const TextStyle(fontSize: 10),
|
sizeSmall: const TextStyle(fontSize: 10),
|
||||||
sizeLarge: const TextStyle(fontSize: 18),
|
sizeLarge: const TextStyle(fontSize: 18),
|
||||||
sizeHuge: const TextStyle(fontSize: 22));
|
sizeHuge: const TextStyle(fontSize: 22));
|
@ -1,6 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:app_flowy/workspace/application/grid/grid_service.dart';
|
import 'package:app_flowy/plugins/grid/application/grid_service.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/row/row_service.dart';
|
import 'package:app_flowy/plugins/grid/application/row/row_service.dart';
|
||||||
import 'package:flowy_sdk/log.dart';
|
import 'package:flowy_sdk/log.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
|
|
||||||
import 'package:app_flowy/workspace/application/grid/grid_service.dart';
|
import 'package:app_flowy/plugins/grid/application/grid_service.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||||
@ -14,8 +14,8 @@ import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
|||||||
import 'package:flowy_sdk/protobuf/flowy-grid/url_type_option_entities.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/url_type_option_entities.pb.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/cell/cell_listener.dart';
|
import 'package:app_flowy/plugins/grid/application/cell/cell_listener.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
|
import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
|
||||||
import 'dart:convert' show utf8;
|
import 'dart:convert' show utf8;
|
||||||
|
|
||||||
import '../../field/type_option/type_option_service.dart';
|
import '../../field/type_option/type_option_service.dart';
|
@ -1,8 +1,10 @@
|
|||||||
part of 'cell_service.dart';
|
part of 'cell_service.dart';
|
||||||
|
|
||||||
typedef GridCellController = IGridCellController<String, String>;
|
typedef GridCellController = IGridCellController<String, String>;
|
||||||
typedef GridSelectOptionCellController = IGridCellController<SelectOptionCellDataPB, String>;
|
typedef GridSelectOptionCellController
|
||||||
typedef GridDateCellController = IGridCellController<DateCellDataPB, CalendarData>;
|
= IGridCellController<SelectOptionCellDataPB, String>;
|
||||||
|
typedef GridDateCellController
|
||||||
|
= IGridCellController<DateCellDataPB, CalendarData>;
|
||||||
typedef GridURLCellController = IGridCellController<URLCellDataPB, String>;
|
typedef GridURLCellController = IGridCellController<URLCellDataPB, String>;
|
||||||
|
|
||||||
class GridCellControllerBuilder {
|
class GridCellControllerBuilder {
|
||||||
@ -19,7 +21,8 @@ class GridCellControllerBuilder {
|
|||||||
_cellId = cellId;
|
_cellId = cellId;
|
||||||
|
|
||||||
IGridCellController build() {
|
IGridCellController build() {
|
||||||
final cellFieldNotifier = GridCellFieldNotifier(notifier: _GridFieldChangedNotifierImpl(_fieldCache));
|
final cellFieldNotifier = GridCellFieldNotifier(
|
||||||
|
notifier: _GridFieldChangedNotifierImpl(_fieldCache));
|
||||||
|
|
||||||
switch (_cellId.fieldType) {
|
switch (_cellId.fieldType) {
|
||||||
case FieldType.Checkbox:
|
case FieldType.Checkbox:
|
||||||
@ -142,8 +145,10 @@ class IGridCellController<T, D> extends Equatable {
|
|||||||
_cellDataLoader = cellDataLoader,
|
_cellDataLoader = cellDataLoader,
|
||||||
_cellDataPersistence = cellDataPersistence,
|
_cellDataPersistence = cellDataPersistence,
|
||||||
_fieldNotifier = fieldNotifier,
|
_fieldNotifier = fieldNotifier,
|
||||||
_fieldService = FieldService(gridId: cellId.gridId, fieldId: cellId.field.id),
|
_fieldService =
|
||||||
_cacheKey = GridCellCacheKey(rowId: cellId.rowId, fieldId: cellId.field.id);
|
FieldService(gridId: cellId.gridId, fieldId: cellId.field.id),
|
||||||
|
_cacheKey =
|
||||||
|
GridCellCacheKey(rowId: cellId.rowId, fieldId: cellId.field.id);
|
||||||
|
|
||||||
IGridCellController<T, D> clone() {
|
IGridCellController<T, D> clone() {
|
||||||
return IGridCellController(
|
return IGridCellController(
|
||||||
@ -164,7 +169,9 @@ class IGridCellController<T, D> extends Equatable {
|
|||||||
|
|
||||||
FieldType get fieldType => cellId.field.fieldType;
|
FieldType get fieldType => cellId.field.fieldType;
|
||||||
|
|
||||||
VoidCallback? startListening({required void Function(T?) onCellChanged, VoidCallback? onCellFieldChanged}) {
|
VoidCallback? startListening(
|
||||||
|
{required void Function(T?) onCellChanged,
|
||||||
|
VoidCallback? onCellFieldChanged}) {
|
||||||
if (isListening) {
|
if (isListening) {
|
||||||
Log.error("Already started. It seems like you should call clone first");
|
Log.error("Already started. It seems like you should call clone first");
|
||||||
return null;
|
return null;
|
||||||
@ -226,8 +233,11 @@ class IGridCellController<T, D> extends Equatable {
|
|||||||
|
|
||||||
/// Return the FieldTypeOptionDataPB that can be parsed into corresponding class using the [parser].
|
/// Return the FieldTypeOptionDataPB that can be parsed into corresponding class using the [parser].
|
||||||
/// [PD] is the type that the parser return.
|
/// [PD] is the type that the parser return.
|
||||||
Future<Either<PD, FlowyError>> getFieldTypeOption<PD, P extends TypeOptionDataParser>(P parser) {
|
Future<Either<PD, FlowyError>>
|
||||||
return _fieldService.getFieldTypeOptionData(fieldType: fieldType).then((result) {
|
getFieldTypeOption<PD, P extends TypeOptionDataParser>(P parser) {
|
||||||
|
return _fieldService
|
||||||
|
.getFieldTypeOptionData(fieldType: fieldType)
|
||||||
|
.then((result) {
|
||||||
return result.fold(
|
return result.fold(
|
||||||
(data) => parser.fromBuffer(data.typeOptionData),
|
(data) => parser.fromBuffer(data.typeOptionData),
|
||||||
(err) => right(err),
|
(err) => right(err),
|
||||||
@ -239,7 +249,9 @@ class IGridCellController<T, D> extends Equatable {
|
|||||||
/// You can set [dedeplicate] to true (default is false) to reduce the save operation.
|
/// You can set [dedeplicate] to true (default is false) to reduce the save operation.
|
||||||
/// It's useful when you call this method when user editing the [TextField].
|
/// It's useful when you call this method when user editing the [TextField].
|
||||||
/// The default debounce interval is 300 milliseconds.
|
/// The default debounce interval is 300 milliseconds.
|
||||||
void saveCellData(D data, {bool deduplicate = false, void Function(Option<FlowyError>)? resultCallback}) async {
|
void saveCellData(D data,
|
||||||
|
{bool deduplicate = false,
|
||||||
|
void Function(Option<FlowyError>)? resultCallback}) async {
|
||||||
if (deduplicate) {
|
if (deduplicate) {
|
||||||
_loadDataOperation?.cancel();
|
_loadDataOperation?.cancel();
|
||||||
|
|
||||||
@ -288,7 +300,8 @@ class IGridCellController<T, D> extends Equatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [_cellsCache.get(_cacheKey) ?? "", cellId.rowId + cellId.field.id];
|
List<Object> get props =>
|
||||||
|
[_cellsCache.get(_cacheKey) ?? "", cellId.rowId + cellId.field.id];
|
||||||
}
|
}
|
||||||
|
|
||||||
class _GridFieldChangedNotifierImpl extends GridFieldChangedNotifier {
|
class _GridFieldChangedNotifierImpl extends GridFieldChangedNotifier {
|
||||||
@ -300,7 +313,7 @@ class _GridFieldChangedNotifierImpl extends GridFieldChangedNotifier {
|
|||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
if (_onChangesetFn != null) {
|
if (_onChangesetFn != null) {
|
||||||
_cache.removeListener(onChangsetListener: _onChangesetFn!);
|
_cache.removeListener(onChangesetListener: _onChangesetFn!);
|
||||||
_onChangesetFn = null;
|
_onChangesetFn = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
|
import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart' show StringTranslateExtension;
|
import 'package:easy_localization/easy_localization.dart'
|
||||||
|
show StringTranslateExtension;
|
||||||
import 'package:flowy_sdk/log.dart';
|
import 'package:flowy_sdk/log.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-error-code/code.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-error-code/code.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||||
@ -40,7 +41,8 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
|
|||||||
},
|
},
|
||||||
didReceiveCellUpdate: (DateCellDataPB? cellData) {
|
didReceiveCellUpdate: (DateCellDataPB? cellData) {
|
||||||
final calData = calDataFromCellData(cellData);
|
final calData = calDataFromCellData(cellData);
|
||||||
final time = calData.foldRight("", (dateData, previous) => dateData.time);
|
final time =
|
||||||
|
calData.foldRight("", (dateData, previous) => dateData.time);
|
||||||
emit(state.copyWith(calData: calData, time: time));
|
emit(state.copyWith(calData: calData, time: time));
|
||||||
},
|
},
|
||||||
setIncludeTime: (includeTime) async {
|
setIncludeTime: (includeTime) async {
|
||||||
@ -57,15 +59,18 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
|
|||||||
await _updateDateData(emit, time: time);
|
await _updateDateData(emit, time: time);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
didUpdateCalData: (Option<CalendarData> data, Option<String> timeFormatError) {
|
didUpdateCalData:
|
||||||
emit(state.copyWith(calData: data, timeFormatError: timeFormatError));
|
(Option<CalendarData> data, Option<String> timeFormatError) {
|
||||||
|
emit(state.copyWith(
|
||||||
|
calData: data, timeFormatError: timeFormatError));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _updateDateData(Emitter<DateCalState> emit, {DateTime? date, String? time}) {
|
Future<void> _updateDateData(Emitter<DateCalState> emit,
|
||||||
|
{DateTime? date, String? time}) {
|
||||||
final CalendarData newDateData = state.calData.fold(
|
final CalendarData newDateData = state.calData.fold(
|
||||||
() => CalendarData(date: date ?? DateTime.now(), time: time),
|
() => CalendarData(date: date ?? DateTime.now(), time: time),
|
||||||
(dateData) {
|
(dateData) {
|
||||||
@ -84,13 +89,17 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
|
|||||||
return _saveDateData(emit, newDateData);
|
return _saveDateData(emit, newDateData);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _saveDateData(Emitter<DateCalState> emit, CalendarData newCalData) async {
|
Future<void> _saveDateData(
|
||||||
|
Emitter<DateCalState> emit, CalendarData newCalData) async {
|
||||||
if (state.calData == Some(newCalData)) {
|
if (state.calData == Some(newCalData)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCalData(Option<CalendarData> calData, Option<String> timeFormatError) {
|
updateCalData(
|
||||||
if (!isClosed) add(DateCalEvent.didUpdateCalData(calData, timeFormatError));
|
Option<CalendarData> calData, Option<String> timeFormatError) {
|
||||||
|
if (!isClosed) {
|
||||||
|
add(DateCalEvent.didUpdateCalData(calData, timeFormatError));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cellContext.saveCellData(newCalData, resultCallback: (result) {
|
cellContext.saveCellData(newCalData, resultCallback: (result) {
|
||||||
@ -172,7 +181,9 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
result.fold(
|
result.fold(
|
||||||
(l) => emit(state.copyWith(dateTypeOption: newDateTypeOption, timeHintText: _timeHintText(newDateTypeOption))),
|
(l) => emit(state.copyWith(
|
||||||
|
dateTypeOption: newDateTypeOption,
|
||||||
|
timeHintText: _timeHintText(newDateTypeOption))),
|
||||||
(err) => Log.error(err),
|
(err) => Log.error(err),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -182,14 +193,17 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
|
|||||||
class DateCalEvent with _$DateCalEvent {
|
class DateCalEvent with _$DateCalEvent {
|
||||||
const factory DateCalEvent.initial() = _Initial;
|
const factory DateCalEvent.initial() = _Initial;
|
||||||
const factory DateCalEvent.selectDay(DateTime day) = _SelectDay;
|
const factory DateCalEvent.selectDay(DateTime day) = _SelectDay;
|
||||||
const factory DateCalEvent.setCalFormat(CalendarFormat format) = _CalendarFormat;
|
const factory DateCalEvent.setCalFormat(CalendarFormat format) =
|
||||||
|
_CalendarFormat;
|
||||||
const factory DateCalEvent.setFocusedDay(DateTime day) = _FocusedDay;
|
const factory DateCalEvent.setFocusedDay(DateTime day) = _FocusedDay;
|
||||||
const factory DateCalEvent.setTimeFormat(TimeFormat timeFormat) = _TimeFormat;
|
const factory DateCalEvent.setTimeFormat(TimeFormat timeFormat) = _TimeFormat;
|
||||||
const factory DateCalEvent.setDateFormat(DateFormat dateFormat) = _DateFormat;
|
const factory DateCalEvent.setDateFormat(DateFormat dateFormat) = _DateFormat;
|
||||||
const factory DateCalEvent.setIncludeTime(bool includeTime) = _IncludeTime;
|
const factory DateCalEvent.setIncludeTime(bool includeTime) = _IncludeTime;
|
||||||
const factory DateCalEvent.setTime(String time) = _Time;
|
const factory DateCalEvent.setTime(String time) = _Time;
|
||||||
const factory DateCalEvent.didReceiveCellUpdate(DateCellDataPB? data) = _DidReceiveCellUpdate;
|
const factory DateCalEvent.didReceiveCellUpdate(DateCellDataPB? data) =
|
||||||
const factory DateCalEvent.didUpdateCalData(Option<CalendarData> data, Option<String> timeFormatError) =
|
_DidReceiveCellUpdate;
|
||||||
|
const factory DateCalEvent.didUpdateCalData(
|
||||||
|
Option<CalendarData> data, Option<String> timeFormatError) =
|
||||||
_DidUpdateCalData;
|
_DidUpdateCalData;
|
||||||
}
|
}
|
||||||
|
|
@ -2,11 +2,12 @@ import 'dart:async';
|
|||||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart';
|
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
||||||
|
|
||||||
part 'select_option_cell_bloc.freezed.dart';
|
part 'select_option_cell_bloc.freezed.dart';
|
||||||
|
|
||||||
class SelectOptionCellBloc extends Bloc<SelectOptionCellEvent, SelectOptionCellState> {
|
class SelectOptionCellBloc
|
||||||
|
extends Bloc<SelectOptionCellEvent, SelectOptionCellState> {
|
||||||
final GridSelectOptionCellController cellContext;
|
final GridSelectOptionCellController cellContext;
|
||||||
void Function()? _onCellChangedFn;
|
void Function()? _onCellChangedFn;
|
||||||
|
|
||||||
@ -66,7 +67,8 @@ class SelectOptionCellState with _$SelectOptionCellState {
|
|||||||
required List<SelectOptionPB> selectedOptions,
|
required List<SelectOptionPB> selectedOptions,
|
||||||
}) = _SelectOptionCellState;
|
}) = _SelectOptionCellState;
|
||||||
|
|
||||||
factory SelectOptionCellState.initial(GridSelectOptionCellController context) {
|
factory SelectOptionCellState.initial(
|
||||||
|
GridSelectOptionCellController context) {
|
||||||
final data = context.getCellData();
|
final data = context.getCellData();
|
||||||
|
|
||||||
return SelectOptionCellState(
|
return SelectOptionCellState(
|
@ -4,20 +4,22 @@ import 'package:flowy_sdk/log.dart';
|
|||||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart';
|
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
||||||
import 'select_option_service.dart';
|
import 'select_option_service.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
|
|
||||||
part 'select_option_editor_bloc.freezed.dart';
|
part 'select_option_editor_bloc.freezed.dart';
|
||||||
|
|
||||||
class SelectOptionCellEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOptionEditorState> {
|
class SelectOptionCellEditorBloc
|
||||||
|
extends Bloc<SelectOptionEditorEvent, SelectOptionEditorState> {
|
||||||
final SelectOptionService _selectOptionService;
|
final SelectOptionService _selectOptionService;
|
||||||
final GridSelectOptionCellController cellController;
|
final GridSelectOptionCellController cellController;
|
||||||
Timer? _delayOperation;
|
Timer? _delayOperation;
|
||||||
|
|
||||||
SelectOptionCellEditorBloc({
|
SelectOptionCellEditorBloc({
|
||||||
required this.cellController,
|
required this.cellController,
|
||||||
}) : _selectOptionService = SelectOptionService(cellId: cellController.cellId),
|
}) : _selectOptionService =
|
||||||
|
SelectOptionService(cellId: cellController.cellId),
|
||||||
super(SelectOptionEditorState.initial(cellController)) {
|
super(SelectOptionEditorState.initial(cellController)) {
|
||||||
on<SelectOptionEditorEvent>(
|
on<SelectOptionEditorEvent>(
|
||||||
(event, emit) async {
|
(event, emit) async {
|
||||||
@ -87,7 +89,8 @@ class SelectOptionCellEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOpt
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _onSelectOption(String optionId) {
|
void _onSelectOption(String optionId) {
|
||||||
final hasSelected = state.selectedOptions.firstWhereOrNull((option) => option.id == optionId);
|
final hasSelected = state.selectedOptions
|
||||||
|
.firstWhereOrNull((option) => option.id == optionId);
|
||||||
if (hasSelected != null) {
|
if (hasSelected != null) {
|
||||||
_selectOptionService.unSelect(optionId: optionId);
|
_selectOptionService.unSelect(optionId: optionId);
|
||||||
} else {
|
} else {
|
||||||
@ -96,7 +99,8 @@ class SelectOptionCellEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOpt
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _filterOption(String optionName, Emitter<SelectOptionEditorState> emit) {
|
void _filterOption(String optionName, Emitter<SelectOptionEditorState> emit) {
|
||||||
final _MakeOptionResult result = _makeOptions(Some(optionName), state.allOptions);
|
final _MakeOptionResult result =
|
||||||
|
_makeOptions(Some(optionName), state.allOptions);
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
filter: Some(optionName),
|
filter: Some(optionName),
|
||||||
options: result.options,
|
options: result.options,
|
||||||
@ -112,7 +116,8 @@ class SelectOptionCellEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOpt
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return result.fold(
|
return result.fold(
|
||||||
(data) => add(SelectOptionEditorEvent.didReceiveOptions(data.options, data.selectOptions)),
|
(data) => add(SelectOptionEditorEvent.didReceiveOptions(
|
||||||
|
data.options, data.selectOptions)),
|
||||||
(err) {
|
(err) {
|
||||||
Log.error(err);
|
Log.error(err);
|
||||||
return null;
|
return null;
|
||||||
@ -122,7 +127,8 @@ class SelectOptionCellEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOpt
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_MakeOptionResult _makeOptions(Option<String> filter, List<SelectOptionPB> allOptions) {
|
_MakeOptionResult _makeOptions(
|
||||||
|
Option<String> filter, List<SelectOptionPB> allOptions) {
|
||||||
final List<SelectOptionPB> options = List.from(allOptions);
|
final List<SelectOptionPB> options = List.from(allOptions);
|
||||||
Option<String> createOption = filter;
|
Option<String> createOption = filter;
|
||||||
|
|
||||||
@ -165,12 +171,18 @@ class SelectOptionCellEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOpt
|
|||||||
class SelectOptionEditorEvent with _$SelectOptionEditorEvent {
|
class SelectOptionEditorEvent with _$SelectOptionEditorEvent {
|
||||||
const factory SelectOptionEditorEvent.initial() = _Initial;
|
const factory SelectOptionEditorEvent.initial() = _Initial;
|
||||||
const factory SelectOptionEditorEvent.didReceiveOptions(
|
const factory SelectOptionEditorEvent.didReceiveOptions(
|
||||||
List<SelectOptionPB> options, List<SelectOptionPB> selectedOptions) = _DidReceiveOptions;
|
List<SelectOptionPB> options, List<SelectOptionPB> selectedOptions) =
|
||||||
const factory SelectOptionEditorEvent.newOption(String optionName) = _NewOption;
|
_DidReceiveOptions;
|
||||||
const factory SelectOptionEditorEvent.selectOption(String optionId) = _SelectOption;
|
const factory SelectOptionEditorEvent.newOption(String optionName) =
|
||||||
const factory SelectOptionEditorEvent.updateOption(SelectOptionPB option) = _UpdateOption;
|
_NewOption;
|
||||||
const factory SelectOptionEditorEvent.deleteOption(SelectOptionPB option) = _DeleteOption;
|
const factory SelectOptionEditorEvent.selectOption(String optionId) =
|
||||||
const factory SelectOptionEditorEvent.filterOption(String optionName) = _SelectOptionFilter;
|
_SelectOption;
|
||||||
|
const factory SelectOptionEditorEvent.updateOption(SelectOptionPB option) =
|
||||||
|
_UpdateOption;
|
||||||
|
const factory SelectOptionEditorEvent.deleteOption(SelectOptionPB option) =
|
||||||
|
_DeleteOption;
|
||||||
|
const factory SelectOptionEditorEvent.filterOption(String optionName) =
|
||||||
|
_SelectOptionFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
@ -183,7 +195,8 @@ class SelectOptionEditorState with _$SelectOptionEditorState {
|
|||||||
required Option<String> filter,
|
required Option<String> filter,
|
||||||
}) = _SelectOptionEditorState;
|
}) = _SelectOptionEditorState;
|
||||||
|
|
||||||
factory SelectOptionEditorState.initial(GridSelectOptionCellController context) {
|
factory SelectOptionEditorState.initial(
|
||||||
|
GridSelectOptionCellController context) {
|
||||||
final data = context.getCellData(loadIfNotExist: false);
|
final data = context.getCellData(loadIfNotExist: false);
|
||||||
return SelectOptionEditorState(
|
return SelectOptionEditorState(
|
||||||
options: data?.options ?? [],
|
options: data?.options ?? [],
|
@ -2,7 +2,7 @@ import 'package:dartz/dartz.dart';
|
|||||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/cell_entities.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/cell_entities.pb.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart';
|
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_service.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
||||||
import 'cell_service/cell_service.dart';
|
import 'cell_service/cell_service.dart';
|
||||||
|
|
||||||
@ -15,7 +15,9 @@ class SelectOptionService {
|
|||||||
String get rowId => cellId.rowId;
|
String get rowId => cellId.rowId;
|
||||||
|
|
||||||
Future<Either<Unit, FlowyError>> create({required String name}) {
|
Future<Either<Unit, FlowyError>> create({required String name}) {
|
||||||
return TypeOptionService(gridId: gridId, fieldId: fieldId).newOption(name: name).then(
|
return TypeOptionService(gridId: gridId, fieldId: fieldId)
|
||||||
|
.newOption(name: name)
|
||||||
|
.then(
|
||||||
(result) {
|
(result) {
|
||||||
return result.fold(
|
return result.fold(
|
||||||
(option) {
|
(option) {
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:app_flowy/workspace/application/grid/field/field_listener.dart';
|
import 'package:app_flowy/plugins/grid/application/field/field_listener.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
|
import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
|
||||||
import 'package:flowy_sdk/log.dart';
|
import 'package:flowy_sdk/log.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -15,7 +15,8 @@ class FieldCellBloc extends Bloc<FieldCellEvent, FieldCellState> {
|
|||||||
FieldCellBloc({
|
FieldCellBloc({
|
||||||
required GridFieldCellContext cellContext,
|
required GridFieldCellContext cellContext,
|
||||||
}) : _fieldListener = SingleFieldListener(fieldId: cellContext.field.id),
|
}) : _fieldListener = SingleFieldListener(fieldId: cellContext.field.id),
|
||||||
_fieldService = FieldService(gridId: cellContext.gridId, fieldId: cellContext.field.id),
|
_fieldService = FieldService(
|
||||||
|
gridId: cellContext.gridId, fieldId: cellContext.field.id),
|
||||||
super(FieldCellState.initial(cellContext)) {
|
super(FieldCellState.initial(cellContext)) {
|
||||||
on<FieldCellEvent>(
|
on<FieldCellEvent>(
|
||||||
(event, emit) async {
|
(event, emit) async {
|
||||||
@ -62,8 +63,10 @@ class FieldCellBloc extends Bloc<FieldCellEvent, FieldCellState> {
|
|||||||
@freezed
|
@freezed
|
||||||
class FieldCellEvent with _$FieldCellEvent {
|
class FieldCellEvent with _$FieldCellEvent {
|
||||||
const factory FieldCellEvent.initial() = _InitialCell;
|
const factory FieldCellEvent.initial() = _InitialCell;
|
||||||
const factory FieldCellEvent.didReceiveFieldUpdate(GridFieldPB field) = _DidReceiveFieldUpdate;
|
const factory FieldCellEvent.didReceiveFieldUpdate(GridFieldPB field) =
|
||||||
const factory FieldCellEvent.startUpdateWidth(double offset) = _StartUpdateWidth;
|
_DidReceiveFieldUpdate;
|
||||||
|
const factory FieldCellEvent.startUpdateWidth(double offset) =
|
||||||
|
_StartUpdateWidth;
|
||||||
const factory FieldCellEvent.endUpdateWidth() = _EndUpdateWidth;
|
const factory FieldCellEvent.endUpdateWidth() = _EndUpdateWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +78,8 @@ class FieldCellState with _$FieldCellState {
|
|||||||
required double width,
|
required double width,
|
||||||
}) = _FieldCellState;
|
}) = _FieldCellState;
|
||||||
|
|
||||||
factory FieldCellState.initial(GridFieldCellContext cellContext) => FieldCellState(
|
factory FieldCellState.initial(GridFieldCellContext cellContext) =>
|
||||||
|
FieldCellState(
|
||||||
gridId: cellContext.gridId,
|
gridId: cellContext.gridId,
|
||||||
field: cellContext.field,
|
field: cellContext.field,
|
||||||
width: cellContext.field.width.toDouble(),
|
width: cellContext.field.width.toDouble(),
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart';
|
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_service.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option_entities.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option_entities.pb.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -16,20 +16,24 @@ class DateTypeOptionDataParser extends TypeOptionDataParser<DateTypeOption> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DateTypeOptionBloc extends Bloc<DateTypeOptionEvent, DateTypeOptionState> {
|
class DateTypeOptionBloc
|
||||||
|
extends Bloc<DateTypeOptionEvent, DateTypeOptionState> {
|
||||||
DateTypeOptionBloc({required DateTypeOptionContext typeOptionContext})
|
DateTypeOptionBloc({required DateTypeOptionContext typeOptionContext})
|
||||||
: super(DateTypeOptionState.initial(typeOptionContext.typeOption)) {
|
: super(DateTypeOptionState.initial(typeOptionContext.typeOption)) {
|
||||||
on<DateTypeOptionEvent>(
|
on<DateTypeOptionEvent>(
|
||||||
(event, emit) async {
|
(event, emit) async {
|
||||||
event.map(
|
event.map(
|
||||||
didSelectDateFormat: (_DidSelectDateFormat value) {
|
didSelectDateFormat: (_DidSelectDateFormat value) {
|
||||||
emit(state.copyWith(typeOption: _updateTypeOption(dateFormat: value.format)));
|
emit(state.copyWith(
|
||||||
|
typeOption: _updateTypeOption(dateFormat: value.format)));
|
||||||
},
|
},
|
||||||
didSelectTimeFormat: (_DidSelectTimeFormat value) {
|
didSelectTimeFormat: (_DidSelectTimeFormat value) {
|
||||||
emit(state.copyWith(typeOption: _updateTypeOption(timeFormat: value.format)));
|
emit(state.copyWith(
|
||||||
|
typeOption: _updateTypeOption(timeFormat: value.format)));
|
||||||
},
|
},
|
||||||
includeTime: (_IncludeTime value) {
|
includeTime: (_IncludeTime value) {
|
||||||
emit(state.copyWith(typeOption: _updateTypeOption(includeTime: value.includeTime)));
|
emit(state.copyWith(
|
||||||
|
typeOption: _updateTypeOption(includeTime: value.includeTime)));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -65,9 +69,12 @@ class DateTypeOptionBloc extends Bloc<DateTypeOptionEvent, DateTypeOptionState>
|
|||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class DateTypeOptionEvent with _$DateTypeOptionEvent {
|
class DateTypeOptionEvent with _$DateTypeOptionEvent {
|
||||||
const factory DateTypeOptionEvent.didSelectDateFormat(DateFormat format) = _DidSelectDateFormat;
|
const factory DateTypeOptionEvent.didSelectDateFormat(DateFormat format) =
|
||||||
const factory DateTypeOptionEvent.didSelectTimeFormat(TimeFormat format) = _DidSelectTimeFormat;
|
_DidSelectDateFormat;
|
||||||
const factory DateTypeOptionEvent.includeTime(bool includeTime) = _IncludeTime;
|
const factory DateTypeOptionEvent.didSelectTimeFormat(TimeFormat format) =
|
||||||
|
_DidSelectTimeFormat;
|
||||||
|
const factory DateTypeOptionEvent.includeTime(bool includeTime) =
|
||||||
|
_IncludeTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
@ -76,5 +83,6 @@ class DateTypeOptionState with _$DateTypeOptionState {
|
|||||||
required DateTypeOption typeOption,
|
required DateTypeOption typeOption,
|
||||||
}) = _DateTypeOptionState;
|
}) = _DateTypeOptionState;
|
||||||
|
|
||||||
factory DateTypeOptionState.initial(DateTypeOption typeOption) => DateTypeOptionState(typeOption: typeOption);
|
factory DateTypeOptionState.initial(DateTypeOption typeOption) =>
|
||||||
|
DateTypeOptionState(typeOption: typeOption);
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
|
import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
|
||||||
import 'package:flowy_sdk/log.dart';
|
import 'package:flowy_sdk/log.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/multi_select_type_option.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/multi_select_type_option.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
||||||
@ -7,7 +7,8 @@ import 'package:protobuf/protobuf.dart';
|
|||||||
import 'select_option_type_option_bloc.dart';
|
import 'select_option_type_option_bloc.dart';
|
||||||
import 'type_option_service.dart';
|
import 'type_option_service.dart';
|
||||||
|
|
||||||
class MultiSelectTypeOptionContext extends TypeOptionWidgetContext<MultiSelectTypeOption>
|
class MultiSelectTypeOptionContext
|
||||||
|
extends TypeOptionWidgetContext<MultiSelectTypeOption>
|
||||||
with SelectOptionTypeOptionAction {
|
with SelectOptionTypeOptionAction {
|
||||||
final TypeOptionService service;
|
final TypeOptionService service;
|
||||||
|
|
||||||
@ -25,7 +26,8 @@ class MultiSelectTypeOptionContext extends TypeOptionWidgetContext<MultiSelectTy
|
|||||||
return (SelectOptionPB option) {
|
return (SelectOptionPB option) {
|
||||||
typeOption.freeze();
|
typeOption.freeze();
|
||||||
typeOption = typeOption.rebuild((typeOption) {
|
typeOption = typeOption.rebuild((typeOption) {
|
||||||
final index = typeOption.options.indexWhere((element) => element.id == option.id);
|
final index =
|
||||||
|
typeOption.options.indexWhere((element) => element.id == option.id);
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
typeOption.options.removeAt(index);
|
typeOption.options.removeAt(index);
|
||||||
}
|
}
|
||||||
@ -61,7 +63,8 @@ class MultiSelectTypeOptionContext extends TypeOptionWidgetContext<MultiSelectTy
|
|||||||
return (SelectOptionPB option) {
|
return (SelectOptionPB option) {
|
||||||
typeOption.freeze();
|
typeOption.freeze();
|
||||||
typeOption = typeOption.rebuild((typeOption) {
|
typeOption = typeOption.rebuild((typeOption) {
|
||||||
final index = typeOption.options.indexWhere((element) => element.id == option.id);
|
final index =
|
||||||
|
typeOption.options.indexWhere((element) => element.id == option.id);
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
typeOption.options[index] = option;
|
typeOption.options[index] = option;
|
||||||
}
|
}
|
||||||
@ -71,7 +74,8 @@ class MultiSelectTypeOptionContext extends TypeOptionWidgetContext<MultiSelectTy
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MultiSelectTypeOptionWidgetDataParser extends TypeOptionDataParser<MultiSelectTypeOption> {
|
class MultiSelectTypeOptionWidgetDataParser
|
||||||
|
extends TypeOptionDataParser<MultiSelectTypeOption> {
|
||||||
@override
|
@override
|
||||||
MultiSelectTypeOption fromBuffer(List<int> buffer) {
|
MultiSelectTypeOption fromBuffer(List<int> buffer) {
|
||||||
return MultiSelectTypeOption.fromBuffer(buffer);
|
return MultiSelectTypeOption.fromBuffer(buffer);
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart';
|
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_service.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/format.pbenum.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/format.pbenum.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/number_type_option.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/number_type_option.pb.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -10,14 +10,16 @@ part 'number_bloc.freezed.dart';
|
|||||||
|
|
||||||
typedef NumberTypeOptionContext = TypeOptionWidgetContext<NumberTypeOption>;
|
typedef NumberTypeOptionContext = TypeOptionWidgetContext<NumberTypeOption>;
|
||||||
|
|
||||||
class NumberTypeOptionWidgetDataParser extends TypeOptionDataParser<NumberTypeOption> {
|
class NumberTypeOptionWidgetDataParser
|
||||||
|
extends TypeOptionDataParser<NumberTypeOption> {
|
||||||
@override
|
@override
|
||||||
NumberTypeOption fromBuffer(List<int> buffer) {
|
NumberTypeOption fromBuffer(List<int> buffer) {
|
||||||
return NumberTypeOption.fromBuffer(buffer);
|
return NumberTypeOption.fromBuffer(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NumberTypeOptionBloc extends Bloc<NumberTypeOptionEvent, NumberTypeOptionState> {
|
class NumberTypeOptionBloc
|
||||||
|
extends Bloc<NumberTypeOptionEvent, NumberTypeOptionState> {
|
||||||
NumberTypeOptionBloc({required NumberTypeOptionContext typeOptionContext})
|
NumberTypeOptionBloc({required NumberTypeOptionContext typeOptionContext})
|
||||||
: super(NumberTypeOptionState.initial(typeOptionContext.typeOption)) {
|
: super(NumberTypeOptionState.initial(typeOptionContext.typeOption)) {
|
||||||
on<NumberTypeOptionEvent>(
|
on<NumberTypeOptionEvent>(
|
||||||
@ -46,7 +48,8 @@ class NumberTypeOptionBloc extends Bloc<NumberTypeOptionEvent, NumberTypeOptionS
|
|||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class NumberTypeOptionEvent with _$NumberTypeOptionEvent {
|
class NumberTypeOptionEvent with _$NumberTypeOptionEvent {
|
||||||
const factory NumberTypeOptionEvent.didSelectFormat(NumberFormat format) = _DidSelectFormat;
|
const factory NumberTypeOptionEvent.didSelectFormat(NumberFormat format) =
|
||||||
|
_DidSelectFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
@ -55,7 +58,8 @@ class NumberTypeOptionState with _$NumberTypeOptionState {
|
|||||||
required NumberTypeOption typeOption,
|
required NumberTypeOption typeOption,
|
||||||
}) = _NumberTypeOptionState;
|
}) = _NumberTypeOptionState;
|
||||||
|
|
||||||
factory NumberTypeOptionState.initial(NumberTypeOption typeOption) => NumberTypeOptionState(
|
factory NumberTypeOptionState.initial(NumberTypeOption typeOption) =>
|
||||||
|
NumberTypeOptionState(
|
||||||
typeOption: typeOption,
|
typeOption: typeOption,
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
|
import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
|
||||||
import 'package:flowy_sdk/log.dart';
|
import 'package:flowy_sdk/log.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/single_select_type_option.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/single_select_type_option.pb.dart';
|
||||||
@ -7,7 +7,8 @@ import 'package:protobuf/protobuf.dart';
|
|||||||
import 'select_option_type_option_bloc.dart';
|
import 'select_option_type_option_bloc.dart';
|
||||||
import 'type_option_service.dart';
|
import 'type_option_service.dart';
|
||||||
|
|
||||||
class SingleSelectTypeOptionContext extends TypeOptionWidgetContext<SingleSelectTypeOptionPB>
|
class SingleSelectTypeOptionContext
|
||||||
|
extends TypeOptionWidgetContext<SingleSelectTypeOptionPB>
|
||||||
with SelectOptionTypeOptionAction {
|
with SelectOptionTypeOptionAction {
|
||||||
final TypeOptionService service;
|
final TypeOptionService service;
|
||||||
|
|
||||||
@ -25,7 +26,8 @@ class SingleSelectTypeOptionContext extends TypeOptionWidgetContext<SingleSelect
|
|||||||
return (SelectOptionPB option) {
|
return (SelectOptionPB option) {
|
||||||
typeOption.freeze();
|
typeOption.freeze();
|
||||||
typeOption = typeOption.rebuild((typeOption) {
|
typeOption = typeOption.rebuild((typeOption) {
|
||||||
final index = typeOption.options.indexWhere((element) => element.id == option.id);
|
final index =
|
||||||
|
typeOption.options.indexWhere((element) => element.id == option.id);
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
typeOption.options.removeAt(index);
|
typeOption.options.removeAt(index);
|
||||||
}
|
}
|
||||||
@ -61,7 +63,8 @@ class SingleSelectTypeOptionContext extends TypeOptionWidgetContext<SingleSelect
|
|||||||
return (SelectOptionPB option) {
|
return (SelectOptionPB option) {
|
||||||
typeOption.freeze();
|
typeOption.freeze();
|
||||||
typeOption = typeOption.rebuild((typeOption) {
|
typeOption = typeOption.rebuild((typeOption) {
|
||||||
final index = typeOption.options.indexWhere((element) => element.id == option.id);
|
final index =
|
||||||
|
typeOption.options.indexWhere((element) => element.id == option.id);
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
typeOption.options[index] = option;
|
typeOption.options[index] = option;
|
||||||
}
|
}
|
||||||
@ -71,7 +74,8 @@ class SingleSelectTypeOptionContext extends TypeOptionWidgetContext<SingleSelect
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SingleSelectTypeOptionWidgetDataParser extends TypeOptionDataParser<SingleSelectTypeOptionPB> {
|
class SingleSelectTypeOptionWidgetDataParser
|
||||||
|
extends TypeOptionDataParser<SingleSelectTypeOptionPB> {
|
||||||
@override
|
@override
|
||||||
SingleSelectTypeOptionPB fromBuffer(List<int> buffer) {
|
SingleSelectTypeOptionPB fromBuffer(List<int> buffer) {
|
||||||
return SingleSelectTypeOptionPB.fromBuffer(buffer);
|
return SingleSelectTypeOptionPB.fromBuffer(buffer);
|
@ -1,6 +1,6 @@
|
|||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
|
import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||||
@ -92,7 +92,9 @@ class TypeOptionContext2<T> {
|
|||||||
return Future(() => left(_data!));
|
return Future(() => left(_data!));
|
||||||
}
|
}
|
||||||
|
|
||||||
return _fieldService.getFieldTypeOptionData(fieldType: field.fieldType).then((result) {
|
return _fieldService
|
||||||
|
.getFieldTypeOptionData(fieldType: field.fieldType)
|
||||||
|
.then((result) {
|
||||||
return result.fold(
|
return result.fold(
|
||||||
(data) {
|
(data) {
|
||||||
_data = dataBuilder.fromBuffer(data.typeOptionData);
|
_data = dataBuilder.fromBuffer(data.typeOptionData);
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
|
import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
|
||||||
import 'package:flowy_sdk/log.dart';
|
import 'package:flowy_sdk/log.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -33,7 +33,8 @@ class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _moveField(_MoveField value, Emitter<GridHeaderState> emit) async {
|
Future<void> _moveField(
|
||||||
|
_MoveField value, Emitter<GridHeaderState> emit) async {
|
||||||
final fields = List<GridFieldPB>.from(state.fields);
|
final fields = List<GridFieldPB>.from(state.fields);
|
||||||
fields.insert(value.toIndex, fields.removeAt(value.fromIndex));
|
fields.insert(value.toIndex, fields.removeAt(value.fromIndex));
|
||||||
emit(state.copyWith(fields: fields));
|
emit(state.copyWith(fields: fields));
|
||||||
@ -62,13 +63,16 @@ class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> {
|
|||||||
@freezed
|
@freezed
|
||||||
class GridHeaderEvent with _$GridHeaderEvent {
|
class GridHeaderEvent with _$GridHeaderEvent {
|
||||||
const factory GridHeaderEvent.initial() = _InitialHeader;
|
const factory GridHeaderEvent.initial() = _InitialHeader;
|
||||||
const factory GridHeaderEvent.didReceiveFieldUpdate(List<GridFieldPB> fields) = _DidReceiveFieldUpdate;
|
const factory GridHeaderEvent.didReceiveFieldUpdate(
|
||||||
const factory GridHeaderEvent.moveField(GridFieldPB field, int fromIndex, int toIndex) = _MoveField;
|
List<GridFieldPB> fields) = _DidReceiveFieldUpdate;
|
||||||
|
const factory GridHeaderEvent.moveField(
|
||||||
|
GridFieldPB field, int fromIndex, int toIndex) = _MoveField;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class GridHeaderState with _$GridHeaderState {
|
class GridHeaderState with _$GridHeaderState {
|
||||||
const factory GridHeaderState({required List<GridFieldPB> fields}) = _GridHeaderState;
|
const factory GridHeaderState({required List<GridFieldPB> fields}) =
|
||||||
|
_GridHeaderState;
|
||||||
|
|
||||||
factory GridHeaderState.initial(List<GridFieldPB> fields) {
|
factory GridHeaderState.initial(List<GridFieldPB> fields) {
|
||||||
// final List<GridFieldPB> newFields = List.from(fields);
|
// final List<GridFieldPB> newFields = List.from(fields);
|
@ -1,6 +1,6 @@
|
|||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
|
|
||||||
import 'package:app_flowy/workspace/application/grid/field/grid_listenr.dart';
|
import 'package:app_flowy/plugins/grid/application/field/grid_listener.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||||
import 'package:flowy_sdk/log.dart';
|
import 'package:flowy_sdk/log.dart';
|
||||||
@ -26,13 +26,15 @@ class GridService {
|
|||||||
return GridEventGetGrid(payload).send();
|
return GridEventGetGrid(payload).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<GridRowPB, FlowyError>> createRow({Option<String>? startRowId}) {
|
Future<Either<GridRowPB, FlowyError>> createRow(
|
||||||
|
{Option<String>? startRowId}) {
|
||||||
CreateRowPayloadPB payload = CreateRowPayloadPB.create()..gridId = gridId;
|
CreateRowPayloadPB payload = CreateRowPayloadPB.create()..gridId = gridId;
|
||||||
startRowId?.fold(() => null, (id) => payload.startRowId = id);
|
startRowId?.fold(() => null, (id) => payload.startRowId = id);
|
||||||
return GridEventCreateRow(payload).send();
|
return GridEventCreateRow(payload).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<RepeatedGridFieldPB, FlowyError>> getFields({required List<GridFieldIdPB> fieldIds}) {
|
Future<Either<RepeatedGridFieldPB, FlowyError>> getFields(
|
||||||
|
{required List<GridFieldIdPB> fieldIds}) {
|
||||||
final payload = QueryFieldPayloadPB.create()
|
final payload = QueryFieldPayloadPB.create()
|
||||||
..gridId = gridId
|
..gridId = gridId
|
||||||
..fieldIds = RepeatedGridFieldIdPB(items: fieldIds);
|
..fieldIds = RepeatedGridFieldIdPB(items: fieldIds);
|
||||||
@ -64,9 +66,11 @@ class GridFieldCache {
|
|||||||
final GridFieldsListener _fieldListener;
|
final GridFieldsListener _fieldListener;
|
||||||
FieldsNotifier? _fieldNotifier = FieldsNotifier();
|
FieldsNotifier? _fieldNotifier = FieldsNotifier();
|
||||||
final Map<FieldsCallback, VoidCallback> _fieldsCallbackMap = {};
|
final Map<FieldsCallback, VoidCallback> _fieldsCallbackMap = {};
|
||||||
final Map<FieldChangesetCallback, FieldChangesetCallback> _changesetCallbackMap = {};
|
final Map<FieldChangesetCallback, FieldChangesetCallback>
|
||||||
|
_changesetCallbackMap = {};
|
||||||
|
|
||||||
GridFieldCache({required this.gridId}) : _fieldListener = GridFieldsListener(gridId: gridId) {
|
GridFieldCache({required this.gridId})
|
||||||
|
: _fieldListener = GridFieldsListener(gridId: gridId) {
|
||||||
_fieldListener.start(onFieldsChanged: (result) {
|
_fieldListener.start(onFieldsChanged: (result) {
|
||||||
result.fold(
|
result.fold(
|
||||||
(changeset) {
|
(changeset) {
|
||||||
@ -88,7 +92,8 @@ class GridFieldCache {
|
|||||||
_fieldNotifier = null;
|
_fieldNotifier = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
UnmodifiableListView<GridFieldPB> get unmodifiableFields => UnmodifiableListView(_fieldNotifier?.fields ?? []);
|
UnmodifiableListView<GridFieldPB> get unmodifiableFields =>
|
||||||
|
UnmodifiableListView(_fieldNotifier?.fields ?? []);
|
||||||
|
|
||||||
List<GridFieldPB> get fields => [..._fieldNotifier?.fields ?? []];
|
List<GridFieldPB> get fields => [..._fieldNotifier?.fields ?? []];
|
||||||
|
|
||||||
@ -127,7 +132,7 @@ class GridFieldCache {
|
|||||||
|
|
||||||
void removeListener({
|
void removeListener({
|
||||||
FieldsCallback? onFieldsListener,
|
FieldsCallback? onFieldsListener,
|
||||||
FieldChangesetCallback? onChangsetListener,
|
FieldChangesetCallback? onChangesetListener,
|
||||||
}) {
|
}) {
|
||||||
if (onFieldsListener != null) {
|
if (onFieldsListener != null) {
|
||||||
final fn = _fieldsCallbackMap.remove(onFieldsListener);
|
final fn = _fieldsCallbackMap.remove(onFieldsListener);
|
||||||
@ -136,8 +141,8 @@ class GridFieldCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onChangsetListener != null) {
|
if (onChangesetListener != null) {
|
||||||
_changesetCallbackMap.remove(onChangsetListener);
|
_changesetCallbackMap.remove(onChangesetListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,7 +180,8 @@ class GridFieldCache {
|
|||||||
}
|
}
|
||||||
final List<GridFieldPB> newFields = fields;
|
final List<GridFieldPB> newFields = fields;
|
||||||
for (final updatedField in updatedFields) {
|
for (final updatedField in updatedFields) {
|
||||||
final index = newFields.indexWhere((field) => field.id == updatedField.id);
|
final index =
|
||||||
|
newFields.indexWhere((field) => field.id == updatedField.id);
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
newFields.removeAt(index);
|
newFields.removeAt(index);
|
||||||
newFields.insert(index, updatedField);
|
newFields.insert(index, updatedField);
|
||||||
@ -219,7 +225,7 @@ class GridRowCacheFieldNotifierImpl extends GridRowCacheFieldNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_onChangesetFn != null) {
|
if (_onChangesetFn != null) {
|
||||||
_cache.removeListener(onChangsetListener: _onChangesetFn!);
|
_cache.removeListener(onChangesetListener: _onChangesetFn!);
|
||||||
_onChangesetFn = null;
|
_onChangesetFn = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:app_flowy/workspace/application/grid/row/row_service.dart';
|
import 'package:app_flowy/plugins/grid/application/row/row_service.dart';
|
||||||
import 'package:flowy_sdk/log.dart';
|
import 'package:flowy_sdk/log.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -8,7 +8,8 @@ import 'package:dartz/dartz.dart';
|
|||||||
|
|
||||||
part 'row_action_sheet_bloc.freezed.dart';
|
part 'row_action_sheet_bloc.freezed.dart';
|
||||||
|
|
||||||
class RowActionSheetBloc extends Bloc<RowActionSheetEvent, RowActionSheetState> {
|
class RowActionSheetBloc
|
||||||
|
extends Bloc<RowActionSheetEvent, RowActionSheetState> {
|
||||||
final RowService _rowService;
|
final RowService _rowService;
|
||||||
|
|
||||||
RowActionSheetBloc({required GridRowInfo rowData})
|
RowActionSheetBloc({required GridRowInfo rowData})
|
||||||
@ -56,7 +57,8 @@ class RowActionSheetState with _$RowActionSheetState {
|
|||||||
required GridRowInfo rowData,
|
required GridRowInfo rowData,
|
||||||
}) = _RowActionSheetState;
|
}) = _RowActionSheetState;
|
||||||
|
|
||||||
factory RowActionSheetState.initial(GridRowInfo rowData) => RowActionSheetState(
|
factory RowActionSheetState.initial(GridRowInfo rowData) =>
|
||||||
|
RowActionSheetState(
|
||||||
rowData: rowData,
|
rowData: rowData,
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart';
|
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -34,7 +34,9 @@ class RowBloc extends Bloc<RowEvent, RowState> {
|
|||||||
_rowService.createRow();
|
_rowService.createRow();
|
||||||
},
|
},
|
||||||
didReceiveCellDatas: (_DidReceiveCellDatas value) async {
|
didReceiveCellDatas: (_DidReceiveCellDatas value) async {
|
||||||
final fields = value.gridCellMap.values.map((e) => GridCellEquatable(e.field)).toList();
|
final fields = value.gridCellMap.values
|
||||||
|
.map((e) => GridCellEquatable(e.field))
|
||||||
|
.toList();
|
||||||
final snapshots = UnmodifiableListView(fields);
|
final snapshots = UnmodifiableListView(fields);
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
gridCellMap: value.gridCellMap,
|
gridCellMap: value.gridCellMap,
|
||||||
@ -59,7 +61,8 @@ class RowBloc extends Bloc<RowEvent, RowState> {
|
|||||||
Future<void> _startListening() async {
|
Future<void> _startListening() async {
|
||||||
_rowListenFn = _rowCache.addListener(
|
_rowListenFn = _rowCache.addListener(
|
||||||
rowId: state.rowInfo.id,
|
rowId: state.rowInfo.id,
|
||||||
onCellUpdated: (cellDatas, reason) => add(RowEvent.didReceiveCellDatas(cellDatas, reason)),
|
onCellUpdated: (cellDatas, reason) =>
|
||||||
|
add(RowEvent.didReceiveCellDatas(cellDatas, reason)),
|
||||||
listenWhen: () => !isClosed,
|
listenWhen: () => !isClosed,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -69,7 +72,8 @@ class RowBloc extends Bloc<RowEvent, RowState> {
|
|||||||
class RowEvent with _$RowEvent {
|
class RowEvent with _$RowEvent {
|
||||||
const factory RowEvent.initial() = _InitialRow;
|
const factory RowEvent.initial() = _InitialRow;
|
||||||
const factory RowEvent.createRow() = _CreateRow;
|
const factory RowEvent.createRow() = _CreateRow;
|
||||||
const factory RowEvent.didReceiveCellDatas(GridCellMap gridCellMap, GridRowChangeReason reason) =
|
const factory RowEvent.didReceiveCellDatas(
|
||||||
|
GridCellMap gridCellMap, GridRowChangeReason reason) =
|
||||||
_DidReceiveCellDatas;
|
_DidReceiveCellDatas;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,10 +86,12 @@ class RowState with _$RowState {
|
|||||||
GridRowChangeReason? changeReason,
|
GridRowChangeReason? changeReason,
|
||||||
}) = _RowState;
|
}) = _RowState;
|
||||||
|
|
||||||
factory RowState.initial(GridRowInfo rowInfo, GridCellMap cellDataMap) => RowState(
|
factory RowState.initial(GridRowInfo rowInfo, GridCellMap cellDataMap) =>
|
||||||
|
RowState(
|
||||||
rowInfo: rowInfo,
|
rowInfo: rowInfo,
|
||||||
gridCellMap: cellDataMap,
|
gridCellMap: cellDataMap,
|
||||||
snapshots: UnmodifiableListView(cellDataMap.values.map((e) => GridCellEquatable(e.field)).toList()),
|
snapshots: UnmodifiableListView(
|
||||||
|
cellDataMap.values.map((e) => GridCellEquatable(e.field)).toList()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart';
|
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
@ -42,7 +42,8 @@ class RowDetailBloc extends Bloc<RowDetailEvent, RowDetailState> {
|
|||||||
Future<void> _startListening() async {
|
Future<void> _startListening() async {
|
||||||
_rowListenFn = _rowCache.addListener(
|
_rowListenFn = _rowCache.addListener(
|
||||||
rowId: rowInfo.id,
|
rowId: rowInfo.id,
|
||||||
onCellUpdated: (cellDatas, reason) => add(RowDetailEvent.didReceiveCellDatas(cellDatas.values.toList())),
|
onCellUpdated: (cellDatas, reason) =>
|
||||||
|
add(RowDetailEvent.didReceiveCellDatas(cellDatas.values.toList())),
|
||||||
listenWhen: () => !isClosed,
|
listenWhen: () => !isClosed,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -58,7 +59,8 @@ class RowDetailBloc extends Bloc<RowDetailEvent, RowDetailState> {
|
|||||||
@freezed
|
@freezed
|
||||||
class RowDetailEvent with _$RowDetailEvent {
|
class RowDetailEvent with _$RowDetailEvent {
|
||||||
const factory RowDetailEvent.initial() = _Initial;
|
const factory RowDetailEvent.initial() = _Initial;
|
||||||
const factory RowDetailEvent.didReceiveCellDatas(List<GridCellIdentifier> gridCells) = _DidReceiveCellDatas;
|
const factory RowDetailEvent.didReceiveCellDatas(
|
||||||
|
List<GridCellIdentifier> gridCells) = _DidReceiveCellDatas;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
@ -1,5 +1,5 @@
|
|||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart';
|
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||||
import 'package:flowy_sdk/log.dart';
|
import 'package:flowy_sdk/log.dart';
|
||||||
@ -53,9 +53,12 @@ class GridRowCache {
|
|||||||
_rowChangeReasonNotifier = _GridRowChangesetNotifier(),
|
_rowChangeReasonNotifier = _GridRowChangesetNotifier(),
|
||||||
_fieldNotifier = notifier {
|
_fieldNotifier = notifier {
|
||||||
//
|
//
|
||||||
notifier.onFieldsChanged(() => _rowChangeReasonNotifier.receive(const GridRowChangeReason.fieldDidChange()));
|
notifier.onFieldsChanged(() => _rowChangeReasonNotifier
|
||||||
|
.receive(const GridRowChangeReason.fieldDidChange()));
|
||||||
notifier.onFieldChanged((field) => _cellCache.remove(field.id));
|
notifier.onFieldChanged((field) => _cellCache.remove(field.id));
|
||||||
_rowInfos = block.rows.map((rowInfo) => buildGridRow(rowInfo.id, rowInfo.height.toDouble())).toList();
|
_rowInfos = block.rows
|
||||||
|
.map((rowInfo) => buildGridRow(rowInfo.id, rowInfo.height.toDouble()))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> dispose() async {
|
Future<void> dispose() async {
|
||||||
@ -81,7 +84,9 @@ class GridRowCache {
|
|||||||
|
|
||||||
final List<GridRowInfo> newRows = [];
|
final List<GridRowInfo> newRows = [];
|
||||||
final DeletedIndexs deletedIndex = [];
|
final DeletedIndexs deletedIndex = [];
|
||||||
final Map<String, String> deletedRowByRowId = {for (var rowId in deletedRows) rowId: rowId};
|
final Map<String, String> deletedRowByRowId = {
|
||||||
|
for (var rowId in deletedRows) rowId: rowId
|
||||||
|
};
|
||||||
|
|
||||||
_rowInfos.asMap().forEach((index, row) {
|
_rowInfos.asMap().forEach((index, row) {
|
||||||
if (deletedRowByRowId[row.id] == null) {
|
if (deletedRowByRowId[row.id] == null) {
|
||||||
@ -107,7 +112,8 @@ class GridRowCache {
|
|||||||
rowId: insertRow.rowId,
|
rowId: insertRow.rowId,
|
||||||
);
|
);
|
||||||
insertIndexs.add(insertIndex);
|
insertIndexs.add(insertIndex);
|
||||||
_rowInfos.insert(insertRow.index, (buildGridRow(insertRow.rowId, insertRow.height.toDouble())));
|
_rowInfos.insert(insertRow.index,
|
||||||
|
(buildGridRow(insertRow.rowId, insertRow.height.toDouble())));
|
||||||
}
|
}
|
||||||
|
|
||||||
_rowChangeReasonNotifier.receive(GridRowChangeReason.insert(insertIndexs));
|
_rowChangeReasonNotifier.receive(GridRowChangeReason.insert(insertIndexs));
|
||||||
@ -126,7 +132,8 @@ class GridRowCache {
|
|||||||
_rowByRowId[rowId] = updatedRow.row;
|
_rowByRowId[rowId] = updatedRow.row;
|
||||||
|
|
||||||
_rowInfos.removeAt(index);
|
_rowInfos.removeAt(index);
|
||||||
_rowInfos.insert(index, buildGridRow(rowId, updatedRow.row.height.toDouble()));
|
_rowInfos.insert(
|
||||||
|
index, buildGridRow(rowId, updatedRow.row.height.toDouble()));
|
||||||
updatedIndexs[rowId] = UpdatedIndex(index: index, rowId: rowId);
|
updatedIndexs[rowId] = UpdatedIndex(index: index, rowId: rowId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -225,7 +232,8 @@ class GridRowCache {
|
|||||||
updatedRow.freeze();
|
updatedRow.freeze();
|
||||||
|
|
||||||
_rowByRowId[updatedRow.id] = updatedRow;
|
_rowByRowId[updatedRow.id] = updatedRow;
|
||||||
final index = _rowInfos.indexWhere((gridRow) => gridRow.id == updatedRow.id);
|
final index =
|
||||||
|
_rowInfos.indexWhere((gridRow) => gridRow.id == updatedRow.id);
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
// update the corresponding row in _rows if they are not the same
|
// update the corresponding row in _rows if they are not the same
|
||||||
if (_rowInfos[index].rawRow != updatedRow) {
|
if (_rowInfos[index].rawRow != updatedRow) {
|
||||||
@ -237,7 +245,8 @@ class GridRowCache {
|
|||||||
updatedIndexs[row.id] = UpdatedIndex(index: index, rowId: row.id);
|
updatedIndexs[row.id] = UpdatedIndex(index: index, rowId: row.id);
|
||||||
|
|
||||||
//
|
//
|
||||||
_rowChangeReasonNotifier.receive(GridRowChangeReason.update(updatedIndexs));
|
_rowChangeReasonNotifier
|
||||||
|
.receive(GridRowChangeReason.update(updatedIndexs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -275,7 +284,8 @@ class RowService {
|
|||||||
final String blockId;
|
final String blockId;
|
||||||
final String rowId;
|
final String rowId;
|
||||||
|
|
||||||
RowService({required this.gridId, required this.blockId, required this.rowId});
|
RowService(
|
||||||
|
{required this.gridId, required this.blockId, required this.rowId});
|
||||||
|
|
||||||
Future<Either<GridRowPB, FlowyError>> createRow() {
|
Future<Either<GridRowPB, FlowyError>> createRow() {
|
||||||
CreateRowPayloadPB payload = CreateRowPayloadPB.create()
|
CreateRowPayloadPB payload = CreateRowPayloadPB.create()
|
||||||
@ -285,7 +295,8 @@ class RowService {
|
|||||||
return GridEventCreateRow(payload).send();
|
return GridEventCreateRow(payload).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<Unit, FlowyError>> moveRow(String rowId, int fromIndex, int toIndex) {
|
Future<Either<Unit, FlowyError>> moveRow(
|
||||||
|
String rowId, int fromIndex, int toIndex) {
|
||||||
final payload = MoveItemPayloadPB.create()
|
final payload = MoveItemPayloadPB.create()
|
||||||
..gridId = gridId
|
..gridId = gridId
|
||||||
..itemId = rowId
|
..itemId = rowId
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
|
import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/grid_service.dart';
|
import 'package:app_flowy/plugins/grid/application/grid_service.dart';
|
||||||
import 'package:flowy_sdk/log.dart';
|
import 'package:flowy_sdk/log.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -22,8 +22,10 @@ class GridPropertyBloc extends Bloc<GridPropertyEvent, GridPropertyState> {
|
|||||||
_startListening();
|
_startListening();
|
||||||
},
|
},
|
||||||
setFieldVisibility: (_SetFieldVisibility value) async {
|
setFieldVisibility: (_SetFieldVisibility value) async {
|
||||||
final fieldService = FieldService(gridId: gridId, fieldId: value.fieldId);
|
final fieldService =
|
||||||
final result = await fieldService.updateField(visibility: value.visibility);
|
FieldService(gridId: gridId, fieldId: value.fieldId);
|
||||||
|
final result =
|
||||||
|
await fieldService.updateField(visibility: value.visibility);
|
||||||
result.fold(
|
result.fold(
|
||||||
(l) => null,
|
(l) => null,
|
||||||
(err) => Log.error(err),
|
(err) => Log.error(err),
|
||||||
@ -50,7 +52,8 @@ class GridPropertyBloc extends Bloc<GridPropertyEvent, GridPropertyState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _startListening() {
|
void _startListening() {
|
||||||
_onFieldsFn = (fields) => add(GridPropertyEvent.didReceiveFieldUpdate(fields));
|
_onFieldsFn =
|
||||||
|
(fields) => add(GridPropertyEvent.didReceiveFieldUpdate(fields));
|
||||||
_fieldCache.addListener(
|
_fieldCache.addListener(
|
||||||
onFields: _onFieldsFn,
|
onFields: _onFieldsFn,
|
||||||
listenWhen: () => !isClosed,
|
listenWhen: () => !isClosed,
|
||||||
@ -61,9 +64,12 @@ class GridPropertyBloc extends Bloc<GridPropertyEvent, GridPropertyState> {
|
|||||||
@freezed
|
@freezed
|
||||||
class GridPropertyEvent with _$GridPropertyEvent {
|
class GridPropertyEvent with _$GridPropertyEvent {
|
||||||
const factory GridPropertyEvent.initial() = _Initial;
|
const factory GridPropertyEvent.initial() = _Initial;
|
||||||
const factory GridPropertyEvent.setFieldVisibility(String fieldId, bool visibility) = _SetFieldVisibility;
|
const factory GridPropertyEvent.setFieldVisibility(
|
||||||
const factory GridPropertyEvent.didReceiveFieldUpdate(List<GridFieldPB> fields) = _DidReceiveFieldUpdate;
|
String fieldId, bool visibility) = _SetFieldVisibility;
|
||||||
const factory GridPropertyEvent.moveField(int fromIndex, int toIndex) = _MoveField;
|
const factory GridPropertyEvent.didReceiveFieldUpdate(
|
||||||
|
List<GridFieldPB> fields) = _DidReceiveFieldUpdate;
|
||||||
|
const factory GridPropertyEvent.moveField(int fromIndex, int toIndex) =
|
||||||
|
_MoveField;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
@ -73,7 +79,8 @@ class GridPropertyState with _$GridPropertyState {
|
|||||||
required List<GridFieldPB> fields,
|
required List<GridFieldPB> fields,
|
||||||
}) = _GridPropertyState;
|
}) = _GridPropertyState;
|
||||||
|
|
||||||
factory GridPropertyState.initial(String gridId, List<GridFieldPB> fields) => GridPropertyState(
|
factory GridPropertyState.initial(String gridId, List<GridFieldPB> fields) =>
|
||||||
|
GridPropertyState(
|
||||||
gridId: gridId,
|
gridId: gridId,
|
||||||
fields: fields,
|
fields: fields,
|
||||||
);
|
);
|
@ -1,12 +1,12 @@
|
|||||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||||
import 'package:app_flowy/plugin/plugin.dart';
|
import 'package:app_flowy/startup/plugin/plugin.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
|
import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/widgets/left_bar_item.dart';
|
import 'package:app_flowy/workspace/presentation/widgets/left_bar_item.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'src/grid_page.dart';
|
import 'presentation/grid_page.dart';
|
||||||
|
|
||||||
class GridPluginBuilder implements PluginBuilder {
|
class GridPluginBuilder implements PluginBuilder {
|
||||||
@override
|
@override
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:app_flowy/startup/startup.dart';
|
import 'package:app_flowy/startup/startup.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/grid_bloc.dart';
|
import 'package:app_flowy/plugins/grid/application/grid_bloc.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/row/row_service.dart';
|
import 'package:app_flowy/plugins/grid/application/row/row_service.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
|
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart';
|
import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart';
|
||||||
@ -35,13 +35,15 @@ class _GridPageState extends State<GridPage> {
|
|||||||
return MultiBlocProvider(
|
return MultiBlocProvider(
|
||||||
providers: [
|
providers: [
|
||||||
BlocProvider<GridBloc>(
|
BlocProvider<GridBloc>(
|
||||||
create: (context) => getIt<GridBloc>(param1: widget.view)..add(const GridEvent.initial()),
|
create: (context) => getIt<GridBloc>(param1: widget.view)
|
||||||
|
..add(const GridEvent.initial()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
child: BlocBuilder<GridBloc, GridState>(
|
child: BlocBuilder<GridBloc, GridState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return state.loadingState.map(
|
return state.loadingState.map(
|
||||||
loading: (_) => const Center(child: CircularProgressIndicator.adaptive()),
|
loading: (_) =>
|
||||||
|
const Center(child: CircularProgressIndicator.adaptive()),
|
||||||
finish: (result) => result.successOrFail.fold(
|
finish: (result) => result.successOrFail.fold(
|
||||||
(_) => const GridShortcuts(child: FlowyGrid()),
|
(_) => const GridShortcuts(child: FlowyGrid()),
|
||||||
(err) => FlowyErrorPage(err.toString()),
|
(err) => FlowyErrorPage(err.toString()),
|
||||||
@ -76,7 +78,8 @@ class FlowyGrid extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _FlowyGridState extends State<FlowyGrid> {
|
class _FlowyGridState extends State<FlowyGrid> {
|
||||||
final _scrollController = GridScrollController(scrollGroupContorller: LinkedScrollControllerGroup());
|
final _scrollController = GridScrollController(
|
||||||
|
scrollGroupContorller: LinkedScrollControllerGroup());
|
||||||
late ScrollController headerScrollController;
|
late ScrollController headerScrollController;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -204,7 +207,8 @@ class _GridRowsState extends State<_GridRows> {
|
|||||||
for (final item in value.items) {
|
for (final item in value.items) {
|
||||||
_key.currentState?.removeItem(
|
_key.currentState?.removeItem(
|
||||||
item.index,
|
item.index,
|
||||||
(context, animation) => _renderRow(context, item.row, animation),
|
(context, animation) =>
|
||||||
|
_renderRow(context, item.row, animation),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -215,8 +219,10 @@ class _GridRowsState extends State<_GridRows> {
|
|||||||
return SliverAnimatedList(
|
return SliverAnimatedList(
|
||||||
key: _key,
|
key: _key,
|
||||||
initialItemCount: context.read<GridBloc>().state.rowInfos.length,
|
initialItemCount: context.read<GridBloc>().state.rowInfos.length,
|
||||||
itemBuilder: (BuildContext context, int index, Animation<double> animation) {
|
itemBuilder:
|
||||||
final GridRowInfo rowInfo = context.read<GridBloc>().state.rowInfos[index];
|
(BuildContext context, int index, Animation<double> animation) {
|
||||||
|
final GridRowInfo rowInfo =
|
||||||
|
context.read<GridBloc>().state.rowInfos[index];
|
||||||
return _renderRow(context, rowInfo, animation);
|
return _renderRow(context, rowInfo, animation);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -229,7 +235,8 @@ class _GridRowsState extends State<_GridRows> {
|
|||||||
GridRowInfo rowInfo,
|
GridRowInfo rowInfo,
|
||||||
Animation<double> animation,
|
Animation<double> animation,
|
||||||
) {
|
) {
|
||||||
final rowCache = context.read<GridBloc>().getRowCache(rowInfo.blockId, rowInfo.id);
|
final rowCache =
|
||||||
|
context.read<GridBloc>().getRowCache(rowInfo.blockId, rowInfo.id);
|
||||||
final fieldCache = context.read<GridBloc>().fieldCache;
|
final fieldCache = context.read<GridBloc>().fieldCache;
|
||||||
if (rowCache != null) {
|
if (rowCache != null) {
|
||||||
return SizeTransition(
|
return SizeTransition(
|
||||||
@ -266,10 +273,10 @@ class _GridFooter extends StatelessWidget {
|
|||||||
SizedBox(width: GridSize.leadingHeaderPadding),
|
SizedBox(width: GridSize.leadingHeaderPadding),
|
||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(width: 120, child: GridAddRowButton()),
|
const SizedBox(width: 120, child: GridAddRowButton()),
|
||||||
const SizedBox(height: 30),
|
const SizedBox(height: 30),
|
||||||
_rowCountTextWidget(theme: theme,count: rowCount)
|
_rowCountTextWidget(theme: theme, count: rowCount)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -280,16 +287,18 @@ class _GridFooter extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _rowCountTextWidget({required AppTheme theme, required int count}){
|
Widget _rowCountTextWidget({required AppTheme theme, required int count}) {
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
FlowyText.regular('Count : ',
|
FlowyText.regular(
|
||||||
fontSize: 13,
|
'Count : ',
|
||||||
color: theme.shader3,
|
fontSize: 13,
|
||||||
|
color: theme.shader3,
|
||||||
),
|
),
|
||||||
FlowyText.regular(count.toString(),
|
FlowyText.regular(
|
||||||
fontSize: 13,
|
count.toString(),
|
||||||
|
fontSize: 13,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart';
|
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/grid_service.dart';
|
import 'package:app_flowy/plugins/grid/application/grid_service.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
@ -30,19 +30,36 @@ class GridCellBuilder {
|
|||||||
final key = cell.key();
|
final key = cell.key();
|
||||||
switch (cell.fieldType) {
|
switch (cell.fieldType) {
|
||||||
case FieldType.Checkbox:
|
case FieldType.Checkbox:
|
||||||
return GridCheckboxCell(cellControllerBuilder: cellControllerBuilder, key: key);
|
return GridCheckboxCell(
|
||||||
|
cellControllerBuilder: cellControllerBuilder, key: key);
|
||||||
case FieldType.DateTime:
|
case FieldType.DateTime:
|
||||||
return GridDateCell(cellControllerBuilder: cellControllerBuilder, key: key, style: style);
|
return GridDateCell(
|
||||||
|
cellControllerBuilder: cellControllerBuilder,
|
||||||
|
key: key,
|
||||||
|
style: style);
|
||||||
case FieldType.SingleSelect:
|
case FieldType.SingleSelect:
|
||||||
return GridSingleSelectCell(cellContorllerBuilder: cellControllerBuilder, style: style, key: key);
|
return GridSingleSelectCell(
|
||||||
|
cellContorllerBuilder: cellControllerBuilder,
|
||||||
|
style: style,
|
||||||
|
key: key);
|
||||||
case FieldType.MultiSelect:
|
case FieldType.MultiSelect:
|
||||||
return GridMultiSelectCell(cellContorllerBuilder: cellControllerBuilder, style: style, key: key);
|
return GridMultiSelectCell(
|
||||||
|
cellContorllerBuilder: cellControllerBuilder,
|
||||||
|
style: style,
|
||||||
|
key: key);
|
||||||
case FieldType.Number:
|
case FieldType.Number:
|
||||||
return GridNumberCell(cellContorllerBuilder: cellControllerBuilder, key: key);
|
return GridNumberCell(
|
||||||
|
cellContorllerBuilder: cellControllerBuilder, key: key);
|
||||||
case FieldType.RichText:
|
case FieldType.RichText:
|
||||||
return GridTextCell(cellContorllerBuilder: cellControllerBuilder, style: style, key: key);
|
return GridTextCell(
|
||||||
|
cellContorllerBuilder: cellControllerBuilder,
|
||||||
|
style: style,
|
||||||
|
key: key);
|
||||||
case FieldType.URL:
|
case FieldType.URL:
|
||||||
return GridURLCell(cellContorllerBuilder: cellControllerBuilder, style: style, key: key);
|
return GridURLCell(
|
||||||
|
cellContorllerBuilder: cellControllerBuilder,
|
||||||
|
style: style,
|
||||||
|
key: key);
|
||||||
}
|
}
|
||||||
throw UnimplementedError;
|
throw UnimplementedError;
|
||||||
}
|
}
|
||||||
@ -65,7 +82,8 @@ abstract class CellEditable {
|
|||||||
ValueNotifier<bool> get onCellEditing;
|
ValueNotifier<bool> get onCellEditing;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class GridCellWidget extends StatefulWidget implements CellAccessory, CellEditable, CellShortcuts {
|
abstract class GridCellWidget extends StatefulWidget
|
||||||
|
implements CellAccessory, CellEditable, CellShortcuts {
|
||||||
GridCellWidget({Key? key}) : super(key: key) {
|
GridCellWidget({Key? key}) : super(key: key) {
|
||||||
onCellEditing.addListener(() {
|
onCellEditing.addListener(() {
|
||||||
onCellFocus.value = onCellEditing.value;
|
onCellFocus.value = onCellEditing.value;
|
||||||
@ -83,7 +101,8 @@ abstract class GridCellWidget extends StatefulWidget implements CellAccessory, C
|
|||||||
final ValueNotifier<bool> onCellEditing = ValueNotifier<bool>(false);
|
final ValueNotifier<bool> onCellEditing = ValueNotifier<bool>(false);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<GridCellAccessory> Function(GridCellAccessoryBuildContext buildContext)? get accessoryBuilder => null;
|
List<GridCellAccessory> Function(GridCellAccessoryBuildContext buildContext)?
|
||||||
|
get accessoryBuilder => null;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final GridCellFocusListener beginFocus = GridCellFocusListener();
|
final GridCellFocusListener beginFocus = GridCellFocusListener();
|
||||||
@ -129,12 +148,14 @@ abstract class GridCellState<T extends GridCellWidget> extends State<T> {
|
|||||||
void onInsert(String value) {}
|
void onInsert(String value) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class GridFocusNodeCellState<T extends GridCellWidget> extends GridCellState<T> {
|
abstract class GridFocusNodeCellState<T extends GridCellWidget>
|
||||||
|
extends GridCellState<T> {
|
||||||
SingleListenrFocusNode focusNode = SingleListenrFocusNode();
|
SingleListenrFocusNode focusNode = SingleListenrFocusNode();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
widget.shortcutHandlers[CellKeyboardKey.onEnter] = () => focusNode.unfocus();
|
widget.shortcutHandlers[CellKeyboardKey.onEnter] =
|
||||||
|
() => focusNode.unfocus();
|
||||||
_listenOnFocusNodeChanged();
|
_listenOnFocusNodeChanged();
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
@ -1,10 +1,10 @@
|
|||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
|
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart';
|
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
|
||||||
|
import '../../layout/sizes.dart';
|
||||||
|
import '../row/grid_row.dart';
|
||||||
import 'cell_accessory.dart';
|
import 'cell_accessory.dart';
|
||||||
import 'cell_builder.dart';
|
import 'cell_builder.dart';
|
||||||
import 'cell_shortcuts.dart';
|
import 'cell_shortcuts.dart';
|
||||||
@ -24,9 +24,11 @@ class CellContainer extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ChangeNotifierProxyProvider<RegionStateNotifier, CellContainerNotifier>(
|
return ChangeNotifierProxyProvider<RegionStateNotifier,
|
||||||
|
CellContainerNotifier>(
|
||||||
create: (_) => CellContainerNotifier(child),
|
create: (_) => CellContainerNotifier(child),
|
||||||
update: (_, rowStateNotifier, cellStateNotifier) => cellStateNotifier!..onEnter = rowStateNotifier.onEnter,
|
update: (_, rowStateNotifier, cellStateNotifier) =>
|
||||||
|
cellStateNotifier!..onEnter = rowStateNotifier.onEnter,
|
||||||
child: Selector<CellContainerNotifier, bool>(
|
child: Selector<CellContainerNotifier, bool>(
|
||||||
selector: (context, notifier) => notifier.isFocus,
|
selector: (context, notifier) => notifier.isFocus,
|
||||||
builder: (context, isFocus, _) {
|
builder: (context, isFocus, _) {
|
||||||
@ -39,7 +41,8 @@ class CellContainer extends StatelessWidget {
|
|||||||
));
|
));
|
||||||
|
|
||||||
if (accessories.isNotEmpty) {
|
if (accessories.isNotEmpty) {
|
||||||
container = CellEnterRegion(child: container, accessories: accessories);
|
container =
|
||||||
|
CellEnterRegion(child: container, accessories: accessories);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +68,8 @@ class CellContainer extends StatelessWidget {
|
|||||||
return BoxDecoration(border: Border.fromBorderSide(borderSide));
|
return BoxDecoration(border: Border.fromBorderSide(borderSide));
|
||||||
} else {
|
} else {
|
||||||
final borderSide = BorderSide(color: theme.shader5, width: 1.0);
|
final borderSide = BorderSide(color: theme.shader5, width: 1.0);
|
||||||
return BoxDecoration(border: Border(right: borderSide, bottom: borderSide));
|
return BoxDecoration(
|
||||||
|
border: Border(right: borderSide, bottom: borderSide));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -73,7 +77,9 @@ class CellContainer extends StatelessWidget {
|
|||||||
class CellEnterRegion extends StatelessWidget {
|
class CellEnterRegion extends StatelessWidget {
|
||||||
final Widget child;
|
final Widget child;
|
||||||
final List<GridCellAccessory> accessories;
|
final List<GridCellAccessory> accessories;
|
||||||
const CellEnterRegion({required this.child, required this.accessories, Key? key}) : super(key: key);
|
const CellEnterRegion(
|
||||||
|
{required this.child, required this.accessories, Key? key})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -82,13 +88,18 @@ class CellEnterRegion extends StatelessWidget {
|
|||||||
builder: (context, onEnter, _) {
|
builder: (context, onEnter, _) {
|
||||||
List<Widget> children = [child];
|
List<Widget> children = [child];
|
||||||
if (onEnter) {
|
if (onEnter) {
|
||||||
children.add(CellAccessoryContainer(accessories: accessories).positioned(right: 0));
|
children.add(CellAccessoryContainer(accessories: accessories)
|
||||||
|
.positioned(right: 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
return MouseRegion(
|
return MouseRegion(
|
||||||
cursor: SystemMouseCursors.click,
|
cursor: SystemMouseCursors.click,
|
||||||
onEnter: (p) => Provider.of<CellContainerNotifier>(context, listen: false).onEnter = true,
|
onEnter: (p) =>
|
||||||
onExit: (p) => Provider.of<CellContainerNotifier>(context, listen: false).onEnter = false,
|
Provider.of<CellContainerNotifier>(context, listen: false)
|
||||||
|
.onEnter = true,
|
||||||
|
onExit: (p) =>
|
||||||
|
Provider.of<CellContainerNotifier>(context, listen: false)
|
||||||
|
.onEnter = false,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
alignment: AlignmentDirectional.center,
|
alignment: AlignmentDirectional.center,
|
||||||
fit: StackFit.expand,
|
fit: StackFit.expand,
|
||||||
@ -102,7 +113,6 @@ class CellEnterRegion extends StatelessWidget {
|
|||||||
|
|
||||||
class CellContainerNotifier extends ChangeNotifier {
|
class CellContainerNotifier extends ChangeNotifier {
|
||||||
final CellEditable cellEditable;
|
final CellEditable cellEditable;
|
||||||
bool mouted = false;
|
|
||||||
VoidCallback? _onCellFocusListener;
|
VoidCallback? _onCellFocusListener;
|
||||||
bool _isFocus = false;
|
bool _isFocus = false;
|
||||||
bool _onEnter = false;
|
bool _onEnter = false;
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:app_flowy/startup/startup.dart';
|
import 'package:app_flowy/startup/startup.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/prelude.dart';
|
import 'package:app_flowy/plugins/grid/application/prelude.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/icon_button.dart';
|
import 'package:flowy_infra_ui/style_widget/icon_button.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
@ -23,7 +23,8 @@ class _CheckboxCellState extends GridCellState<GridCheckboxCell> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
final cellContext = widget.cellControllerBuilder.build();
|
final cellContext = widget.cellControllerBuilder.build();
|
||||||
_cellBloc = getIt<CheckboxCellBloc>(param1: cellContext)..add(const CheckboxCellEvent.initial());
|
_cellBloc = getIt<CheckboxCellBloc>(param1: cellContext)
|
||||||
|
..add(const CheckboxCellEvent.initial());
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,11 +34,15 @@ class _CheckboxCellState extends GridCellState<GridCheckboxCell> {
|
|||||||
value: _cellBloc,
|
value: _cellBloc,
|
||||||
child: BlocBuilder<CheckboxCellBloc, CheckboxCellState>(
|
child: BlocBuilder<CheckboxCellBloc, CheckboxCellState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
final icon = state.isSelected ? svgWidget('editor/editor_check') : svgWidget('editor/editor_uncheck');
|
final icon = state.isSelected
|
||||||
|
? svgWidget('editor/editor_check')
|
||||||
|
: svgWidget('editor/editor_uncheck');
|
||||||
return Align(
|
return Align(
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
child: FlowyIconButton(
|
child: FlowyIconButton(
|
||||||
onPressed: () => context.read<CheckboxCellBloc>().add(const CheckboxCellEvent.select()),
|
onPressed: () => context
|
||||||
|
.read<CheckboxCellBloc>()
|
||||||
|
.add(const CheckboxCellEvent.select()),
|
||||||
iconPadding: EdgeInsets.zero,
|
iconPadding: EdgeInsets.zero,
|
||||||
icon: icon,
|
icon: icon,
|
||||||
width: 20,
|
width: 20,
|
@ -2,7 +2,7 @@ import 'package:flowy_infra_ui/style_widget/text.dart';
|
|||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:app_flowy/startup/startup.dart';
|
import 'package:app_flowy/startup/startup.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/prelude.dart';
|
import 'package:app_flowy/plugins/grid/application/prelude.dart';
|
||||||
|
|
||||||
import '../cell_builder.dart';
|
import '../cell_builder.dart';
|
||||||
import 'date_editor.dart';
|
import 'date_editor.dart';
|
||||||
@ -44,13 +44,16 @@ class _DateCellState extends GridCellState<GridDateCell> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
final cellContext = widget.cellControllerBuilder.build();
|
final cellContext = widget.cellControllerBuilder.build();
|
||||||
_cellBloc = getIt<DateCellBloc>(param1: cellContext)..add(const DateCellEvent.initial());
|
_cellBloc = getIt<DateCellBloc>(param1: cellContext)
|
||||||
|
..add(const DateCellEvent.initial());
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final alignment = widget.cellStyle != null ? widget.cellStyle!.alignment : Alignment.center;
|
final alignment = widget.cellStyle != null
|
||||||
|
? widget.cellStyle!.alignment
|
||||||
|
: Alignment.center;
|
||||||
return BlocProvider.value(
|
return BlocProvider.value(
|
||||||
value: _cellBloc,
|
value: _cellBloc,
|
||||||
child: BlocBuilder<DateCellBloc, DateCellState>(
|
child: BlocBuilder<DateCellBloc, DateCellState>(
|
||||||
@ -77,7 +80,8 @@ class _DateCellState extends GridCellState<GridDateCell> {
|
|||||||
void _showCalendar(BuildContext context) {
|
void _showCalendar(BuildContext context) {
|
||||||
final bloc = context.read<DateCellBloc>();
|
final bloc = context.read<DateCellBloc>();
|
||||||
widget.onCellEditing.value = true;
|
widget.onCellEditing.value = true;
|
||||||
final calendar = DateCellEditor(onDismissed: () => widget.onCellEditing.value = false);
|
final calendar =
|
||||||
|
DateCellEditor(onDismissed: () => widget.onCellEditing.value = false);
|
||||||
calendar.show(
|
calendar.show(
|
||||||
context,
|
context,
|
||||||
cellController: bloc.cellContext.clone(),
|
cellController: bloc.cellContext.clone(),
|
@ -1,7 +1,5 @@
|
|||||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/cell/date_cal_bloc.dart';
|
import 'package:app_flowy/plugins/grid/application/cell/date_cal_bloc.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
|
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart';
|
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
@ -15,7 +13,10 @@ import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:table_calendar/table_calendar.dart';
|
import 'package:table_calendar/table_calendar.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/prelude.dart';
|
import 'package:app_flowy/plugins/grid/application/prelude.dart';
|
||||||
|
|
||||||
|
import '../../../layout/sizes.dart';
|
||||||
|
import '../../header/type_option/date.dart';
|
||||||
|
|
||||||
final kToday = DateTime.now();
|
final kToday = DateTime.now();
|
||||||
final kFirstDay = DateTime(kToday.year, kToday.month - 3, kToday.day);
|
final kFirstDay = DateTime(kToday.year, kToday.month - 3, kToday.day);
|
||||||
@ -35,7 +36,8 @@ class DateCellEditor with FlowyOverlayDelegate {
|
|||||||
}) async {
|
}) async {
|
||||||
DateCellEditor.remove(context);
|
DateCellEditor.remove(context);
|
||||||
|
|
||||||
final result = await cellController.getFieldTypeOption(DateTypeOptionDataParser());
|
final result =
|
||||||
|
await cellController.getFieldTypeOption(DateTypeOptionDataParser());
|
||||||
result.fold(
|
result.fold(
|
||||||
(dateTypeOption) {
|
(dateTypeOption) {
|
||||||
final calendar = _CellCalendarWidget(
|
final calendar = _CellCalendarWidget(
|
||||||
@ -167,7 +169,9 @@ class _CellCalendarWidget extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
onDaySelected: (selectedDay, focusedDay) {
|
onDaySelected: (selectedDay, focusedDay) {
|
||||||
_CalDateTimeSetting.hide(context);
|
_CalDateTimeSetting.hide(context);
|
||||||
context.read<DateCalBloc>().add(DateCalEvent.selectDay(selectedDay));
|
context
|
||||||
|
.read<DateCalBloc>()
|
||||||
|
.add(DateCalEvent.selectDay(selectedDay));
|
||||||
},
|
},
|
||||||
onFormatChanged: (format) {
|
onFormatChanged: (format) {
|
||||||
_CalDateTimeSetting.hide(context);
|
_CalDateTimeSetting.hide(context);
|
||||||
@ -175,7 +179,9 @@ class _CellCalendarWidget extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
onPageChanged: (focusedDay) {
|
onPageChanged: (focusedDay) {
|
||||||
_CalDateTimeSetting.hide(context);
|
_CalDateTimeSetting.hide(context);
|
||||||
context.read<DateCalBloc>().add(DateCalEvent.setFocusedDay(focusedDay));
|
context
|
||||||
|
.read<DateCalBloc>()
|
||||||
|
.add(DateCalEvent.setFocusedDay(focusedDay));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -200,11 +206,14 @@ class _IncludeTimeButton extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
svgWidget("grid/clock", color: theme.iconColor),
|
svgWidget("grid/clock", color: theme.iconColor),
|
||||||
const HSpace(4),
|
const HSpace(4),
|
||||||
FlowyText.medium(LocaleKeys.grid_field_includeTime.tr(), fontSize: 14),
|
FlowyText.medium(LocaleKeys.grid_field_includeTime.tr(),
|
||||||
|
fontSize: 14),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
Switch(
|
Switch(
|
||||||
value: includeTime,
|
value: includeTime,
|
||||||
onChanged: (newValue) => context.read<DateCalBloc>().add(DateCalEvent.setIncludeTime(newValue)),
|
onChanged: (newValue) => context
|
||||||
|
.read<DateCalBloc>()
|
||||||
|
.add(DateCalEvent.setIncludeTime(newValue)),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -294,7 +303,9 @@ class _DateTypeOptionButton extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final theme = context.watch<AppTheme>();
|
final theme = context.watch<AppTheme>();
|
||||||
final title = LocaleKeys.grid_field_dateFormat.tr() + " &" + LocaleKeys.grid_field_timeFormat.tr();
|
final title = LocaleKeys.grid_field_dateFormat.tr() +
|
||||||
|
" &" +
|
||||||
|
LocaleKeys.grid_field_timeFormat.tr();
|
||||||
return BlocSelector<DateCalBloc, DateCalState, DateTypeOption>(
|
return BlocSelector<DateCalBloc, DateCalState, DateTypeOption>(
|
||||||
selector: (state) => state.dateTypeOption,
|
selector: (state) => state.dateTypeOption,
|
||||||
builder: (context, dateTypeOption) {
|
builder: (context, dateTypeOption) {
|
||||||
@ -321,7 +332,9 @@ class _DateTypeOptionButton extends StatelessWidget {
|
|||||||
class _CalDateTimeSetting extends StatefulWidget {
|
class _CalDateTimeSetting extends StatefulWidget {
|
||||||
final DateTypeOption dateTypeOption;
|
final DateTypeOption dateTypeOption;
|
||||||
final Function(DateCalEvent) onEvent;
|
final Function(DateCalEvent) onEvent;
|
||||||
const _CalDateTimeSetting({required this.dateTypeOption, required this.onEvent, Key? key}) : super(key: key);
|
const _CalDateTimeSetting(
|
||||||
|
{required this.dateTypeOption, required this.onEvent, Key? key})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<_CalDateTimeSetting> createState() => _CalDateTimeSettingState();
|
State<_CalDateTimeSetting> createState() => _CalDateTimeSettingState();
|
||||||
@ -358,7 +371,8 @@ class _CalDateTimeSettingState extends State<_CalDateTimeSetting> {
|
|||||||
DateFormatButton(onTap: () {
|
DateFormatButton(onTap: () {
|
||||||
final list = DateFormatList(
|
final list = DateFormatList(
|
||||||
selectedFormat: widget.dateTypeOption.dateFormat,
|
selectedFormat: widget.dateTypeOption.dateFormat,
|
||||||
onSelected: (format) => widget.onEvent(DateCalEvent.setDateFormat(format)),
|
onSelected: (format) =>
|
||||||
|
widget.onEvent(DateCalEvent.setDateFormat(format)),
|
||||||
);
|
);
|
||||||
_showOverlay(context, list);
|
_showOverlay(context, list);
|
||||||
}),
|
}),
|
||||||
@ -367,7 +381,8 @@ class _CalDateTimeSettingState extends State<_CalDateTimeSetting> {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
final list = TimeFormatList(
|
final list = TimeFormatList(
|
||||||
selectedFormat: widget.dateTypeOption.timeFormat,
|
selectedFormat: widget.dateTypeOption.timeFormat,
|
||||||
onSelected: (format) => widget.onEvent(DateCalEvent.setTimeFormat(format)),
|
onSelected: (format) =>
|
||||||
|
widget.onEvent(DateCalEvent.setTimeFormat(format)),
|
||||||
);
|
);
|
||||||
_showOverlay(context, list);
|
_showOverlay(context, list);
|
||||||
},
|
},
|
@ -1,6 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:app_flowy/startup/startup.dart';
|
import 'package:app_flowy/startup/startup.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/prelude.dart';
|
import 'package:app_flowy/plugins/grid/application/prelude.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
@ -26,8 +26,10 @@ class _NumberCellState extends GridFocusNodeCellState<GridNumberCell> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
final cellContext = widget.cellContorllerBuilder.build();
|
final cellContext = widget.cellContorllerBuilder.build();
|
||||||
_cellBloc = getIt<NumberCellBloc>(param1: cellContext)..add(const NumberCellEvent.initial());
|
_cellBloc = getIt<NumberCellBloc>(param1: cellContext)
|
||||||
_controller = TextEditingController(text: contentFromState(_cellBloc.state));
|
..add(const NumberCellEvent.initial());
|
||||||
|
_controller =
|
||||||
|
TextEditingController(text: contentFromState(_cellBloc.state));
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,7 +41,8 @@ class _NumberCellState extends GridFocusNodeCellState<GridNumberCell> {
|
|||||||
listeners: [
|
listeners: [
|
||||||
BlocListener<NumberCellBloc, NumberCellState>(
|
BlocListener<NumberCellBloc, NumberCellState>(
|
||||||
listenWhen: (p, c) => p.content != c.content,
|
listenWhen: (p, c) => p.content != c.content,
|
||||||
listener: (context, state) => _controller.text = contentFromState(state),
|
listener: (context, state) =>
|
||||||
|
_controller.text = contentFromState(state),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
child: TextField(
|
child: TextField(
|
||||||
@ -70,7 +73,8 @@ class _NumberCellState extends GridFocusNodeCellState<GridNumberCell> {
|
|||||||
if (mounted) {
|
if (mounted) {
|
||||||
_delayOperation?.cancel();
|
_delayOperation?.cancel();
|
||||||
_delayOperation = Timer(const Duration(milliseconds: 300), () {
|
_delayOperation = Timer(const Duration(milliseconds: 300), () {
|
||||||
if (_cellBloc.isClosed == false && _controller.text != contentFromState(_cellBloc.state)) {
|
if (_cellBloc.isClosed == false &&
|
||||||
|
_controller.text != contentFromState(_cellBloc.state)) {
|
||||||
_cellBloc.add(NumberCellEvent.updateCell(_controller.text));
|
_cellBloc.add(NumberCellEvent.updateCell(_controller.text));
|
||||||
}
|
}
|
||||||
});
|
});
|
@ -4,3 +4,4 @@ export 'number_cell.dart';
|
|||||||
export 'date_cell/date_cell.dart';
|
export 'date_cell/date_cell.dart';
|
||||||
export 'checkbox_cell.dart';
|
export 'checkbox_cell.dart';
|
||||||
export 'select_option_cell/select_option_cell.dart';
|
export 'select_option_cell/select_option_cell.dart';
|
||||||
|
export 'url_cell/url_cell.dart';
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:app_flowy/startup/startup.dart';
|
import 'package:app_flowy/startup/startup.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/prelude.dart';
|
import 'package:app_flowy/plugins/grid/application/prelude.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart';
|
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
// ignore: unused_import
|
// ignore: unused_import
|
||||||
@ -9,6 +9,7 @@ import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
|
import '../cell_builder.dart';
|
||||||
import 'extension.dart';
|
import 'extension.dart';
|
||||||
import 'select_option_editor.dart';
|
import 'select_option_editor.dart';
|
||||||
|
|
||||||
@ -45,8 +46,10 @@ class _SingleSelectCellState extends State<GridSingleSelectCell> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
final cellContext = widget.cellContorllerBuilder.build() as GridSelectOptionCellController;
|
final cellContext =
|
||||||
_cellBloc = getIt<SelectOptionCellBloc>(param1: cellContext)..add(const SelectOptionCellEvent.initial());
|
widget.cellContorllerBuilder.build() as GridSelectOptionCellController;
|
||||||
|
_cellBloc = getIt<SelectOptionCellBloc>(param1: cellContext)
|
||||||
|
..add(const SelectOptionCellEvent.initial());
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,8 +102,10 @@ class _MultiSelectCellState extends State<GridMultiSelectCell> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
final cellContext = widget.cellContorllerBuilder.build() as GridSelectOptionCellController;
|
final cellContext =
|
||||||
_cellBloc = getIt<SelectOptionCellBloc>(param1: cellContext)..add(const SelectOptionCellEvent.initial());
|
widget.cellContorllerBuilder.build() as GridSelectOptionCellController;
|
||||||
|
_cellBloc = getIt<SelectOptionCellBloc>(param1: cellContext)
|
||||||
|
..add(const SelectOptionCellEvent.initial());
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +152,8 @@ class _SelectOptionCell extends StatelessWidget {
|
|||||||
if (selectOptions.isEmpty && cellStyle != null) {
|
if (selectOptions.isEmpty && cellStyle != null) {
|
||||||
child = Align(
|
child = Align(
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
child: FlowyText.medium(cellStyle!.placeholder, fontSize: 14, color: theme.shader3),
|
child: FlowyText.medium(cellStyle!.placeholder,
|
||||||
|
fontSize: 14, color: theme.shader3),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
final tags = selectOptions
|
final tags = selectOptions
|
||||||
@ -172,8 +178,10 @@ class _SelectOptionCell extends StatelessWidget {
|
|||||||
InkWell(
|
InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
onFocus(true);
|
onFocus(true);
|
||||||
final cellContext = cellContorllerBuilder.build() as GridSelectOptionCellController;
|
final cellContext =
|
||||||
SelectOptionCellEditor.show(context, cellContext, () => onFocus(false));
|
cellContorllerBuilder.build() as GridSelectOptionCellController;
|
||||||
|
SelectOptionCellEditor.show(
|
||||||
|
context, cellContext, () => onFocus(false));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
@ -1,9 +1,7 @@
|
|||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart';
|
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/cell/select_option_editor_bloc.dart';
|
import 'package:app_flowy/plugins/grid/application/cell/select_option_editor_bloc.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
|
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/select_option_editor.dart';
|
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/common/text_field.dart';
|
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
@ -18,6 +16,9 @@ import 'package:easy_localization/easy_localization.dart';
|
|||||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||||
import 'package:textfield_tags/textfield_tags.dart';
|
import 'package:textfield_tags/textfield_tags.dart';
|
||||||
|
|
||||||
|
import '../../../layout/sizes.dart';
|
||||||
|
import '../../common/text_field.dart';
|
||||||
|
import '../../header/type_option/select_option_editor.dart';
|
||||||
import 'extension.dart';
|
import 'extension.dart';
|
||||||
import 'text_field.dart';
|
import 'text_field.dart';
|
||||||
|
|
||||||
@ -105,7 +106,8 @@ class _OptionList extends StatelessWidget {
|
|||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
List<Widget> cells = [];
|
List<Widget> cells = [];
|
||||||
cells.addAll(state.options.map((option) {
|
cells.addAll(state.options.map((option) {
|
||||||
return _SelectOptionCell(option, state.selectedOptions.contains(option));
|
return _SelectOptionCell(
|
||||||
|
option, state.selectedOptions.contains(option));
|
||||||
}).toList());
|
}).toList());
|
||||||
|
|
||||||
state.createOption.fold(
|
state.createOption.fold(
|
||||||
@ -146,8 +148,10 @@ class _TextField extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<SelectOptionCellEditorBloc, SelectOptionEditorState>(
|
return BlocBuilder<SelectOptionCellEditorBloc, SelectOptionEditorState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
final optionMap = LinkedHashMap<String, SelectOptionPB>.fromIterable(state.selectedOptions,
|
final optionMap = LinkedHashMap<String, SelectOptionPB>.fromIterable(
|
||||||
key: (option) => option.name, value: (option) => option);
|
state.selectedOptions,
|
||||||
|
key: (option) => option.name,
|
||||||
|
value: (option) => option);
|
||||||
|
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: 42,
|
height: 42,
|
||||||
@ -156,12 +160,17 @@ class _TextField extends StatelessWidget {
|
|||||||
selectedOptionMap: optionMap,
|
selectedOptionMap: optionMap,
|
||||||
distanceToText: _editorPannelWidth * 0.7,
|
distanceToText: _editorPannelWidth * 0.7,
|
||||||
tagController: _tagController,
|
tagController: _tagController,
|
||||||
onClick: () => FlowyOverlay.of(context).remove(SelectOptionTypeOptionEditor.identifier),
|
onClick: () => FlowyOverlay.of(context)
|
||||||
|
.remove(SelectOptionTypeOptionEditor.identifier),
|
||||||
newText: (text) {
|
newText: (text) {
|
||||||
context.read<SelectOptionCellEditorBloc>().add(SelectOptionEditorEvent.filterOption(text));
|
context
|
||||||
|
.read<SelectOptionCellEditorBloc>()
|
||||||
|
.add(SelectOptionEditorEvent.filterOption(text));
|
||||||
},
|
},
|
||||||
onNewTag: (tagName) {
|
onNewTag: (tagName) {
|
||||||
context.read<SelectOptionCellEditorBloc>().add(SelectOptionEditorEvent.newOption(tagName));
|
context
|
||||||
|
.read<SelectOptionCellEditorBloc>()
|
||||||
|
.add(SelectOptionEditorEvent.newOption(tagName));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -208,7 +217,9 @@ class _CreateOptionCell extends StatelessWidget {
|
|||||||
SelectOptionTag(
|
SelectOptionTag(
|
||||||
name: name,
|
name: name,
|
||||||
color: theme.shader6,
|
color: theme.shader6,
|
||||||
onSelected: () => context.read<SelectOptionCellEditorBloc>().add(SelectOptionEditorEvent.newOption(name)),
|
onSelected: () => context
|
||||||
|
.read<SelectOptionCellEditorBloc>()
|
||||||
|
.add(SelectOptionEditorEvent.newOption(name)),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@ -218,7 +229,8 @@ class _CreateOptionCell extends StatelessWidget {
|
|||||||
class _SelectOptionCell extends StatelessWidget {
|
class _SelectOptionCell extends StatelessWidget {
|
||||||
final SelectOptionPB option;
|
final SelectOptionPB option;
|
||||||
final bool isSelected;
|
final bool isSelected;
|
||||||
const _SelectOptionCell(this.option, this.isSelected, {Key? key}) : super(key: key);
|
const _SelectOptionCell(this.option, this.isSelected, {Key? key})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -232,7 +244,9 @@ class _SelectOptionCell extends StatelessWidget {
|
|||||||
child: SelectOptionTagCell(
|
child: SelectOptionTagCell(
|
||||||
option: option,
|
option: option,
|
||||||
onSelected: (option) {
|
onSelected: (option) {
|
||||||
context.read<SelectOptionCellEditorBloc>().add(SelectOptionEditorEvent.selectOption(option.id));
|
context
|
||||||
|
.read<SelectOptionCellEditorBloc>()
|
||||||
|
.add(SelectOptionEditorEvent.selectOption(option.id));
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
if (isSelected)
|
if (isSelected)
|
||||||
@ -258,12 +272,17 @@ class _SelectOptionCell extends StatelessWidget {
|
|||||||
final pannel = SelectOptionTypeOptionEditor(
|
final pannel = SelectOptionTypeOptionEditor(
|
||||||
option: option,
|
option: option,
|
||||||
onDeleted: () {
|
onDeleted: () {
|
||||||
context.read<SelectOptionCellEditorBloc>().add(SelectOptionEditorEvent.deleteOption(option));
|
context
|
||||||
|
.read<SelectOptionCellEditorBloc>()
|
||||||
|
.add(SelectOptionEditorEvent.deleteOption(option));
|
||||||
},
|
},
|
||||||
onUpdated: (updatedOption) {
|
onUpdated: (updatedOption) {
|
||||||
context.read<SelectOptionCellEditorBloc>().add(SelectOptionEditorEvent.updateOption(updatedOption));
|
context
|
||||||
|
.read<SelectOptionCellEditorBloc>()
|
||||||
|
.add(SelectOptionEditorEvent.updateOption(updatedOption));
|
||||||
},
|
},
|
||||||
key: ValueKey(option.id), // Use ValueKey to refresh the UI, otherwise, it will remain the old value.
|
key: ValueKey(option
|
||||||
|
.id), // Use ValueKey to refresh the UI, otherwise, it will remain the old value.
|
||||||
);
|
);
|
||||||
final overlayIdentifier = (SelectOptionTypeOptionEditor).toString();
|
final overlayIdentifier = (SelectOptionTypeOptionEditor).toString();
|
||||||
|
|
@ -2,7 +2,7 @@ import 'dart:async';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:app_flowy/startup/startup.dart';
|
import 'package:app_flowy/startup/startup.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/prelude.dart';
|
import 'package:app_flowy/plugins/grid/application/prelude.dart';
|
||||||
import 'cell_builder.dart';
|
import 'cell_builder.dart';
|
||||||
|
|
||||||
class GridTextCellStyle extends GridCellStyle {
|
class GridTextCellStyle extends GridCellStyle {
|
||||||
@ -86,7 +86,8 @@ class _GridTextCellState extends GridFocusNodeCellState<GridTextCell> {
|
|||||||
if (mounted) {
|
if (mounted) {
|
||||||
_delayOperation?.cancel();
|
_delayOperation?.cancel();
|
||||||
_delayOperation = Timer(const Duration(milliseconds: 300), () {
|
_delayOperation = Timer(const Duration(milliseconds: 300), () {
|
||||||
if (_cellBloc.isClosed == false && _controller.text != _cellBloc.state.content) {
|
if (_cellBloc.isClosed == false &&
|
||||||
|
_controller.text != _cellBloc.state.content) {
|
||||||
_cellBloc.add(TextCellEvent.updateText(_controller.text));
|
_cellBloc.add(TextCellEvent.updateText(_controller.text));
|
||||||
}
|
}
|
||||||
});
|
});
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart';
|
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/cell/url_cell_editor_bloc.dart';
|
import 'package:app_flowy/plugins/grid/application/cell/url_cell_editor_bloc.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
@ -9,7 +9,9 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
class URLCellEditor extends StatefulWidget with FlowyOverlayDelegate {
|
class URLCellEditor extends StatefulWidget with FlowyOverlayDelegate {
|
||||||
final GridURLCellController cellController;
|
final GridURLCellController cellController;
|
||||||
final VoidCallback completed;
|
final VoidCallback completed;
|
||||||
const URLCellEditor({required this.cellController, required this.completed, Key? key}) : super(key: key);
|
const URLCellEditor(
|
||||||
|
{required this.cellController, required this.completed, Key? key})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<URLCellEditor> createState() => _URLCellEditorState();
|
State<URLCellEditor> createState() => _URLCellEditorState();
|
||||||
@ -105,7 +107,8 @@ class _URLCellEditorState extends State<URLCellEditor> {
|
|||||||
|
|
||||||
Future<void> focusChanged() async {
|
Future<void> focusChanged() async {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
if (_cellBloc.isClosed == false && _controller.text != _cellBloc.state.content) {
|
if (_cellBloc.isClosed == false &&
|
||||||
|
_controller.text != _cellBloc.state.content) {
|
||||||
_cellBloc.add(URLCellEditorEvent.updateText(_controller.text));
|
_cellBloc.add(URLCellEditorEvent.updateText(_controller.text));
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,16 +1,16 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/cell/url_cell_bloc.dart';
|
import 'package:app_flowy/plugins/grid/application/cell/url_cell_bloc.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/home/toast.dart';
|
import 'package:app_flowy/workspace/presentation/home/toast.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/cell_accessory.dart';
|
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/prelude.dart';
|
import 'package:app_flowy/plugins/grid/application/prelude.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
import '../cell_accessory.dart';
|
||||||
import '../cell_builder.dart';
|
import '../cell_builder.dart';
|
||||||
import 'cell_editor.dart';
|
import 'cell_editor.dart';
|
||||||
|
|
||||||
@ -48,34 +48,41 @@ class GridURLCell extends GridCellWidget {
|
|||||||
@override
|
@override
|
||||||
GridCellState<GridURLCell> createState() => _GridURLCellState();
|
GridCellState<GridURLCell> createState() => _GridURLCellState();
|
||||||
|
|
||||||
GridCellAccessory accessoryFromType(GridURLCellAccessoryType ty, GridCellAccessoryBuildContext buildContext) {
|
GridCellAccessory accessoryFromType(
|
||||||
|
GridURLCellAccessoryType ty, GridCellAccessoryBuildContext buildContext) {
|
||||||
switch (ty) {
|
switch (ty) {
|
||||||
case GridURLCellAccessoryType.edit:
|
case GridURLCellAccessoryType.edit:
|
||||||
final cellContext = cellContorllerBuilder.build() as GridURLCellController;
|
final cellContext =
|
||||||
return _EditURLAccessory(cellContext: cellContext, anchorContext: buildContext.anchorContext);
|
cellContorllerBuilder.build() as GridURLCellController;
|
||||||
|
return _EditURLAccessory(
|
||||||
|
cellContext: cellContext,
|
||||||
|
anchorContext: buildContext.anchorContext);
|
||||||
|
|
||||||
case GridURLCellAccessoryType.copyURL:
|
case GridURLCellAccessoryType.copyURL:
|
||||||
final cellContext = cellContorllerBuilder.build() as GridURLCellController;
|
final cellContext =
|
||||||
|
cellContorllerBuilder.build() as GridURLCellController;
|
||||||
return _CopyURLAccessory(cellContext: cellContext);
|
return _CopyURLAccessory(cellContext: cellContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<GridCellAccessory> Function(GridCellAccessoryBuildContext buildContext) get accessoryBuilder => (buildContext) {
|
List<GridCellAccessory> Function(GridCellAccessoryBuildContext buildContext)
|
||||||
final List<GridCellAccessory> accessories = [];
|
get accessoryBuilder => (buildContext) {
|
||||||
if (cellStyle != null) {
|
final List<GridCellAccessory> accessories = [];
|
||||||
accessories.addAll(cellStyle!.accessoryTypes.map((ty) {
|
if (cellStyle != null) {
|
||||||
return accessoryFromType(ty, buildContext);
|
accessories.addAll(cellStyle!.accessoryTypes.map((ty) {
|
||||||
}));
|
return accessoryFromType(ty, buildContext);
|
||||||
}
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
// If the accessories is empty then the default accessory will be GridURLCellAccessoryType.edit
|
// If the accessories is empty then the default accessory will be GridURLCellAccessoryType.edit
|
||||||
if (accessories.isEmpty) {
|
if (accessories.isEmpty) {
|
||||||
accessories.add(accessoryFromType(GridURLCellAccessoryType.edit, buildContext));
|
accessories.add(accessoryFromType(
|
||||||
}
|
GridURLCellAccessoryType.edit, buildContext));
|
||||||
|
}
|
||||||
|
|
||||||
return accessories;
|
return accessories;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class _GridURLCellState extends GridCellState<GridURLCell> {
|
class _GridURLCellState extends GridCellState<GridURLCell> {
|
||||||
@ -83,7 +90,8 @@ class _GridURLCellState extends GridCellState<GridURLCell> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
final cellContext = widget.cellContorllerBuilder.build() as GridURLCellController;
|
final cellContext =
|
||||||
|
widget.cellContorllerBuilder.build() as GridURLCellController;
|
||||||
_cellBloc = URLCellBloc(cellContext: cellContext);
|
_cellBloc = URLCellBloc(cellContext: cellContext);
|
||||||
_cellBloc.add(const URLCellEvent.initial());
|
_cellBloc.add(const URLCellEvent.initial());
|
||||||
super.initState();
|
super.initState();
|
||||||
@ -132,7 +140,8 @@ class _GridURLCellState extends GridCellState<GridURLCell> {
|
|||||||
if (url.isNotEmpty && await canLaunchUrl(uri)) {
|
if (url.isNotEmpty && await canLaunchUrl(uri)) {
|
||||||
await launchUrl(uri);
|
await launchUrl(uri);
|
||||||
} else {
|
} else {
|
||||||
final cellContext = widget.cellContorllerBuilder.build() as GridURLCellController;
|
final cellContext =
|
||||||
|
widget.cellContorllerBuilder.build() as GridURLCellController;
|
||||||
widget.onCellEditing.value = true;
|
widget.onCellEditing.value = true;
|
||||||
URLCellEditor.show(context, cellContext, () {
|
URLCellEditor.show(context, cellContext, () {
|
||||||
widget.onCellEditing.value = false;
|
widget.onCellEditing.value = false;
|
||||||
@ -177,7 +186,8 @@ class _EditURLAccessory extends StatelessWidget with GridCellAccessory {
|
|||||||
|
|
||||||
class _CopyURLAccessory extends StatelessWidget with GridCellAccessory {
|
class _CopyURLAccessory extends StatelessWidget with GridCellAccessory {
|
||||||
final GridURLCellController cellContext;
|
final GridURLCellController cellContext;
|
||||||
const _CopyURLAccessory({required this.cellContext, Key? key}) : super(key: key);
|
const _CopyURLAccessory({required this.cellContext, Key? key})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -187,7 +197,8 @@ class _CopyURLAccessory extends StatelessWidget with GridCellAccessory {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void onTap() {
|
void onTap() {
|
||||||
final content = cellContext.getCellData(loadIfNotExist: false)?.content ?? "";
|
final content =
|
||||||
|
cellContext.getCellData(loadIfNotExist: false)?.content ?? "";
|
||||||
Clipboard.setData(ClipboardData(text: content));
|
Clipboard.setData(ClipboardData(text: content));
|
||||||
showMessageToast(LocaleKeys.grid_row_copyProperty.tr());
|
showMessageToast(LocaleKeys.grid_row_copyProperty.tr());
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:app_flowy/workspace/application/grid/grid_bloc.dart';
|
import 'package:app_flowy/plugins/grid/application/grid_bloc.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
import 'package:flowy_infra_ui/style_widget/button.dart';
|
@ -1,6 +1,5 @@
|
|||||||
import 'package:app_flowy/workspace/application/grid/field/field_cell_bloc.dart';
|
import 'package:app_flowy/plugins/grid/application/field/field_cell_bloc.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
|
import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
|
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||||
@ -9,6 +8,7 @@ import 'package:flowy_infra_ui/style_widget/text.dart';
|
|||||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import '../../layout/sizes.dart';
|
||||||
import 'field_type_extension.dart';
|
import 'field_type_extension.dart';
|
||||||
|
|
||||||
import 'field_cell_action_sheet.dart';
|
import 'field_cell_action_sheet.dart';
|
||||||
@ -21,7 +21,8 @@ class GridFieldCell extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) => FieldCellBloc(cellContext: cellContext)..add(const FieldCellEvent.initial()),
|
create: (context) => FieldCellBloc(cellContext: cellContext)
|
||||||
|
..add(const FieldCellEvent.initial()),
|
||||||
child: BlocBuilder<FieldCellBloc, FieldCellState>(
|
child: BlocBuilder<FieldCellBloc, FieldCellState>(
|
||||||
// buildWhen: (p, c) => p.field != c.field,
|
// buildWhen: (p, c) => p.field != c.field,
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
@ -53,7 +54,8 @@ class GridFieldCell extends StatelessWidget {
|
|||||||
void _showActionSheet(BuildContext context) {
|
void _showActionSheet(BuildContext context) {
|
||||||
final state = context.read<FieldCellBloc>().state;
|
final state = context.read<FieldCellBloc>().state;
|
||||||
GridFieldCellActionSheet(
|
GridFieldCellActionSheet(
|
||||||
cellContext: GridFieldCellContext(gridId: state.gridId, field: state.field),
|
cellContext:
|
||||||
|
GridFieldCellContext(gridId: state.gridId, field: state.field),
|
||||||
onEdited: () => _showFieldEditor(context),
|
onEdited: () => _showFieldEditor(context),
|
||||||
).show(context);
|
).show(context);
|
||||||
}
|
}
|
||||||
@ -96,7 +98,8 @@ class _GridHeaderCellContainer extends StatelessWidget {
|
|||||||
return Container(
|
return Container(
|
||||||
width: width,
|
width: width,
|
||||||
decoration: decoration,
|
decoration: decoration,
|
||||||
child: ConstrainedBox(constraints: const BoxConstraints.expand(), child: child),
|
child: ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints.expand(), child: child),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,5 @@
|
|||||||
import 'package:app_flowy/startup/startup.dart';
|
import 'package:app_flowy/startup/startup.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/prelude.dart';
|
import 'package:app_flowy/plugins/grid/application/prelude.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
|
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
@ -12,10 +11,15 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||||
|
|
||||||
class GridFieldCellActionSheet extends StatelessWidget with FlowyOverlayDelegate {
|
import '../../layout/sizes.dart';
|
||||||
|
|
||||||
|
class GridFieldCellActionSheet extends StatelessWidget
|
||||||
|
with FlowyOverlayDelegate {
|
||||||
final GridFieldCellContext cellContext;
|
final GridFieldCellContext cellContext;
|
||||||
final VoidCallback onEdited;
|
final VoidCallback onEdited;
|
||||||
const GridFieldCellActionSheet({required this.cellContext, required this.onEdited, Key? key}) : super(key: key);
|
const GridFieldCellActionSheet(
|
||||||
|
{required this.cellContext, required this.onEdited, Key? key})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
void show(BuildContext overlayContext) {
|
void show(BuildContext overlayContext) {
|
||||||
FlowyOverlay.of(overlayContext).insertWithAnchor(
|
FlowyOverlay.of(overlayContext).insertWithAnchor(
|
||||||
@ -44,7 +48,8 @@ class GridFieldCellActionSheet extends StatelessWidget with FlowyOverlayDelegate
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
const VSpace(6),
|
const VSpace(6),
|
||||||
_FieldOperationList(cellContext, () => FlowyOverlay.of(context).remove(identifier())),
|
_FieldOperationList(cellContext,
|
||||||
|
() => FlowyOverlay.of(context).remove(identifier())),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -73,7 +78,8 @@ class _EditFieldButton extends StatelessWidget {
|
|||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: GridSize.typeOptionItemHeight,
|
height: GridSize.typeOptionItemHeight,
|
||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
text: FlowyText.medium(LocaleKeys.grid_field_editProperty.tr(), fontSize: 12),
|
text: FlowyText.medium(LocaleKeys.grid_field_editProperty.tr(),
|
||||||
|
fontSize: 12),
|
||||||
hoverColor: theme.hover,
|
hoverColor: theme.hover,
|
||||||
onTap: onEdited,
|
onTap: onEdited,
|
||||||
),
|
),
|
||||||
@ -86,7 +92,8 @@ class _EditFieldButton extends StatelessWidget {
|
|||||||
class _FieldOperationList extends StatelessWidget {
|
class _FieldOperationList extends StatelessWidget {
|
||||||
final GridFieldCellContext fieldData;
|
final GridFieldCellContext fieldData;
|
||||||
final VoidCallback onDismissed;
|
final VoidCallback onDismissed;
|
||||||
const _FieldOperationList(this.fieldData, this.onDismissed, {Key? key}) : super(key: key);
|
const _FieldOperationList(this.fieldData, this.onDismissed, {Key? key})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -143,7 +150,8 @@ class FieldActionCell extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final theme = context.watch<AppTheme>();
|
final theme = context.watch<AppTheme>();
|
||||||
return FlowyButton(
|
return FlowyButton(
|
||||||
text: FlowyText.medium(action.title(), fontSize: 12, color: enable ? null : theme.shader4),
|
text: FlowyText.medium(action.title(),
|
||||||
|
fontSize: 12, color: enable ? null : theme.shader4),
|
||||||
hoverColor: theme.hover,
|
hoverColor: theme.hover,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (enable) {
|
if (enable) {
|
||||||
@ -188,13 +196,19 @@ extension _FieldActionExtension on FieldAction {
|
|||||||
void run(BuildContext context) {
|
void run(BuildContext context) {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case FieldAction.hide:
|
case FieldAction.hide:
|
||||||
context.read<FieldActionSheetBloc>().add(const FieldActionSheetEvent.hideField());
|
context
|
||||||
|
.read<FieldActionSheetBloc>()
|
||||||
|
.add(const FieldActionSheetEvent.hideField());
|
||||||
break;
|
break;
|
||||||
case FieldAction.duplicate:
|
case FieldAction.duplicate:
|
||||||
context.read<FieldActionSheetBloc>().add(const FieldActionSheetEvent.duplicateField());
|
context
|
||||||
|
.read<FieldActionSheetBloc>()
|
||||||
|
.add(const FieldActionSheetEvent.duplicateField());
|
||||||
break;
|
break;
|
||||||
case FieldAction.delete:
|
case FieldAction.delete:
|
||||||
context.read<FieldActionSheetBloc>().add(const FieldActionSheetEvent.deleteField());
|
context
|
||||||
|
.read<FieldActionSheetBloc>()
|
||||||
|
.add(const FieldActionSheetEvent.deleteField());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:app_flowy/workspace/application/grid/field/field_editor_bloc.dart';
|
import 'package:app_flowy/plugins/grid/application/field/field_editor_bloc.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
|
import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
@ -36,7 +36,8 @@ class FieldEditor extends StatelessWidget with FlowyOverlayDelegate {
|
|||||||
return ListView(
|
return ListView(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
children: [
|
children: [
|
||||||
FlowyText.medium(LocaleKeys.grid_field_editProperty.tr(), fontSize: 12),
|
FlowyText.medium(LocaleKeys.grid_field_editProperty.tr(),
|
||||||
|
fontSize: 12),
|
||||||
const VSpace(10),
|
const VSpace(10),
|
||||||
const _FieldNameCell(),
|
const _FieldNameCell(),
|
||||||
const VSpace(10),
|
const VSpace(10),
|
||||||
@ -85,7 +86,8 @@ class _FieldTypeOptionCell extends StatelessWidget {
|
|||||||
return state.field.fold(
|
return state.field.fold(
|
||||||
() => const SizedBox(),
|
() => const SizedBox(),
|
||||||
(fieldContext) {
|
(fieldContext) {
|
||||||
final dataController = context.read<FieldEditorBloc>().dataController;
|
final dataController =
|
||||||
|
context.read<FieldEditorBloc>().dataController;
|
||||||
return FieldTypeOptionEditor(dataController: dataController);
|
return FieldTypeOptionEditor(dataController: dataController);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -105,7 +107,9 @@ class _FieldNameCell extends StatelessWidget {
|
|||||||
name: state.name,
|
name: state.name,
|
||||||
errorText: context.read<FieldEditorBloc>().state.errorText,
|
errorText: context.read<FieldEditorBloc>().state.errorText,
|
||||||
onNameChanged: (newName) {
|
onNameChanged: (newName) {
|
||||||
context.read<FieldEditorBloc>().add(FieldEditorEvent.updateName(newName));
|
context
|
||||||
|
.read<FieldEditorBloc>()
|
||||||
|
.add(FieldEditorEvent.updateName(newName));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user