chore: code cleanup according to unintroduced lints (#4488)

* chore: remove redundant arguments

* chore: remove unused constructor params

* chore: reorganize constructors

* chore: remove unnecessary awaits in returns

* chore: remove unnecessary paranthesis

* chore: add lints

* chore: clean up after merge

* chore: add sort constructors first

* chore: organize constructors in blocs

* chore: use sizedbox.shrink over empty container
This commit is contained in:
Mathias Mogensen 2024-01-25 16:37:36 +01:00 committed by GitHub
parent 747abba87f
commit acc03b8cc4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
447 changed files with 3333 additions and 3412 deletions

View File

@ -36,11 +36,19 @@ linter:
- prefer_final_locals - prefer_final_locals
- sized_box_for_whitespace - sized_box_for_whitespace
- use_decorated_box
- unnecessary_parenthesis
- unnecessary_await_in_return
- unnecessary_raw_strings
- avoid_unnecessary_containers - avoid_unnecessary_containers
- avoid_redundant_argument_values
- avoid_unused_constructor_parameters
- always_declare_return_types - always_declare_return_types
- unnecessary_raw_strings
- use_decorated_box - sort_constructors_first
# Additional information about this file can be found at # Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options # https://dart.dev/guides/language/analysis-options

View File

@ -32,8 +32,8 @@ void main() {
const service = TestWorkspaceService(TestWorkspace.board); const service = TestWorkspaceService(TestWorkspace.board);
group('board', () { group('board', () {
setUpAll(() async => await service.setUpAll()); setUpAll(() async => service.setUpAll());
setUp(() async => await service.setUp()); setUp(() async => service.setUp());
testWidgets('open the board with data structure in v0.2.0', (tester) async { testWidgets('open the board with data structure in v0.2.0', (tester) async {
await tester.initializeAppFlowy(); await tester.initializeAppFlowy();

View File

@ -38,9 +38,7 @@ void main() {
await tester.expectToSeeHomePageWithGetStartedPage(); await tester.expectToSeeHomePageWithGetStartedPage();
// create a new document called Sample // create a new document called Sample
await tester.createNewPage( await tester.createNewPage();
layout: ViewLayoutPB.Document,
);
// focus on the editor // focus on the editor
await tester.editor.tapLineOfEditorAt(0); await tester.editor.tapLineOfEditorAt(0);

View File

@ -80,7 +80,7 @@ void main() {
// Hover over today's calendar cell // Hover over today's calendar cell
await tester.hoverOnTodayCalendarCell( await tester.hoverOnTodayCalendarCell(
// Tap on create new event button // Tap on create new event button
onHover: () async => await tester.tapAddCalendarEventButton(), onHover: () async => tester.tapAddCalendarEventButton(),
); );
// Make sure that the event editor popup is shown // Make sure that the event editor popup is shown
@ -158,7 +158,7 @@ void main() {
// Create a new event on the first of this month // Create a new event on the first of this month
final today = DateTime.now(); final today = DateTime.now();
final firstOfThisMonth = DateTime(today.year, today.month, 1); final firstOfThisMonth = DateTime(today.year, today.month);
await tester.doubleClickCalendarCell(firstOfThisMonth); await tester.doubleClickCalendarCell(firstOfThisMonth);
await tester.dismissEventEditor(); await tester.dismissEventEditor();

View File

@ -60,7 +60,6 @@ void main() {
rowIndex: 0, rowIndex: 0,
fieldType: FieldType.RichText, fieldType: FieldType.RichText,
content: 'hello', content: 'hello',
cellIndex: 0,
); );
await tester.assertCellContent( await tester.assertCellContent(

View File

@ -35,7 +35,7 @@ void main() {
// delete the readme page // delete the readme page
await tester.hoverOnPageName( await tester.hoverOnPageName(
gettingStarted, gettingStarted,
onHover: () async => await tester.tapDeletePageButton(), onHover: () async => tester.tapDeletePageButton(),
); );
// the banner should show up and the readme page should be gone // the banner should show up and the readme page should be gone
@ -59,7 +59,7 @@ void main() {
// delete the readme page // delete the readme page
await tester.hoverOnPageName( await tester.hoverOnPageName(
gettingStarted, gettingStarted,
onHover: () async => await tester.tapDeletePageButton(), onHover: () async => tester.tapDeletePageButton(),
); );
// the banner should show up and the readme page should be gone // the banner should show up and the readme page should be gone

View File

@ -3,7 +3,6 @@ import 'package:flutter/services.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/mention/mention_page_block.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/mention/mention_page_block.dart';
import 'package:appflowy/plugins/inline_actions/widgets/inline_actions_handler.dart'; import 'package:appflowy/plugins/inline_actions/widgets/inline_actions_handler.dart';
import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart'; import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
import 'package:flowy_infra/uuid.dart'; import 'package:flowy_infra/uuid.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart'; import 'package:integration_test/integration_test.dart';
@ -89,7 +88,6 @@ Future<String> createDocumentToReference(WidgetTester tester) async {
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent(
name: name, name: name,
layout: ViewLayoutPB.Document,
openAfterCreated: false, openAfterCreated: false,
); );

View File

@ -144,8 +144,6 @@ Future<void> insertReferenceDatabase(
// create a new document // create a new document
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent(
name: 'insert_a_reference_${layout.name}', name: 'insert_a_reference_${layout.name}',
layout: ViewLayoutPB.Document,
openAfterCreated: true,
); );
// tap the first line of the document // tap the first line of the document
await tester.editor.tapLineOfEditorAt(0); await tester.editor.tapLineOfEditorAt(0);
@ -173,8 +171,6 @@ Future<void> createInlineDatabase(
final documentName = 'insert_a_inline_${layout.name}'; final documentName = 'insert_a_inline_${layout.name}';
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent(
name: documentName, name: documentName,
layout: ViewLayoutPB.Document,
openAfterCreated: true,
); );
// tap the first line of the document // tap the first line of the document
await tester.editor.tapLineOfEditorAt(0); await tester.editor.tapLineOfEditorAt(0);

View File

@ -10,7 +10,6 @@ import 'package:appflowy/plugins/document/presentation/editor_plugins/image/resi
import 'package:appflowy/plugins/document/presentation/editor_plugins/image/unsplash_image_widget.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/image/unsplash_image_widget.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/image/upload_image_menu.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/image/upload_image_menu.dart';
import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/startup/startup.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
import 'package:appflowy_editor/appflowy_editor.dart' import 'package:appflowy_editor/appflowy_editor.dart'
hide UploadImageMenu, ResizableImage; hide UploadImageMenu, ResizableImage;
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
@ -38,7 +37,6 @@ void main() {
// create a new document // create a new document
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent(
name: LocaleKeys.document_plugins_image_addAnImage.tr(), name: LocaleKeys.document_plugins_image_addAnImage.tr(),
layout: ViewLayoutPB.Document,
); );
// tap the first line of the document // tap the first line of the document
@ -87,7 +85,6 @@ void main() {
// create a new document // create a new document
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent(
name: LocaleKeys.document_plugins_image_addAnImage.tr(), name: LocaleKeys.document_plugins_image_addAnImage.tr(),
layout: ViewLayoutPB.Document,
); );
// tap the first line of the document // tap the first line of the document
@ -141,7 +138,6 @@ void main() {
// create a new document // create a new document
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent(
name: LocaleKeys.document_plugins_image_addAnImage.tr(), name: LocaleKeys.document_plugins_image_addAnImage.tr(),
layout: ViewLayoutPB.Document,
); );
// tap the first line of the document // tap the first line of the document

View File

@ -1,6 +1,5 @@
import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/button.dart';
@ -22,7 +21,6 @@ void main() {
// create a new document // create a new document
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent(
name: 'math equation', name: 'math equation',
layout: ViewLayoutPB.Document,
); );
// tap the first line of the document // tap the first line of the document
@ -68,7 +66,6 @@ void main() {
// create a new document // create a new document
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent(
name: 'math equation', name: 'math equation',
layout: ViewLayoutPB.Document,
); );
// tap the first line of the document // tap the first line of the document

View File

@ -65,7 +65,7 @@ void main() {
const newName = 'RenameToNewPageName'; const newName = 'RenameToNewPageName';
await tester.hoverOnPageName( await tester.hoverOnPageName(
pageName, pageName,
onHover: () async => await tester.renamePage(newName), onHover: () async => tester.renamePage(newName),
); );
final finder = find.descendant( final finder = find.descendant(
of: find.byType(MentionPageBlock), of: find.byType(MentionPageBlock),
@ -84,7 +84,7 @@ void main() {
await tester.hoverOnPageName( await tester.hoverOnPageName(
pageName, pageName,
layout: ViewLayoutPB.Grid, layout: ViewLayoutPB.Grid,
onHover: () async => await tester.tapDeletePageButton(), onHover: () async => tester.tapDeletePageButton(),
); );
final finder = find.descendant( final finder = find.descendant(
of: find.byType(MentionPageBlock), of: find.byType(MentionPageBlock),
@ -114,7 +114,6 @@ Future<String> insertInlinePage(
// create a new document // create a new document
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent(
name: 'insert_a_inline_page_${layout.name}', name: 'insert_a_inline_page_${layout.name}',
layout: ViewLayoutPB.Document,
); );
// tap the first line of the document // tap the first line of the document

View File

@ -1,4 +1,3 @@
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -24,9 +23,7 @@ void main() {
await tester.tapGoButton(); await tester.tapGoButton();
// create a new document // create a new document
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent();
layout: ViewLayoutPB.Document,
);
// tap the first line of the document // tap the first line of the document
await tester.editor.tapLineOfEditorAt(0); await tester.editor.tapLineOfEditorAt(0);

View File

@ -1,6 +1,5 @@
import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/outline/outline_block_component.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/outline/outline_block_component.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart'; import 'package:integration_test/integration_test.dart';
@ -17,7 +16,6 @@ void main() {
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent(
name: 'outline_test', name: 'outline_test',
layout: ViewLayoutPB.Document,
); );
await tester.editor.tapLineOfEditorAt(0); await tester.editor.tapLineOfEditorAt(0);
@ -34,7 +32,6 @@ void main() {
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent(
name: 'outline_test', name: 'outline_test',
layout: ViewLayoutPB.Document,
); );
await tester.editor.tapLineOfEditorAt(0); await tester.editor.tapLineOfEditorAt(0);

View File

@ -1,7 +1,6 @@
import 'dart:io'; import 'dart:io';
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -40,9 +39,7 @@ void main() {
await tester.tapGoButton(); await tester.tapGoButton();
// create a new document // create a new document
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent();
layout: ViewLayoutPB.Document,
);
// tap the first line of the document // tap the first line of the document
await tester.editor.tapLineOfEditorAt(0); await tester.editor.tapLineOfEditorAt(0);
@ -86,9 +83,7 @@ void main() {
await tester.tapGoButton(); await tester.tapGoButton();
// create a new document // create a new document
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent();
layout: ViewLayoutPB.Document,
);
// tap the first line of the document // tap the first line of the document
await tester.editor.tapLineOfEditorAt(0); await tester.editor.tapLineOfEditorAt(0);
@ -125,9 +120,7 @@ void main() {
await tester.tapGoButton(); await tester.tapGoButton();
// create a new document // create a new document
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent();
layout: ViewLayoutPB.Document,
);
// tap the first line of the document // tap the first line of the document
await tester.editor.tapLineOfEditorAt(0); await tester.editor.tapLineOfEditorAt(0);
@ -162,9 +155,7 @@ void main() {
await tester.tapGoButton(); await tester.tapGoButton();
// create a new document // create a new document
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent();
layout: ViewLayoutPB.Document,
);
// tap the first line of the document // tap the first line of the document
await tester.editor.tapLineOfEditorAt(0); await tester.editor.tapLineOfEditorAt(0);
@ -176,11 +167,8 @@ void main() {
final toggleListIcon = find.byIcon(Icons.arrow_right); final toggleListIcon = find.byIcon(Icons.arrow_right);
await tester.tapButton(toggleListIcon); await tester.tapButton(toggleListIcon);
await tester.editor.updateSelection( await tester.editor
Selection.collapsed( .updateSelection(Selection.collapsed(Position(path: [0])));
Position(path: [0], offset: 0),
),
);
await tester.ime.insertCharacter('\n'); await tester.ime.insertCharacter('\n');
final editorState = tester.editor.getCurrentEditorState(); final editorState = tester.editor.getCurrentEditorState();
@ -196,9 +184,7 @@ void main() {
await tester.tapGoButton(); await tester.tapGoButton();
// create a new document // create a new document
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent();
layout: ViewLayoutPB.Document,
);
// tap the first line of the document // tap the first line of the document
await tester.editor.tapLineOfEditorAt(0); await tester.editor.tapLineOfEditorAt(0);
@ -209,7 +195,7 @@ void main() {
await tester.editor.updateSelection( await tester.editor.updateSelection(
Selection.collapsed( Selection.collapsed(
Position(path: [0], offset: 0), Position(path: [0]),
), ),
); );
await tester.simulateKeyEvent( await tester.simulateKeyEvent(

View File

@ -1,6 +1,5 @@
import 'dart:io'; import 'dart:io';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
@ -18,10 +17,7 @@ void main() {
// create a new document called Sample // create a new document called Sample
const pageName = 'Sample'; const pageName = 'Sample';
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent(name: pageName);
name: pageName,
layout: ViewLayoutPB.Document,
);
// focus on the editor // focus on the editor
await tester.editor.tapLineOfEditorAt(0); await tester.editor.tapLineOfEditorAt(0);
@ -75,10 +71,7 @@ void main() {
// create a new document called Sample // create a new document called Sample
const pageName = 'Sample'; const pageName = 'Sample';
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent(name: pageName);
name: pageName,
layout: ViewLayoutPB.Document,
);
// focus on the editor // focus on the editor
await tester.editor.tapLineOfEditorAt(0); await tester.editor.tapLineOfEditorAt(0);

View File

@ -28,8 +28,8 @@ void main() {
const service = TestWorkspaceService(TestWorkspace.emptyDocument); const service = TestWorkspaceService(TestWorkspace.emptyDocument);
group('Tests on a workspace with only an empty document', () { group('Tests on a workspace with only an empty document', () {
setUpAll(() async => await service.setUpAll()); setUpAll(() async => service.setUpAll());
setUp(() async => await service.setUp()); setUp(() async => service.setUp());
testWidgets('/board shortcut creates a new board and view of the board', testWidgets('/board shortcut creates a new board and view of the board',
(tester) async { (tester) async {

View File

@ -15,8 +15,8 @@ void main() {
const service = TestWorkspaceService(TestWorkspace.aiWorkSpace); const service = TestWorkspaceService(TestWorkspace.aiWorkSpace);
group('integration tests for open-ai smart menu', () { group('integration tests for open-ai smart menu', () {
setUpAll(() async => await service.setUpAll()); setUpAll(() async => service.setUpAll());
setUp(() async => await service.setUp()); setUp(() async => service.setUp());
testWidgets('testing selection on open-ai smart menu replace', testWidgets('testing selection on open-ai smart menu replace',
(tester) async { (tester) async {
@ -59,7 +59,7 @@ void main() {
editorState.service.selectionService.updateSelection( editorState.service.selectionService.updateSelection(
Selection( Selection(
start: Position(path: [1], offset: 0), start: Position(path: [1]),
end: Position(path: [1], offset: 5), end: Position(path: [1], offset: 5),
), ),
); );
@ -80,8 +80,8 @@ void main() {
expect( expect(
editorState.service.selectionService.currentSelection.value, editorState.service.selectionService.currentSelection.value,
Selection( Selection(
start: Position(path: [2], offset: 0), start: Position(path: [2]),
end: Position(path: [3], offset: 0), end: Position(path: [3]),
), ),
); );
}); });
@ -99,7 +99,7 @@ Future<AppFlowyEditor> setUpOpenAITesting(WidgetTester tester) async {
final Finder editor = find.byType(AppFlowyEditor); final Finder editor = find.byType(AppFlowyEditor);
await tester.tap(editor); await tester.tap(editor);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
return (tester.state(editor).widget as AppFlowyEditor); return tester.state(editor).widget as AppFlowyEditor;
} }
Future<void> mockOpenAIRepository() async { Future<void> mockOpenAIRepository() async {

View File

@ -1,7 +1,6 @@
import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/folder/favorite_folder.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/folder/favorite_folder.dart';
import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart'; import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
@ -34,14 +33,8 @@ void main() {
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent(
name: names[i], name: names[i],
parentName: parentName, parentName: parentName,
layout: ViewLayoutPB.Document,
);
tester.expectToSeePageName(
names[i],
parentName: parentName,
layout: ViewLayoutPB.Document,
parentLayout: ViewLayoutPB.Document,
); );
tester.expectToSeePageName(names[i], parentName: parentName);
} }
await tester.favoriteViewByName(gettingStarted); await tester.favoriteViewByName(gettingStarted);
@ -87,7 +80,6 @@ void main() {
await tester.favoriteViewByName(gettingStarted); await tester.favoriteViewByName(gettingStarted);
await tester.hoverOnPageName( await tester.hoverOnPageName(
gettingStarted, gettingStarted,
layout: ViewLayoutPB.Document,
onHover: () async { onHover: () async {
await tester.renamePage(name); await tester.renamePage(name);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
@ -116,7 +108,6 @@ void main() {
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent(
name: names[i], name: names[i],
parentName: parentName, parentName: parentName,
layout: ViewLayoutPB.Document,
); );
tester.expectToSeePageName(names[i], parentName: parentName); tester.expectToSeePageName(names[i], parentName: parentName);
} }
@ -136,7 +127,6 @@ void main() {
await tester.hoverOnPageName( await tester.hoverOnPageName(
names[1], names[1],
layout: ViewLayoutPB.Document,
onHover: () async { onHover: () async {
await tester.tapDeletePageButton(); await tester.tapDeletePageButton();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
@ -150,7 +140,6 @@ void main() {
await tester.hoverOnPageName( await tester.hoverOnPageName(
gettingStarted, gettingStarted,
layout: ViewLayoutPB.Document,
onHover: () async { onHover: () async {
await tester.tapDeletePageButton(); await tester.tapDeletePageButton();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
@ -194,7 +183,6 @@ void main() {
await tester.favoriteViewByName(gettingStarted); await tester.favoriteViewByName(gettingStarted);
await tester.hoverOnPageName( await tester.hoverOnPageName(
gettingStarted, gettingStarted,
layout: ViewLayoutPB.Document,
useLast: false, useLast: false,
onHover: () async { onHover: () async {
await tester.tapPageOptionButton(); await tester.tapPageOptionButton();

View File

@ -82,7 +82,6 @@ void main() {
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent(
name: names[i], name: names[i],
parentName: parentName, parentName: parentName,
layout: ViewLayoutPB.Document,
); );
tester.expectToSeePageName(names[i], parentName: parentName); tester.expectToSeePageName(names[i], parentName: parentName);
} }
@ -148,7 +147,7 @@ void main() {
name: document, name: document,
openAfterCreated: false, openAfterCreated: false,
); );
tester.expectToSeePageName(document, layout: ViewLayoutPB.Document); tester.expectToSeePageName(document);
const grid = 'grid'; const grid = 'grid';
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent(
@ -190,7 +189,6 @@ void main() {
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent(
name: grid, name: grid,
layout: ViewLayoutPB.Grid, layout: ViewLayoutPB.Grid,
openAfterCreated: true,
); );
tester.expectToSeePageName(grid, layout: ViewLayoutPB.Grid); tester.expectToSeePageName(grid, layout: ViewLayoutPB.Grid);

View File

@ -32,15 +32,9 @@ void main() {
findsNothing, findsNothing,
); );
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent(name: _documentName);
name: _documentName,
layout: ViewLayoutPB.Document,
);
await tester.createNewPageWithNameUnderParent( await tester.createNewPageWithNameUnderParent(name: _documentTwoName);
name: _documentTwoName,
layout: ViewLayoutPB.Document,
);
/// Open second menu item in a new tab /// Open second menu item in a new tab
await tester.openAppInNewTab(gettingStarted, ViewLayoutPB.Document); await tester.openAppInNewTab(gettingStarted, ViewLayoutPB.Document);

View File

@ -129,7 +129,7 @@ extension AppFlowyTestBase on WidgetTester {
} }
Future<void> waitForSeconds(int seconds) async { Future<void> waitForSeconds(int seconds) async {
await Future.delayed((Duration(seconds: seconds)), () {}); await Future.delayed(Duration(seconds: seconds), () {});
} }
Future<void> pumpUntilFound( Future<void> pumpUntilFound(

View File

@ -397,7 +397,6 @@ extension CommonOperations on WidgetTester {
await hoverOnPageName( await hoverOnPageName(
name, name,
layout: layout, layout: layout,
useLast: true,
onHover: () async { onHover: () async {
await tapFavoritePageButton(); await tapFavoritePageButton();
await pumpAndSettle(); await pumpAndSettle();
@ -412,7 +411,6 @@ extension CommonOperations on WidgetTester {
await hoverOnPageName( await hoverOnPageName(
name, name,
layout: layout, layout: layout,
useLast: true,
onHover: () async { onHover: () async {
await tapUnfavoritePageButton(); await tapUnfavoritePageButton();
await pumpAndSettle(); await pumpAndSettle();

View File

@ -205,7 +205,7 @@ extension AppFlowyDatabaseTest on WidgetTester {
}) async { }) async {
final cell = cellFinder(rowIndex, fieldType); final cell = cellFinder(rowIndex, fieldType);
expect(cell, findsOneWidget); expect(cell, findsOneWidget);
await tapButton(cell, warnIfMissed: false); await tapButton(cell);
} }
/// The [fieldName] must be unique in the grid. /// The [fieldName] must be unique in the grid.
@ -1110,7 +1110,7 @@ extension AppFlowyDatabaseTest on WidgetTester {
skipOffstage: false, skipOffstage: false,
); );
expect(findCell, findsOneWidget); expect(findCell, findsOneWidget);
await tapButton(findCell, warnIfMissed: false); await tapButton(findCell);
} }
Future<void> tapCheckedButtonOnCheckboxFilter() async { Future<void> tapCheckedButtonOnCheckboxFilter() async {

View File

@ -34,7 +34,6 @@ class IMESimulator {
selection: TextSelection.collapsed( selection: TextSelection.collapsed(
offset: value.selection.baseOffset + 1, offset: value.selection.baseOffset + 1,
), ),
composing: TextRange.empty,
); );
client.updateEditingValue(textEditingValue); client.updateEditingValue(textEditingValue);
await tester.pumpAndSettle(); await tester.pumpAndSettle();

View File

@ -41,7 +41,7 @@ class MoveWindowDetectorState extends State<MoveWindowDetector> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (!Platform.isMacOS) { if (!Platform.isMacOS) {
return widget.child ?? Container(); return widget.child ?? const SizedBox.shrink();
} }
return GestureDetector( return GestureDetector(
// https://stackoverflow.com/questions/52965799/flutter-gesturedetector-not-working-with-containers-in-stack // https://stackoverflow.com/questions/52965799/flutter-gesturedetector-not-working-with-containers-in-stack

View File

@ -7,21 +7,21 @@ import 'package:appflowy_backend/dispatch/dispatch.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
class NetworkListener { class NetworkListener {
final Connectivity _connectivity = Connectivity();
late StreamSubscription<ConnectivityResult> _connectivitySubscription;
NetworkListener() { NetworkListener() {
_connectivitySubscription = _connectivitySubscription =
_connectivity.onConnectivityChanged.listen(_updateConnectionStatus); _connectivity.onConnectivityChanged.listen(_updateConnectionStatus);
} }
final Connectivity _connectivity = Connectivity();
late StreamSubscription<ConnectivityResult> _connectivitySubscription;
Future<void> start() async { Future<void> start() async {
late ConnectivityResult result; late ConnectivityResult result;
// Platform messages may fail, so we use a try/catch PlatformException. // Platform messages may fail, so we use a try/catch PlatformException.
try { try {
result = await _connectivity.checkConnectivity(); result = await _connectivity.checkConnectivity();
} on PlatformException catch (e) { } on PlatformException catch (e) {
Log.error('Couldn\'t check connectivity status. $e'); Log.error("Couldn't check connectivity status. $e");
return; return;
} }
return _updateConnectionStatus(result); return _updateConnectionStatus(result);

View File

@ -31,9 +31,6 @@ typedef FolderNotificationHandler = Function(
); );
class FolderNotificationListener { class FolderNotificationListener {
StreamSubscription<SubscribeObject>? _subscription;
FolderNotificationParser? _parser;
FolderNotificationListener({ FolderNotificationListener({
required String objectId, required String objectId,
required FolderNotificationHandler handler, required FolderNotificationHandler handler,
@ -45,6 +42,9 @@ class FolderNotificationListener {
RustStreamReceiver.listen((observable) => _parser?.parse(observable)); RustStreamReceiver.listen((observable) => _parser?.parse(observable));
} }
FolderNotificationParser? _parser;
StreamSubscription<SubscribeObject>? _subscription;
Future<void> stop() async { Future<void> stop() async {
_parser = null; _parser = null;
await _subscription?.cancel(); await _subscription?.cancel();

View File

@ -31,9 +31,6 @@ typedef DatabaseNotificationHandler = Function(
); );
class DatabaseNotificationListener { class DatabaseNotificationListener {
StreamSubscription<SubscribeObject>? _subscription;
DatabaseNotificationParser? _parser;
DatabaseNotificationListener({ DatabaseNotificationListener({
required String objectId, required String objectId,
required DatabaseNotificationHandler handler, required DatabaseNotificationHandler handler,
@ -42,6 +39,9 @@ class DatabaseNotificationListener {
RustStreamReceiver.listen((observable) => _parser?.parse(observable)); RustStreamReceiver.listen((observable) => _parser?.parse(observable));
} }
DatabaseNotificationParser? _parser;
StreamSubscription<SubscribeObject>? _subscription;
Future<void> stop() async { Future<void> stop() async {
_parser = null; _parser = null;
await _subscription?.cancel(); await _subscription?.cancel();

View File

@ -3,18 +3,18 @@ import 'package:appflowy_backend/protobuf/flowy-notification/protobuf.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
class NotificationParser<T, E> { class NotificationParser<T, E> {
String? id;
void Function(T, Either<Uint8List, E>) callback;
T? Function(int) tyParser;
E Function(Uint8List) errorParser;
NotificationParser({ NotificationParser({
this.id, this.id,
required this.callback, required this.callback,
required this.errorParser, required this.errorParser,
required this.tyParser, required this.tyParser,
}); });
String? id;
void Function(T, Either<Uint8List, E>) callback;
E Function(Uint8List) errorParser;
T? Function(int) tyParser;
void parse(SubscribeObject subject) { void parse(SubscribeObject subject) {
if (id != null) { if (id != null) {
if (subject.id != id) { if (subject.id != id) {

View File

@ -31,9 +31,6 @@ typedef UserNotificationHandler = Function(
); );
class UserNotificationListener { class UserNotificationListener {
StreamSubscription<SubscribeObject>? _subscription;
UserNotificationParser? _parser;
UserNotificationListener({ UserNotificationListener({
required String objectId, required String objectId,
required UserNotificationHandler handler, required UserNotificationHandler handler,
@ -42,6 +39,9 @@ class UserNotificationListener {
RustStreamReceiver.listen((observable) => _parser?.parse(observable)); RustStreamReceiver.listen((observable) => _parser?.parse(observable));
} }
UserNotificationParser? _parser;
StreamSubscription<SubscribeObject>? _subscription;
Future<void> stop() async { Future<void> stop() async {
_parser = null; _parser = null;
await _subscription?.cancel(); await _subscription?.cancel();

View File

@ -5,15 +5,6 @@ part 'backend_env.g.dart';
@JsonSerializable() @JsonSerializable()
class AppFlowyConfiguration { class AppFlowyConfiguration {
final String root;
final String custom_app_path;
final String origin_app_path;
final String device_id;
final int authenticator_type;
final SupabaseConfiguration supabase_config;
final AppFlowyCloudConfiguration appflowy_cloud_config;
final Map<String, String> envs;
AppFlowyConfiguration({ AppFlowyConfiguration({
required this.root, required this.root,
required this.custom_app_path, required this.custom_app_path,
@ -28,15 +19,20 @@ class AppFlowyConfiguration {
factory AppFlowyConfiguration.fromJson(Map<String, dynamic> json) => factory AppFlowyConfiguration.fromJson(Map<String, dynamic> json) =>
_$AppFlowyConfigurationFromJson(json); _$AppFlowyConfigurationFromJson(json);
final String root;
final String custom_app_path;
final String origin_app_path;
final String device_id;
final int authenticator_type;
final SupabaseConfiguration supabase_config;
final AppFlowyCloudConfiguration appflowy_cloud_config;
final Map<String, String> envs;
Map<String, dynamic> toJson() => _$AppFlowyConfigurationToJson(this); Map<String, dynamic> toJson() => _$AppFlowyConfigurationToJson(this);
} }
@JsonSerializable() @JsonSerializable()
class SupabaseConfiguration { class SupabaseConfiguration {
/// Indicates whether the sync feature is enabled.
final String url;
final String anon_key;
SupabaseConfiguration({ SupabaseConfiguration({
required this.url, required this.url,
required this.anon_key, required this.anon_key,
@ -45,6 +41,10 @@ class SupabaseConfiguration {
factory SupabaseConfiguration.fromJson(Map<String, dynamic> json) => factory SupabaseConfiguration.fromJson(Map<String, dynamic> json) =>
_$SupabaseConfigurationFromJson(json); _$SupabaseConfigurationFromJson(json);
/// Indicates whether the sync feature is enabled.
final String url;
final String anon_key;
Map<String, dynamic> toJson() => _$SupabaseConfigurationToJson(this); Map<String, dynamic> toJson() => _$SupabaseConfigurationToJson(this);
static SupabaseConfiguration defaultConfig() { static SupabaseConfiguration defaultConfig() {
@ -61,10 +61,6 @@ class SupabaseConfiguration {
@JsonSerializable() @JsonSerializable()
class AppFlowyCloudConfiguration { class AppFlowyCloudConfiguration {
final String base_url;
final String ws_base_url;
final String gotrue_url;
AppFlowyCloudConfiguration({ AppFlowyCloudConfiguration({
required this.base_url, required this.base_url,
required this.ws_base_url, required this.ws_base_url,
@ -74,6 +70,10 @@ class AppFlowyCloudConfiguration {
factory AppFlowyCloudConfiguration.fromJson(Map<String, dynamic> json) => factory AppFlowyCloudConfiguration.fromJson(Map<String, dynamic> json) =>
_$AppFlowyCloudConfigurationFromJson(json); _$AppFlowyCloudConfigurationFromJson(json);
final String base_url;
final String ws_base_url;
final String gotrue_url;
Map<String, dynamic> toJson() => _$AppFlowyCloudConfigurationToJson(this); Map<String, dynamic> toJson() => _$AppFlowyCloudConfigurationToJson(this);
static AppFlowyCloudConfiguration defaultConfig() { static AppFlowyCloudConfiguration defaultConfig() {

View File

@ -180,16 +180,16 @@ Future<void> setAppFlowyCloudUrl(Option<String> url) async {
/// Use getIt<AppFlowyCloudSharedEnv>() to get the shared environment. /// Use getIt<AppFlowyCloudSharedEnv>() to get the shared environment.
class AppFlowyCloudSharedEnv { class AppFlowyCloudSharedEnv {
final AuthenticatorType _authenticatorType;
final AppFlowyCloudConfiguration appflowyCloudConfig;
final SupabaseConfiguration supabaseConfig;
AppFlowyCloudSharedEnv({ AppFlowyCloudSharedEnv({
required AuthenticatorType authenticatorType, required AuthenticatorType authenticatorType,
required this.appflowyCloudConfig, required this.appflowyCloudConfig,
required this.supabaseConfig, required this.supabaseConfig,
}) : _authenticatorType = authenticatorType; }) : _authenticatorType = authenticatorType;
final AuthenticatorType _authenticatorType;
final AppFlowyCloudConfiguration appflowyCloudConfig;
final SupabaseConfiguration supabaseConfig;
AuthenticatorType get authenticatorType => _authenticatorType; AuthenticatorType get authenticatorType => _authenticatorType;
static Future<AppFlowyCloudSharedEnv> fromEnv() async { static Future<AppFlowyCloudSharedEnv> fromEnv() async {

View File

@ -102,7 +102,6 @@ class AppBarButton extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return InkWell( return InkWell(
enableFeedback: true,
borderRadius: BorderRadius.circular(28), borderRadius: BorderRadius.circular(28),
splashColor: Colors.transparent, splashColor: Colors.transparent,
focusColor: Colors.transparent, focusColor: Colors.transparent,

View File

@ -34,7 +34,6 @@ class BottomSheetHeader extends StatelessWidget {
), ),
if (title != null) if (title != null)
Align( Align(
alignment: Alignment.center,
child: FlowyText.medium( child: FlowyText.medium(
title!, title!,
fontSize: 16, fontSize: 16,

View File

@ -31,7 +31,6 @@ class MobileViewItemBottomSheetBody extends StatelessWidget {
children: [ children: [
// rename, duplicate // rename, duplicate
Row( Row(
mainAxisSize: MainAxisSize.max,
children: [ children: [
Expanded( Expanded(
child: BottomSheetActionWidget( child: BottomSheetActionWidget(
@ -58,7 +57,6 @@ class MobileViewItemBottomSheetBody extends StatelessWidget {
// share, delete // share, delete
Row( Row(
mainAxisSize: MainAxisSize.max,
children: [ children: [
Expanded( Expanded(
child: BottomSheetActionWidget( child: BottomSheetActionWidget(

View File

@ -119,7 +119,6 @@ class MobileViewBottomSheetBody extends StatelessWidget {
children: [ children: [
// rename, duplicate // rename, duplicate
Row( Row(
mainAxisSize: MainAxisSize.max,
children: [ children: [
Expanded( Expanded(
child: BottomSheetActionWidget( child: BottomSheetActionWidget(
@ -146,7 +145,6 @@ class MobileViewBottomSheetBody extends StatelessWidget {
// share, delete // share, delete
Row( Row(
mainAxisSize: MainAxisSize.max,
children: [ children: [
Expanded( Expanded(
child: BottomSheetActionWidget( child: BottomSheetActionWidget(

View File

@ -3,10 +3,6 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class MobileBoardScreen extends StatelessWidget { class MobileBoardScreen extends StatelessWidget {
static const routeName = '/board';
static const viewId = 'id';
static const viewTitle = 'title';
const MobileBoardScreen({ const MobileBoardScreen({
super.key, super.key,
required this.id, required this.id,
@ -17,6 +13,10 @@ class MobileBoardScreen extends StatelessWidget {
final String id; final String id;
final String? title; final String? title;
static const routeName = '/board';
static const viewId = 'id';
static const viewTitle = 'title';
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MobileViewPage( return MobileViewPage(

View File

@ -82,7 +82,6 @@ class _GroupCardHeaderState extends State<GroupCardHeader> {
_controller.text, _controller.text,
), ),
), ),
maxLines: 1,
style: titleTextStyle, style: titleTextStyle,
onTapOutside: (_) => context.read<BoardBloc>().add( onTapOutside: (_) => context.read<BoardBloc>().add(
// group header switch from TextField to Text // group header switch from TextField to Text

View File

@ -233,7 +233,6 @@ class RowDetailFab extends StatelessWidget {
BoxShadow( BoxShadow(
offset: Offset(0, 8), offset: Offset(0, 8),
blurRadius: 20, blurRadius: 20,
spreadRadius: 0,
color: Color(0x191F2329), color: Color(0x191F2329),
), ),
], ],

View File

@ -25,7 +25,6 @@ class MobileRowDetailCreateFieldButton extends StatelessWidget {
shape: MaterialStateProperty.all<RoundedRectangleBorder>( shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder( RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0), borderRadius: BorderRadius.circular(12.0),
side: BorderSide.none,
), ),
), ),
overlayColor: MaterialStateProperty.all<Color>( overlayColor: MaterialStateProperty.all<Color>(

View File

@ -14,14 +14,6 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
class MobileDateCellEditScreen extends StatefulWidget { class MobileDateCellEditScreen extends StatefulWidget {
static const routeName = '/edit_date_cell';
// the type is DateCellController
static const dateCellController = 'date_cell_controller';
// bool value, default is true
static const fullScreen = 'full_screen';
const MobileDateCellEditScreen({ const MobileDateCellEditScreen({
super.key, super.key,
required this.controller, required this.controller,
@ -31,6 +23,14 @@ class MobileDateCellEditScreen extends StatefulWidget {
final DateCellController controller; final DateCellController controller;
final bool showAsFullScreen; final bool showAsFullScreen;
static const routeName = '/edit_date_cell';
// the type is DateCellController
static const dateCellController = 'date_cell_controller';
// bool value, default is true
static const fullScreen = 'full_screen';
@override @override
State<MobileDateCellEditScreen> createState() => State<MobileDateCellEditScreen> createState() =>
_MobileDateCellEditScreenState(); _MobileDateCellEditScreenState();

View File

@ -9,10 +9,6 @@ import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
class MobileNewPropertyScreen extends StatefulWidget { class MobileNewPropertyScreen extends StatefulWidget {
static const routeName = '/new_property';
static const argViewId = 'view_id';
static const argFieldTypeId = 'field_type_id';
const MobileNewPropertyScreen({ const MobileNewPropertyScreen({
super.key, super.key,
required this.viewId, required this.viewId,
@ -22,6 +18,10 @@ class MobileNewPropertyScreen extends StatefulWidget {
final String viewId; final String viewId;
final FieldType? fieldType; final FieldType? fieldType;
static const routeName = '/new_property';
static const argViewId = 'view_id';
static const argFieldTypeId = 'field_type_id';
@override @override
State<MobileNewPropertyScreen> createState() => State<MobileNewPropertyScreen> createState() =>
_MobileNewPropertyScreenState(); _MobileNewPropertyScreenState();
@ -92,7 +92,6 @@ class _SaveButton extends StatelessWidget {
return Padding( return Padding(
padding: const EdgeInsets.only(right: 16.0), padding: const EdgeInsets.only(right: 16.0),
child: Align( child: Align(
alignment: Alignment.center,
child: GestureDetector( child: GestureDetector(
onTap: onSave, onTap: onSave,
child: FlowyText.medium( child: FlowyText.medium(

View File

@ -12,10 +12,6 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
class MobileEditPropertyScreen extends StatefulWidget { class MobileEditPropertyScreen extends StatefulWidget {
static const routeName = '/edit_property';
static const argViewId = 'view_id';
static const argField = 'field';
const MobileEditPropertyScreen({ const MobileEditPropertyScreen({
super.key, super.key,
required this.viewId, required this.viewId,
@ -25,6 +21,10 @@ class MobileEditPropertyScreen extends StatefulWidget {
final String viewId; final String viewId;
final FieldInfo field; final FieldInfo field;
static const routeName = '/edit_property';
static const argViewId = 'view_id';
static const argField = 'field';
@override @override
State<MobileEditPropertyScreen> createState() => State<MobileEditPropertyScreen> createState() =>
_MobileEditPropertyScreenState(); _MobileEditPropertyScreenState();

View File

@ -72,7 +72,6 @@ class _FieldHeader extends StatelessWidget {
return SizedBox( return SizedBox(
height: 56, height: 56,
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
SizedBox( SizedBox(

View File

@ -39,6 +39,31 @@ class FieldOptionValues {
this.selectOption = const [], this.selectOption = const [],
}); });
factory FieldOptionValues.fromField({required FieldPB field}) {
final fieldType = field.fieldType;
final buffer = field.typeOptionData;
return FieldOptionValues(
type: fieldType,
name: field.name,
numberFormat: fieldType == FieldType.Number
? NumberTypeOptionPB.fromBuffer(buffer).format
: null,
dateFormate: fieldType == FieldType.DateTime
? DateTypeOptionPB.fromBuffer(buffer).dateFormat
: null,
timeFormat: fieldType == FieldType.DateTime
? DateTypeOptionPB.fromBuffer(buffer).timeFormat
: null,
selectOption: switch (fieldType) {
FieldType.SingleSelect =>
SingleSelectTypeOptionPB.fromBuffer(buffer).options,
FieldType.MultiSelect =>
MultiSelectTypeOptionPB.fromBuffer(buffer).options,
_ => [],
},
);
}
FieldType type; FieldType type;
String name; String name;
@ -95,33 +120,6 @@ class FieldOptionValues {
throw UnimplementedError(); throw UnimplementedError();
} }
} }
factory FieldOptionValues.fromField({
required FieldPB field,
}) {
final fieldType = field.fieldType;
final buffer = field.typeOptionData;
return FieldOptionValues(
type: fieldType,
name: field.name,
numberFormat: fieldType == FieldType.Number
? NumberTypeOptionPB.fromBuffer(buffer).format
: null,
dateFormate: fieldType == FieldType.DateTime
? DateTypeOptionPB.fromBuffer(buffer).dateFormat
: null,
timeFormat: fieldType == FieldType.DateTime
? DateTypeOptionPB.fromBuffer(buffer).timeFormat
: null,
selectOption: switch (fieldType) {
FieldType.SingleSelect =>
SingleSelectTypeOptionPB.fromBuffer(buffer).options,
FieldType.MultiSelect =>
MultiSelectTypeOptionPB.fromBuffer(buffer).options,
_ => [],
},
);
}
} }
enum FieldOptionAction { enum FieldOptionAction {
@ -365,7 +363,6 @@ class _PropertyType extends StatelessWidget {
return FlowyOptionTile.text( return FlowyOptionTile.text(
text: LocaleKeys.grid_field_propertyType.tr(), text: LocaleKeys.grid_field_propertyType.tr(),
trailing: Row( trailing: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
FlowySvg( FlowySvg(
type.smallSvgData, type.smallSvgData,
@ -542,7 +539,6 @@ class _NumberOption extends StatelessWidget {
return FlowyOptionTile.text( return FlowyOptionTile.text(
text: LocaleKeys.grid_field_numberFormat.tr(), text: LocaleKeys.grid_field_numberFormat.tr(),
trailing: Row( trailing: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
FlowyText( FlowyText(
selectedFormat.title(), selectedFormat.title(),
@ -773,10 +769,6 @@ class __SelectOptionTileState extends State<_SelectOptionTile> {
textFieldHintText: LocaleKeys.grid_field_typeANewOption.tr(), textFieldHintText: LocaleKeys.grid_field_typeANewOption.tr(),
showTopBorder: widget.showTopBorder, showTopBorder: widget.showTopBorder,
showBottomBorder: widget.showBottomBorder, showBottomBorder: widget.showBottomBorder,
textFieldPadding: const EdgeInsets.symmetric(
horizontal: 0.0,
vertical: 16.0,
),
trailing: _SelectOptionColor( trailing: _SelectOptionColor(
color: option.color, color: option.color,
onChanged: (color) { onChanged: (color) {

View File

@ -11,15 +11,6 @@ import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
class MobileCalendarEventsScreen extends StatefulWidget { class MobileCalendarEventsScreen extends StatefulWidget {
static const routeName = '/calendar_events';
// GoRouter Arguments
static const calendarBlocKey = 'calendar_bloc';
static const calendarDateKey = 'date';
static const calendarEventsKey = 'events';
static const calendarRowCacheKey = 'row_cache';
static const calendarViewIdKey = 'view_id';
const MobileCalendarEventsScreen({ const MobileCalendarEventsScreen({
super.key, super.key,
required this.calendarBloc, required this.calendarBloc,
@ -35,6 +26,15 @@ class MobileCalendarEventsScreen extends StatefulWidget {
final RowCache rowCache; final RowCache rowCache;
final String viewId; final String viewId;
static const routeName = '/calendar_events';
// GoRouter Arguments
static const calendarBlocKey = 'calendar_bloc';
static const calendarDateKey = 'date';
static const calendarEventsKey = 'events';
static const calendarRowCacheKey = 'row_cache';
static const calendarViewIdKey = 'view_id';
@override @override
State<MobileCalendarEventsScreen> createState() => State<MobileCalendarEventsScreen> createState() =>
_MobileCalendarEventsScreenState(); _MobileCalendarEventsScreenState();

View File

@ -3,10 +3,6 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class MobileCalendarScreen extends StatelessWidget { class MobileCalendarScreen extends StatelessWidget {
static const routeName = '/calendar';
static const viewId = 'id';
static const viewTitle = 'title';
const MobileCalendarScreen({ const MobileCalendarScreen({
super.key, super.key,
required this.id, required this.id,
@ -17,6 +13,10 @@ class MobileCalendarScreen extends StatelessWidget {
final String id; final String id;
final String? title; final String? title;
static const routeName = '/calendar';
static const viewId = 'id';
static const viewTitle = 'title';
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MobileViewPage( return MobileViewPage(

View File

@ -4,11 +4,6 @@ import 'package:appflowy/mobile/presentation/base/mobile_view_page.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
class MobileGridScreen extends StatelessWidget { class MobileGridScreen extends StatelessWidget {
static const routeName = '/grid';
static const viewId = 'id';
static const viewTitle = 'title';
static const viewArgs = 'arguments';
const MobileGridScreen({ const MobileGridScreen({
super.key, super.key,
required this.id, required this.id,
@ -21,6 +16,11 @@ class MobileGridScreen extends StatelessWidget {
final String? title; final String? title;
final Map<String, dynamic>? arguments; final Map<String, dynamic>? arguments;
static const routeName = '/grid';
static const viewId = 'id';
static const viewTitle = 'title';
static const viewArgs = 'arguments';
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MobileViewPage( return MobileViewPage(

View File

@ -74,13 +74,10 @@ class _MobileDatabaseFieldListHeader extends StatelessWidget {
FlowySvgs.arrow_left_m, FlowySvgs.arrow_left_m,
size: Size.square(iconWidth), size: Size.square(iconWidth),
), ),
width: iconWidth,
iconPadding: EdgeInsets.zero,
onPressed: () => Navigator.of(context).maybePop(), onPressed: () => Navigator.of(context).maybePop(),
), ),
), ),
Align( Align(
alignment: Alignment.center,
child: FlowyText.medium( child: FlowyText.medium(
LocaleKeys.grid_settings_properties.tr(), LocaleKeys.grid_settings_properties.tr(),
fontSize: 16, fontSize: 16,
@ -160,7 +157,6 @@ class _MobileDatabaseFieldListBody extends StatelessWidget {
}, },
); );
}, },
buildDefaultDragHandles: true,
shrinkWrap: true, shrinkWrap: true,
onReorder: (from, to) { onReorder: (from, to) {
from++; from++;

View File

@ -67,13 +67,10 @@ class _Header extends StatelessWidget {
FlowySvgs.close_s, FlowySvgs.close_s,
size: Size.square(iconWidth), size: Size.square(iconWidth),
), ),
width: iconWidth,
iconPadding: EdgeInsets.zero,
onPressed: () => context.pop(), onPressed: () => context.pop(),
), ),
), ),
Align( Align(
alignment: Alignment.center,
child: FlowyText.medium( child: FlowyText.medium(
LocaleKeys.grid_settings_viewList.tr(), LocaleKeys.grid_settings_viewList.tr(),
fontSize: 16, fontSize: 16,

View File

@ -127,13 +127,10 @@ class _EditDatabaseViewHeader extends StatelessWidget {
FlowySvgs.close_s, FlowySvgs.close_s,
size: Size.square(iconWidth), size: Size.square(iconWidth),
), ),
width: iconWidth,
iconPadding: EdgeInsets.zero,
onPressed: () => context.pop(), onPressed: () => context.pop(),
), ),
), ),
Align( Align(
alignment: Alignment.center,
child: FlowyText.medium( child: FlowyText.medium(
LocaleKeys.grid_settings_editView.tr(), LocaleKeys.grid_settings_editView.tr(),
fontSize: 16, fontSize: 16,

View File

@ -3,10 +3,6 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class MobileEditorScreen extends StatelessWidget { class MobileEditorScreen extends StatelessWidget {
static const routeName = '/docs';
static const viewId = 'id';
static const viewTitle = 'title';
const MobileEditorScreen({ const MobileEditorScreen({
super.key, super.key,
required this.id, required this.id,
@ -17,6 +13,10 @@ class MobileEditorScreen extends StatelessWidget {
final String id; final String id;
final String? title; final String? title;
static const routeName = '/docs';
static const viewId = 'id';
static const viewTitle = 'title';
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MobileViewPage( return MobileViewPage(

View File

@ -27,7 +27,6 @@ class _MobileFavoriteFolderHeaderState
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Row( return Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Expanded( Expanded(
child: FlowyButton( child: FlowyButton(

View File

@ -34,7 +34,6 @@ class MobileHomePageHeader extends StatelessWidget {
const HSpace(12), const HSpace(12),
Expanded( Expanded(
child: Column( child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const FlowyText.medium('AppFlowy', fontSize: 18), const FlowyText.medium('AppFlowy', fontSize: 18),

View File

@ -28,7 +28,7 @@ class _MobileHomeSettingPageState extends State<MobileHomeSettingPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return FutureBuilder( return FutureBuilder(
future: getIt<AuthService>().getUser(), future: getIt<AuthService>().getUser(),
builder: ((context, snapshot) { builder: (context, snapshot) {
String? errorMsg; String? errorMsg;
if (!snapshot.hasData) { if (!snapshot.hasData) {
return const Center(child: CircularProgressIndicator.adaptive()); return const Center(child: CircularProgressIndicator.adaptive());
@ -49,7 +49,7 @@ class _MobileHomeSettingPageState extends State<MobileHomeSettingPage> {
? _buildErrorWidget(errorMsg) ? _buildErrorWidget(errorMsg)
: _buildSettingsWidget(userProfile), : _buildSettingsWidget(userProfile),
); );
}), },
); );
} }

View File

@ -44,7 +44,6 @@ class MobileHomeTrashPage extends StatelessWidget {
Expanded( Expanded(
child: _TrashActionAllButton( child: _TrashActionAllButton(
trashBloc: trashBloc, trashBloc: trashBloc,
type: _TrashActionType.deleteAll,
), ),
), ),
const SizedBox( const SizedBox(

View File

@ -47,7 +47,6 @@ class MobilePersonalFolder extends StatelessWidget {
key: ValueKey( key: ValueKey(
'${FolderCategoryType.personal.name} ${view.id}', '${FolderCategoryType.personal.name} ${view.id}',
), ),
isDraggable: true,
categoryType: FolderCategoryType.personal, categoryType: FolderCategoryType.personal,
isFirstChild: view.id == views.first.id, isFirstChild: view.id == views.first.id,
view: view, view: view,

View File

@ -31,7 +31,6 @@ class _MobilePersonalFolderHeaderState
Widget build(BuildContext context) { Widget build(BuildContext context) {
const iconSize = 32.0; const iconSize = 32.0;
return Row( return Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Expanded( Expanded(
child: FlowyButton( child: FlowyButton(

View File

@ -142,7 +142,7 @@ class _MobileRecentViewState extends State<MobileRecentView> {
Widget _buildCoverWidget() { Widget _buildCoverWidget() {
return FutureBuilder<Node?>( return FutureBuilder<Node?>(
future: _getPageNode(), future: _getPageNode(),
builder: ((context, snapshot) { builder: (context, snapshot) {
final node = snapshot.data; final node = snapshot.data;
final placeholder = Container( final placeholder = Container(
// random color, update it once we have a better placeholder // random color, update it once we have a better placeholder
@ -189,7 +189,7 @@ class _MobileRecentViewState extends State<MobileRecentView> {
case CoverType.none: case CoverType.none:
return placeholder; return placeholder;
} }
}), },
); );
} }

View File

@ -323,7 +323,6 @@ class _SingleMobileInnerViewItemState extends State<SingleMobileInnerViewItem> {
Widget child = InkWell( Widget child = InkWell(
borderRadius: BorderRadius.circular(4.0), borderRadius: BorderRadius.circular(4.0),
enableFeedback: true,
onTap: () => widget.onSelected(widget.view), onTap: () => widget.onSelected(widget.view),
child: SizedBox( child: SizedBox(
height: _itemHeight, height: _itemHeight,

View File

@ -39,7 +39,6 @@ class AboutSettingGroup extends StatelessWidget {
), ),
), ),
], ],
showDivider: true,
); );
} }
} }

View File

@ -12,11 +12,9 @@ import 'package:google_fonts/google_fonts.dart';
final List<String> _availableFonts = GoogleFonts.asMap().keys.toList(); final List<String> _availableFonts = GoogleFonts.asMap().keys.toList();
class FontPickerScreen extends StatelessWidget { class FontPickerScreen extends StatelessWidget {
static const routeName = '/font_picker'; const FontPickerScreen({super.key});
const FontPickerScreen({ static const routeName = '/font_picker';
super.key,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@ -7,16 +7,12 @@ import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
class LanguagePickerScreen extends StatelessWidget { class LanguagePickerScreen extends StatelessWidget {
const LanguagePickerScreen({super.key});
static const routeName = '/language_picker'; static const routeName = '/language_picker';
const LanguagePickerScreen({
super.key,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) => const LanguagePickerPage();
return const LanguagePickerPage();
}
} }
class LanguagePickerPage extends StatefulWidget { class LanguagePickerPage extends StatefulWidget {

View File

@ -30,7 +30,7 @@ class UserSessionSettingGroup extends StatelessWidget {
() => null, () => null,
(result) => result.fold( (result) => result.fold(
(l) {}, (l) {},
(r) async => await runAppFlowy(), (r) async => runAppFlowy(),
), ),
); );
}, },

View File

@ -45,7 +45,6 @@ class FlowyMobileStateContainer extends StatelessWidget {
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 32), padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 32),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Text( Text(
emoji ?? emoji ??

View File

@ -47,7 +47,6 @@ class FlowyOptionTile extends StatelessWidget {
type: FlowyOptionTileType.text, type: FlowyOptionTileType.text,
text: text, text: text,
textColor: textColor, textColor: textColor,
controller: null,
onTap: onTap, onTap: onTap,
showTopBorder: showTopBorder, showTopBorder: showTopBorder,
showBottomBorder: showBottomBorder, showBottomBorder: showBottomBorder,
@ -61,7 +60,6 @@ class FlowyOptionTile extends StatelessWidget {
void Function(String value)? onTextChanged, void Function(String value)? onTextChanged,
void Function(String value)? onTextSubmitted, void Function(String value)? onTextSubmitted,
EdgeInsets textFieldPadding = const EdgeInsets.symmetric( EdgeInsets textFieldPadding = const EdgeInsets.symmetric(
horizontal: 0.0,
vertical: 16.0, vertical: 16.0,
), ),
bool showTopBorder = true, bool showTopBorder = true,
@ -75,8 +73,6 @@ class FlowyOptionTile extends StatelessWidget {
type: FlowyOptionTileType.textField, type: FlowyOptionTileType.textField,
controller: controller, controller: controller,
textFieldPadding: textFieldPadding, textFieldPadding: textFieldPadding,
text: null,
onTap: null,
showTopBorder: showTopBorder, showTopBorder: showTopBorder,
showBottomBorder: showBottomBorder, showBottomBorder: showBottomBorder,
leading: leftIcon, leading: leftIcon,
@ -126,7 +122,6 @@ class FlowyOptionTile extends StatelessWidget {
return FlowyOptionTile._( return FlowyOptionTile._(
type: FlowyOptionTileType.toggle, type: FlowyOptionTileType.toggle,
text: text, text: text,
controller: null,
onTap: onTap ?? () => onValueChanged(!isSelected), onTap: onTap ?? () => onValueChanged(!isSelected),
onValueChanged: onValueChanged, onValueChanged: onValueChanged,
showTopBorder: showTopBorder, showTopBorder: showTopBorder,
@ -172,7 +167,6 @@ class FlowyOptionTile extends StatelessWidget {
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0), padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
if (leadingWidget != null) leadingWidget, if (leadingWidget != null) leadingWidget,
_buildText(), _buildText(),

View File

@ -44,7 +44,6 @@ class FlowyMobileColorPicker extends StatelessWidget {
), ),
leftIcon: _ColorIcon( leftIcon: _ColorIcon(
color: color.color, color: color.color,
size: 24.0,
), ),
leftIconSize: const Size.square(36.0), leftIconSize: const Size.square(36.0),
iconPadding: 12.0, iconPadding: 12.0,
@ -65,18 +64,14 @@ class FlowyMobileColorPicker extends StatelessWidget {
} }
class _ColorIcon extends StatelessWidget { class _ColorIcon extends StatelessWidget {
const _ColorIcon({ const _ColorIcon({required this.color});
this.size = 24.0,
required this.color,
});
final double size;
final Color color; final Color color;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SizedBox.square( return SizedBox.square(
dimension: size, dimension: 24,
child: DecoratedBox( child: DecoratedBox(
decoration: BoxDecoration( decoration: BoxDecoration(
color: color, color: color,

View File

@ -7,16 +7,13 @@ import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
class MobileColorPickerScreen extends StatelessWidget { class MobileColorPickerScreen extends StatelessWidget {
static const routeName = '/color_picker'; const MobileColorPickerScreen({super.key, this.title});
static const pageTitle = 'title';
const MobileColorPickerScreen({
super.key,
this.title,
});
final String? title; final String? title;
static const routeName = '/color_picker';
static const pageTitle = 'title';
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(

View File

@ -71,7 +71,6 @@ class _FlowyEmojiPickerState extends State<FlowyEmojiPicker> {
return EmojiPicker( return EmojiPicker(
emojiData: emojiData!, emojiData: emojiData!,
configuration: EmojiPickerConfiguration( configuration: EmojiPickerConfiguration(
showSectionHeader: true,
showTabs: false, showTabs: false,
defaultSkinTone: lastSelectedEmojiSkinTone ?? EmojiSkinTone.none, defaultSkinTone: lastSelectedEmojiSkinTone ?? EmojiSkinTone.none,
perLine: widget.emojiPerLine, perLine: widget.emojiPerLine,

View File

@ -4,16 +4,13 @@ import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
class MobileEmojiPickerScreen extends StatelessWidget { class MobileEmojiPickerScreen extends StatelessWidget {
static const routeName = '/emoji_picker'; const MobileEmojiPickerScreen({super.key, this.title});
static const pageTitle = 'title';
const MobileEmojiPickerScreen({
super.key,
this.title,
});
final String? title; final String? title;
static const routeName = '/emoji_picker';
static const pageTitle = 'title';
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return IconPickerPage( return IconPickerPage(

View File

@ -67,9 +67,9 @@ class _BlankPageState extends State<BlankPage> {
return SizedBox.expand( return SizedBox.expand(
child: Container( child: Container(
color: Theme.of(context).colorScheme.surface, color: Theme.of(context).colorScheme.surface,
child: Padding( child: const Padding(
padding: const EdgeInsets.all(10), padding: EdgeInsets.all(10),
child: Container(), child: SizedBox.shrink(),
), ),
), ),
); );

View File

@ -7,11 +7,11 @@ import 'cell_controller.dart';
/// Read https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/architecture/frontend/grid /// Read https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/architecture/frontend/grid
/// for more information /// for more information
class CellMemCache { class CellMemCache {
CellMemCache();
/// fieldId: {rowId: cellData} /// fieldId: {rowId: cellData}
final Map<String, Map<RowId, dynamic>> _cellByFieldId = {}; final Map<String, Map<RowId, dynamic>> _cellByFieldId = {};
CellMemCache();
void removeCellWithFieldId(String fieldId) { void removeCellWithFieldId(String fieldId) {
_cellByFieldId.remove(fieldId); _cellByFieldId.remove(fieldId);
} }

View File

@ -38,9 +38,27 @@ class CellContext with _$CellContext {
/// T represents the type of the cell data. /// T represents the type of the cell data.
/// D represents the type of data that will be saved to the disk. /// D represents the type of data that will be saved to the disk.
class CellController<T, D> { class CellController<T, D> {
CellController({
required this.viewId,
required FieldController fieldController,
required CellContext cellContext,
required RowCache rowCache,
required CellDataLoader<T> cellDataLoader,
required CellDataPersistence<D> cellDataPersistence,
}) : _fieldController = fieldController,
_cellContext = cellContext,
_rowCache = rowCache,
_cellDataLoader = cellDataLoader,
_cellDataPersistence = cellDataPersistence,
_fieldListener = SingleFieldListener(fieldId: cellContext.fieldId),
_cellDataNotifier =
CellDataNotifier(value: rowCache.cellCache.get(cellContext)) {
_startListening();
}
final String viewId; final String viewId;
final CellContext _cellContext;
final FieldController _fieldController; final FieldController _fieldController;
final CellContext _cellContext;
final RowCache _rowCache; final RowCache _rowCache;
final CellDataLoader<T> _cellDataLoader; final CellDataLoader<T> _cellDataLoader;
final CellDataPersistence<D> _cellDataPersistence; final CellDataPersistence<D> _cellDataPersistence;
@ -64,24 +82,6 @@ class CellController<T, D> {
String? get icon => rowMeta?.icon; String? get icon => rowMeta?.icon;
CellMemCache get _cellCache => _rowCache.cellCache; CellMemCache get _cellCache => _rowCache.cellCache;
CellController({
required this.viewId,
required FieldController fieldController,
required CellContext cellContext,
required RowCache rowCache,
required CellDataLoader<T> cellDataLoader,
required CellDataPersistence<D> cellDataPersistence,
}) : _fieldController = fieldController,
_cellContext = cellContext,
_rowCache = rowCache,
_cellDataLoader = cellDataLoader,
_cellDataPersistence = cellDataPersistence,
_fieldListener = SingleFieldListener(fieldId: cellContext.fieldId),
_cellDataNotifier =
CellDataNotifier(value: rowCache.cellCache.get(cellContext)) {
_startListening();
}
/// casting method for painless type coersion /// casting method for painless type coersion
CellController<A, B> as<A, B>() => this as CellController<A, B>; CellController<A, B> as<A, B>() => this as CellController<A, B>;
@ -233,9 +233,10 @@ class CellController<T, D> {
} }
class CellDataNotifier<T> extends ChangeNotifier { class CellDataNotifier<T> extends ChangeNotifier {
CellDataNotifier({required T value, this.listenWhen}) : _value = value;
T _value; T _value;
bool Function(T? oldValue, T? newValue)? listenWhen; bool Function(T? oldValue, T? newValue)? listenWhen;
CellDataNotifier({required T value, this.listenWhen}) : _value = value;
set value(T newValue) { set value(T newValue) {
if (listenWhen?.call(_value, newValue) ?? false) { if (listenWhen?.call(_value, newValue) ?? false) {

View File

@ -16,16 +16,16 @@ abstract class CellDataParser<T> {
} }
class CellDataLoader<T> { class CellDataLoader<T> {
final CellDataParser<T> parser;
/// Reload the cell data if the field is changed.
final bool reloadOnFieldChange;
CellDataLoader({ CellDataLoader({
required this.parser, required this.parser,
this.reloadOnFieldChange = false, this.reloadOnFieldChange = false,
}); });
final CellDataParser<T> parser;
/// Reload the cell data if the field is changed.
final bool reloadOnFieldChange;
Future<T?> loadData({ Future<T?> loadData({
required String viewId, required String viewId,
required CellContext cellContext, required CellContext cellContext,

View File

@ -12,12 +12,14 @@ import '../row/row_service.dart';
typedef UpdateFieldNotifiedValue = Either<Unit, FlowyError>; typedef UpdateFieldNotifiedValue = Either<Unit, FlowyError>;
class CellListener { class CellListener {
CellListener({required this.rowId, required this.fieldId});
final RowId rowId; final RowId rowId;
final String fieldId; final String fieldId;
PublishNotifier<UpdateFieldNotifiedValue>? _updateCellNotifier = PublishNotifier<UpdateFieldNotifiedValue>? _updateCellNotifier =
PublishNotifier(); PublishNotifier();
DatabaseNotificationListener? _listener; DatabaseNotificationListener? _listener;
CellListener({required this.rowId, required this.fieldId});
void start({required void Function(UpdateFieldNotifiedValue) onCellChanged}) { void start({required void Function(UpdateFieldNotifiedValue) onCellChanged}) {
_updateCellNotifier?.addPublishListener(onCellChanged); _updateCellNotifier?.addPublishListener(onCellChanged);

View File

@ -6,16 +6,16 @@ import 'package:dartz/dartz.dart';
import 'package:protobuf/protobuf.dart'; import 'package:protobuf/protobuf.dart';
class ChecklistCellBackendService { class ChecklistCellBackendService {
final String viewId;
final String fieldId;
final String rowId;
ChecklistCellBackendService({ ChecklistCellBackendService({
required this.viewId, required this.viewId,
required this.fieldId, required this.fieldId,
required this.rowId, required this.rowId,
}); });
final String viewId;
final String fieldId;
final String rowId;
Future<Either<Unit, FlowyError>> create({ Future<Either<Unit, FlowyError>> create({
required String name, required String name,
}) { }) {

View File

@ -6,8 +6,6 @@ import 'package:dartz/dartz.dart';
import 'package:fixnum/fixnum.dart'; import 'package:fixnum/fixnum.dart';
final class DateCellBackendService { final class DateCellBackendService {
final CellIdPB cellId;
DateCellBackendService({ DateCellBackendService({
required String viewId, required String viewId,
required String fieldId, required String fieldId,
@ -17,6 +15,8 @@ final class DateCellBackendService {
..fieldId = fieldId ..fieldId = fieldId
..rowId = rowId; ..rowId = rowId;
final CellIdPB cellId;
Future<Either<Unit, FlowyError>> update({ Future<Either<Unit, FlowyError>> update({
required bool includeTime, required bool includeTime,
required bool isRange, required bool isRange,

View File

@ -6,16 +6,16 @@ import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/cell_entities.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/cell_entities.pb.dart';
class SelectOptionCellBackendService { class SelectOptionCellBackendService {
final String viewId;
final String fieldId;
final String rowId;
SelectOptionCellBackendService({ SelectOptionCellBackendService({
required this.viewId, required this.viewId,
required this.fieldId, required this.fieldId,
required this.rowId, required this.rowId,
}); });
final String viewId;
final String fieldId;
final String rowId;
Future<Either<Unit, FlowyError>> create({ Future<Either<Unit, FlowyError>> create({
required String name, required String name,
bool isSelected = true, bool isSelected = true,

View File

@ -29,12 +29,6 @@ typedef OnDeleteGroup = void Function(List<String>);
typedef OnInsertGroup = void Function(InsertedGroupPB); typedef OnInsertGroup = void Function(InsertedGroupPB);
class GroupCallbacks { class GroupCallbacks {
final OnGroupConfigurationChanged? onGroupConfigurationChanged;
final OnGroupByField? onGroupByField;
final OnUpdateGroup? onUpdateGroup;
final OnDeleteGroup? onDeleteGroup;
final OnInsertGroup? onInsertGroup;
GroupCallbacks({ GroupCallbacks({
this.onGroupConfigurationChanged, this.onGroupConfigurationChanged,
this.onGroupByField, this.onGroupByField,
@ -42,26 +36,21 @@ class GroupCallbacks {
this.onDeleteGroup, this.onDeleteGroup,
this.onInsertGroup, this.onInsertGroup,
}); });
final OnGroupConfigurationChanged? onGroupConfigurationChanged;
final OnGroupByField? onGroupByField;
final OnUpdateGroup? onUpdateGroup;
final OnDeleteGroup? onDeleteGroup;
final OnInsertGroup? onInsertGroup;
} }
class DatabaseLayoutSettingCallbacks { class DatabaseLayoutSettingCallbacks {
final void Function(DatabaseLayoutSettingPB) onLayoutSettingsChanged; DatabaseLayoutSettingCallbacks({required this.onLayoutSettingsChanged});
DatabaseLayoutSettingCallbacks({ final void Function(DatabaseLayoutSettingPB) onLayoutSettingsChanged;
required this.onLayoutSettingsChanged,
});
} }
class DatabaseCallbacks { class DatabaseCallbacks {
OnDatabaseChanged? onDatabaseChanged;
OnFieldsChanged? onFieldsChanged;
OnFiltersChanged? onFiltersChanged;
OnSortsChanged? onSortsChanged;
OnNumOfRowsChanged? onNumOfRowsChanged;
OnRowsDeleted? onRowsDeleted;
OnRowsUpdated? onRowsUpdated;
OnRowsCreated? onRowsCreated;
DatabaseCallbacks({ DatabaseCallbacks({
this.onDatabaseChanged, this.onDatabaseChanged,
this.onNumOfRowsChanged, this.onNumOfRowsChanged,
@ -72,9 +61,36 @@ class DatabaseCallbacks {
this.onRowsDeleted, this.onRowsDeleted,
this.onRowsCreated, this.onRowsCreated,
}); });
OnDatabaseChanged? onDatabaseChanged;
OnFieldsChanged? onFieldsChanged;
OnFiltersChanged? onFiltersChanged;
OnSortsChanged? onSortsChanged;
OnNumOfRowsChanged? onNumOfRowsChanged;
OnRowsDeleted? onRowsDeleted;
OnRowsUpdated? onRowsUpdated;
OnRowsCreated? onRowsCreated;
} }
class DatabaseController { class DatabaseController {
DatabaseController({required ViewPB view})
: viewId = view.id,
_databaseViewBackendSvc = DatabaseViewBackendService(viewId: view.id),
fieldController = FieldController(viewId: view.id),
_groupListener = DatabaseGroupListener(view.id),
databaseLayout = databaseLayoutFromViewLayout(view.layout),
_layoutListener = DatabaseLayoutSettingListener(view.id) {
_viewCache = DatabaseViewCache(
viewId: viewId,
fieldController: fieldController,
);
_listenOnRowsChanged();
_listenOnFieldsChanged();
_listenOnGroupChanged();
_listenOnLayoutChanged();
}
final String viewId; final String viewId;
final DatabaseViewBackendService _databaseViewBackendSvc; final DatabaseViewBackendService _databaseViewBackendSvc;
final FieldController fieldController; final FieldController fieldController;
@ -96,23 +112,6 @@ class DatabaseController {
final ValueNotifier<bool> _isLoading = ValueNotifier(true); final ValueNotifier<bool> _isLoading = ValueNotifier(true);
DatabaseController({required ViewPB view})
: viewId = view.id,
_databaseViewBackendSvc = DatabaseViewBackendService(viewId: view.id),
fieldController = FieldController(viewId: view.id),
_groupListener = DatabaseGroupListener(view.id),
databaseLayout = databaseLayoutFromViewLayout(view.layout),
_layoutListener = DatabaseLayoutSettingListener(view.id) {
_viewCache = DatabaseViewCache(
viewId: viewId,
fieldController: fieldController,
);
_listenOnRowsChanged();
_listenOnFieldsChanged();
_listenOnGroupChanged();
_listenOnLayoutChanged();
}
void setIsLoading(bool isLoading) { void setIsLoading(bool isLoading) {
_isLoading.value = isLoading; _isLoading.value = isLoading;
} }

View File

@ -8,10 +8,9 @@ import 'package:dartz/dartz.dart';
import 'layout/layout_service.dart'; import 'layout/layout_service.dart';
class DatabaseViewBackendService { class DatabaseViewBackendService {
DatabaseViewBackendService({required this.viewId});
final String viewId; final String viewId;
DatabaseViewBackendService({
required this.viewId,
});
/// Returns the datbaase id associated with the view. /// Returns the datbaase id associated with the view.
Future<Either<String, FlowyError>> getDatabaseId() async { Future<Either<String, FlowyError>> getDatabaseId() async {

View File

@ -9,32 +9,31 @@ import 'field_info.dart';
part 'field_cell_bloc.freezed.dart'; part 'field_cell_bloc.freezed.dart';
class FieldCellBloc extends Bloc<FieldCellEvent, FieldCellState> { class FieldCellBloc extends Bloc<FieldCellEvent, FieldCellState> {
FieldInfo fieldInfo; FieldCellBloc({required String viewId, required FieldInfo fieldInfo})
: _fieldSettingsService = FieldSettingsBackendService(viewId: viewId),
super(FieldCellState.initial(fieldInfo)) {
_dispatch();
}
final FieldSettingsBackendService _fieldSettingsService; final FieldSettingsBackendService _fieldSettingsService;
FieldCellBloc({required String viewId, required this.fieldInfo}) void _dispatch() {
: _fieldSettingsService = FieldSettingsBackendService(
viewId: viewId,
),
super(FieldCellState.initial(fieldInfo)) {
on<FieldCellEvent>( on<FieldCellEvent>(
(event, emit) async { (event, emit) async {
event.when( event.when(
onFieldChanged: (newFieldInfo) { onFieldChanged: (newFieldInfo) =>
fieldInfo = newFieldInfo; emit(FieldCellState.initial(newFieldInfo)),
emit(FieldCellState.initial(newFieldInfo)); onResizeStart: () =>
}, emit(state.copyWith(isResizing: true, resizeStart: state.width)),
onResizeStart: () {
emit(state.copyWith(isResizing: true, resizeStart: state.width));
},
startUpdateWidth: (offset) { startUpdateWidth: (offset) {
final width = max(offset + state.resizeStart, 50).toDouble(); final width = max(offset + state.resizeStart, 50).toDouble();
emit(state.copyWith(width: width)); emit(state.copyWith(width: width));
}, },
endUpdateWidth: () { endUpdateWidth: () {
if (state.width != fieldInfo.fieldSettings?.width.toDouble()) { if (state.width !=
state.fieldInfo.fieldSettings?.width.toDouble()) {
_fieldSettingsService.updateFieldSettings( _fieldSettingsService.updateFieldSettings(
fieldId: fieldInfo.id, fieldId: state.fieldInfo.id,
width: state.width, width: state.width,
); );
} }
@ -58,17 +57,17 @@ class FieldCellEvent with _$FieldCellEvent {
@freezed @freezed
class FieldCellState with _$FieldCellState { class FieldCellState with _$FieldCellState {
const factory FieldCellState({
required FieldInfo fieldInfo,
required double width,
required bool isResizing,
required double resizeStart,
}) = _FieldCellState;
factory FieldCellState.initial(FieldInfo fieldInfo) => FieldCellState( factory FieldCellState.initial(FieldInfo fieldInfo) => FieldCellState(
fieldInfo: fieldInfo, fieldInfo: fieldInfo,
isResizing: false, isResizing: false,
width: fieldInfo.fieldSettings!.width.toDouble(), width: fieldInfo.fieldSettings!.width.toDouble(),
resizeStart: 0, resizeStart: 0,
); );
const factory FieldCellState({
required FieldInfo fieldInfo,
required double width,
required bool isResizing,
required double resizeStart,
}) = _FieldCellState;
} }

View File

@ -79,6 +79,24 @@ typedef OnReceiveSorts = void Function(List<SortInfo>);
typedef OnReceiveFieldSettings = void Function(List<FieldInfo>); typedef OnReceiveFieldSettings = void Function(List<FieldInfo>);
class FieldController { class FieldController {
FieldController({required this.viewId})
: _fieldListener = FieldsListener(viewId: viewId),
_settingListener = DatabaseSettingListener(viewId: viewId),
_filterBackendSvc = FilterBackendService(viewId: viewId),
_filtersListener = FiltersListener(viewId: viewId),
_databaseViewBackendSvc = DatabaseViewBackendService(viewId: viewId),
_sortBackendSvc = SortBackendService(viewId: viewId),
_sortsListener = SortsListener(viewId: viewId),
_fieldSettingsListener = FieldSettingsListener(viewId: viewId),
_fieldSettingsBackendSvc = FieldSettingsBackendService(viewId: viewId) {
// Start listeners
_listenOnFieldChanges();
_listenOnSettingChanges();
_listenOnFilterChanges();
_listenOnSortChanged();
_listenOnFieldSettingsChanged();
}
final String viewId; final String viewId;
// Listeners // Listeners
@ -146,24 +164,6 @@ class FieldController {
.firstWhereOrNull((element) => element.fieldId == fieldId); .firstWhereOrNull((element) => element.fieldId == fieldId);
} }
FieldController({required this.viewId})
: _fieldListener = FieldsListener(viewId: viewId),
_settingListener = DatabaseSettingListener(viewId: viewId),
_filterBackendSvc = FilterBackendService(viewId: viewId),
_filtersListener = FiltersListener(viewId: viewId),
_databaseViewBackendSvc = DatabaseViewBackendService(viewId: viewId),
_sortBackendSvc = SortBackendService(viewId: viewId),
_sortsListener = SortsListener(viewId: viewId),
_fieldSettingsListener = FieldSettingsListener(viewId: viewId),
_fieldSettingsBackendSvc = FieldSettingsBackendService(viewId: viewId) {
// Start listeners
_listenOnFieldChanges();
_listenOnSettingChanges();
_listenOnFilterChanges();
_listenOnSortChanged();
_listenOnFieldSettingsChanged();
}
/// Listen for filter changes in the backend. /// Listen for filter changes in the backend.
void _listenOnFilterChanges() { void _listenOnFilterChanges() {
void deleteFilterFromChangeset( void deleteFilterFromChangeset(
@ -402,7 +402,7 @@ class FieldController {
for (final fieldOrder in deletedFields) fieldOrder.fieldId: fieldOrder, for (final fieldOrder in deletedFields) fieldOrder.fieldId: fieldOrder,
}; };
newFields.retainWhere((field) => (deletedFieldMap[field.id] == null)); newFields.retainWhere((field) => deletedFieldMap[field.id] == null);
return newFields; return newFields;
} }
@ -784,9 +784,10 @@ class FieldController {
} }
class RowCacheDependenciesImpl extends RowFieldsDelegate with RowLifeCycle { class RowCacheDependenciesImpl extends RowFieldsDelegate with RowLifeCycle {
RowCacheDependenciesImpl(FieldController cache) : _fieldController = cache;
final FieldController _fieldController; final FieldController _fieldController;
OnReceiveFields? _onFieldFn; OnReceiveFields? _onFieldFn;
RowCacheDependenciesImpl(FieldController cache) : _fieldController = cache;
@override @override
UnmodifiableListView<FieldInfo> get fieldInfos => UnmodifiableListView<FieldInfo> get fieldInfos =>

View File

@ -16,14 +16,6 @@ import 'field_service.dart';
part 'field_editor_bloc.freezed.dart'; part 'field_editor_bloc.freezed.dart';
class FieldEditorBloc extends Bloc<FieldEditorEvent, FieldEditorState> { class FieldEditorBloc extends Bloc<FieldEditorEvent, FieldEditorState> {
final String viewId;
final String fieldId;
final FieldController fieldController;
final SingleFieldListener _singleFieldListener;
final FieldBackendService fieldService;
final FieldSettingsBackendService fieldSettingsService;
final void Function(String newFieldId)? onFieldInserted;
FieldEditorBloc({ FieldEditorBloc({
required this.viewId, required this.viewId,
required this.fieldController, required this.fieldController,
@ -37,6 +29,24 @@ class FieldEditorBloc extends Bloc<FieldEditorEvent, FieldEditorState> {
), ),
fieldSettingsService = FieldSettingsBackendService(viewId: viewId), fieldSettingsService = FieldSettingsBackendService(viewId: viewId),
super(FieldEditorState(field: FieldInfo.initial(field))) { super(FieldEditorState(field: FieldInfo.initial(field))) {
_dispatch();
}
final String viewId;
final String fieldId;
final FieldController fieldController;
final SingleFieldListener _singleFieldListener;
final FieldBackendService fieldService;
final FieldSettingsBackendService fieldSettingsService;
final void Function(String newFieldId)? onFieldInserted;
@override
Future<void> close() {
_singleFieldListener.stop();
return super.close();
}
void _dispatch() {
on<FieldEditorEvent>( on<FieldEditorEvent>(
(event, emit) async { (event, emit) async {
await event.when( await event.when(
@ -107,13 +117,6 @@ class FieldEditorBloc extends Bloc<FieldEditorEvent, FieldEditorState> {
(err) => Log.error(err), (err) => Log.error(err),
); );
} }
@override
Future<void> close() {
_singleFieldListener.stop();
return super.close();
}
} }
@freezed @freezed

View File

@ -7,6 +7,14 @@ part 'field_info.freezed.dart';
class FieldInfo with _$FieldInfo { class FieldInfo with _$FieldInfo {
const FieldInfo._(); const FieldInfo._();
factory FieldInfo.initial(FieldPB field) => FieldInfo(
field: field,
fieldSettings: null,
hasFilter: false,
hasSort: false,
isGroupField: false,
);
const factory FieldInfo({ const factory FieldInfo({
required FieldPB field, required FieldPB field,
required FieldSettingsPB? fieldSettings, required FieldSettingsPB? fieldSettings,
@ -25,14 +33,6 @@ class FieldInfo with _$FieldInfo {
FieldVisibility? get visibility => fieldSettings?.visibility; FieldVisibility? get visibility => fieldSettings?.visibility;
factory FieldInfo.initial(FieldPB field) => FieldInfo(
field: field,
fieldSettings: null,
hasFilter: false,
hasSort: false,
isGroupField: false,
);
bool get canBeGroup { bool get canBeGroup {
switch (field.fieldType) { switch (field.fieldType) {
case FieldType.URL: case FieldType.URL:

View File

@ -11,12 +11,13 @@ import 'package:flowy_infra/notifier.dart';
typedef UpdateFieldNotifiedValue = FieldPB; typedef UpdateFieldNotifiedValue = FieldPB;
class SingleFieldListener { class SingleFieldListener {
SingleFieldListener({required this.fieldId});
final String fieldId; final String fieldId;
void Function(UpdateFieldNotifiedValue)? _updateFieldNotifier; void Function(UpdateFieldNotifiedValue)? _updateFieldNotifier;
DatabaseNotificationListener? _listener; DatabaseNotificationListener? _listener;
SingleFieldListener({required this.fieldId});
void start({ void start({
required void Function(UpdateFieldNotifiedValue) onFieldChanged, required void Function(UpdateFieldNotifiedValue) onFieldChanged,
}) { }) {
@ -53,11 +54,13 @@ typedef UpdateFieldsNotifiedValue
= Either<DatabaseFieldChangesetPB, FlowyError>; = Either<DatabaseFieldChangesetPB, FlowyError>;
class FieldsListener { class FieldsListener {
FieldsListener({required this.viewId});
final String viewId; final String viewId;
PublishNotifier<UpdateFieldsNotifiedValue>? updateFieldsNotifier = PublishNotifier<UpdateFieldsNotifiedValue>? updateFieldsNotifier =
PublishNotifier(); PublishNotifier();
DatabaseNotificationListener? _listener; DatabaseNotificationListener? _listener;
FieldsListener({required this.viewId});
void start({ void start({
required void Function(UpdateFieldsNotifiedValue) onFieldsChanged, required void Function(UpdateFieldsNotifiedValue) onFieldsChanged,

View File

@ -9,11 +9,11 @@ import 'package:dartz/dartz.dart';
/// `rust-lib/flowy-database/event_map.rs` for a list of events and their /// `rust-lib/flowy-database/event_map.rs` for a list of events and their
/// implementations. /// implementations.
class FieldBackendService { class FieldBackendService {
FieldBackendService({required this.viewId, required this.fieldId});
final String viewId; final String viewId;
final String fieldId; final String fieldId;
FieldBackendService({required this.viewId, required this.fieldId});
/// Create a field in a database view. The position will only be applicable /// Create a field in a database view. The position will only be applicable
/// in this view; for other views it will be appended to the end /// in this view; for other views it will be appended to the end
static Future<Either<FieldPB, FlowyError>> createField({ static Future<Either<FieldPB, FlowyError>> createField({
@ -167,19 +167,16 @@ class FieldBackendService {
Future<Either<Unit, FlowyError>> updateType({ Future<Either<Unit, FlowyError>> updateType({
required FieldType fieldType, required FieldType fieldType,
}) { }) =>
return updateFieldType( updateFieldType(
viewId: viewId, viewId: viewId,
fieldId: fieldId, fieldId: fieldId,
fieldType: fieldType, fieldType: fieldType,
); );
}
Future<Either<Unit, FlowyError>> delete() { Future<Either<Unit, FlowyError>> delete() =>
return deleteField(viewId: viewId, fieldId: fieldId); deleteField(viewId: viewId, fieldId: fieldId);
}
Future<Either<Unit, FlowyError>> duplicate() { Future<Either<Unit, FlowyError>> duplicate() =>
return duplicateField(viewId: viewId, fieldId: fieldId); duplicateField(viewId: viewId, fieldId: fieldId);
}
} }

View File

@ -1,8 +1,8 @@
import 'package:appflowy_backend/protobuf/flowy-database2/select_option_entities.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/select_option_entities.pb.dart';
import 'package:dartz/dartz.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:protobuf/protobuf.dart'; import 'package:protobuf/protobuf.dart';
import 'package:dartz/dartz.dart';
part 'edit_select_option_bloc.freezed.dart'; part 'edit_select_option_bloc.freezed.dart';
class EditSelectOptionBloc class EditSelectOptionBloc

View File

@ -8,15 +8,15 @@ import 'select_option_type_option_bloc.dart';
import 'type_option_service.dart'; import 'type_option_service.dart';
class MultiSelectAction implements ISelectOptionAction { class MultiSelectAction implements ISelectOptionAction {
final TypeOptionBackendService service;
final TypeOptionDataCallback onTypeOptionUpdated;
MultiSelectAction({ MultiSelectAction({
required this.onTypeOptionUpdated, required this.onTypeOptionUpdated,
required String viewId, required String viewId,
required String fieldId, required String fieldId,
}) : service = TypeOptionBackendService(viewId: viewId, fieldId: fieldId); }) : service = TypeOptionBackendService(viewId: viewId, fieldId: fieldId);
final TypeOptionBackendService service;
final TypeOptionDataCallback onTypeOptionUpdated;
@override @override
Future<List<SelectOptionPB>> insertOption( Future<List<SelectOptionPB>> insertOption(
List<SelectOptionPB> options, List<SelectOptionPB> options,

View File

@ -1,6 +1,7 @@
import 'package:appflowy_backend/protobuf/flowy-database2/number_entities.pbenum.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/number_entities.pbenum.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
part 'number_format_bloc.freezed.dart'; part 'number_format_bloc.freezed.dart';
class NumberFormatBloc extends Bloc<NumberFormatEvent, NumberFormatState> { class NumberFormatBloc extends Bloc<NumberFormatEvent, NumberFormatState> {

View File

@ -1,8 +1,9 @@
import 'dart:async';
import 'package:appflowy_backend/protobuf/flowy-database2/select_option_entities.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/select_option_entities.pb.dart';
import 'package:dartz/dartz.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async';
import 'package:dartz/dartz.dart';
part 'select_option_type_option_bloc.freezed.dart'; part 'select_option_type_option_bloc.freezed.dart';
abstract class ISelectOptionAction { abstract class ISelectOptionAction {
@ -24,12 +25,16 @@ abstract class ISelectOptionAction {
class SelectOptionTypeOptionBloc class SelectOptionTypeOptionBloc
extends Bloc<SelectOptionTypeOptionEvent, SelectOptionTypeOptionState> { extends Bloc<SelectOptionTypeOptionEvent, SelectOptionTypeOptionState> {
final ISelectOptionAction typeOptionAction;
SelectOptionTypeOptionBloc({ SelectOptionTypeOptionBloc({
required List<SelectOptionPB> options, required List<SelectOptionPB> options,
required this.typeOptionAction, required this.typeOptionAction,
}) : super(SelectOptionTypeOptionState.initial(options)) { }) : super(SelectOptionTypeOptionState.initial(options)) {
_dispatch();
}
final ISelectOptionAction typeOptionAction;
void _dispatch() {
on<SelectOptionTypeOptionEvent>( on<SelectOptionTypeOptionEvent>(
(event, emit) async { (event, emit) async {
await event.when( await event.when(

View File

@ -8,15 +8,15 @@ import 'select_option_type_option_bloc.dart';
import 'type_option_service.dart'; import 'type_option_service.dart';
class SingleSelectAction implements ISelectOptionAction { class SingleSelectAction implements ISelectOptionAction {
final TypeOptionBackendService service;
final TypeOptionDataCallback onTypeOptionUpdated;
SingleSelectAction({ SingleSelectAction({
required this.onTypeOptionUpdated, required this.onTypeOptionUpdated,
required String viewId, required String viewId,
required String fieldId, required String fieldId,
}) : service = TypeOptionBackendService(viewId: viewId, fieldId: fieldId); }) : service = TypeOptionBackendService(viewId: viewId, fieldId: fieldId);
final TypeOptionBackendService service;
final TypeOptionDataCallback onTypeOptionUpdated;
@override @override
Future<List<SelectOptionPB>> insertOption( Future<List<SelectOptionPB>> insertOption(
List<SelectOptionPB> options, List<SelectOptionPB> options,

View File

@ -4,14 +4,14 @@ import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
class TypeOptionBackendService { class TypeOptionBackendService {
final String viewId;
final String fieldId;
TypeOptionBackendService({ TypeOptionBackendService({
required this.viewId, required this.viewId,
required this.fieldId, required this.fieldId,
}); });
final String viewId;
final String fieldId;
Future<Either<SelectOptionPB, FlowyError>> newOption({ Future<Either<SelectOptionPB, FlowyError>> newOption({
required String name, required String name,
}) { }) {

View File

@ -9,13 +9,14 @@ import 'package:flowy_infra/notifier.dart';
typedef FieldSettingsValue = Either<FieldSettingsPB, FlowyError>; typedef FieldSettingsValue = Either<FieldSettingsPB, FlowyError>;
class FieldSettingsListener { class FieldSettingsListener {
FieldSettingsListener({required this.viewId});
final String viewId; final String viewId;
PublishNotifier<FieldSettingsValue>? _fieldSettingsNotifier = PublishNotifier<FieldSettingsValue>? _fieldSettingsNotifier =
PublishNotifier(); PublishNotifier();
DatabaseNotificationListener? _listener; DatabaseNotificationListener? _listener;
FieldSettingsListener({required this.viewId});
void start({ void start({
required void Function(FieldSettingsValue) onFieldSettingsChanged, required void Function(FieldSettingsValue) onFieldSettingsChanged,
}) { }) {

View File

@ -12,12 +12,13 @@ typedef UpdateFilterNotifiedValue
= Either<FilterChangesetNotificationPB, FlowyError>; = Either<FilterChangesetNotificationPB, FlowyError>;
class FiltersListener { class FiltersListener {
FiltersListener({required this.viewId});
final String viewId; final String viewId;
PublishNotifier<UpdateFilterNotifiedValue>? _filterNotifier = PublishNotifier<UpdateFilterNotifiedValue>? _filterNotifier =
PublishNotifier(); PublishNotifier();
DatabaseNotificationListener? _listener; DatabaseNotificationListener? _listener;
FiltersListener({required this.viewId});
void start({ void start({
required void Function(UpdateFilterNotifiedValue) onFilterChanged, required void Function(UpdateFilterNotifiedValue) onFilterChanged,
@ -54,6 +55,8 @@ class FiltersListener {
} }
class FilterListener { class FilterListener {
FilterListener({required this.viewId, required this.filterId});
final String viewId; final String viewId;
final String filterId; final String filterId;
@ -61,7 +64,6 @@ class FilterListener {
PublishNotifier<FilterPB>? _onUpdateNotifier = PublishNotifier(); PublishNotifier<FilterPB>? _onUpdateNotifier = PublishNotifier();
DatabaseNotificationListener? _listener; DatabaseNotificationListener? _listener;
FilterListener({required this.viewId, required this.filterId});
void start({ void start({
void Function()? onDeleted, void Function()? onDeleted,

View File

@ -15,9 +15,10 @@ import 'package:appflowy_backend/protobuf/flowy-database2/util.pb.dart';
import 'package:fixnum/fixnum.dart' as $fixnum; import 'package:fixnum/fixnum.dart' as $fixnum;
class FilterBackendService { class FilterBackendService {
final String viewId;
const FilterBackendService({required this.viewId}); const FilterBackendService({required this.viewId});
final String viewId;
Future<Either<List<FilterPB>, FlowyError>> getAllFilters() { Future<Either<List<FilterPB>, FlowyError>> getAllFilters() {
final payload = DatabaseViewIdPB()..value = viewId; final payload = DatabaseViewIdPB()..value = viewId;

View File

@ -14,12 +14,14 @@ typedef GroupUpdateValue = Either<GroupChangesPB, FlowyError>;
typedef GroupByNewFieldValue = Either<List<GroupPB>, FlowyError>; typedef GroupByNewFieldValue = Either<List<GroupPB>, FlowyError>;
class DatabaseGroupListener { class DatabaseGroupListener {
DatabaseGroupListener(this.viewId);
final String viewId; final String viewId;
PublishNotifier<GroupUpdateValue>? _numOfGroupsNotifier = PublishNotifier(); PublishNotifier<GroupUpdateValue>? _numOfGroupsNotifier = PublishNotifier();
PublishNotifier<GroupByNewFieldValue>? _groupByFieldNotifier = PublishNotifier<GroupByNewFieldValue>? _groupByFieldNotifier =
PublishNotifier(); PublishNotifier();
DatabaseNotificationListener? _listener; DatabaseNotificationListener? _listener;
DatabaseGroupListener(this.viewId);
void start({ void start({
required void Function(GroupUpdateValue) onNumOfGroupsChanged, required void Function(GroupUpdateValue) onNumOfGroupsChanged,

View File

@ -4,10 +4,10 @@ import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
class GroupBackendService { class GroupBackendService {
final String viewId;
GroupBackendService(this.viewId); GroupBackendService(this.viewId);
final String viewId;
Future<Either<Unit, FlowyError>> groupByField({ Future<Either<Unit, FlowyError>> groupByField({
required String fieldId, required String fieldId,
}) { }) {

View File

@ -8,11 +8,13 @@ import 'package:dartz/dartz.dart';
/// Listener for database layout changes. /// Listener for database layout changes.
class DatabaseLayoutListener { class DatabaseLayoutListener {
DatabaseLayoutListener(this.viewId);
final String viewId; final String viewId;
PublishNotifier<Either<DatabaseLayoutPB, FlowyError>>? _layoutNotifier = PublishNotifier<Either<DatabaseLayoutPB, FlowyError>>? _layoutNotifier =
PublishNotifier(); PublishNotifier();
DatabaseNotificationListener? _listener; DatabaseNotificationListener? _listener;
DatabaseLayoutListener(this.viewId);
void start({ void start({
required void Function(Either<DatabaseLayoutPB, FlowyError>) required void Function(Either<DatabaseLayoutPB, FlowyError>)

View File

@ -9,11 +9,13 @@ import 'package:dartz/dartz.dart';
typedef LayoutSettingsValue<T> = Either<T, FlowyError>; typedef LayoutSettingsValue<T> = Either<T, FlowyError>;
class DatabaseLayoutSettingListener { class DatabaseLayoutSettingListener {
DatabaseLayoutSettingListener(this.viewId);
final String viewId; final String viewId;
PublishNotifier<LayoutSettingsValue<DatabaseLayoutSettingPB>>? PublishNotifier<LayoutSettingsValue<DatabaseLayoutSettingPB>>?
_settingNotifier = PublishNotifier(); _settingNotifier = PublishNotifier();
DatabaseNotificationListener? _listener; DatabaseNotificationListener? _listener;
DatabaseLayoutSettingListener(this.viewId);
void start({ void start({
required void Function(LayoutSettingsValue<DatabaseLayoutSettingPB>) required void Function(LayoutSettingsValue<DatabaseLayoutSettingPB>)

View File

@ -11,17 +11,30 @@ import 'row_meta_listener.dart';
part 'row_banner_bloc.freezed.dart'; part 'row_banner_bloc.freezed.dart';
class RowBannerBloc extends Bloc<RowBannerEvent, RowBannerState> { class RowBannerBloc extends Bloc<RowBannerEvent, RowBannerState> {
final String viewId;
final RowBackendService _rowBackendSvc;
final RowMetaListener _metaListener;
SingleFieldListener? _fieldListener;
RowBannerBloc({ RowBannerBloc({
required this.viewId, required this.viewId,
required RowMetaPB rowMeta, required RowMetaPB rowMeta,
}) : _rowBackendSvc = RowBackendService(viewId: viewId), }) : _rowBackendSvc = RowBackendService(viewId: viewId),
_metaListener = RowMetaListener(rowMeta.id), _metaListener = RowMetaListener(rowMeta.id),
super(RowBannerState.initial(rowMeta)) { super(RowBannerState.initial(rowMeta)) {
_dispatch();
}
final String viewId;
final RowBackendService _rowBackendSvc;
final RowMetaListener _metaListener;
SingleFieldListener? _fieldListener;
@override
Future<void> close() async {
await _metaListener.stop();
await _fieldListener?.stop();
_fieldListener = null;
return super.close();
}
void _dispatch() {
on<RowBannerEvent>( on<RowBannerEvent>(
(event, emit) { (event, emit) {
event.when( event.when(
@ -32,12 +45,8 @@ class RowBannerBloc extends Bloc<RowBannerEvent, RowBannerState> {
didReceiveRowMeta: (RowMetaPB rowMeta) { didReceiveRowMeta: (RowMetaPB rowMeta) {
emit(state.copyWith(rowMeta: rowMeta)); emit(state.copyWith(rowMeta: rowMeta));
}, },
setCover: (String coverURL) { setCover: (String coverURL) => _updateMeta(coverURL: coverURL),
_updateMeta(coverURL: coverURL); setIcon: (String iconURL) => _updateMeta(iconURL: iconURL),
},
setIcon: (String iconURL) {
_updateMeta(iconURL: iconURL);
},
didReceiveFieldUpdate: (updatedField) { didReceiveFieldUpdate: (updatedField) {
emit( emit(
state.copyWith( state.copyWith(
@ -51,15 +60,6 @@ class RowBannerBloc extends Bloc<RowBannerEvent, RowBannerState> {
); );
} }
@override
Future<void> close() async {
await _metaListener.stop();
await _fieldListener?.stop();
_fieldListener = null;
return super.close();
}
Future<void> _loadPrimaryField() async { Future<void> _loadPrimaryField() async {
final fieldOrError = final fieldOrError =
await FieldBackendService.getPrimaryField(viewId: viewId); await FieldBackendService.getPrimaryField(viewId: viewId);

Some files were not shown because too many files have changed in this diff Show More