mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
Merge branch '#692' of https://github.com/naughtz/appflowy into #692
This commit is contained in:
commit
1a59bd75e2
2
.github/workflows/ci.yaml
vendored
2
.github/workflows/ci.yaml
vendored
@ -34,7 +34,7 @@ jobs:
|
||||
with:
|
||||
channel: 'stable'
|
||||
cache: true
|
||||
flutter-version: '3.0.0'
|
||||
flutter-version: '3.0.5'
|
||||
|
||||
- name: Cache Cargo
|
||||
uses: actions/cache@v2
|
||||
|
2
.github/workflows/dart_lint.yml
vendored
2
.github/workflows/dart_lint.yml
vendored
@ -23,7 +23,7 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
- uses: subosito/flutter-action@v1
|
||||
with:
|
||||
flutter-version: '3.0.0'
|
||||
flutter-version: '3.0.5'
|
||||
channel: "stable"
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
|
2
.github/workflows/dart_test.yml
vendored
2
.github/workflows/dart_test.yml
vendored
@ -26,7 +26,7 @@ jobs:
|
||||
- uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version: '3.0.0'
|
||||
flutter-version: '3.0.5'
|
||||
cache: true
|
||||
|
||||
- name: Cache Cargo
|
||||
|
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@ -50,7 +50,7 @@ jobs:
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version: '3.0.0'
|
||||
flutter-version: '3.0.5'
|
||||
|
||||
- name: Pre build
|
||||
working-directory: frontend
|
||||
@ -99,7 +99,7 @@ jobs:
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version: '3.0.0'
|
||||
flutter-version: '3.0.5'
|
||||
|
||||
- name: Pre build
|
||||
working-directory: frontend
|
||||
|
2
.github/workflows/rust_lint.yml
vendored
2
.github/workflows/rust_lint.yml
vendored
@ -22,7 +22,7 @@ jobs:
|
||||
override: true
|
||||
- uses: subosito/flutter-action@v1
|
||||
with:
|
||||
flutter-version: '3.0.0'
|
||||
flutter-version: '3.0.5'
|
||||
channel: "stable"
|
||||
|
||||
- name: Rust Deps
|
||||
|
@ -94,7 +94,8 @@
|
||||
},
|
||||
"tooltip": {
|
||||
"lightMode": "Switch to Light mode",
|
||||
"darkMode": "Switch to Dark mode"
|
||||
"darkMode": "Switch to Dark mode",
|
||||
"openAsPage": "Open as a Page"
|
||||
},
|
||||
"notifications": {
|
||||
"export": {
|
||||
@ -219,4 +220,4 @@
|
||||
"openSidebar": "Open sidebar",
|
||||
"closeSidebar": "Close sidebar"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flutter/material.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 {
|
||||
@override
|
||||
@ -42,7 +42,8 @@ class BlankPagePlugin extends Plugin {
|
||||
|
||||
class BlankPagePluginDisplay extends PluginDisplay with NavigationItem {
|
||||
@override
|
||||
Widget get leftBarItem => FlowyText.medium(LocaleKeys.blankPageTitle.tr(), fontSize: 12);
|
||||
Widget get leftBarItem =>
|
||||
FlowyText.medium(LocaleKeys.blankPageTitle.tr(), fontSize: 12);
|
||||
|
||||
@override
|
||||
Widget buildWidget() => const BlankPage();
|
@ -1,10 +1,10 @@
|
||||
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:app_flowy/plugin/plugin.dart';
|
||||
import 'package:app_flowy/startup/plugin/plugin.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'src/board_page.dart';
|
||||
import 'presentation/board_page.dart';
|
||||
|
||||
class BoardPluginBuilder implements PluginBuilder {
|
||||
@override
|
||||
@ -28,7 +28,7 @@ class BoardPluginBuilder implements PluginBuilder {
|
||||
|
||||
class BoardPluginConfig implements PluginConfig {
|
||||
@override
|
||||
bool get creatable => false;
|
||||
bool get creatable => true;
|
||||
}
|
||||
|
||||
class BoardPlugin extends Plugin {
|
@ -1,7 +1,7 @@
|
||||
import 'dart:convert';
|
||||
import 'package:app_flowy/workspace/application/doc/doc_service.dart';
|
||||
import 'package:app_flowy/workspace/application/trash/trash_service.dart';
|
||||
import 'package:app_flowy/plugins/trash/application/trash_service.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-error/errors.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));
|
||||
},
|
||||
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);
|
||||
},
|
||||
restorePage: (RestorePage value) async {
|
||||
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);
|
||||
},
|
||||
);
|
||||
@ -93,10 +96,12 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
|
||||
final documentDelta = document.toDelta();
|
||||
_composeDelta(delta, documentDelta);
|
||||
});
|
||||
emit(state.copyWith(loadingState: DocumentLoadingState.finish(left(unit))));
|
||||
emit(state.copyWith(
|
||||
loadingState: DocumentLoadingState.finish(left(unit))));
|
||||
},
|
||||
(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
|
||||
class DocumentLoadingState with _$DocumentLoadingState {
|
||||
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:io';
|
||||
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/plugins/doc/application/share_service.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-error/errors.pb.dart';
|
||||
@ -14,13 +14,15 @@ part 'share_bloc.freezed.dart';
|
||||
class DocShareBloc extends Bloc<DocShareEvent, DocShareState> {
|
||||
ShareService service;
|
||||
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 {
|
||||
await event.map(
|
||||
shareMarkdown: (ShareMarkdown value) async {
|
||||
await service.exportMarkdown(view.id).then((result) {
|
||||
result.fold(
|
||||
(value) => emit(DocShareState.finish(left(_convertDeltaToMarkdown(value)))),
|
||||
(value) => emit(
|
||||
DocShareState.finish(left(_convertDeltaToMarkdown(value)))),
|
||||
(error) => emit(DocShareState.finish(right(error))),
|
||||
);
|
||||
});
|
||||
@ -73,5 +75,6 @@ class DocShareEvent with _$DocShareEvent {
|
||||
class DocShareState with _$DocShareState {
|
||||
const factory DocShareState.initial() = _Initial;
|
||||
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;
|
||||
|
||||
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/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/plugins/doc/application/share_bloc.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/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/pop_up_action.dart';
|
||||
import 'package:clipboard/clipboard.dart';
|
||||
@ -26,12 +26,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'src/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';
|
||||
import 'document_page.dart';
|
||||
|
||||
class DocumentPluginBuilder extends PluginBuilder {
|
||||
@override
|
||||
@ -58,7 +53,9 @@ class DocumentPlugin implements Plugin {
|
||||
ViewListener? _listener;
|
||||
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;
|
||||
_listener = getIt<ViewListener>(param1: view);
|
||||
_listener?.start(onViewUpdated: (result) {
|
||||
@ -112,7 +109,8 @@ class DocumentPluginDisplay extends PluginDisplay<int> with NavigationItem {
|
||||
|
||||
class DocumentShareButton extends StatelessWidget {
|
||||
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
|
||||
Widget build(BuildContext context) {
|
||||
@ -149,7 +147,8 @@ class DocumentShareButton extends StatelessWidget {
|
||||
fontSize: 12,
|
||||
borderRadius: Corners.s6Border,
|
||||
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:
|
||||
break;
|
||||
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;
|
||||
case ExportType.Text:
|
||||
break;
|
||||
@ -179,11 +179,15 @@ class DocumentShareButton extends StatelessWidget {
|
||||
result.fold(() {}, (action) {
|
||||
switch (action) {
|
||||
case ShareAction.markdown:
|
||||
context.read<DocShareBloc>().add(const DocShareEvent.shareMarkdown());
|
||||
showMessageToast('Exported to: ${LocaleKeys.notifications_export_path.tr()}');
|
||||
context
|
||||
.read<DocShareBloc>()
|
||||
.add(const DocShareEvent.shareMarkdown());
|
||||
showMessageToast(
|
||||
'Exported to: ${LocaleKeys.notifications_export_path.tr()}');
|
||||
break;
|
||||
case ShareAction.copyLink:
|
||||
FlowyAlertDialog(title: LocaleKeys.shareAction_workInProgress.tr()).show(context);
|
||||
FlowyAlertDialog(title: LocaleKeys.shareAction_workInProgress.tr())
|
||||
.show(context);
|
||||
break;
|
||||
}
|
||||
});
|
||||
@ -198,7 +202,8 @@ class DocumentShareButton extends StatelessWidget {
|
||||
|
||||
class ShareActions with ActionList<ShareActionWrapper>, FlowyOverlayDelegate {
|
||||
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});
|
||||
|
||||
@ -212,7 +217,8 @@ class ShareActions with ActionList<ShareActionWrapper>, FlowyOverlayDelegate {
|
||||
List<ShareActionWrapper> get items => _items;
|
||||
|
||||
@override
|
||||
void Function(dartz.Option<ShareActionWrapper> p1) get selectCallback => (result) {
|
||||
void Function(dartz.Option<ShareActionWrapper> p1) get selectCallback =>
|
||||
(result) {
|
||||
result.fold(
|
||||
() => onSelected(dartz.none()),
|
||||
(wrapper) => onSelected(
|
@ -1,7 +1,7 @@
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/workspace/application/appearance.dart';
|
||||
import 'package:app_flowy/workspace/application/doc/doc_bloc.dart';
|
||||
import 'package:app_flowy/workspace/presentation/plugins/doc/document.dart';
|
||||
import 'package:app_flowy/plugins/doc/presentation/banner.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/widget/spacing.dart';
|
||||
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_bloc/flutter_bloc.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'application/doc_bloc.dart';
|
||||
import 'styles.dart';
|
||||
import 'widget/banner.dart';
|
||||
|
||||
class DocumentPage extends StatefulWidget {
|
||||
final ViewPB view;
|
||||
@ -29,7 +29,8 @@ class _DocumentPageState extends State<DocumentPage> {
|
||||
|
||||
@override
|
||||
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();
|
||||
}
|
||||
|
||||
@ -39,10 +40,12 @@ class _DocumentPageState extends State<DocumentPage> {
|
||||
providers: [
|
||||
BlocProvider<DocumentBloc>.value(value: documentBloc),
|
||||
],
|
||||
child: BlocBuilder<DocumentBloc, DocumentState>(builder: (context, state) {
|
||||
child:
|
||||
BlocBuilder<DocumentBloc, DocumentState>(builder: (context, state) {
|
||||
return state.loadingState.map(
|
||||
// loading: (_) => const FlowyProgressIndicator(),
|
||||
loading: (_) => SizedBox.expand(child: Container(color: Colors.transparent)),
|
||||
loading: (_) =>
|
||||
SizedBox.expand(child: Container(color: Colors.transparent)),
|
||||
finish: (result) => result.successOrFail.fold(
|
||||
(_) {
|
||||
if (state.forceClose) {
|
||||
@ -90,8 +93,11 @@ class _DocumentPageState extends State<DocumentPage> {
|
||||
|
||||
Widget _renderBanner(BuildContext context) {
|
||||
return DocumentBanner(
|
||||
onRestore: () => context.read<DocumentBloc>().add(const DocumentEvent.restorePage()),
|
||||
onDelete: () => context.read<DocumentBloc>().add(const DocumentEvent.deletePermanently()),
|
||||
onRestore: () =>
|
||||
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_quill/flutter_quill.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
|
||||
import 'widget/style_widgets.dart';
|
||||
|
||||
DefaultStyles customStyles(BuildContext context) {
|
||||
const baseSpacing = Tuple2<double, double>(6, 0);
|
||||
|
||||
@ -53,7 +52,8 @@ DefaultStyles customStyles(BuildContext context) {
|
||||
const Tuple2(8, 0),
|
||||
const Tuple2(0, 0),
|
||||
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),
|
||||
italic: const TextStyle(fontStyle: FontStyle.italic),
|
||||
small: const TextStyle(fontSize: 12, color: Colors.black45),
|
||||
@ -78,8 +78,8 @@ DefaultStyles customStyles(BuildContext context) {
|
||||
const Tuple2(0, 0),
|
||||
const Tuple2(0, 0),
|
||||
null),
|
||||
lists:
|
||||
DefaultListBlockStyle(baseStyle, baseSpacing, const Tuple2(0, 6), null, StyleWidgetBuilder.checkbox(theme)),
|
||||
lists: DefaultListBlockStyle(baseStyle, baseSpacing, const Tuple2(0, 6),
|
||||
null, StyleWidgetBuilder.checkbox(theme)),
|
||||
quote: DefaultTextBlockStyle(
|
||||
TextStyle(color: baseStyle.color!.withOpacity(0.6)),
|
||||
baseSpacing,
|
||||
@ -102,9 +102,12 @@ DefaultStyles customStyles(BuildContext context) {
|
||||
color: Colors.grey.shade50,
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
)),
|
||||
indent: DefaultTextBlockStyle(baseStyle, baseSpacing, const Tuple2(0, 6), 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),
|
||||
indent: DefaultTextBlockStyle(
|
||||
baseStyle, baseSpacing, const Tuple2(0, 6), 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),
|
||||
sizeLarge: const TextStyle(fontSize: 18),
|
||||
sizeHuge: const TextStyle(fontSize: 22));
|
@ -1,6 +1,6 @@
|
||||
import 'dart:async';
|
||||
import 'package:app_flowy/workspace/application/grid/grid_service.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/row/row_service.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/grid_service.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/row/row_service.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import 'dart:async';
|
||||
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:equatable/equatable.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:flutter/foundation.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/cell/cell_listener.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/cell/cell_listener.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
|
||||
import 'dart:convert' show utf8;
|
||||
|
||||
import '../../field/type_option/type_option_service.dart';
|
@ -1,8 +1,10 @@
|
||||
part of 'cell_service.dart';
|
||||
|
||||
typedef GridCellController = IGridCellController<String, String>;
|
||||
typedef GridSelectOptionCellController = IGridCellController<SelectOptionCellDataPB, String>;
|
||||
typedef GridDateCellController = IGridCellController<DateCellDataPB, CalendarData>;
|
||||
typedef GridSelectOptionCellController
|
||||
= IGridCellController<SelectOptionCellDataPB, String>;
|
||||
typedef GridDateCellController
|
||||
= IGridCellController<DateCellDataPB, CalendarData>;
|
||||
typedef GridURLCellController = IGridCellController<URLCellDataPB, String>;
|
||||
|
||||
class GridCellControllerBuilder {
|
||||
@ -19,7 +21,8 @@ class GridCellControllerBuilder {
|
||||
_cellId = cellId;
|
||||
|
||||
IGridCellController build() {
|
||||
final cellFieldNotifier = GridCellFieldNotifier(notifier: _GridFieldChangedNotifierImpl(_fieldCache));
|
||||
final cellFieldNotifier = GridCellFieldNotifier(
|
||||
notifier: _GridFieldChangedNotifierImpl(_fieldCache));
|
||||
|
||||
switch (_cellId.fieldType) {
|
||||
case FieldType.Checkbox:
|
||||
@ -142,8 +145,10 @@ class IGridCellController<T, D> extends Equatable {
|
||||
_cellDataLoader = cellDataLoader,
|
||||
_cellDataPersistence = cellDataPersistence,
|
||||
_fieldNotifier = fieldNotifier,
|
||||
_fieldService = FieldService(gridId: cellId.gridId, fieldId: cellId.field.id),
|
||||
_cacheKey = GridCellCacheKey(rowId: cellId.rowId, fieldId: cellId.field.id);
|
||||
_fieldService =
|
||||
FieldService(gridId: cellId.gridId, fieldId: cellId.field.id),
|
||||
_cacheKey =
|
||||
GridCellCacheKey(rowId: cellId.rowId, fieldId: cellId.field.id);
|
||||
|
||||
IGridCellController<T, D> clone() {
|
||||
return IGridCellController(
|
||||
@ -164,7 +169,9 @@ class IGridCellController<T, D> extends Equatable {
|
||||
|
||||
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) {
|
||||
Log.error("Already started. It seems like you should call clone first");
|
||||
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].
|
||||
/// [PD] is the type that the parser return.
|
||||
Future<Either<PD, FlowyError>> getFieldTypeOption<PD, P extends TypeOptionDataParser>(P parser) {
|
||||
return _fieldService.getFieldTypeOptionData(fieldType: fieldType).then((result) {
|
||||
Future<Either<PD, FlowyError>>
|
||||
getFieldTypeOption<PD, P extends TypeOptionDataParser>(P parser) {
|
||||
return _fieldService
|
||||
.getFieldTypeOptionData(fieldType: fieldType)
|
||||
.then((result) {
|
||||
return result.fold(
|
||||
(data) => parser.fromBuffer(data.typeOptionData),
|
||||
(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.
|
||||
/// It's useful when you call this method when user editing the [TextField].
|
||||
/// 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) {
|
||||
_loadDataOperation?.cancel();
|
||||
|
||||
@ -288,7 +300,8 @@ class IGridCellController<T, D> extends Equatable {
|
||||
}
|
||||
|
||||
@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 {
|
||||
@ -300,7 +313,7 @@ class _GridFieldChangedNotifierImpl extends GridFieldChangedNotifier {
|
||||
@override
|
||||
void dispose() {
|
||||
if (_onChangesetFn != null) {
|
||||
_cache.removeListener(onChangsetListener: _onChangesetFn!);
|
||||
_cache.removeListener(onChangesetListener: _onChangesetFn!);
|
||||
_onChangesetFn = null;
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
|
||||
import 'package:easy_localization/easy_localization.dart' show StringTranslateExtension;
|
||||
import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
|
||||
import 'package:easy_localization/easy_localization.dart'
|
||||
show StringTranslateExtension;
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error-code/code.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) {
|
||||
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));
|
||||
},
|
||||
setIncludeTime: (includeTime) async {
|
||||
@ -57,15 +59,18 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
|
||||
await _updateDateData(emit, time: time);
|
||||
}
|
||||
},
|
||||
didUpdateCalData: (Option<CalendarData> data, Option<String> timeFormatError) {
|
||||
emit(state.copyWith(calData: data, timeFormatError: timeFormatError));
|
||||
didUpdateCalData:
|
||||
(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(
|
||||
() => CalendarData(date: date ?? DateTime.now(), time: time),
|
||||
(dateData) {
|
||||
@ -84,13 +89,17 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
|
||||
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)) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateCalData(Option<CalendarData> calData, Option<String> timeFormatError) {
|
||||
if (!isClosed) add(DateCalEvent.didUpdateCalData(calData, timeFormatError));
|
||||
updateCalData(
|
||||
Option<CalendarData> calData, Option<String> timeFormatError) {
|
||||
if (!isClosed) {
|
||||
add(DateCalEvent.didUpdateCalData(calData, timeFormatError));
|
||||
}
|
||||
}
|
||||
|
||||
cellContext.saveCellData(newCalData, resultCallback: (result) {
|
||||
@ -172,7 +181,9 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
|
||||
);
|
||||
|
||||
result.fold(
|
||||
(l) => emit(state.copyWith(dateTypeOption: newDateTypeOption, timeHintText: _timeHintText(newDateTypeOption))),
|
||||
(l) => emit(state.copyWith(
|
||||
dateTypeOption: newDateTypeOption,
|
||||
timeHintText: _timeHintText(newDateTypeOption))),
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
}
|
||||
@ -182,14 +193,17 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
|
||||
class DateCalEvent with _$DateCalEvent {
|
||||
const factory DateCalEvent.initial() = _Initial;
|
||||
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.setTimeFormat(TimeFormat timeFormat) = _TimeFormat;
|
||||
const factory DateCalEvent.setDateFormat(DateFormat dateFormat) = _DateFormat;
|
||||
const factory DateCalEvent.setIncludeTime(bool includeTime) = _IncludeTime;
|
||||
const factory DateCalEvent.setTime(String time) = _Time;
|
||||
const factory DateCalEvent.didReceiveCellUpdate(DateCellDataPB? data) = _DidReceiveCellUpdate;
|
||||
const factory DateCalEvent.didUpdateCalData(Option<CalendarData> data, Option<String> timeFormatError) =
|
||||
const factory DateCalEvent.didReceiveCellUpdate(DateCellDataPB? data) =
|
||||
_DidReceiveCellUpdate;
|
||||
const factory DateCalEvent.didUpdateCalData(
|
||||
Option<CalendarData> data, Option<String> timeFormatError) =
|
||||
_DidUpdateCalData;
|
||||
}
|
||||
|
@ -2,11 +2,12 @@ import 'dart:async';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.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';
|
||||
|
||||
class SelectOptionCellBloc extends Bloc<SelectOptionCellEvent, SelectOptionCellState> {
|
||||
class SelectOptionCellBloc
|
||||
extends Bloc<SelectOptionCellEvent, SelectOptionCellState> {
|
||||
final GridSelectOptionCellController cellContext;
|
||||
void Function()? _onCellChangedFn;
|
||||
|
||||
@ -66,7 +67,8 @@ class SelectOptionCellState with _$SelectOptionCellState {
|
||||
required List<SelectOptionPB> selectedOptions,
|
||||
}) = _SelectOptionCellState;
|
||||
|
||||
factory SelectOptionCellState.initial(GridSelectOptionCellController context) {
|
||||
factory SelectOptionCellState.initial(
|
||||
GridSelectOptionCellController context) {
|
||||
final data = context.getCellData();
|
||||
|
||||
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:flutter_bloc/flutter_bloc.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 'package:collection/collection.dart';
|
||||
|
||||
part 'select_option_editor_bloc.freezed.dart';
|
||||
|
||||
class SelectOptionCellEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOptionEditorState> {
|
||||
class SelectOptionCellEditorBloc
|
||||
extends Bloc<SelectOptionEditorEvent, SelectOptionEditorState> {
|
||||
final SelectOptionService _selectOptionService;
|
||||
final GridSelectOptionCellController cellController;
|
||||
Timer? _delayOperation;
|
||||
|
||||
SelectOptionCellEditorBloc({
|
||||
required this.cellController,
|
||||
}) : _selectOptionService = SelectOptionService(cellId: cellController.cellId),
|
||||
}) : _selectOptionService =
|
||||
SelectOptionService(cellId: cellController.cellId),
|
||||
super(SelectOptionEditorState.initial(cellController)) {
|
||||
on<SelectOptionEditorEvent>(
|
||||
(event, emit) async {
|
||||
@ -87,7 +89,8 @@ class SelectOptionCellEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOpt
|
||||
}
|
||||
|
||||
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) {
|
||||
_selectOptionService.unSelect(optionId: optionId);
|
||||
} else {
|
||||
@ -96,7 +99,8 @@ class SelectOptionCellEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOpt
|
||||
}
|
||||
|
||||
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(
|
||||
filter: Some(optionName),
|
||||
options: result.options,
|
||||
@ -112,7 +116,8 @@ class SelectOptionCellEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOpt
|
||||
return;
|
||||
}
|
||||
return result.fold(
|
||||
(data) => add(SelectOptionEditorEvent.didReceiveOptions(data.options, data.selectOptions)),
|
||||
(data) => add(SelectOptionEditorEvent.didReceiveOptions(
|
||||
data.options, data.selectOptions)),
|
||||
(err) {
|
||||
Log.error(err);
|
||||
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);
|
||||
Option<String> createOption = filter;
|
||||
|
||||
@ -165,12 +171,18 @@ class SelectOptionCellEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOpt
|
||||
class SelectOptionEditorEvent with _$SelectOptionEditorEvent {
|
||||
const factory SelectOptionEditorEvent.initial() = _Initial;
|
||||
const factory SelectOptionEditorEvent.didReceiveOptions(
|
||||
List<SelectOptionPB> options, List<SelectOptionPB> selectedOptions) = _DidReceiveOptions;
|
||||
const factory SelectOptionEditorEvent.newOption(String optionName) = _NewOption;
|
||||
const factory SelectOptionEditorEvent.selectOption(String optionId) = _SelectOption;
|
||||
const factory SelectOptionEditorEvent.updateOption(SelectOptionPB option) = _UpdateOption;
|
||||
const factory SelectOptionEditorEvent.deleteOption(SelectOptionPB option) = _DeleteOption;
|
||||
const factory SelectOptionEditorEvent.filterOption(String optionName) = _SelectOptionFilter;
|
||||
List<SelectOptionPB> options, List<SelectOptionPB> selectedOptions) =
|
||||
_DidReceiveOptions;
|
||||
const factory SelectOptionEditorEvent.newOption(String optionName) =
|
||||
_NewOption;
|
||||
const factory SelectOptionEditorEvent.selectOption(String optionId) =
|
||||
_SelectOption;
|
||||
const factory SelectOptionEditorEvent.updateOption(SelectOptionPB option) =
|
||||
_UpdateOption;
|
||||
const factory SelectOptionEditorEvent.deleteOption(SelectOptionPB option) =
|
||||
_DeleteOption;
|
||||
const factory SelectOptionEditorEvent.filterOption(String optionName) =
|
||||
_SelectOptionFilter;
|
||||
}
|
||||
|
||||
@freezed
|
||||
@ -183,7 +195,8 @@ class SelectOptionEditorState with _$SelectOptionEditorState {
|
||||
required Option<String> filter,
|
||||
}) = _SelectOptionEditorState;
|
||||
|
||||
factory SelectOptionEditorState.initial(GridSelectOptionCellController context) {
|
||||
factory SelectOptionEditorState.initial(
|
||||
GridSelectOptionCellController context) {
|
||||
final data = context.getCellData(loadIfNotExist: false);
|
||||
return SelectOptionEditorState(
|
||||
options: data?.options ?? [],
|
@ -2,7 +2,7 @@ import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.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 'cell_service/cell_service.dart';
|
||||
|
||||
@ -15,7 +15,9 @@ class SelectOptionService {
|
||||
String get rowId => cellId.rowId;
|
||||
|
||||
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) {
|
||||
return result.fold(
|
||||
(option) {
|
@ -1,5 +1,5 @@
|
||||
import 'package:app_flowy/workspace/application/grid/field/field_listener.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/field/field_listener.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
@ -15,7 +15,8 @@ class FieldCellBloc extends Bloc<FieldCellEvent, FieldCellState> {
|
||||
FieldCellBloc({
|
||||
required GridFieldCellContext cellContext,
|
||||
}) : _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)) {
|
||||
on<FieldCellEvent>(
|
||||
(event, emit) async {
|
||||
@ -62,8 +63,10 @@ class FieldCellBloc extends Bloc<FieldCellEvent, FieldCellState> {
|
||||
@freezed
|
||||
class FieldCellEvent with _$FieldCellEvent {
|
||||
const factory FieldCellEvent.initial() = _InitialCell;
|
||||
const factory FieldCellEvent.didReceiveFieldUpdate(GridFieldPB field) = _DidReceiveFieldUpdate;
|
||||
const factory FieldCellEvent.startUpdateWidth(double offset) = _StartUpdateWidth;
|
||||
const factory FieldCellEvent.didReceiveFieldUpdate(GridFieldPB field) =
|
||||
_DidReceiveFieldUpdate;
|
||||
const factory FieldCellEvent.startUpdateWidth(double offset) =
|
||||
_StartUpdateWidth;
|
||||
const factory FieldCellEvent.endUpdateWidth() = _EndUpdateWidth;
|
||||
}
|
||||
|
||||
@ -75,7 +78,8 @@ class FieldCellState with _$FieldCellState {
|
||||
required double width,
|
||||
}) = _FieldCellState;
|
||||
|
||||
factory FieldCellState.initial(GridFieldCellContext cellContext) => FieldCellState(
|
||||
factory FieldCellState.initial(GridFieldCellContext cellContext) =>
|
||||
FieldCellState(
|
||||
gridId: cellContext.gridId,
|
||||
field: cellContext.field,
|
||||
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_entities.pb.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})
|
||||
: super(DateTypeOptionState.initial(typeOptionContext.typeOption)) {
|
||||
on<DateTypeOptionEvent>(
|
||||
(event, emit) async {
|
||||
event.map(
|
||||
didSelectDateFormat: (_DidSelectDateFormat value) {
|
||||
emit(state.copyWith(typeOption: _updateTypeOption(dateFormat: value.format)));
|
||||
emit(state.copyWith(
|
||||
typeOption: _updateTypeOption(dateFormat: value.format)));
|
||||
},
|
||||
didSelectTimeFormat: (_DidSelectTimeFormat value) {
|
||||
emit(state.copyWith(typeOption: _updateTypeOption(timeFormat: value.format)));
|
||||
emit(state.copyWith(
|
||||
typeOption: _updateTypeOption(timeFormat: value.format)));
|
||||
},
|
||||
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
|
||||
class DateTypeOptionEvent with _$DateTypeOptionEvent {
|
||||
const factory DateTypeOptionEvent.didSelectDateFormat(DateFormat format) = _DidSelectDateFormat;
|
||||
const factory DateTypeOptionEvent.didSelectTimeFormat(TimeFormat format) = _DidSelectTimeFormat;
|
||||
const factory DateTypeOptionEvent.includeTime(bool includeTime) = _IncludeTime;
|
||||
const factory DateTypeOptionEvent.didSelectDateFormat(DateFormat format) =
|
||||
_DidSelectDateFormat;
|
||||
const factory DateTypeOptionEvent.didSelectTimeFormat(TimeFormat format) =
|
||||
_DidSelectTimeFormat;
|
||||
const factory DateTypeOptionEvent.includeTime(bool includeTime) =
|
||||
_IncludeTime;
|
||||
}
|
||||
|
||||
@freezed
|
||||
@ -76,5 +83,6 @@ class DateTypeOptionState with _$DateTypeOptionState {
|
||||
required DateTypeOption typeOption,
|
||||
}) = _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/protobuf/flowy-grid/multi_select_type_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 'type_option_service.dart';
|
||||
|
||||
class MultiSelectTypeOptionContext extends TypeOptionWidgetContext<MultiSelectTypeOption>
|
||||
class MultiSelectTypeOptionContext
|
||||
extends TypeOptionWidgetContext<MultiSelectTypeOption>
|
||||
with SelectOptionTypeOptionAction {
|
||||
final TypeOptionService service;
|
||||
|
||||
@ -25,7 +26,8 @@ class MultiSelectTypeOptionContext extends TypeOptionWidgetContext<MultiSelectTy
|
||||
return (SelectOptionPB option) {
|
||||
typeOption.freeze();
|
||||
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) {
|
||||
typeOption.options.removeAt(index);
|
||||
}
|
||||
@ -61,7 +63,8 @@ class MultiSelectTypeOptionContext extends TypeOptionWidgetContext<MultiSelectTy
|
||||
return (SelectOptionPB option) {
|
||||
typeOption.freeze();
|
||||
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) {
|
||||
typeOption.options[index] = option;
|
||||
}
|
||||
@ -71,7 +74,8 @@ class MultiSelectTypeOptionContext extends TypeOptionWidgetContext<MultiSelectTy
|
||||
}
|
||||
}
|
||||
|
||||
class MultiSelectTypeOptionWidgetDataParser extends TypeOptionDataParser<MultiSelectTypeOption> {
|
||||
class MultiSelectTypeOptionWidgetDataParser
|
||||
extends TypeOptionDataParser<MultiSelectTypeOption> {
|
||||
@override
|
||||
MultiSelectTypeOption fromBuffer(List<int> 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/number_type_option.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
@ -10,14 +10,16 @@ part 'number_bloc.freezed.dart';
|
||||
|
||||
typedef NumberTypeOptionContext = TypeOptionWidgetContext<NumberTypeOption>;
|
||||
|
||||
class NumberTypeOptionWidgetDataParser extends TypeOptionDataParser<NumberTypeOption> {
|
||||
class NumberTypeOptionWidgetDataParser
|
||||
extends TypeOptionDataParser<NumberTypeOption> {
|
||||
@override
|
||||
NumberTypeOption fromBuffer(List<int> buffer) {
|
||||
return NumberTypeOption.fromBuffer(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
class NumberTypeOptionBloc extends Bloc<NumberTypeOptionEvent, NumberTypeOptionState> {
|
||||
class NumberTypeOptionBloc
|
||||
extends Bloc<NumberTypeOptionEvent, NumberTypeOptionState> {
|
||||
NumberTypeOptionBloc({required NumberTypeOptionContext typeOptionContext})
|
||||
: super(NumberTypeOptionState.initial(typeOptionContext.typeOption)) {
|
||||
on<NumberTypeOptionEvent>(
|
||||
@ -46,7 +48,8 @@ class NumberTypeOptionBloc extends Bloc<NumberTypeOptionEvent, NumberTypeOptionS
|
||||
|
||||
@freezed
|
||||
class NumberTypeOptionEvent with _$NumberTypeOptionEvent {
|
||||
const factory NumberTypeOptionEvent.didSelectFormat(NumberFormat format) = _DidSelectFormat;
|
||||
const factory NumberTypeOptionEvent.didSelectFormat(NumberFormat format) =
|
||||
_DidSelectFormat;
|
||||
}
|
||||
|
||||
@freezed
|
||||
@ -55,7 +58,8 @@ class NumberTypeOptionState with _$NumberTypeOptionState {
|
||||
required NumberTypeOption typeOption,
|
||||
}) = _NumberTypeOptionState;
|
||||
|
||||
factory NumberTypeOptionState.initial(NumberTypeOption typeOption) => NumberTypeOptionState(
|
||||
factory NumberTypeOptionState.initial(NumberTypeOption typeOption) =>
|
||||
NumberTypeOptionState(
|
||||
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/protobuf/flowy-grid/select_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 'type_option_service.dart';
|
||||
|
||||
class SingleSelectTypeOptionContext extends TypeOptionWidgetContext<SingleSelectTypeOptionPB>
|
||||
class SingleSelectTypeOptionContext
|
||||
extends TypeOptionWidgetContext<SingleSelectTypeOptionPB>
|
||||
with SelectOptionTypeOptionAction {
|
||||
final TypeOptionService service;
|
||||
|
||||
@ -25,7 +26,8 @@ class SingleSelectTypeOptionContext extends TypeOptionWidgetContext<SingleSelect
|
||||
return (SelectOptionPB option) {
|
||||
typeOption.freeze();
|
||||
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) {
|
||||
typeOption.options.removeAt(index);
|
||||
}
|
||||
@ -61,7 +63,8 @@ class SingleSelectTypeOptionContext extends TypeOptionWidgetContext<SingleSelect
|
||||
return (SelectOptionPB option) {
|
||||
typeOption.freeze();
|
||||
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) {
|
||||
typeOption.options[index] = option;
|
||||
}
|
||||
@ -71,7 +74,8 @@ class SingleSelectTypeOptionContext extends TypeOptionWidgetContext<SingleSelect
|
||||
}
|
||||
}
|
||||
|
||||
class SingleSelectTypeOptionWidgetDataParser extends TypeOptionDataParser<SingleSelectTypeOptionPB> {
|
||||
class SingleSelectTypeOptionWidgetDataParser
|
||||
extends TypeOptionDataParser<SingleSelectTypeOptionPB> {
|
||||
@override
|
||||
SingleSelectTypeOptionPB fromBuffer(List<int> buffer) {
|
||||
return SingleSelectTypeOptionPB.fromBuffer(buffer);
|
@ -1,6 +1,6 @@
|
||||
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:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
@ -92,7 +92,9 @@ class TypeOptionContext2<T> {
|
||||
return Future(() => left(_data!));
|
||||
}
|
||||
|
||||
return _fieldService.getFieldTypeOptionData(fieldType: field.fieldType).then((result) {
|
||||
return _fieldService
|
||||
.getFieldTypeOptionData(fieldType: field.fieldType)
|
||||
.then((result) {
|
||||
return result.fold(
|
||||
(data) {
|
||||
_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/protobuf/flowy-grid/field_entities.pb.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);
|
||||
fields.insert(value.toIndex, fields.removeAt(value.fromIndex));
|
||||
emit(state.copyWith(fields: fields));
|
||||
@ -62,13 +63,16 @@ class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> {
|
||||
@freezed
|
||||
class GridHeaderEvent with _$GridHeaderEvent {
|
||||
const factory GridHeaderEvent.initial() = _InitialHeader;
|
||||
const factory GridHeaderEvent.didReceiveFieldUpdate(List<GridFieldPB> fields) = _DidReceiveFieldUpdate;
|
||||
const factory GridHeaderEvent.moveField(GridFieldPB field, int fromIndex, int toIndex) = _MoveField;
|
||||
const factory GridHeaderEvent.didReceiveFieldUpdate(
|
||||
List<GridFieldPB> fields) = _DidReceiveFieldUpdate;
|
||||
const factory GridHeaderEvent.moveField(
|
||||
GridFieldPB field, int fromIndex, int toIndex) = _MoveField;
|
||||
}
|
||||
|
||||
@freezed
|
||||
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) {
|
||||
// final List<GridFieldPB> newFields = List.from(fields);
|
@ -1,6 +1,6 @@
|
||||
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:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
@ -26,13 +26,15 @@ class GridService {
|
||||
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;
|
||||
startRowId?.fold(() => null, (id) => payload.startRowId = id);
|
||||
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()
|
||||
..gridId = gridId
|
||||
..fieldIds = RepeatedGridFieldIdPB(items: fieldIds);
|
||||
@ -64,9 +66,11 @@ class GridFieldCache {
|
||||
final GridFieldsListener _fieldListener;
|
||||
FieldsNotifier? _fieldNotifier = FieldsNotifier();
|
||||
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) {
|
||||
result.fold(
|
||||
(changeset) {
|
||||
@ -88,7 +92,8 @@ class GridFieldCache {
|
||||
_fieldNotifier = null;
|
||||
}
|
||||
|
||||
UnmodifiableListView<GridFieldPB> get unmodifiableFields => UnmodifiableListView(_fieldNotifier?.fields ?? []);
|
||||
UnmodifiableListView<GridFieldPB> get unmodifiableFields =>
|
||||
UnmodifiableListView(_fieldNotifier?.fields ?? []);
|
||||
|
||||
List<GridFieldPB> get fields => [..._fieldNotifier?.fields ?? []];
|
||||
|
||||
@ -127,7 +132,7 @@ class GridFieldCache {
|
||||
|
||||
void removeListener({
|
||||
FieldsCallback? onFieldsListener,
|
||||
FieldChangesetCallback? onChangsetListener,
|
||||
FieldChangesetCallback? onChangesetListener,
|
||||
}) {
|
||||
if (onFieldsListener != null) {
|
||||
final fn = _fieldsCallbackMap.remove(onFieldsListener);
|
||||
@ -136,8 +141,8 @@ class GridFieldCache {
|
||||
}
|
||||
}
|
||||
|
||||
if (onChangsetListener != null) {
|
||||
_changesetCallbackMap.remove(onChangsetListener);
|
||||
if (onChangesetListener != null) {
|
||||
_changesetCallbackMap.remove(onChangesetListener);
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,7 +180,8 @@ class GridFieldCache {
|
||||
}
|
||||
final List<GridFieldPB> newFields = fields;
|
||||
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) {
|
||||
newFields.removeAt(index);
|
||||
newFields.insert(index, updatedField);
|
||||
@ -219,7 +225,7 @@ class GridRowCacheFieldNotifierImpl extends GridRowCacheFieldNotifier {
|
||||
}
|
||||
|
||||
if (_onChangesetFn != null) {
|
||||
_cache.removeListener(onChangsetListener: _onChangesetFn!);
|
||||
_cache.removeListener(onChangesetListener: _onChangesetFn!);
|
||||
_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/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
@ -8,7 +8,8 @@ import 'package:dartz/dartz.dart';
|
||||
|
||||
part 'row_action_sheet_bloc.freezed.dart';
|
||||
|
||||
class RowActionSheetBloc extends Bloc<RowActionSheetEvent, RowActionSheetState> {
|
||||
class RowActionSheetBloc
|
||||
extends Bloc<RowActionSheetEvent, RowActionSheetState> {
|
||||
final RowService _rowService;
|
||||
|
||||
RowActionSheetBloc({required GridRowInfo rowData})
|
||||
@ -56,7 +57,8 @@ class RowActionSheetState with _$RowActionSheetState {
|
||||
required GridRowInfo rowData,
|
||||
}) = _RowActionSheetState;
|
||||
|
||||
factory RowActionSheetState.initial(GridRowInfo rowData) => RowActionSheetState(
|
||||
factory RowActionSheetState.initial(GridRowInfo rowData) =>
|
||||
RowActionSheetState(
|
||||
rowData: rowData,
|
||||
);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
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:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
@ -34,7 +34,9 @@ class RowBloc extends Bloc<RowEvent, RowState> {
|
||||
_rowService.createRow();
|
||||
},
|
||||
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);
|
||||
emit(state.copyWith(
|
||||
gridCellMap: value.gridCellMap,
|
||||
@ -59,7 +61,8 @@ class RowBloc extends Bloc<RowEvent, RowState> {
|
||||
Future<void> _startListening() async {
|
||||
_rowListenFn = _rowCache.addListener(
|
||||
rowId: state.rowInfo.id,
|
||||
onCellUpdated: (cellDatas, reason) => add(RowEvent.didReceiveCellDatas(cellDatas, reason)),
|
||||
onCellUpdated: (cellDatas, reason) =>
|
||||
add(RowEvent.didReceiveCellDatas(cellDatas, reason)),
|
||||
listenWhen: () => !isClosed,
|
||||
);
|
||||
}
|
||||
@ -69,7 +72,8 @@ class RowBloc extends Bloc<RowEvent, RowState> {
|
||||
class RowEvent with _$RowEvent {
|
||||
const factory RowEvent.initial() = _InitialRow;
|
||||
const factory RowEvent.createRow() = _CreateRow;
|
||||
const factory RowEvent.didReceiveCellDatas(GridCellMap gridCellMap, GridRowChangeReason reason) =
|
||||
const factory RowEvent.didReceiveCellDatas(
|
||||
GridCellMap gridCellMap, GridRowChangeReason reason) =
|
||||
_DidReceiveCellDatas;
|
||||
}
|
||||
|
||||
@ -82,10 +86,12 @@ class RowState with _$RowState {
|
||||
GridRowChangeReason? changeReason,
|
||||
}) = _RowState;
|
||||
|
||||
factory RowState.initial(GridRowInfo rowInfo, GridCellMap cellDataMap) => RowState(
|
||||
factory RowState.initial(GridRowInfo rowInfo, GridCellMap cellDataMap) =>
|
||||
RowState(
|
||||
rowInfo: rowInfo,
|
||||
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:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
@ -42,7 +42,8 @@ class RowDetailBloc extends Bloc<RowDetailEvent, RowDetailState> {
|
||||
Future<void> _startListening() async {
|
||||
_rowListenFn = _rowCache.addListener(
|
||||
rowId: rowInfo.id,
|
||||
onCellUpdated: (cellDatas, reason) => add(RowDetailEvent.didReceiveCellDatas(cellDatas.values.toList())),
|
||||
onCellUpdated: (cellDatas, reason) =>
|
||||
add(RowDetailEvent.didReceiveCellDatas(cellDatas.values.toList())),
|
||||
listenWhen: () => !isClosed,
|
||||
);
|
||||
}
|
||||
@ -58,7 +59,8 @@ class RowDetailBloc extends Bloc<RowDetailEvent, RowDetailState> {
|
||||
@freezed
|
||||
class RowDetailEvent with _$RowDetailEvent {
|
||||
const factory RowDetailEvent.initial() = _Initial;
|
||||
const factory RowDetailEvent.didReceiveCellDatas(List<GridCellIdentifier> gridCells) = _DidReceiveCellDatas;
|
||||
const factory RowDetailEvent.didReceiveCellDatas(
|
||||
List<GridCellIdentifier> gridCells) = _DidReceiveCellDatas;
|
||||
}
|
||||
|
||||
@freezed
|
@ -1,5 +1,5 @@
|
||||
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:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
@ -53,9 +53,12 @@ class GridRowCache {
|
||||
_rowChangeReasonNotifier = _GridRowChangesetNotifier(),
|
||||
_fieldNotifier = notifier {
|
||||
//
|
||||
notifier.onFieldsChanged(() => _rowChangeReasonNotifier.receive(const GridRowChangeReason.fieldDidChange()));
|
||||
notifier.onFieldsChanged(() => _rowChangeReasonNotifier
|
||||
.receive(const GridRowChangeReason.fieldDidChange()));
|
||||
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 {
|
||||
@ -81,7 +84,9 @@ class GridRowCache {
|
||||
|
||||
final List<GridRowInfo> newRows = [];
|
||||
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) {
|
||||
if (deletedRowByRowId[row.id] == null) {
|
||||
@ -107,7 +112,8 @@ class GridRowCache {
|
||||
rowId: insertRow.rowId,
|
||||
);
|
||||
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));
|
||||
@ -126,7 +132,8 @@ class GridRowCache {
|
||||
_rowByRowId[rowId] = updatedRow.row;
|
||||
|
||||
_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);
|
||||
}
|
||||
}
|
||||
@ -225,7 +232,8 @@ class GridRowCache {
|
||||
updatedRow.freeze();
|
||||
|
||||
_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) {
|
||||
// update the corresponding row in _rows if they are not the same
|
||||
if (_rowInfos[index].rawRow != updatedRow) {
|
||||
@ -237,7 +245,8 @@ class GridRowCache {
|
||||
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 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() {
|
||||
CreateRowPayloadPB payload = CreateRowPayloadPB.create()
|
||||
@ -285,7 +295,8 @@ class RowService {
|
||||
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()
|
||||
..gridId = gridId
|
||||
..itemId = rowId
|
@ -1,5 +1,5 @@
|
||||
import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/grid_service.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/grid_service.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
@ -22,8 +22,10 @@ class GridPropertyBloc extends Bloc<GridPropertyEvent, GridPropertyState> {
|
||||
_startListening();
|
||||
},
|
||||
setFieldVisibility: (_SetFieldVisibility value) async {
|
||||
final fieldService = FieldService(gridId: gridId, fieldId: value.fieldId);
|
||||
final result = await fieldService.updateField(visibility: value.visibility);
|
||||
final fieldService =
|
||||
FieldService(gridId: gridId, fieldId: value.fieldId);
|
||||
final result =
|
||||
await fieldService.updateField(visibility: value.visibility);
|
||||
result.fold(
|
||||
(l) => null,
|
||||
(err) => Log.error(err),
|
||||
@ -50,7 +52,8 @@ class GridPropertyBloc extends Bloc<GridPropertyEvent, GridPropertyState> {
|
||||
}
|
||||
|
||||
void _startListening() {
|
||||
_onFieldsFn = (fields) => add(GridPropertyEvent.didReceiveFieldUpdate(fields));
|
||||
_onFieldsFn =
|
||||
(fields) => add(GridPropertyEvent.didReceiveFieldUpdate(fields));
|
||||
_fieldCache.addListener(
|
||||
onFields: _onFieldsFn,
|
||||
listenWhen: () => !isClosed,
|
||||
@ -61,9 +64,12 @@ class GridPropertyBloc extends Bloc<GridPropertyEvent, GridPropertyState> {
|
||||
@freezed
|
||||
class GridPropertyEvent with _$GridPropertyEvent {
|
||||
const factory GridPropertyEvent.initial() = _Initial;
|
||||
const factory GridPropertyEvent.setFieldVisibility(String fieldId, bool visibility) = _SetFieldVisibility;
|
||||
const factory GridPropertyEvent.didReceiveFieldUpdate(List<GridFieldPB> fields) = _DidReceiveFieldUpdate;
|
||||
const factory GridPropertyEvent.moveField(int fromIndex, int toIndex) = _MoveField;
|
||||
const factory GridPropertyEvent.setFieldVisibility(
|
||||
String fieldId, bool visibility) = _SetFieldVisibility;
|
||||
const factory GridPropertyEvent.didReceiveFieldUpdate(
|
||||
List<GridFieldPB> fields) = _DidReceiveFieldUpdate;
|
||||
const factory GridPropertyEvent.moveField(int fromIndex, int toIndex) =
|
||||
_MoveField;
|
||||
}
|
||||
|
||||
@freezed
|
||||
@ -73,7 +79,8 @@ class GridPropertyState with _$GridPropertyState {
|
||||
required List<GridFieldPB> fields,
|
||||
}) = _GridPropertyState;
|
||||
|
||||
factory GridPropertyState.initial(String gridId, List<GridFieldPB> fields) => GridPropertyState(
|
||||
factory GridPropertyState.initial(String gridId, List<GridFieldPB> fields) =>
|
||||
GridPropertyState(
|
||||
gridId: gridId,
|
||||
fields: fields,
|
||||
);
|
@ -1,12 +1,12 @@
|
||||
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/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:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'src/grid_page.dart';
|
||||
import 'presentation/grid_page.dart';
|
||||
|
||||
class GridPluginBuilder implements PluginBuilder {
|
||||
@override
|
@ -1,6 +1,6 @@
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/grid_bloc.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/row/row_service.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/grid_bloc.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/row/row_service.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_scroll_bar.dart';
|
||||
@ -35,13 +35,15 @@ class _GridPageState extends State<GridPage> {
|
||||
return MultiBlocProvider(
|
||||
providers: [
|
||||
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>(
|
||||
builder: (context, state) {
|
||||
return state.loadingState.map(
|
||||
loading: (_) => const Center(child: CircularProgressIndicator.adaptive()),
|
||||
loading: (_) =>
|
||||
const Center(child: CircularProgressIndicator.adaptive()),
|
||||
finish: (result) => result.successOrFail.fold(
|
||||
(_) => const GridShortcuts(child: FlowyGrid()),
|
||||
(err) => FlowyErrorPage(err.toString()),
|
||||
@ -76,7 +78,8 @@ class FlowyGrid extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _FlowyGridState extends State<FlowyGrid> {
|
||||
final _scrollController = GridScrollController(scrollGroupContorller: LinkedScrollControllerGroup());
|
||||
final _scrollController = GridScrollController(
|
||||
scrollGroupContorller: LinkedScrollControllerGroup());
|
||||
late ScrollController headerScrollController;
|
||||
|
||||
@override
|
||||
@ -204,7 +207,8 @@ class _GridRowsState extends State<_GridRows> {
|
||||
for (final item in value.items) {
|
||||
_key.currentState?.removeItem(
|
||||
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(
|
||||
key: _key,
|
||||
initialItemCount: context.read<GridBloc>().state.rowInfos.length,
|
||||
itemBuilder: (BuildContext context, int index, Animation<double> animation) {
|
||||
final GridRowInfo rowInfo = context.read<GridBloc>().state.rowInfos[index];
|
||||
itemBuilder:
|
||||
(BuildContext context, int index, Animation<double> animation) {
|
||||
final GridRowInfo rowInfo =
|
||||
context.read<GridBloc>().state.rowInfos[index];
|
||||
return _renderRow(context, rowInfo, animation);
|
||||
},
|
||||
);
|
||||
@ -229,7 +235,8 @@ class _GridRowsState extends State<_GridRows> {
|
||||
GridRowInfo rowInfo,
|
||||
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;
|
||||
if (rowCache != null) {
|
||||
return SizeTransition(
|
||||
@ -266,10 +273,10 @@ class _GridFooter extends StatelessWidget {
|
||||
SizedBox(width: GridSize.leadingHeaderPadding),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
children: [
|
||||
const SizedBox(width: 120, child: GridAddRowButton()),
|
||||
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(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
FlowyText.regular('Count : ',
|
||||
fontSize: 13,
|
||||
color: theme.shader3,
|
||||
FlowyText.regular(
|
||||
'Count : ',
|
||||
fontSize: 13,
|
||||
color: theme.shader3,
|
||||
),
|
||||
FlowyText.regular(count.toString(),
|
||||
fontSize: 13,
|
||||
FlowyText.regular(
|
||||
count.toString(),
|
||||
fontSize: 13,
|
||||
),
|
||||
],
|
||||
);
|
@ -1,11 +1,12 @@
|
||||
import 'package:flowy_infra/image.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
|
||||
class GridCellAccessoryBuildContext {
|
||||
final BuildContext anchorContext;
|
||||
@ -39,7 +40,13 @@ class PrimaryCellAccessory extends StatelessWidget with GridCellAccessory {
|
||||
return const SizedBox();
|
||||
} else {
|
||||
final theme = context.watch<AppTheme>();
|
||||
return svgWidget("grid/expander", color: theme.main1);
|
||||
return Tooltip(
|
||||
message: LocaleKeys.tooltip_openAsPage.tr(),
|
||||
child: svgWidget(
|
||||
"grid/expander",
|
||||
color: theme.main1,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,7 +57,8 @@ class PrimaryCellAccessory extends StatelessWidget with GridCellAccessory {
|
||||
bool enable() => !isCellEditing;
|
||||
}
|
||||
|
||||
typedef AccessoryBuilder = List<GridCellAccessory> Function(GridCellAccessoryBuildContext buildContext);
|
||||
typedef AccessoryBuilder = List<GridCellAccessory> Function(
|
||||
GridCellAccessoryBuildContext buildContext);
|
||||
|
||||
abstract class CellAccessory extends Widget {
|
||||
const CellAccessory({Key? key}) : super(key: key);
|
||||
@ -81,7 +89,8 @@ class _AccessoryHoverState extends State<AccessoryHover> {
|
||||
@override
|
||||
void initState() {
|
||||
_hoverState = AccessoryHoverState();
|
||||
_listenerFn = () => _hoverState.onHover = widget.child.onAccessoryHover?.value ?? false;
|
||||
_listenerFn = () =>
|
||||
_hoverState.onHover = widget.child.onAccessoryHover?.value ?? false;
|
||||
widget.child.onAccessoryHover?.addListener(_listenerFn!);
|
||||
|
||||
super.initState();
|
||||
@ -159,7 +168,8 @@ class _Background extends StatelessWidget {
|
||||
builder: (context, state, child) {
|
||||
if (state.onHover) {
|
||||
return FlowyHoverContainer(
|
||||
style: HoverStyle(borderRadius: Corners.s6Border, hoverColor: theme.shader6),
|
||||
style: HoverStyle(
|
||||
borderRadius: Corners.s6Border, hoverColor: theme.shader6),
|
||||
);
|
||||
} else {
|
||||
return const SizedBox();
|
||||
@ -171,14 +181,17 @@ class _Background extends StatelessWidget {
|
||||
|
||||
class CellAccessoryContainer extends StatelessWidget {
|
||||
final List<GridCellAccessory> accessories;
|
||||
const CellAccessoryContainer({required this.accessories, Key? key}) : super(key: key);
|
||||
const CellAccessoryContainer({required this.accessories, Key? key})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = context.watch<AppTheme>();
|
||||
final children = accessories.where((accessory) => accessory.enable()).map((accessory) {
|
||||
final children =
|
||||
accessories.where((accessory) => accessory.enable()).map((accessory) {
|
||||
final hover = FlowyHover(
|
||||
style: HoverStyle(hoverColor: theme.bg3, backgroundColor: theme.surface),
|
||||
style:
|
||||
HoverStyle(hoverColor: theme.bg3, backgroundColor: theme.surface),
|
||||
builder: (_, onHover) => Container(
|
||||
width: 26,
|
||||
height: 26,
|
@ -1,5 +1,5 @@
|
||||
import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/grid_service.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_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:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
@ -30,19 +30,36 @@ class GridCellBuilder {
|
||||
final key = cell.key();
|
||||
switch (cell.fieldType) {
|
||||
case FieldType.Checkbox:
|
||||
return GridCheckboxCell(cellControllerBuilder: cellControllerBuilder, key: key);
|
||||
return GridCheckboxCell(
|
||||
cellControllerBuilder: cellControllerBuilder, key: key);
|
||||
case FieldType.DateTime:
|
||||
return GridDateCell(cellControllerBuilder: cellControllerBuilder, key: key, style: style);
|
||||
return GridDateCell(
|
||||
cellControllerBuilder: cellControllerBuilder,
|
||||
key: key,
|
||||
style: style);
|
||||
case FieldType.SingleSelect:
|
||||
return GridSingleSelectCell(cellContorllerBuilder: cellControllerBuilder, style: style, key: key);
|
||||
return GridSingleSelectCell(
|
||||
cellContorllerBuilder: cellControllerBuilder,
|
||||
style: style,
|
||||
key: key);
|
||||
case FieldType.MultiSelect:
|
||||
return GridMultiSelectCell(cellContorllerBuilder: cellControllerBuilder, style: style, key: key);
|
||||
return GridMultiSelectCell(
|
||||
cellContorllerBuilder: cellControllerBuilder,
|
||||
style: style,
|
||||
key: key);
|
||||
case FieldType.Number:
|
||||
return GridNumberCell(cellContorllerBuilder: cellControllerBuilder, key: key);
|
||||
return GridNumberCell(
|
||||
cellContorllerBuilder: cellControllerBuilder, key: key);
|
||||
case FieldType.RichText:
|
||||
return GridTextCell(cellContorllerBuilder: cellControllerBuilder, style: style, key: key);
|
||||
return GridTextCell(
|
||||
cellContorllerBuilder: cellControllerBuilder,
|
||||
style: style,
|
||||
key: key);
|
||||
case FieldType.URL:
|
||||
return GridURLCell(cellContorllerBuilder: cellControllerBuilder, style: style, key: key);
|
||||
return GridURLCell(
|
||||
cellContorllerBuilder: cellControllerBuilder,
|
||||
style: style,
|
||||
key: key);
|
||||
}
|
||||
throw UnimplementedError;
|
||||
}
|
||||
@ -65,7 +82,8 @@ abstract class CellEditable {
|
||||
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) {
|
||||
onCellEditing.addListener(() {
|
||||
onCellFocus.value = onCellEditing.value;
|
||||
@ -83,7 +101,8 @@ abstract class GridCellWidget extends StatefulWidget implements CellAccessory, C
|
||||
final ValueNotifier<bool> onCellEditing = ValueNotifier<bool>(false);
|
||||
|
||||
@override
|
||||
List<GridCellAccessory> Function(GridCellAccessoryBuildContext buildContext)? get accessoryBuilder => null;
|
||||
List<GridCellAccessory> Function(GridCellAccessoryBuildContext buildContext)?
|
||||
get accessoryBuilder => null;
|
||||
|
||||
@override
|
||||
final GridCellFocusListener beginFocus = GridCellFocusListener();
|
||||
@ -129,12 +148,14 @@ abstract class GridCellState<T extends GridCellWidget> extends State<T> {
|
||||
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();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
widget.shortcutHandlers[CellKeyboardKey.onEnter] = () => focusNode.unfocus();
|
||||
widget.shortcutHandlers[CellKeyboardKey.onEnter] =
|
||||
() => focusNode.unfocus();
|
||||
_listenOnFocusNodeChanged();
|
||||
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:flutter/widgets.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
|
||||
import '../../layout/sizes.dart';
|
||||
import '../row/grid_row.dart';
|
||||
import 'cell_accessory.dart';
|
||||
import 'cell_builder.dart';
|
||||
import 'cell_shortcuts.dart';
|
||||
@ -24,9 +24,11 @@ class CellContainer extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProxyProvider<RegionStateNotifier, CellContainerNotifier>(
|
||||
return ChangeNotifierProxyProvider<RegionStateNotifier,
|
||||
CellContainerNotifier>(
|
||||
create: (_) => CellContainerNotifier(child),
|
||||
update: (_, rowStateNotifier, cellStateNotifier) => cellStateNotifier!..onEnter = rowStateNotifier.onEnter,
|
||||
update: (_, rowStateNotifier, cellStateNotifier) =>
|
||||
cellStateNotifier!..onEnter = rowStateNotifier.onEnter,
|
||||
child: Selector<CellContainerNotifier, bool>(
|
||||
selector: (context, notifier) => notifier.isFocus,
|
||||
builder: (context, isFocus, _) {
|
||||
@ -39,7 +41,8 @@ class CellContainer extends StatelessWidget {
|
||||
));
|
||||
|
||||
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));
|
||||
} else {
|
||||
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 {
|
||||
final Widget child;
|
||||
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
|
||||
Widget build(BuildContext context) {
|
||||
@ -82,13 +88,18 @@ class CellEnterRegion extends StatelessWidget {
|
||||
builder: (context, onEnter, _) {
|
||||
List<Widget> children = [child];
|
||||
if (onEnter) {
|
||||
children.add(CellAccessoryContainer(accessories: accessories).positioned(right: 0));
|
||||
children.add(CellAccessoryContainer(accessories: accessories)
|
||||
.positioned(right: 0));
|
||||
}
|
||||
|
||||
return MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
onEnter: (p) => Provider.of<CellContainerNotifier>(context, listen: false).onEnter = true,
|
||||
onExit: (p) => Provider.of<CellContainerNotifier>(context, listen: false).onEnter = false,
|
||||
onEnter: (p) =>
|
||||
Provider.of<CellContainerNotifier>(context, listen: false)
|
||||
.onEnter = true,
|
||||
onExit: (p) =>
|
||||
Provider.of<CellContainerNotifier>(context, listen: false)
|
||||
.onEnter = false,
|
||||
child: Stack(
|
||||
alignment: AlignmentDirectional.center,
|
||||
fit: StackFit.expand,
|
||||
@ -102,7 +113,6 @@ class CellEnterRegion extends StatelessWidget {
|
||||
|
||||
class CellContainerNotifier extends ChangeNotifier {
|
||||
final CellEditable cellEditable;
|
||||
bool mouted = false;
|
||||
VoidCallback? _onCellFocusListener;
|
||||
bool _isFocus = false;
|
||||
bool _onEnter = false;
|
@ -1,5 +1,5 @@
|
||||
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_ui/style_widget/icon_button.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
@ -23,7 +23,8 @@ class _CheckboxCellState extends GridCellState<GridCheckboxCell> {
|
||||
@override
|
||||
void initState() {
|
||||
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();
|
||||
}
|
||||
|
||||
@ -33,11 +34,15 @@ class _CheckboxCellState extends GridCellState<GridCheckboxCell> {
|
||||
value: _cellBloc,
|
||||
child: BlocBuilder<CheckboxCellBloc, CheckboxCellState>(
|
||||
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(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: FlowyIconButton(
|
||||
onPressed: () => context.read<CheckboxCellBloc>().add(const CheckboxCellEvent.select()),
|
||||
onPressed: () => context
|
||||
.read<CheckboxCellBloc>()
|
||||
.add(const CheckboxCellEvent.select()),
|
||||
iconPadding: EdgeInsets.zero,
|
||||
icon: icon,
|
||||
width: 20,
|
@ -2,7 +2,7 @@ import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.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 'date_editor.dart';
|
||||
@ -44,13 +44,16 @@ class _DateCellState extends GridCellState<GridDateCell> {
|
||||
@override
|
||||
void initState() {
|
||||
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();
|
||||
}
|
||||
|
||||
@override
|
||||
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(
|
||||
value: _cellBloc,
|
||||
child: BlocBuilder<DateCellBloc, DateCellState>(
|
||||
@ -77,7 +80,8 @@ class _DateCellState extends GridCellState<GridDateCell> {
|
||||
void _showCalendar(BuildContext context) {
|
||||
final bloc = context.read<DateCellBloc>();
|
||||
widget.onCellEditing.value = true;
|
||||
final calendar = DateCellEditor(onDismissed: () => widget.onCellEditing.value = false);
|
||||
final calendar =
|
||||
DateCellEditor(onDismissed: () => widget.onCellEditing.value = false);
|
||||
calendar.show(
|
||||
context,
|
||||
cellController: bloc.cellContext.clone(),
|
@ -1,7 +1,5 @@
|
||||
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/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:app_flowy/plugins/grid/application/cell/date_cal_bloc.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/image.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_bloc/flutter_bloc.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 kFirstDay = DateTime(kToday.year, kToday.month - 3, kToday.day);
|
||||
@ -35,7 +36,8 @@ class DateCellEditor with FlowyOverlayDelegate {
|
||||
}) async {
|
||||
DateCellEditor.remove(context);
|
||||
|
||||
final result = await cellController.getFieldTypeOption(DateTypeOptionDataParser());
|
||||
final result =
|
||||
await cellController.getFieldTypeOption(DateTypeOptionDataParser());
|
||||
result.fold(
|
||||
(dateTypeOption) {
|
||||
final calendar = _CellCalendarWidget(
|
||||
@ -167,7 +169,9 @@ class _CellCalendarWidget extends StatelessWidget {
|
||||
},
|
||||
onDaySelected: (selectedDay, focusedDay) {
|
||||
_CalDateTimeSetting.hide(context);
|
||||
context.read<DateCalBloc>().add(DateCalEvent.selectDay(selectedDay));
|
||||
context
|
||||
.read<DateCalBloc>()
|
||||
.add(DateCalEvent.selectDay(selectedDay));
|
||||
},
|
||||
onFormatChanged: (format) {
|
||||
_CalDateTimeSetting.hide(context);
|
||||
@ -175,7 +179,9 @@ class _CellCalendarWidget extends StatelessWidget {
|
||||
},
|
||||
onPageChanged: (focusedDay) {
|
||||
_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: [
|
||||
svgWidget("grid/clock", color: theme.iconColor),
|
||||
const HSpace(4),
|
||||
FlowyText.medium(LocaleKeys.grid_field_includeTime.tr(), fontSize: 14),
|
||||
FlowyText.medium(LocaleKeys.grid_field_includeTime.tr(),
|
||||
fontSize: 14),
|
||||
const Spacer(),
|
||||
Switch(
|
||||
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
|
||||
Widget build(BuildContext context) {
|
||||
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>(
|
||||
selector: (state) => state.dateTypeOption,
|
||||
builder: (context, dateTypeOption) {
|
||||
@ -321,7 +332,9 @@ class _DateTypeOptionButton extends StatelessWidget {
|
||||
class _CalDateTimeSetting extends StatefulWidget {
|
||||
final DateTypeOption dateTypeOption;
|
||||
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
|
||||
State<_CalDateTimeSetting> createState() => _CalDateTimeSettingState();
|
||||
@ -358,7 +371,8 @@ class _CalDateTimeSettingState extends State<_CalDateTimeSetting> {
|
||||
DateFormatButton(onTap: () {
|
||||
final list = DateFormatList(
|
||||
selectedFormat: widget.dateTypeOption.dateFormat,
|
||||
onSelected: (format) => widget.onEvent(DateCalEvent.setDateFormat(format)),
|
||||
onSelected: (format) =>
|
||||
widget.onEvent(DateCalEvent.setDateFormat(format)),
|
||||
);
|
||||
_showOverlay(context, list);
|
||||
}),
|
||||
@ -367,7 +381,8 @@ class _CalDateTimeSettingState extends State<_CalDateTimeSetting> {
|
||||
onTap: () {
|
||||
final list = TimeFormatList(
|
||||
selectedFormat: widget.dateTypeOption.timeFormat,
|
||||
onSelected: (format) => widget.onEvent(DateCalEvent.setTimeFormat(format)),
|
||||
onSelected: (format) =>
|
||||
widget.onEvent(DateCalEvent.setTimeFormat(format)),
|
||||
);
|
||||
_showOverlay(context, list);
|
||||
},
|
@ -1,6 +1,6 @@
|
||||
import 'dart:async';
|
||||
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_bloc/flutter_bloc.dart';
|
||||
|
||||
@ -26,8 +26,10 @@ class _NumberCellState extends GridFocusNodeCellState<GridNumberCell> {
|
||||
@override
|
||||
void initState() {
|
||||
final cellContext = widget.cellContorllerBuilder.build();
|
||||
_cellBloc = getIt<NumberCellBloc>(param1: cellContext)..add(const NumberCellEvent.initial());
|
||||
_controller = TextEditingController(text: contentFromState(_cellBloc.state));
|
||||
_cellBloc = getIt<NumberCellBloc>(param1: cellContext)
|
||||
..add(const NumberCellEvent.initial());
|
||||
_controller =
|
||||
TextEditingController(text: contentFromState(_cellBloc.state));
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@ -39,7 +41,8 @@ class _NumberCellState extends GridFocusNodeCellState<GridNumberCell> {
|
||||
listeners: [
|
||||
BlocListener<NumberCellBloc, NumberCellState>(
|
||||
listenWhen: (p, c) => p.content != c.content,
|
||||
listener: (context, state) => _controller.text = contentFromState(state),
|
||||
listener: (context, state) =>
|
||||
_controller.text = contentFromState(state),
|
||||
),
|
||||
],
|
||||
child: TextField(
|
||||
@ -70,7 +73,8 @@ class _NumberCellState extends GridFocusNodeCellState<GridNumberCell> {
|
||||
if (mounted) {
|
||||
_delayOperation?.cancel();
|
||||
_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));
|
||||
}
|
||||
});
|
@ -4,3 +4,4 @@ export 'number_cell.dart';
|
||||
export 'date_cell/date_cell.dart';
|
||||
export 'checkbox_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/workspace/application/grid/prelude.dart';
|
||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/prelude.dart';
|
||||
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
// 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_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../cell_builder.dart';
|
||||
import 'extension.dart';
|
||||
import 'select_option_editor.dart';
|
||||
|
||||
@ -45,8 +46,10 @@ class _SingleSelectCellState extends State<GridSingleSelectCell> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
final cellContext = widget.cellContorllerBuilder.build() as GridSelectOptionCellController;
|
||||
_cellBloc = getIt<SelectOptionCellBloc>(param1: cellContext)..add(const SelectOptionCellEvent.initial());
|
||||
final cellContext =
|
||||
widget.cellContorllerBuilder.build() as GridSelectOptionCellController;
|
||||
_cellBloc = getIt<SelectOptionCellBloc>(param1: cellContext)
|
||||
..add(const SelectOptionCellEvent.initial());
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@ -99,8 +102,10 @@ class _MultiSelectCellState extends State<GridMultiSelectCell> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
final cellContext = widget.cellContorllerBuilder.build() as GridSelectOptionCellController;
|
||||
_cellBloc = getIt<SelectOptionCellBloc>(param1: cellContext)..add(const SelectOptionCellEvent.initial());
|
||||
final cellContext =
|
||||
widget.cellContorllerBuilder.build() as GridSelectOptionCellController;
|
||||
_cellBloc = getIt<SelectOptionCellBloc>(param1: cellContext)
|
||||
..add(const SelectOptionCellEvent.initial());
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@ -147,7 +152,8 @@ class _SelectOptionCell extends StatelessWidget {
|
||||
if (selectOptions.isEmpty && cellStyle != null) {
|
||||
child = Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: FlowyText.medium(cellStyle!.placeholder, fontSize: 14, color: theme.shader3),
|
||||
child: FlowyText.medium(cellStyle!.placeholder,
|
||||
fontSize: 14, color: theme.shader3),
|
||||
);
|
||||
} else {
|
||||
final tags = selectOptions
|
||||
@ -172,8 +178,10 @@ class _SelectOptionCell extends StatelessWidget {
|
||||
InkWell(
|
||||
onTap: () {
|
||||
onFocus(true);
|
||||
final cellContext = cellContorllerBuilder.build() as GridSelectOptionCellController;
|
||||
SelectOptionCellEditor.show(context, cellContext, () => onFocus(false));
|
||||
final cellContext =
|
||||
cellContorllerBuilder.build() as GridSelectOptionCellController;
|
||||
SelectOptionCellEditor.show(
|
||||
context, cellContext, () => onFocus(false));
|
||||
},
|
||||
),
|
||||
],
|
@ -1,9 +1,7 @@
|
||||
import 'dart:collection';
|
||||
import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/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:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/cell/select_option_editor_bloc.dart';
|
||||
|
||||
import 'package:flowy_infra/image.dart';
|
||||
import 'package:flowy_infra/theme.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: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 'text_field.dart';
|
||||
|
||||
@ -105,7 +106,8 @@ class _OptionList extends StatelessWidget {
|
||||
builder: (context, state) {
|
||||
List<Widget> cells = [];
|
||||
cells.addAll(state.options.map((option) {
|
||||
return _SelectOptionCell(option, state.selectedOptions.contains(option));
|
||||
return _SelectOptionCell(
|
||||
option, state.selectedOptions.contains(option));
|
||||
}).toList());
|
||||
|
||||
state.createOption.fold(
|
||||
@ -146,8 +148,10 @@ class _TextField extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<SelectOptionCellEditorBloc, SelectOptionEditorState>(
|
||||
builder: (context, state) {
|
||||
final optionMap = LinkedHashMap<String, SelectOptionPB>.fromIterable(state.selectedOptions,
|
||||
key: (option) => option.name, value: (option) => option);
|
||||
final optionMap = LinkedHashMap<String, SelectOptionPB>.fromIterable(
|
||||
state.selectedOptions,
|
||||
key: (option) => option.name,
|
||||
value: (option) => option);
|
||||
|
||||
return SizedBox(
|
||||
height: 42,
|
||||
@ -156,12 +160,17 @@ class _TextField extends StatelessWidget {
|
||||
selectedOptionMap: optionMap,
|
||||
distanceToText: _editorPannelWidth * 0.7,
|
||||
tagController: _tagController,
|
||||
onClick: () => FlowyOverlay.of(context).remove(SelectOptionTypeOptionEditor.identifier),
|
||||
onClick: () => FlowyOverlay.of(context)
|
||||
.remove(SelectOptionTypeOptionEditor.identifier),
|
||||
newText: (text) {
|
||||
context.read<SelectOptionCellEditorBloc>().add(SelectOptionEditorEvent.filterOption(text));
|
||||
context
|
||||
.read<SelectOptionCellEditorBloc>()
|
||||
.add(SelectOptionEditorEvent.filterOption(text));
|
||||
},
|
||||
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(
|
||||
name: name,
|
||||
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 {
|
||||
final SelectOptionPB option;
|
||||
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
|
||||
Widget build(BuildContext context) {
|
||||
@ -232,7 +244,9 @@ class _SelectOptionCell extends StatelessWidget {
|
||||
child: SelectOptionTagCell(
|
||||
option: option,
|
||||
onSelected: (option) {
|
||||
context.read<SelectOptionCellEditorBloc>().add(SelectOptionEditorEvent.selectOption(option.id));
|
||||
context
|
||||
.read<SelectOptionCellEditorBloc>()
|
||||
.add(SelectOptionEditorEvent.selectOption(option.id));
|
||||
},
|
||||
children: [
|
||||
if (isSelected)
|
||||
@ -258,12 +272,17 @@ class _SelectOptionCell extends StatelessWidget {
|
||||
final pannel = SelectOptionTypeOptionEditor(
|
||||
option: option,
|
||||
onDeleted: () {
|
||||
context.read<SelectOptionCellEditorBloc>().add(SelectOptionEditorEvent.deleteOption(option));
|
||||
context
|
||||
.read<SelectOptionCellEditorBloc>()
|
||||
.add(SelectOptionEditorEvent.deleteOption(option));
|
||||
},
|
||||
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();
|
||||
|
@ -2,7 +2,7 @@ import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.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';
|
||||
|
||||
class GridTextCellStyle extends GridCellStyle {
|
||||
@ -86,7 +86,8 @@ class _GridTextCellState extends GridFocusNodeCellState<GridTextCell> {
|
||||
if (mounted) {
|
||||
_delayOperation?.cancel();
|
||||
_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));
|
||||
}
|
||||
});
|
@ -1,5 +1,5 @@
|
||||
import 'package:app_flowy/workspace/application/grid/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/cell_service/cell_service.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:flutter/material.dart';
|
||||
import 'dart:async';
|
||||
@ -9,7 +9,9 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
class URLCellEditor extends StatefulWidget with FlowyOverlayDelegate {
|
||||
final GridURLCellController cellController;
|
||||
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
|
||||
State<URLCellEditor> createState() => _URLCellEditorState();
|
||||
@ -105,7 +107,8 @@ class _URLCellEditorState extends State<URLCellEditor> {
|
||||
|
||||
Future<void> focusChanged() async {
|
||||
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));
|
||||
}
|
||||
}
|
@ -1,16 +1,16 @@
|
||||
import 'dart:async';
|
||||
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/plugins/grid/src/widgets/cell/cell_accessory.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/image.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.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 '../cell_accessory.dart';
|
||||
import '../cell_builder.dart';
|
||||
import 'cell_editor.dart';
|
||||
|
||||
@ -48,34 +48,41 @@ class GridURLCell extends GridCellWidget {
|
||||
@override
|
||||
GridCellState<GridURLCell> createState() => _GridURLCellState();
|
||||
|
||||
GridCellAccessory accessoryFromType(GridURLCellAccessoryType ty, GridCellAccessoryBuildContext buildContext) {
|
||||
GridCellAccessory accessoryFromType(
|
||||
GridURLCellAccessoryType ty, GridCellAccessoryBuildContext buildContext) {
|
||||
switch (ty) {
|
||||
case GridURLCellAccessoryType.edit:
|
||||
final cellContext = cellContorllerBuilder.build() as GridURLCellController;
|
||||
return _EditURLAccessory(cellContext: cellContext, anchorContext: buildContext.anchorContext);
|
||||
final cellContext =
|
||||
cellContorllerBuilder.build() as GridURLCellController;
|
||||
return _EditURLAccessory(
|
||||
cellContext: cellContext,
|
||||
anchorContext: buildContext.anchorContext);
|
||||
|
||||
case GridURLCellAccessoryType.copyURL:
|
||||
final cellContext = cellContorllerBuilder.build() as GridURLCellController;
|
||||
final cellContext =
|
||||
cellContorllerBuilder.build() as GridURLCellController;
|
||||
return _CopyURLAccessory(cellContext: cellContext);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
List<GridCellAccessory> Function(GridCellAccessoryBuildContext buildContext) get accessoryBuilder => (buildContext) {
|
||||
final List<GridCellAccessory> accessories = [];
|
||||
if (cellStyle != null) {
|
||||
accessories.addAll(cellStyle!.accessoryTypes.map((ty) {
|
||||
return accessoryFromType(ty, buildContext);
|
||||
}));
|
||||
}
|
||||
List<GridCellAccessory> Function(GridCellAccessoryBuildContext buildContext)
|
||||
get accessoryBuilder => (buildContext) {
|
||||
final List<GridCellAccessory> accessories = [];
|
||||
if (cellStyle != null) {
|
||||
accessories.addAll(cellStyle!.accessoryTypes.map((ty) {
|
||||
return accessoryFromType(ty, buildContext);
|
||||
}));
|
||||
}
|
||||
|
||||
// If the accessories is empty then the default accessory will be GridURLCellAccessoryType.edit
|
||||
if (accessories.isEmpty) {
|
||||
accessories.add(accessoryFromType(GridURLCellAccessoryType.edit, buildContext));
|
||||
}
|
||||
// If the accessories is empty then the default accessory will be GridURLCellAccessoryType.edit
|
||||
if (accessories.isEmpty) {
|
||||
accessories.add(accessoryFromType(
|
||||
GridURLCellAccessoryType.edit, buildContext));
|
||||
}
|
||||
|
||||
return accessories;
|
||||
};
|
||||
return accessories;
|
||||
};
|
||||
}
|
||||
|
||||
class _GridURLCellState extends GridCellState<GridURLCell> {
|
||||
@ -83,7 +90,8 @@ class _GridURLCellState extends GridCellState<GridURLCell> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
final cellContext = widget.cellContorllerBuilder.build() as GridURLCellController;
|
||||
final cellContext =
|
||||
widget.cellContorllerBuilder.build() as GridURLCellController;
|
||||
_cellBloc = URLCellBloc(cellContext: cellContext);
|
||||
_cellBloc.add(const URLCellEvent.initial());
|
||||
super.initState();
|
||||
@ -132,7 +140,8 @@ class _GridURLCellState extends GridCellState<GridURLCell> {
|
||||
if (url.isNotEmpty && await canLaunchUrl(uri)) {
|
||||
await launchUrl(uri);
|
||||
} else {
|
||||
final cellContext = widget.cellContorllerBuilder.build() as GridURLCellController;
|
||||
final cellContext =
|
||||
widget.cellContorllerBuilder.build() as GridURLCellController;
|
||||
widget.onCellEditing.value = true;
|
||||
URLCellEditor.show(context, cellContext, () {
|
||||
widget.onCellEditing.value = false;
|
||||
@ -177,7 +186,8 @@ class _EditURLAccessory extends StatelessWidget with GridCellAccessory {
|
||||
|
||||
class _CopyURLAccessory extends StatelessWidget with GridCellAccessory {
|
||||
final GridURLCellController cellContext;
|
||||
const _CopyURLAccessory({required this.cellContext, Key? key}) : super(key: key);
|
||||
const _CopyURLAccessory({required this.cellContext, Key? key})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -187,7 +197,8 @@ class _CopyURLAccessory extends StatelessWidget with GridCellAccessory {
|
||||
|
||||
@override
|
||||
void onTap() {
|
||||
final content = cellContext.getCellData(loadIfNotExist: false)?.content ?? "";
|
||||
final content =
|
||||
cellContext.getCellData(loadIfNotExist: false)?.content ?? "";
|
||||
Clipboard.setData(ClipboardData(text: content));
|
||||
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/theme.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user