mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
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:
parent
747abba87f
commit
acc03b8cc4
@ -36,11 +36,19 @@ linter:
|
||||
- prefer_final_locals
|
||||
|
||||
- sized_box_for_whitespace
|
||||
- use_decorated_box
|
||||
|
||||
- unnecessary_parenthesis
|
||||
- unnecessary_await_in_return
|
||||
- unnecessary_raw_strings
|
||||
|
||||
- avoid_unnecessary_containers
|
||||
- avoid_redundant_argument_values
|
||||
- avoid_unused_constructor_parameters
|
||||
|
||||
- always_declare_return_types
|
||||
- unnecessary_raw_strings
|
||||
- use_decorated_box
|
||||
|
||||
- sort_constructors_first
|
||||
|
||||
# Additional information about this file can be found at
|
||||
# https://dart.dev/guides/language/analysis-options
|
||||
|
@ -32,8 +32,8 @@ void main() {
|
||||
const service = TestWorkspaceService(TestWorkspace.board);
|
||||
|
||||
group('board', () {
|
||||
setUpAll(() async => await service.setUpAll());
|
||||
setUp(() async => await service.setUp());
|
||||
setUpAll(() async => service.setUpAll());
|
||||
setUp(() async => service.setUp());
|
||||
|
||||
testWidgets('open the board with data structure in v0.2.0', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
|
@ -38,9 +38,7 @@ void main() {
|
||||
await tester.expectToSeeHomePageWithGetStartedPage();
|
||||
|
||||
// create a new document called Sample
|
||||
await tester.createNewPage(
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
await tester.createNewPage();
|
||||
|
||||
// focus on the editor
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
|
@ -80,7 +80,7 @@ void main() {
|
||||
// Hover over today's calendar cell
|
||||
await tester.hoverOnTodayCalendarCell(
|
||||
// Tap on create new event button
|
||||
onHover: () async => await tester.tapAddCalendarEventButton(),
|
||||
onHover: () async => tester.tapAddCalendarEventButton(),
|
||||
);
|
||||
|
||||
// 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
|
||||
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.dismissEventEditor();
|
||||
|
||||
|
@ -60,7 +60,6 @@ void main() {
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.RichText,
|
||||
content: 'hello',
|
||||
cellIndex: 0,
|
||||
);
|
||||
|
||||
await tester.assertCellContent(
|
||||
|
@ -35,7 +35,7 @@ void main() {
|
||||
// delete the readme page
|
||||
await tester.hoverOnPageName(
|
||||
gettingStarted,
|
||||
onHover: () async => await tester.tapDeletePageButton(),
|
||||
onHover: () async => tester.tapDeletePageButton(),
|
||||
);
|
||||
|
||||
// the banner should show up and the readme page should be gone
|
||||
@ -59,7 +59,7 @@ void main() {
|
||||
// delete the readme page
|
||||
await tester.hoverOnPageName(
|
||||
gettingStarted,
|
||||
onHover: () async => await tester.tapDeletePageButton(),
|
||||
onHover: () async => tester.tapDeletePageButton(),
|
||||
);
|
||||
|
||||
// the banner should show up and the readme page should be gone
|
||||
|
@ -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/inline_actions/widgets/inline_actions_handler.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:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
@ -89,7 +88,6 @@ Future<String> createDocumentToReference(WidgetTester tester) async {
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: name,
|
||||
layout: ViewLayoutPB.Document,
|
||||
openAfterCreated: false,
|
||||
);
|
||||
|
||||
|
@ -144,8 +144,6 @@ Future<void> insertReferenceDatabase(
|
||||
// create a new document
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: 'insert_a_reference_${layout.name}',
|
||||
layout: ViewLayoutPB.Document,
|
||||
openAfterCreated: true,
|
||||
);
|
||||
// tap the first line of the document
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
@ -173,8 +171,6 @@ Future<void> createInlineDatabase(
|
||||
final documentName = 'insert_a_inline_${layout.name}';
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: documentName,
|
||||
layout: ViewLayoutPB.Document,
|
||||
openAfterCreated: true,
|
||||
);
|
||||
// tap the first line of the document
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
|
@ -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/upload_image_menu.dart';
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart'
|
||||
hide UploadImageMenu, ResizableImage;
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
@ -38,7 +37,6 @@ void main() {
|
||||
// create a new document
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: LocaleKeys.document_plugins_image_addAnImage.tr(),
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
|
||||
// tap the first line of the document
|
||||
@ -87,7 +85,6 @@ void main() {
|
||||
// create a new document
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: LocaleKeys.document_plugins_image_addAnImage.tr(),
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
|
||||
// tap the first line of the document
|
||||
@ -141,7 +138,6 @@ void main() {
|
||||
// create a new document
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: LocaleKeys.document_plugins_image_addAnImage.tr(),
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
|
||||
// tap the first line of the document
|
||||
|
@ -1,6 +1,5 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.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:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||
@ -22,7 +21,6 @@ void main() {
|
||||
// create a new document
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: 'math equation',
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
|
||||
// tap the first line of the document
|
||||
@ -68,7 +66,6 @@ void main() {
|
||||
// create a new document
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: 'math equation',
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
|
||||
// tap the first line of the document
|
||||
|
@ -65,7 +65,7 @@ void main() {
|
||||
const newName = 'RenameToNewPageName';
|
||||
await tester.hoverOnPageName(
|
||||
pageName,
|
||||
onHover: () async => await tester.renamePage(newName),
|
||||
onHover: () async => tester.renamePage(newName),
|
||||
);
|
||||
final finder = find.descendant(
|
||||
of: find.byType(MentionPageBlock),
|
||||
@ -84,7 +84,7 @@ void main() {
|
||||
await tester.hoverOnPageName(
|
||||
pageName,
|
||||
layout: ViewLayoutPB.Grid,
|
||||
onHover: () async => await tester.tapDeletePageButton(),
|
||||
onHover: () async => tester.tapDeletePageButton(),
|
||||
);
|
||||
final finder = find.descendant(
|
||||
of: find.byType(MentionPageBlock),
|
||||
@ -114,7 +114,6 @@ Future<String> insertInlinePage(
|
||||
// create a new document
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: 'insert_a_inline_page_${layout.name}',
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
|
||||
// tap the first line of the document
|
||||
|
@ -1,4 +1,3 @@
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@ -24,9 +23,7 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
// create a new document
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
await tester.createNewPageWithNameUnderParent();
|
||||
|
||||
// tap the first line of the document
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
|
@ -1,6 +1,5 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.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:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
@ -17,7 +16,6 @@ void main() {
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: 'outline_test',
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
@ -34,7 +32,6 @@ void main() {
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: 'outline_test',
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
import 'dart:io';
|
||||
|
||||
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:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@ -40,9 +39,7 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
// create a new document
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
await tester.createNewPageWithNameUnderParent();
|
||||
|
||||
// tap the first line of the document
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
@ -86,9 +83,7 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
// create a new document
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
await tester.createNewPageWithNameUnderParent();
|
||||
|
||||
// tap the first line of the document
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
@ -125,9 +120,7 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
// create a new document
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
await tester.createNewPageWithNameUnderParent();
|
||||
|
||||
// tap the first line of the document
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
@ -162,9 +155,7 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
// create a new document
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
await tester.createNewPageWithNameUnderParent();
|
||||
|
||||
// tap the first line of the document
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
@ -176,11 +167,8 @@ void main() {
|
||||
final toggleListIcon = find.byIcon(Icons.arrow_right);
|
||||
await tester.tapButton(toggleListIcon);
|
||||
|
||||
await tester.editor.updateSelection(
|
||||
Selection.collapsed(
|
||||
Position(path: [0], offset: 0),
|
||||
),
|
||||
);
|
||||
await tester.editor
|
||||
.updateSelection(Selection.collapsed(Position(path: [0])));
|
||||
await tester.ime.insertCharacter('\n');
|
||||
|
||||
final editorState = tester.editor.getCurrentEditorState();
|
||||
@ -196,9 +184,7 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
// create a new document
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
await tester.createNewPageWithNameUnderParent();
|
||||
|
||||
// tap the first line of the document
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
@ -209,7 +195,7 @@ void main() {
|
||||
|
||||
await tester.editor.updateSelection(
|
||||
Selection.collapsed(
|
||||
Position(path: [0], offset: 0),
|
||||
Position(path: [0]),
|
||||
),
|
||||
);
|
||||
await tester.simulateKeyEvent(
|
||||
|
@ -1,6 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
@ -18,10 +17,7 @@ void main() {
|
||||
|
||||
// create a new document called Sample
|
||||
const pageName = 'Sample';
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: pageName,
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
await tester.createNewPageWithNameUnderParent(name: pageName);
|
||||
|
||||
// focus on the editor
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
@ -75,10 +71,7 @@ void main() {
|
||||
|
||||
// create a new document called Sample
|
||||
const pageName = 'Sample';
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: pageName,
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
await tester.createNewPageWithNameUnderParent(name: pageName);
|
||||
|
||||
// focus on the editor
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
|
@ -28,8 +28,8 @@ void main() {
|
||||
const service = TestWorkspaceService(TestWorkspace.emptyDocument);
|
||||
|
||||
group('Tests on a workspace with only an empty document', () {
|
||||
setUpAll(() async => await service.setUpAll());
|
||||
setUp(() async => await service.setUp());
|
||||
setUpAll(() async => service.setUpAll());
|
||||
setUp(() async => service.setUp());
|
||||
|
||||
testWidgets('/board shortcut creates a new board and view of the board',
|
||||
(tester) async {
|
||||
|
@ -15,8 +15,8 @@ void main() {
|
||||
const service = TestWorkspaceService(TestWorkspace.aiWorkSpace);
|
||||
|
||||
group('integration tests for open-ai smart menu', () {
|
||||
setUpAll(() async => await service.setUpAll());
|
||||
setUp(() async => await service.setUp());
|
||||
setUpAll(() async => service.setUpAll());
|
||||
setUp(() async => service.setUp());
|
||||
|
||||
testWidgets('testing selection on open-ai smart menu replace',
|
||||
(tester) async {
|
||||
@ -59,7 +59,7 @@ void main() {
|
||||
|
||||
editorState.service.selectionService.updateSelection(
|
||||
Selection(
|
||||
start: Position(path: [1], offset: 0),
|
||||
start: Position(path: [1]),
|
||||
end: Position(path: [1], offset: 5),
|
||||
),
|
||||
);
|
||||
@ -80,8 +80,8 @@ void main() {
|
||||
expect(
|
||||
editorState.service.selectionService.currentSelection.value,
|
||||
Selection(
|
||||
start: Position(path: [2], offset: 0),
|
||||
end: Position(path: [3], offset: 0),
|
||||
start: Position(path: [2]),
|
||||
end: Position(path: [3]),
|
||||
),
|
||||
);
|
||||
});
|
||||
@ -99,7 +99,7 @@ Future<AppFlowyEditor> setUpOpenAITesting(WidgetTester tester) async {
|
||||
final Finder editor = find.byType(AppFlowyEditor);
|
||||
await tester.tap(editor);
|
||||
await tester.pumpAndSettle();
|
||||
return (tester.state(editor).widget as AppFlowyEditor);
|
||||
return tester.state(editor).widget as AppFlowyEditor;
|
||||
}
|
||||
|
||||
Future<void> mockOpenAIRepository() async {
|
||||
|
@ -1,7 +1,6 @@
|
||||
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/view/view_item.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
@ -34,14 +33,8 @@ void main() {
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: names[i],
|
||||
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);
|
||||
@ -87,7 +80,6 @@ void main() {
|
||||
await tester.favoriteViewByName(gettingStarted);
|
||||
await tester.hoverOnPageName(
|
||||
gettingStarted,
|
||||
layout: ViewLayoutPB.Document,
|
||||
onHover: () async {
|
||||
await tester.renamePage(name);
|
||||
await tester.pumpAndSettle();
|
||||
@ -116,7 +108,6 @@ void main() {
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: names[i],
|
||||
parentName: parentName,
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
tester.expectToSeePageName(names[i], parentName: parentName);
|
||||
}
|
||||
@ -136,7 +127,6 @@ void main() {
|
||||
|
||||
await tester.hoverOnPageName(
|
||||
names[1],
|
||||
layout: ViewLayoutPB.Document,
|
||||
onHover: () async {
|
||||
await tester.tapDeletePageButton();
|
||||
await tester.pumpAndSettle();
|
||||
@ -150,7 +140,6 @@ void main() {
|
||||
|
||||
await tester.hoverOnPageName(
|
||||
gettingStarted,
|
||||
layout: ViewLayoutPB.Document,
|
||||
onHover: () async {
|
||||
await tester.tapDeletePageButton();
|
||||
await tester.pumpAndSettle();
|
||||
@ -194,7 +183,6 @@ void main() {
|
||||
await tester.favoriteViewByName(gettingStarted);
|
||||
await tester.hoverOnPageName(
|
||||
gettingStarted,
|
||||
layout: ViewLayoutPB.Document,
|
||||
useLast: false,
|
||||
onHover: () async {
|
||||
await tester.tapPageOptionButton();
|
||||
|
@ -82,7 +82,6 @@ void main() {
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: names[i],
|
||||
parentName: parentName,
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
tester.expectToSeePageName(names[i], parentName: parentName);
|
||||
}
|
||||
@ -148,7 +147,7 @@ void main() {
|
||||
name: document,
|
||||
openAfterCreated: false,
|
||||
);
|
||||
tester.expectToSeePageName(document, layout: ViewLayoutPB.Document);
|
||||
tester.expectToSeePageName(document);
|
||||
|
||||
const grid = 'grid';
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
@ -190,7 +189,6 @@ void main() {
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: grid,
|
||||
layout: ViewLayoutPB.Grid,
|
||||
openAfterCreated: true,
|
||||
);
|
||||
tester.expectToSeePageName(grid, layout: ViewLayoutPB.Grid);
|
||||
|
||||
|
@ -32,15 +32,9 @@ void main() {
|
||||
findsNothing,
|
||||
);
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: _documentName,
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
await tester.createNewPageWithNameUnderParent(name: _documentName);
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: _documentTwoName,
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
await tester.createNewPageWithNameUnderParent(name: _documentTwoName);
|
||||
|
||||
/// Open second menu item in a new tab
|
||||
await tester.openAppInNewTab(gettingStarted, ViewLayoutPB.Document);
|
||||
|
@ -129,7 +129,7 @@ extension AppFlowyTestBase on WidgetTester {
|
||||
}
|
||||
|
||||
Future<void> waitForSeconds(int seconds) async {
|
||||
await Future.delayed((Duration(seconds: seconds)), () {});
|
||||
await Future.delayed(Duration(seconds: seconds), () {});
|
||||
}
|
||||
|
||||
Future<void> pumpUntilFound(
|
||||
|
@ -397,7 +397,6 @@ extension CommonOperations on WidgetTester {
|
||||
await hoverOnPageName(
|
||||
name,
|
||||
layout: layout,
|
||||
useLast: true,
|
||||
onHover: () async {
|
||||
await tapFavoritePageButton();
|
||||
await pumpAndSettle();
|
||||
@ -412,7 +411,6 @@ extension CommonOperations on WidgetTester {
|
||||
await hoverOnPageName(
|
||||
name,
|
||||
layout: layout,
|
||||
useLast: true,
|
||||
onHover: () async {
|
||||
await tapUnfavoritePageButton();
|
||||
await pumpAndSettle();
|
||||
|
@ -205,7 +205,7 @@ extension AppFlowyDatabaseTest on WidgetTester {
|
||||
}) async {
|
||||
final cell = cellFinder(rowIndex, fieldType);
|
||||
expect(cell, findsOneWidget);
|
||||
await tapButton(cell, warnIfMissed: false);
|
||||
await tapButton(cell);
|
||||
}
|
||||
|
||||
/// The [fieldName] must be unique in the grid.
|
||||
@ -1110,7 +1110,7 @@ extension AppFlowyDatabaseTest on WidgetTester {
|
||||
skipOffstage: false,
|
||||
);
|
||||
expect(findCell, findsOneWidget);
|
||||
await tapButton(findCell, warnIfMissed: false);
|
||||
await tapButton(findCell);
|
||||
}
|
||||
|
||||
Future<void> tapCheckedButtonOnCheckboxFilter() async {
|
||||
|
@ -34,7 +34,6 @@ class IMESimulator {
|
||||
selection: TextSelection.collapsed(
|
||||
offset: value.selection.baseOffset + 1,
|
||||
),
|
||||
composing: TextRange.empty,
|
||||
);
|
||||
client.updateEditingValue(textEditingValue);
|
||||
await tester.pumpAndSettle();
|
||||
|
@ -41,7 +41,7 @@ class MoveWindowDetectorState extends State<MoveWindowDetector> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (!Platform.isMacOS) {
|
||||
return widget.child ?? Container();
|
||||
return widget.child ?? const SizedBox.shrink();
|
||||
}
|
||||
return GestureDetector(
|
||||
// https://stackoverflow.com/questions/52965799/flutter-gesturedetector-not-working-with-containers-in-stack
|
||||
|
@ -7,21 +7,21 @@ import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class NetworkListener {
|
||||
final Connectivity _connectivity = Connectivity();
|
||||
late StreamSubscription<ConnectivityResult> _connectivitySubscription;
|
||||
|
||||
NetworkListener() {
|
||||
_connectivitySubscription =
|
||||
_connectivity.onConnectivityChanged.listen(_updateConnectionStatus);
|
||||
}
|
||||
|
||||
final Connectivity _connectivity = Connectivity();
|
||||
late StreamSubscription<ConnectivityResult> _connectivitySubscription;
|
||||
|
||||
Future<void> start() async {
|
||||
late ConnectivityResult result;
|
||||
// Platform messages may fail, so we use a try/catch PlatformException.
|
||||
try {
|
||||
result = await _connectivity.checkConnectivity();
|
||||
} on PlatformException catch (e) {
|
||||
Log.error('Couldn\'t check connectivity status. $e');
|
||||
Log.error("Couldn't check connectivity status. $e");
|
||||
return;
|
||||
}
|
||||
return _updateConnectionStatus(result);
|
||||
|
@ -31,9 +31,6 @@ typedef FolderNotificationHandler = Function(
|
||||
);
|
||||
|
||||
class FolderNotificationListener {
|
||||
StreamSubscription<SubscribeObject>? _subscription;
|
||||
FolderNotificationParser? _parser;
|
||||
|
||||
FolderNotificationListener({
|
||||
required String objectId,
|
||||
required FolderNotificationHandler handler,
|
||||
@ -45,6 +42,9 @@ class FolderNotificationListener {
|
||||
RustStreamReceiver.listen((observable) => _parser?.parse(observable));
|
||||
}
|
||||
|
||||
FolderNotificationParser? _parser;
|
||||
StreamSubscription<SubscribeObject>? _subscription;
|
||||
|
||||
Future<void> stop() async {
|
||||
_parser = null;
|
||||
await _subscription?.cancel();
|
||||
|
@ -31,9 +31,6 @@ typedef DatabaseNotificationHandler = Function(
|
||||
);
|
||||
|
||||
class DatabaseNotificationListener {
|
||||
StreamSubscription<SubscribeObject>? _subscription;
|
||||
DatabaseNotificationParser? _parser;
|
||||
|
||||
DatabaseNotificationListener({
|
||||
required String objectId,
|
||||
required DatabaseNotificationHandler handler,
|
||||
@ -42,6 +39,9 @@ class DatabaseNotificationListener {
|
||||
RustStreamReceiver.listen((observable) => _parser?.parse(observable));
|
||||
}
|
||||
|
||||
DatabaseNotificationParser? _parser;
|
||||
StreamSubscription<SubscribeObject>? _subscription;
|
||||
|
||||
Future<void> stop() async {
|
||||
_parser = null;
|
||||
await _subscription?.cancel();
|
||||
|
@ -3,18 +3,18 @@ import 'package:appflowy_backend/protobuf/flowy-notification/protobuf.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
|
||||
class NotificationParser<T, E> {
|
||||
String? id;
|
||||
void Function(T, Either<Uint8List, E>) callback;
|
||||
|
||||
T? Function(int) tyParser;
|
||||
E Function(Uint8List) errorParser;
|
||||
|
||||
NotificationParser({
|
||||
this.id,
|
||||
required this.callback,
|
||||
required this.errorParser,
|
||||
required this.tyParser,
|
||||
});
|
||||
|
||||
String? id;
|
||||
void Function(T, Either<Uint8List, E>) callback;
|
||||
E Function(Uint8List) errorParser;
|
||||
T? Function(int) tyParser;
|
||||
|
||||
void parse(SubscribeObject subject) {
|
||||
if (id != null) {
|
||||
if (subject.id != id) {
|
||||
|
@ -31,9 +31,6 @@ typedef UserNotificationHandler = Function(
|
||||
);
|
||||
|
||||
class UserNotificationListener {
|
||||
StreamSubscription<SubscribeObject>? _subscription;
|
||||
UserNotificationParser? _parser;
|
||||
|
||||
UserNotificationListener({
|
||||
required String objectId,
|
||||
required UserNotificationHandler handler,
|
||||
@ -42,6 +39,9 @@ class UserNotificationListener {
|
||||
RustStreamReceiver.listen((observable) => _parser?.parse(observable));
|
||||
}
|
||||
|
||||
UserNotificationParser? _parser;
|
||||
StreamSubscription<SubscribeObject>? _subscription;
|
||||
|
||||
Future<void> stop() async {
|
||||
_parser = null;
|
||||
await _subscription?.cancel();
|
||||
|
@ -5,15 +5,6 @@ part 'backend_env.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
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({
|
||||
required this.root,
|
||||
required this.custom_app_path,
|
||||
@ -28,15 +19,20 @@ class AppFlowyConfiguration {
|
||||
factory AppFlowyConfiguration.fromJson(Map<String, dynamic> 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);
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
class SupabaseConfiguration {
|
||||
/// Indicates whether the sync feature is enabled.
|
||||
final String url;
|
||||
final String anon_key;
|
||||
|
||||
SupabaseConfiguration({
|
||||
required this.url,
|
||||
required this.anon_key,
|
||||
@ -45,6 +41,10 @@ class SupabaseConfiguration {
|
||||
factory SupabaseConfiguration.fromJson(Map<String, dynamic> json) =>
|
||||
_$SupabaseConfigurationFromJson(json);
|
||||
|
||||
/// Indicates whether the sync feature is enabled.
|
||||
final String url;
|
||||
final String anon_key;
|
||||
|
||||
Map<String, dynamic> toJson() => _$SupabaseConfigurationToJson(this);
|
||||
|
||||
static SupabaseConfiguration defaultConfig() {
|
||||
@ -61,10 +61,6 @@ class SupabaseConfiguration {
|
||||
|
||||
@JsonSerializable()
|
||||
class AppFlowyCloudConfiguration {
|
||||
final String base_url;
|
||||
final String ws_base_url;
|
||||
final String gotrue_url;
|
||||
|
||||
AppFlowyCloudConfiguration({
|
||||
required this.base_url,
|
||||
required this.ws_base_url,
|
||||
@ -74,6 +70,10 @@ class AppFlowyCloudConfiguration {
|
||||
factory AppFlowyCloudConfiguration.fromJson(Map<String, dynamic> json) =>
|
||||
_$AppFlowyCloudConfigurationFromJson(json);
|
||||
|
||||
final String base_url;
|
||||
final String ws_base_url;
|
||||
final String gotrue_url;
|
||||
|
||||
Map<String, dynamic> toJson() => _$AppFlowyCloudConfigurationToJson(this);
|
||||
|
||||
static AppFlowyCloudConfiguration defaultConfig() {
|
||||
|
@ -180,16 +180,16 @@ Future<void> setAppFlowyCloudUrl(Option<String> url) async {
|
||||
|
||||
/// Use getIt<AppFlowyCloudSharedEnv>() to get the shared environment.
|
||||
class AppFlowyCloudSharedEnv {
|
||||
final AuthenticatorType _authenticatorType;
|
||||
final AppFlowyCloudConfiguration appflowyCloudConfig;
|
||||
final SupabaseConfiguration supabaseConfig;
|
||||
|
||||
AppFlowyCloudSharedEnv({
|
||||
required AuthenticatorType authenticatorType,
|
||||
required this.appflowyCloudConfig,
|
||||
required this.supabaseConfig,
|
||||
}) : _authenticatorType = authenticatorType;
|
||||
|
||||
final AuthenticatorType _authenticatorType;
|
||||
final AppFlowyCloudConfiguration appflowyCloudConfig;
|
||||
final SupabaseConfiguration supabaseConfig;
|
||||
|
||||
AuthenticatorType get authenticatorType => _authenticatorType;
|
||||
|
||||
static Future<AppFlowyCloudSharedEnv> fromEnv() async {
|
||||
|
@ -102,7 +102,6 @@ class AppBarButton extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
enableFeedback: true,
|
||||
borderRadius: BorderRadius.circular(28),
|
||||
splashColor: Colors.transparent,
|
||||
focusColor: Colors.transparent,
|
||||
|
@ -34,7 +34,6 @@ class BottomSheetHeader extends StatelessWidget {
|
||||
),
|
||||
if (title != null)
|
||||
Align(
|
||||
alignment: Alignment.center,
|
||||
child: FlowyText.medium(
|
||||
title!,
|
||||
fontSize: 16,
|
||||
|
@ -31,7 +31,6 @@ class MobileViewItemBottomSheetBody extends StatelessWidget {
|
||||
children: [
|
||||
// rename, duplicate
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Expanded(
|
||||
child: BottomSheetActionWidget(
|
||||
@ -58,7 +57,6 @@ class MobileViewItemBottomSheetBody extends StatelessWidget {
|
||||
|
||||
// share, delete
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Expanded(
|
||||
child: BottomSheetActionWidget(
|
||||
|
@ -119,7 +119,6 @@ class MobileViewBottomSheetBody extends StatelessWidget {
|
||||
children: [
|
||||
// rename, duplicate
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Expanded(
|
||||
child: BottomSheetActionWidget(
|
||||
@ -146,7 +145,6 @@ class MobileViewBottomSheetBody extends StatelessWidget {
|
||||
|
||||
// share, delete
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Expanded(
|
||||
child: BottomSheetActionWidget(
|
||||
|
@ -3,10 +3,6 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MobileBoardScreen extends StatelessWidget {
|
||||
static const routeName = '/board';
|
||||
static const viewId = 'id';
|
||||
static const viewTitle = 'title';
|
||||
|
||||
const MobileBoardScreen({
|
||||
super.key,
|
||||
required this.id,
|
||||
@ -17,6 +13,10 @@ class MobileBoardScreen extends StatelessWidget {
|
||||
final String id;
|
||||
final String? title;
|
||||
|
||||
static const routeName = '/board';
|
||||
static const viewId = 'id';
|
||||
static const viewTitle = 'title';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MobileViewPage(
|
||||
|
@ -82,7 +82,6 @@ class _GroupCardHeaderState extends State<GroupCardHeader> {
|
||||
_controller.text,
|
||||
),
|
||||
),
|
||||
maxLines: 1,
|
||||
style: titleTextStyle,
|
||||
onTapOutside: (_) => context.read<BoardBloc>().add(
|
||||
// group header switch from TextField to Text
|
||||
|
@ -233,7 +233,6 @@ class RowDetailFab extends StatelessWidget {
|
||||
BoxShadow(
|
||||
offset: Offset(0, 8),
|
||||
blurRadius: 20,
|
||||
spreadRadius: 0,
|
||||
color: Color(0x191F2329),
|
||||
),
|
||||
],
|
||||
|
@ -25,7 +25,6 @@ class MobileRowDetailCreateFieldButton extends StatelessWidget {
|
||||
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
|
||||
RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12.0),
|
||||
side: BorderSide.none,
|
||||
),
|
||||
),
|
||||
overlayColor: MaterialStateProperty.all<Color>(
|
||||
|
@ -14,14 +14,6 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
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({
|
||||
super.key,
|
||||
required this.controller,
|
||||
@ -31,6 +23,14 @@ class MobileDateCellEditScreen extends StatefulWidget {
|
||||
final DateCellController controller;
|
||||
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
|
||||
State<MobileDateCellEditScreen> createState() =>
|
||||
_MobileDateCellEditScreenState();
|
||||
|
@ -9,10 +9,6 @@ import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class MobileNewPropertyScreen extends StatefulWidget {
|
||||
static const routeName = '/new_property';
|
||||
static const argViewId = 'view_id';
|
||||
static const argFieldTypeId = 'field_type_id';
|
||||
|
||||
const MobileNewPropertyScreen({
|
||||
super.key,
|
||||
required this.viewId,
|
||||
@ -22,6 +18,10 @@ class MobileNewPropertyScreen extends StatefulWidget {
|
||||
final String viewId;
|
||||
final FieldType? fieldType;
|
||||
|
||||
static const routeName = '/new_property';
|
||||
static const argViewId = 'view_id';
|
||||
static const argFieldTypeId = 'field_type_id';
|
||||
|
||||
@override
|
||||
State<MobileNewPropertyScreen> createState() =>
|
||||
_MobileNewPropertyScreenState();
|
||||
@ -92,7 +92,6 @@ class _SaveButton extends StatelessWidget {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(right: 16.0),
|
||||
child: Align(
|
||||
alignment: Alignment.center,
|
||||
child: GestureDetector(
|
||||
onTap: onSave,
|
||||
child: FlowyText.medium(
|
||||
|
@ -12,10 +12,6 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class MobileEditPropertyScreen extends StatefulWidget {
|
||||
static const routeName = '/edit_property';
|
||||
static const argViewId = 'view_id';
|
||||
static const argField = 'field';
|
||||
|
||||
const MobileEditPropertyScreen({
|
||||
super.key,
|
||||
required this.viewId,
|
||||
@ -25,6 +21,10 @@ class MobileEditPropertyScreen extends StatefulWidget {
|
||||
final String viewId;
|
||||
final FieldInfo field;
|
||||
|
||||
static const routeName = '/edit_property';
|
||||
static const argViewId = 'view_id';
|
||||
static const argField = 'field';
|
||||
|
||||
@override
|
||||
State<MobileEditPropertyScreen> createState() =>
|
||||
_MobileEditPropertyScreenState();
|
||||
|
@ -72,7 +72,6 @@ class _FieldHeader extends StatelessWidget {
|
||||
return SizedBox(
|
||||
height: 56,
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
SizedBox(
|
||||
|
@ -39,6 +39,31 @@ class FieldOptionValues {
|
||||
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;
|
||||
String name;
|
||||
|
||||
@ -95,33 +120,6 @@ class FieldOptionValues {
|
||||
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 {
|
||||
@ -365,7 +363,6 @@ class _PropertyType extends StatelessWidget {
|
||||
return FlowyOptionTile.text(
|
||||
text: LocaleKeys.grid_field_propertyType.tr(),
|
||||
trailing: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
FlowySvg(
|
||||
type.smallSvgData,
|
||||
@ -542,7 +539,6 @@ class _NumberOption extends StatelessWidget {
|
||||
return FlowyOptionTile.text(
|
||||
text: LocaleKeys.grid_field_numberFormat.tr(),
|
||||
trailing: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
FlowyText(
|
||||
selectedFormat.title(),
|
||||
@ -773,10 +769,6 @@ class __SelectOptionTileState extends State<_SelectOptionTile> {
|
||||
textFieldHintText: LocaleKeys.grid_field_typeANewOption.tr(),
|
||||
showTopBorder: widget.showTopBorder,
|
||||
showBottomBorder: widget.showBottomBorder,
|
||||
textFieldPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 0.0,
|
||||
vertical: 16.0,
|
||||
),
|
||||
trailing: _SelectOptionColor(
|
||||
color: option.color,
|
||||
onChanged: (color) {
|
||||
|
@ -11,15 +11,6 @@ import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
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({
|
||||
super.key,
|
||||
required this.calendarBloc,
|
||||
@ -35,6 +26,15 @@ class MobileCalendarEventsScreen extends StatefulWidget {
|
||||
final RowCache rowCache;
|
||||
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
|
||||
State<MobileCalendarEventsScreen> createState() =>
|
||||
_MobileCalendarEventsScreenState();
|
||||
|
@ -3,10 +3,6 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MobileCalendarScreen extends StatelessWidget {
|
||||
static const routeName = '/calendar';
|
||||
static const viewId = 'id';
|
||||
static const viewTitle = 'title';
|
||||
|
||||
const MobileCalendarScreen({
|
||||
super.key,
|
||||
required this.id,
|
||||
@ -17,6 +13,10 @@ class MobileCalendarScreen extends StatelessWidget {
|
||||
final String id;
|
||||
final String? title;
|
||||
|
||||
static const routeName = '/calendar';
|
||||
static const viewId = 'id';
|
||||
static const viewTitle = 'title';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MobileViewPage(
|
||||
|
@ -4,11 +4,6 @@ import 'package:appflowy/mobile/presentation/base/mobile_view_page.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
|
||||
class MobileGridScreen extends StatelessWidget {
|
||||
static const routeName = '/grid';
|
||||
static const viewId = 'id';
|
||||
static const viewTitle = 'title';
|
||||
static const viewArgs = 'arguments';
|
||||
|
||||
const MobileGridScreen({
|
||||
super.key,
|
||||
required this.id,
|
||||
@ -21,6 +16,11 @@ class MobileGridScreen extends StatelessWidget {
|
||||
final String? title;
|
||||
final Map<String, dynamic>? arguments;
|
||||
|
||||
static const routeName = '/grid';
|
||||
static const viewId = 'id';
|
||||
static const viewTitle = 'title';
|
||||
static const viewArgs = 'arguments';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MobileViewPage(
|
||||
|
@ -74,13 +74,10 @@ class _MobileDatabaseFieldListHeader extends StatelessWidget {
|
||||
FlowySvgs.arrow_left_m,
|
||||
size: Size.square(iconWidth),
|
||||
),
|
||||
width: iconWidth,
|
||||
iconPadding: EdgeInsets.zero,
|
||||
onPressed: () => Navigator.of(context).maybePop(),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.center,
|
||||
child: FlowyText.medium(
|
||||
LocaleKeys.grid_settings_properties.tr(),
|
||||
fontSize: 16,
|
||||
@ -160,7 +157,6 @@ class _MobileDatabaseFieldListBody extends StatelessWidget {
|
||||
},
|
||||
);
|
||||
},
|
||||
buildDefaultDragHandles: true,
|
||||
shrinkWrap: true,
|
||||
onReorder: (from, to) {
|
||||
from++;
|
||||
|
@ -67,13 +67,10 @@ class _Header extends StatelessWidget {
|
||||
FlowySvgs.close_s,
|
||||
size: Size.square(iconWidth),
|
||||
),
|
||||
width: iconWidth,
|
||||
iconPadding: EdgeInsets.zero,
|
||||
onPressed: () => context.pop(),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.center,
|
||||
child: FlowyText.medium(
|
||||
LocaleKeys.grid_settings_viewList.tr(),
|
||||
fontSize: 16,
|
||||
|
@ -127,13 +127,10 @@ class _EditDatabaseViewHeader extends StatelessWidget {
|
||||
FlowySvgs.close_s,
|
||||
size: Size.square(iconWidth),
|
||||
),
|
||||
width: iconWidth,
|
||||
iconPadding: EdgeInsets.zero,
|
||||
onPressed: () => context.pop(),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.center,
|
||||
child: FlowyText.medium(
|
||||
LocaleKeys.grid_settings_editView.tr(),
|
||||
fontSize: 16,
|
||||
|
@ -3,10 +3,6 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MobileEditorScreen extends StatelessWidget {
|
||||
static const routeName = '/docs';
|
||||
static const viewId = 'id';
|
||||
static const viewTitle = 'title';
|
||||
|
||||
const MobileEditorScreen({
|
||||
super.key,
|
||||
required this.id,
|
||||
@ -17,6 +13,10 @@ class MobileEditorScreen extends StatelessWidget {
|
||||
final String id;
|
||||
final String? title;
|
||||
|
||||
static const routeName = '/docs';
|
||||
static const viewId = 'id';
|
||||
static const viewTitle = 'title';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MobileViewPage(
|
||||
|
@ -27,7 +27,6 @@ class _MobileFavoriteFolderHeaderState
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: FlowyButton(
|
||||
|
@ -34,7 +34,6 @@ class MobileHomePageHeader extends StatelessWidget {
|
||||
const HSpace(12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const FlowyText.medium('AppFlowy', fontSize: 18),
|
||||
|
@ -28,7 +28,7 @@ class _MobileHomeSettingPageState extends State<MobileHomeSettingPage> {
|
||||
Widget build(BuildContext context) {
|
||||
return FutureBuilder(
|
||||
future: getIt<AuthService>().getUser(),
|
||||
builder: ((context, snapshot) {
|
||||
builder: (context, snapshot) {
|
||||
String? errorMsg;
|
||||
if (!snapshot.hasData) {
|
||||
return const Center(child: CircularProgressIndicator.adaptive());
|
||||
@ -49,7 +49,7 @@ class _MobileHomeSettingPageState extends State<MobileHomeSettingPage> {
|
||||
? _buildErrorWidget(errorMsg)
|
||||
: _buildSettingsWidget(userProfile),
|
||||
);
|
||||
}),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,6 @@ class MobileHomeTrashPage extends StatelessWidget {
|
||||
Expanded(
|
||||
child: _TrashActionAllButton(
|
||||
trashBloc: trashBloc,
|
||||
type: _TrashActionType.deleteAll,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
|
@ -47,7 +47,6 @@ class MobilePersonalFolder extends StatelessWidget {
|
||||
key: ValueKey(
|
||||
'${FolderCategoryType.personal.name} ${view.id}',
|
||||
),
|
||||
isDraggable: true,
|
||||
categoryType: FolderCategoryType.personal,
|
||||
isFirstChild: view.id == views.first.id,
|
||||
view: view,
|
||||
|
@ -31,7 +31,6 @@ class _MobilePersonalFolderHeaderState
|
||||
Widget build(BuildContext context) {
|
||||
const iconSize = 32.0;
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: FlowyButton(
|
||||
|
@ -142,7 +142,7 @@ class _MobileRecentViewState extends State<MobileRecentView> {
|
||||
Widget _buildCoverWidget() {
|
||||
return FutureBuilder<Node?>(
|
||||
future: _getPageNode(),
|
||||
builder: ((context, snapshot) {
|
||||
builder: (context, snapshot) {
|
||||
final node = snapshot.data;
|
||||
final placeholder = Container(
|
||||
// random color, update it once we have a better placeholder
|
||||
@ -189,7 +189,7 @@ class _MobileRecentViewState extends State<MobileRecentView> {
|
||||
case CoverType.none:
|
||||
return placeholder;
|
||||
}
|
||||
}),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -323,7 +323,6 @@ class _SingleMobileInnerViewItemState extends State<SingleMobileInnerViewItem> {
|
||||
|
||||
Widget child = InkWell(
|
||||
borderRadius: BorderRadius.circular(4.0),
|
||||
enableFeedback: true,
|
||||
onTap: () => widget.onSelected(widget.view),
|
||||
child: SizedBox(
|
||||
height: _itemHeight,
|
||||
|
@ -39,7 +39,6 @@ class AboutSettingGroup extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
],
|
||||
showDivider: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -12,11 +12,9 @@ import 'package:google_fonts/google_fonts.dart';
|
||||
final List<String> _availableFonts = GoogleFonts.asMap().keys.toList();
|
||||
|
||||
class FontPickerScreen extends StatelessWidget {
|
||||
static const routeName = '/font_picker';
|
||||
const FontPickerScreen({super.key});
|
||||
|
||||
const FontPickerScreen({
|
||||
super.key,
|
||||
});
|
||||
static const routeName = '/font_picker';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -7,16 +7,12 @@ import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class LanguagePickerScreen extends StatelessWidget {
|
||||
const LanguagePickerScreen({super.key});
|
||||
|
||||
static const routeName = '/language_picker';
|
||||
|
||||
const LanguagePickerScreen({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const LanguagePickerPage();
|
||||
}
|
||||
Widget build(BuildContext context) => const LanguagePickerPage();
|
||||
}
|
||||
|
||||
class LanguagePickerPage extends StatefulWidget {
|
||||
|
@ -30,7 +30,7 @@ class UserSessionSettingGroup extends StatelessWidget {
|
||||
() => null,
|
||||
(result) => result.fold(
|
||||
(l) {},
|
||||
(r) async => await runAppFlowy(),
|
||||
(r) async => runAppFlowy(),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
@ -45,7 +45,6 @@ class FlowyMobileStateContainer extends StatelessWidget {
|
||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 32),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
emoji ??
|
||||
|
@ -47,7 +47,6 @@ class FlowyOptionTile extends StatelessWidget {
|
||||
type: FlowyOptionTileType.text,
|
||||
text: text,
|
||||
textColor: textColor,
|
||||
controller: null,
|
||||
onTap: onTap,
|
||||
showTopBorder: showTopBorder,
|
||||
showBottomBorder: showBottomBorder,
|
||||
@ -61,7 +60,6 @@ class FlowyOptionTile extends StatelessWidget {
|
||||
void Function(String value)? onTextChanged,
|
||||
void Function(String value)? onTextSubmitted,
|
||||
EdgeInsets textFieldPadding = const EdgeInsets.symmetric(
|
||||
horizontal: 0.0,
|
||||
vertical: 16.0,
|
||||
),
|
||||
bool showTopBorder = true,
|
||||
@ -75,8 +73,6 @@ class FlowyOptionTile extends StatelessWidget {
|
||||
type: FlowyOptionTileType.textField,
|
||||
controller: controller,
|
||||
textFieldPadding: textFieldPadding,
|
||||
text: null,
|
||||
onTap: null,
|
||||
showTopBorder: showTopBorder,
|
||||
showBottomBorder: showBottomBorder,
|
||||
leading: leftIcon,
|
||||
@ -126,7 +122,6 @@ class FlowyOptionTile extends StatelessWidget {
|
||||
return FlowyOptionTile._(
|
||||
type: FlowyOptionTileType.toggle,
|
||||
text: text,
|
||||
controller: null,
|
||||
onTap: onTap ?? () => onValueChanged(!isSelected),
|
||||
onValueChanged: onValueChanged,
|
||||
showTopBorder: showTopBorder,
|
||||
@ -172,7 +167,6 @@ class FlowyOptionTile extends StatelessWidget {
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
if (leadingWidget != null) leadingWidget,
|
||||
_buildText(),
|
||||
|
@ -44,7 +44,6 @@ class FlowyMobileColorPicker extends StatelessWidget {
|
||||
),
|
||||
leftIcon: _ColorIcon(
|
||||
color: color.color,
|
||||
size: 24.0,
|
||||
),
|
||||
leftIconSize: const Size.square(36.0),
|
||||
iconPadding: 12.0,
|
||||
@ -65,18 +64,14 @@ class FlowyMobileColorPicker extends StatelessWidget {
|
||||
}
|
||||
|
||||
class _ColorIcon extends StatelessWidget {
|
||||
const _ColorIcon({
|
||||
this.size = 24.0,
|
||||
required this.color,
|
||||
});
|
||||
const _ColorIcon({required this.color});
|
||||
|
||||
final double size;
|
||||
final Color color;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox.square(
|
||||
dimension: size,
|
||||
dimension: 24,
|
||||
child: DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
color: color,
|
||||
|
@ -7,16 +7,13 @@ import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class MobileColorPickerScreen extends StatelessWidget {
|
||||
static const routeName = '/color_picker';
|
||||
static const pageTitle = 'title';
|
||||
|
||||
const MobileColorPickerScreen({
|
||||
super.key,
|
||||
this.title,
|
||||
});
|
||||
const MobileColorPickerScreen({super.key, this.title});
|
||||
|
||||
final String? title;
|
||||
|
||||
static const routeName = '/color_picker';
|
||||
static const pageTitle = 'title';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
|
@ -71,7 +71,6 @@ class _FlowyEmojiPickerState extends State<FlowyEmojiPicker> {
|
||||
return EmojiPicker(
|
||||
emojiData: emojiData!,
|
||||
configuration: EmojiPickerConfiguration(
|
||||
showSectionHeader: true,
|
||||
showTabs: false,
|
||||
defaultSkinTone: lastSelectedEmojiSkinTone ?? EmojiSkinTone.none,
|
||||
perLine: widget.emojiPerLine,
|
||||
|
@ -4,16 +4,13 @@ import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class MobileEmojiPickerScreen extends StatelessWidget {
|
||||
static const routeName = '/emoji_picker';
|
||||
static const pageTitle = 'title';
|
||||
|
||||
const MobileEmojiPickerScreen({
|
||||
super.key,
|
||||
this.title,
|
||||
});
|
||||
const MobileEmojiPickerScreen({super.key, this.title});
|
||||
|
||||
final String? title;
|
||||
|
||||
static const routeName = '/emoji_picker';
|
||||
static const pageTitle = 'title';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return IconPickerPage(
|
||||
|
@ -67,9 +67,9 @@ class _BlankPageState extends State<BlankPage> {
|
||||
return SizedBox.expand(
|
||||
child: Container(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: Container(),
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(10),
|
||||
child: SizedBox.shrink(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -7,11 +7,11 @@ import 'cell_controller.dart';
|
||||
/// Read https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/architecture/frontend/grid
|
||||
/// for more information
|
||||
class CellMemCache {
|
||||
CellMemCache();
|
||||
|
||||
/// fieldId: {rowId: cellData}
|
||||
final Map<String, Map<RowId, dynamic>> _cellByFieldId = {};
|
||||
|
||||
CellMemCache();
|
||||
|
||||
void removeCellWithFieldId(String fieldId) {
|
||||
_cellByFieldId.remove(fieldId);
|
||||
}
|
||||
|
@ -38,9 +38,27 @@ class CellContext with _$CellContext {
|
||||
/// T represents the type of the cell data.
|
||||
/// D represents the type of data that will be saved to the disk.
|
||||
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 CellContext _cellContext;
|
||||
final FieldController _fieldController;
|
||||
final CellContext _cellContext;
|
||||
final RowCache _rowCache;
|
||||
final CellDataLoader<T> _cellDataLoader;
|
||||
final CellDataPersistence<D> _cellDataPersistence;
|
||||
@ -64,24 +82,6 @@ class CellController<T, D> {
|
||||
String? get icon => rowMeta?.icon;
|
||||
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
|
||||
CellController<A, B> as<A, B>() => this as CellController<A, B>;
|
||||
|
||||
@ -233,9 +233,10 @@ class CellController<T, D> {
|
||||
}
|
||||
|
||||
class CellDataNotifier<T> extends ChangeNotifier {
|
||||
CellDataNotifier({required T value, this.listenWhen}) : _value = value;
|
||||
|
||||
T _value;
|
||||
bool Function(T? oldValue, T? newValue)? listenWhen;
|
||||
CellDataNotifier({required T value, this.listenWhen}) : _value = value;
|
||||
|
||||
set value(T newValue) {
|
||||
if (listenWhen?.call(_value, newValue) ?? false) {
|
||||
|
@ -16,16 +16,16 @@ abstract class CellDataParser<T> {
|
||||
}
|
||||
|
||||
class CellDataLoader<T> {
|
||||
final CellDataParser<T> parser;
|
||||
|
||||
/// Reload the cell data if the field is changed.
|
||||
final bool reloadOnFieldChange;
|
||||
|
||||
CellDataLoader({
|
||||
required this.parser,
|
||||
this.reloadOnFieldChange = false,
|
||||
});
|
||||
|
||||
final CellDataParser<T> parser;
|
||||
|
||||
/// Reload the cell data if the field is changed.
|
||||
final bool reloadOnFieldChange;
|
||||
|
||||
Future<T?> loadData({
|
||||
required String viewId,
|
||||
required CellContext cellContext,
|
||||
|
@ -12,12 +12,14 @@ import '../row/row_service.dart';
|
||||
typedef UpdateFieldNotifiedValue = Either<Unit, FlowyError>;
|
||||
|
||||
class CellListener {
|
||||
CellListener({required this.rowId, required this.fieldId});
|
||||
|
||||
final RowId rowId;
|
||||
final String fieldId;
|
||||
|
||||
PublishNotifier<UpdateFieldNotifiedValue>? _updateCellNotifier =
|
||||
PublishNotifier();
|
||||
DatabaseNotificationListener? _listener;
|
||||
CellListener({required this.rowId, required this.fieldId});
|
||||
|
||||
void start({required void Function(UpdateFieldNotifiedValue) onCellChanged}) {
|
||||
_updateCellNotifier?.addPublishListener(onCellChanged);
|
||||
|
@ -6,16 +6,16 @@ import 'package:dartz/dartz.dart';
|
||||
import 'package:protobuf/protobuf.dart';
|
||||
|
||||
class ChecklistCellBackendService {
|
||||
final String viewId;
|
||||
final String fieldId;
|
||||
final String rowId;
|
||||
|
||||
ChecklistCellBackendService({
|
||||
required this.viewId,
|
||||
required this.fieldId,
|
||||
required this.rowId,
|
||||
});
|
||||
|
||||
final String viewId;
|
||||
final String fieldId;
|
||||
final String rowId;
|
||||
|
||||
Future<Either<Unit, FlowyError>> create({
|
||||
required String name,
|
||||
}) {
|
||||
|
@ -6,8 +6,6 @@ import 'package:dartz/dartz.dart';
|
||||
import 'package:fixnum/fixnum.dart';
|
||||
|
||||
final class DateCellBackendService {
|
||||
final CellIdPB cellId;
|
||||
|
||||
DateCellBackendService({
|
||||
required String viewId,
|
||||
required String fieldId,
|
||||
@ -17,6 +15,8 @@ final class DateCellBackendService {
|
||||
..fieldId = fieldId
|
||||
..rowId = rowId;
|
||||
|
||||
final CellIdPB cellId;
|
||||
|
||||
Future<Either<Unit, FlowyError>> update({
|
||||
required bool includeTime,
|
||||
required bool isRange,
|
||||
|
@ -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';
|
||||
|
||||
class SelectOptionCellBackendService {
|
||||
final String viewId;
|
||||
final String fieldId;
|
||||
final String rowId;
|
||||
|
||||
SelectOptionCellBackendService({
|
||||
required this.viewId,
|
||||
required this.fieldId,
|
||||
required this.rowId,
|
||||
});
|
||||
|
||||
final String viewId;
|
||||
final String fieldId;
|
||||
final String rowId;
|
||||
|
||||
Future<Either<Unit, FlowyError>> create({
|
||||
required String name,
|
||||
bool isSelected = true,
|
||||
|
@ -29,12 +29,6 @@ typedef OnDeleteGroup = void Function(List<String>);
|
||||
typedef OnInsertGroup = void Function(InsertedGroupPB);
|
||||
|
||||
class GroupCallbacks {
|
||||
final OnGroupConfigurationChanged? onGroupConfigurationChanged;
|
||||
final OnGroupByField? onGroupByField;
|
||||
final OnUpdateGroup? onUpdateGroup;
|
||||
final OnDeleteGroup? onDeleteGroup;
|
||||
final OnInsertGroup? onInsertGroup;
|
||||
|
||||
GroupCallbacks({
|
||||
this.onGroupConfigurationChanged,
|
||||
this.onGroupByField,
|
||||
@ -42,26 +36,21 @@ class GroupCallbacks {
|
||||
this.onDeleteGroup,
|
||||
this.onInsertGroup,
|
||||
});
|
||||
|
||||
final OnGroupConfigurationChanged? onGroupConfigurationChanged;
|
||||
final OnGroupByField? onGroupByField;
|
||||
final OnUpdateGroup? onUpdateGroup;
|
||||
final OnDeleteGroup? onDeleteGroup;
|
||||
final OnInsertGroup? onInsertGroup;
|
||||
}
|
||||
|
||||
class DatabaseLayoutSettingCallbacks {
|
||||
final void Function(DatabaseLayoutSettingPB) onLayoutSettingsChanged;
|
||||
DatabaseLayoutSettingCallbacks({required this.onLayoutSettingsChanged});
|
||||
|
||||
DatabaseLayoutSettingCallbacks({
|
||||
required this.onLayoutSettingsChanged,
|
||||
});
|
||||
final void Function(DatabaseLayoutSettingPB) onLayoutSettingsChanged;
|
||||
}
|
||||
|
||||
class DatabaseCallbacks {
|
||||
OnDatabaseChanged? onDatabaseChanged;
|
||||
OnFieldsChanged? onFieldsChanged;
|
||||
OnFiltersChanged? onFiltersChanged;
|
||||
OnSortsChanged? onSortsChanged;
|
||||
OnNumOfRowsChanged? onNumOfRowsChanged;
|
||||
OnRowsDeleted? onRowsDeleted;
|
||||
OnRowsUpdated? onRowsUpdated;
|
||||
OnRowsCreated? onRowsCreated;
|
||||
|
||||
DatabaseCallbacks({
|
||||
this.onDatabaseChanged,
|
||||
this.onNumOfRowsChanged,
|
||||
@ -72,9 +61,36 @@ class DatabaseCallbacks {
|
||||
this.onRowsDeleted,
|
||||
this.onRowsCreated,
|
||||
});
|
||||
|
||||
OnDatabaseChanged? onDatabaseChanged;
|
||||
OnFieldsChanged? onFieldsChanged;
|
||||
OnFiltersChanged? onFiltersChanged;
|
||||
OnSortsChanged? onSortsChanged;
|
||||
OnNumOfRowsChanged? onNumOfRowsChanged;
|
||||
OnRowsDeleted? onRowsDeleted;
|
||||
OnRowsUpdated? onRowsUpdated;
|
||||
OnRowsCreated? onRowsCreated;
|
||||
}
|
||||
|
||||
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 DatabaseViewBackendService _databaseViewBackendSvc;
|
||||
final FieldController fieldController;
|
||||
@ -96,23 +112,6 @@ class DatabaseController {
|
||||
|
||||
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) {
|
||||
_isLoading.value = isLoading;
|
||||
}
|
||||
|
@ -8,10 +8,9 @@ import 'package:dartz/dartz.dart';
|
||||
import 'layout/layout_service.dart';
|
||||
|
||||
class DatabaseViewBackendService {
|
||||
DatabaseViewBackendService({required this.viewId});
|
||||
|
||||
final String viewId;
|
||||
DatabaseViewBackendService({
|
||||
required this.viewId,
|
||||
});
|
||||
|
||||
/// Returns the datbaase id associated with the view.
|
||||
Future<Either<String, FlowyError>> getDatabaseId() async {
|
||||
|
@ -9,32 +9,31 @@ import 'field_info.dart';
|
||||
part 'field_cell_bloc.freezed.dart';
|
||||
|
||||
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;
|
||||
|
||||
FieldCellBloc({required String viewId, required this.fieldInfo})
|
||||
: _fieldSettingsService = FieldSettingsBackendService(
|
||||
viewId: viewId,
|
||||
),
|
||||
super(FieldCellState.initial(fieldInfo)) {
|
||||
void _dispatch() {
|
||||
on<FieldCellEvent>(
|
||||
(event, emit) async {
|
||||
event.when(
|
||||
onFieldChanged: (newFieldInfo) {
|
||||
fieldInfo = newFieldInfo;
|
||||
emit(FieldCellState.initial(newFieldInfo));
|
||||
},
|
||||
onResizeStart: () {
|
||||
emit(state.copyWith(isResizing: true, resizeStart: state.width));
|
||||
},
|
||||
onFieldChanged: (newFieldInfo) =>
|
||||
emit(FieldCellState.initial(newFieldInfo)),
|
||||
onResizeStart: () =>
|
||||
emit(state.copyWith(isResizing: true, resizeStart: state.width)),
|
||||
startUpdateWidth: (offset) {
|
||||
final width = max(offset + state.resizeStart, 50).toDouble();
|
||||
emit(state.copyWith(width: width));
|
||||
},
|
||||
endUpdateWidth: () {
|
||||
if (state.width != fieldInfo.fieldSettings?.width.toDouble()) {
|
||||
if (state.width !=
|
||||
state.fieldInfo.fieldSettings?.width.toDouble()) {
|
||||
_fieldSettingsService.updateFieldSettings(
|
||||
fieldId: fieldInfo.id,
|
||||
fieldId: state.fieldInfo.id,
|
||||
width: state.width,
|
||||
);
|
||||
}
|
||||
@ -58,17 +57,17 @@ class FieldCellEvent with _$FieldCellEvent {
|
||||
|
||||
@freezed
|
||||
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(
|
||||
fieldInfo: fieldInfo,
|
||||
isResizing: false,
|
||||
width: fieldInfo.fieldSettings!.width.toDouble(),
|
||||
resizeStart: 0,
|
||||
);
|
||||
|
||||
const factory FieldCellState({
|
||||
required FieldInfo fieldInfo,
|
||||
required double width,
|
||||
required bool isResizing,
|
||||
required double resizeStart,
|
||||
}) = _FieldCellState;
|
||||
}
|
||||
|
@ -79,6 +79,24 @@ typedef OnReceiveSorts = void Function(List<SortInfo>);
|
||||
typedef OnReceiveFieldSettings = void Function(List<FieldInfo>);
|
||||
|
||||
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;
|
||||
|
||||
// Listeners
|
||||
@ -146,24 +164,6 @@ class FieldController {
|
||||
.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.
|
||||
void _listenOnFilterChanges() {
|
||||
void deleteFilterFromChangeset(
|
||||
@ -402,7 +402,7 @@ class FieldController {
|
||||
for (final fieldOrder in deletedFields) fieldOrder.fieldId: fieldOrder,
|
||||
};
|
||||
|
||||
newFields.retainWhere((field) => (deletedFieldMap[field.id] == null));
|
||||
newFields.retainWhere((field) => deletedFieldMap[field.id] == null);
|
||||
return newFields;
|
||||
}
|
||||
|
||||
@ -784,9 +784,10 @@ class FieldController {
|
||||
}
|
||||
|
||||
class RowCacheDependenciesImpl extends RowFieldsDelegate with RowLifeCycle {
|
||||
RowCacheDependenciesImpl(FieldController cache) : _fieldController = cache;
|
||||
|
||||
final FieldController _fieldController;
|
||||
OnReceiveFields? _onFieldFn;
|
||||
RowCacheDependenciesImpl(FieldController cache) : _fieldController = cache;
|
||||
|
||||
@override
|
||||
UnmodifiableListView<FieldInfo> get fieldInfos =>
|
||||
|
@ -16,14 +16,6 @@ import 'field_service.dart';
|
||||
part 'field_editor_bloc.freezed.dart';
|
||||
|
||||
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({
|
||||
required this.viewId,
|
||||
required this.fieldController,
|
||||
@ -37,6 +29,24 @@ class FieldEditorBloc extends Bloc<FieldEditorEvent, FieldEditorState> {
|
||||
),
|
||||
fieldSettingsService = FieldSettingsBackendService(viewId: viewId),
|
||||
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>(
|
||||
(event, emit) async {
|
||||
await event.when(
|
||||
@ -107,13 +117,6 @@ class FieldEditorBloc extends Bloc<FieldEditorEvent, FieldEditorState> {
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() {
|
||||
_singleFieldListener.stop();
|
||||
|
||||
return super.close();
|
||||
}
|
||||
}
|
||||
|
||||
@freezed
|
||||
|
@ -7,6 +7,14 @@ part 'field_info.freezed.dart';
|
||||
class FieldInfo with _$FieldInfo {
|
||||
const FieldInfo._();
|
||||
|
||||
factory FieldInfo.initial(FieldPB field) => FieldInfo(
|
||||
field: field,
|
||||
fieldSettings: null,
|
||||
hasFilter: false,
|
||||
hasSort: false,
|
||||
isGroupField: false,
|
||||
);
|
||||
|
||||
const factory FieldInfo({
|
||||
required FieldPB field,
|
||||
required FieldSettingsPB? fieldSettings,
|
||||
@ -25,14 +33,6 @@ class FieldInfo with _$FieldInfo {
|
||||
|
||||
FieldVisibility? get visibility => fieldSettings?.visibility;
|
||||
|
||||
factory FieldInfo.initial(FieldPB field) => FieldInfo(
|
||||
field: field,
|
||||
fieldSettings: null,
|
||||
hasFilter: false,
|
||||
hasSort: false,
|
||||
isGroupField: false,
|
||||
);
|
||||
|
||||
bool get canBeGroup {
|
||||
switch (field.fieldType) {
|
||||
case FieldType.URL:
|
||||
|
@ -11,12 +11,13 @@ import 'package:flowy_infra/notifier.dart';
|
||||
typedef UpdateFieldNotifiedValue = FieldPB;
|
||||
|
||||
class SingleFieldListener {
|
||||
SingleFieldListener({required this.fieldId});
|
||||
|
||||
final String fieldId;
|
||||
|
||||
void Function(UpdateFieldNotifiedValue)? _updateFieldNotifier;
|
||||
DatabaseNotificationListener? _listener;
|
||||
|
||||
SingleFieldListener({required this.fieldId});
|
||||
|
||||
void start({
|
||||
required void Function(UpdateFieldNotifiedValue) onFieldChanged,
|
||||
}) {
|
||||
@ -53,11 +54,13 @@ typedef UpdateFieldsNotifiedValue
|
||||
= Either<DatabaseFieldChangesetPB, FlowyError>;
|
||||
|
||||
class FieldsListener {
|
||||
FieldsListener({required this.viewId});
|
||||
|
||||
final String viewId;
|
||||
|
||||
PublishNotifier<UpdateFieldsNotifiedValue>? updateFieldsNotifier =
|
||||
PublishNotifier();
|
||||
DatabaseNotificationListener? _listener;
|
||||
FieldsListener({required this.viewId});
|
||||
|
||||
void start({
|
||||
required void Function(UpdateFieldsNotifiedValue) onFieldsChanged,
|
||||
|
@ -9,11 +9,11 @@ import 'package:dartz/dartz.dart';
|
||||
/// `rust-lib/flowy-database/event_map.rs` for a list of events and their
|
||||
/// implementations.
|
||||
class FieldBackendService {
|
||||
FieldBackendService({required this.viewId, required this.fieldId});
|
||||
|
||||
final String viewId;
|
||||
final String fieldId;
|
||||
|
||||
FieldBackendService({required this.viewId, required this.fieldId});
|
||||
|
||||
/// 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
|
||||
static Future<Either<FieldPB, FlowyError>> createField({
|
||||
@ -167,19 +167,16 @@ class FieldBackendService {
|
||||
|
||||
Future<Either<Unit, FlowyError>> updateType({
|
||||
required FieldType fieldType,
|
||||
}) {
|
||||
return updateFieldType(
|
||||
viewId: viewId,
|
||||
fieldId: fieldId,
|
||||
fieldType: fieldType,
|
||||
);
|
||||
}
|
||||
}) =>
|
||||
updateFieldType(
|
||||
viewId: viewId,
|
||||
fieldId: fieldId,
|
||||
fieldType: fieldType,
|
||||
);
|
||||
|
||||
Future<Either<Unit, FlowyError>> delete() {
|
||||
return deleteField(viewId: viewId, fieldId: fieldId);
|
||||
}
|
||||
Future<Either<Unit, FlowyError>> delete() =>
|
||||
deleteField(viewId: viewId, fieldId: fieldId);
|
||||
|
||||
Future<Either<Unit, FlowyError>> duplicate() {
|
||||
return duplicateField(viewId: viewId, fieldId: fieldId);
|
||||
}
|
||||
Future<Either<Unit, FlowyError>> duplicate() =>
|
||||
duplicateField(viewId: viewId, fieldId: fieldId);
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
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:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:protobuf/protobuf.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
part 'edit_select_option_bloc.freezed.dart';
|
||||
|
||||
class EditSelectOptionBloc
|
||||
|
@ -8,15 +8,15 @@ import 'select_option_type_option_bloc.dart';
|
||||
import 'type_option_service.dart';
|
||||
|
||||
class MultiSelectAction implements ISelectOptionAction {
|
||||
final TypeOptionBackendService service;
|
||||
final TypeOptionDataCallback onTypeOptionUpdated;
|
||||
|
||||
MultiSelectAction({
|
||||
required this.onTypeOptionUpdated,
|
||||
required String viewId,
|
||||
required String fieldId,
|
||||
}) : service = TypeOptionBackendService(viewId: viewId, fieldId: fieldId);
|
||||
|
||||
final TypeOptionBackendService service;
|
||||
final TypeOptionDataCallback onTypeOptionUpdated;
|
||||
|
||||
@override
|
||||
Future<List<SelectOptionPB>> insertOption(
|
||||
List<SelectOptionPB> options,
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/number_entities.pbenum.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'number_format_bloc.freezed.dart';
|
||||
|
||||
class NumberFormatBloc extends Bloc<NumberFormatEvent, NumberFormatState> {
|
||||
|
@ -1,8 +1,9 @@
|
||||
import 'dart:async';
|
||||
|
||||
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:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
import 'package:dartz/dartz.dart';
|
||||
part 'select_option_type_option_bloc.freezed.dart';
|
||||
|
||||
abstract class ISelectOptionAction {
|
||||
@ -24,12 +25,16 @@ abstract class ISelectOptionAction {
|
||||
|
||||
class SelectOptionTypeOptionBloc
|
||||
extends Bloc<SelectOptionTypeOptionEvent, SelectOptionTypeOptionState> {
|
||||
final ISelectOptionAction typeOptionAction;
|
||||
|
||||
SelectOptionTypeOptionBloc({
|
||||
required List<SelectOptionPB> options,
|
||||
required this.typeOptionAction,
|
||||
}) : super(SelectOptionTypeOptionState.initial(options)) {
|
||||
_dispatch();
|
||||
}
|
||||
|
||||
final ISelectOptionAction typeOptionAction;
|
||||
|
||||
void _dispatch() {
|
||||
on<SelectOptionTypeOptionEvent>(
|
||||
(event, emit) async {
|
||||
await event.when(
|
||||
|
@ -8,15 +8,15 @@ import 'select_option_type_option_bloc.dart';
|
||||
import 'type_option_service.dart';
|
||||
|
||||
class SingleSelectAction implements ISelectOptionAction {
|
||||
final TypeOptionBackendService service;
|
||||
final TypeOptionDataCallback onTypeOptionUpdated;
|
||||
|
||||
SingleSelectAction({
|
||||
required this.onTypeOptionUpdated,
|
||||
required String viewId,
|
||||
required String fieldId,
|
||||
}) : service = TypeOptionBackendService(viewId: viewId, fieldId: fieldId);
|
||||
|
||||
final TypeOptionBackendService service;
|
||||
final TypeOptionDataCallback onTypeOptionUpdated;
|
||||
|
||||
@override
|
||||
Future<List<SelectOptionPB>> insertOption(
|
||||
List<SelectOptionPB> options,
|
||||
|
@ -4,14 +4,14 @@ import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
|
||||
class TypeOptionBackendService {
|
||||
final String viewId;
|
||||
final String fieldId;
|
||||
|
||||
TypeOptionBackendService({
|
||||
required this.viewId,
|
||||
required this.fieldId,
|
||||
});
|
||||
|
||||
final String viewId;
|
||||
final String fieldId;
|
||||
|
||||
Future<Either<SelectOptionPB, FlowyError>> newOption({
|
||||
required String name,
|
||||
}) {
|
||||
|
@ -9,13 +9,14 @@ import 'package:flowy_infra/notifier.dart';
|
||||
typedef FieldSettingsValue = Either<FieldSettingsPB, FlowyError>;
|
||||
|
||||
class FieldSettingsListener {
|
||||
FieldSettingsListener({required this.viewId});
|
||||
|
||||
final String viewId;
|
||||
|
||||
PublishNotifier<FieldSettingsValue>? _fieldSettingsNotifier =
|
||||
PublishNotifier();
|
||||
DatabaseNotificationListener? _listener;
|
||||
|
||||
FieldSettingsListener({required this.viewId});
|
||||
|
||||
void start({
|
||||
required void Function(FieldSettingsValue) onFieldSettingsChanged,
|
||||
}) {
|
||||
|
@ -12,12 +12,13 @@ typedef UpdateFilterNotifiedValue
|
||||
= Either<FilterChangesetNotificationPB, FlowyError>;
|
||||
|
||||
class FiltersListener {
|
||||
FiltersListener({required this.viewId});
|
||||
|
||||
final String viewId;
|
||||
|
||||
PublishNotifier<UpdateFilterNotifiedValue>? _filterNotifier =
|
||||
PublishNotifier();
|
||||
DatabaseNotificationListener? _listener;
|
||||
FiltersListener({required this.viewId});
|
||||
|
||||
void start({
|
||||
required void Function(UpdateFilterNotifiedValue) onFilterChanged,
|
||||
@ -54,6 +55,8 @@ class FiltersListener {
|
||||
}
|
||||
|
||||
class FilterListener {
|
||||
FilterListener({required this.viewId, required this.filterId});
|
||||
|
||||
final String viewId;
|
||||
final String filterId;
|
||||
|
||||
@ -61,7 +64,6 @@ class FilterListener {
|
||||
PublishNotifier<FilterPB>? _onUpdateNotifier = PublishNotifier();
|
||||
|
||||
DatabaseNotificationListener? _listener;
|
||||
FilterListener({required this.viewId, required this.filterId});
|
||||
|
||||
void start({
|
||||
void Function()? onDeleted,
|
||||
|
@ -15,9 +15,10 @@ import 'package:appflowy_backend/protobuf/flowy-database2/util.pb.dart';
|
||||
import 'package:fixnum/fixnum.dart' as $fixnum;
|
||||
|
||||
class FilterBackendService {
|
||||
final String viewId;
|
||||
const FilterBackendService({required this.viewId});
|
||||
|
||||
final String viewId;
|
||||
|
||||
Future<Either<List<FilterPB>, FlowyError>> getAllFilters() {
|
||||
final payload = DatabaseViewIdPB()..value = viewId;
|
||||
|
||||
|
@ -14,12 +14,14 @@ typedef GroupUpdateValue = Either<GroupChangesPB, FlowyError>;
|
||||
typedef GroupByNewFieldValue = Either<List<GroupPB>, FlowyError>;
|
||||
|
||||
class DatabaseGroupListener {
|
||||
DatabaseGroupListener(this.viewId);
|
||||
|
||||
final String viewId;
|
||||
|
||||
PublishNotifier<GroupUpdateValue>? _numOfGroupsNotifier = PublishNotifier();
|
||||
PublishNotifier<GroupByNewFieldValue>? _groupByFieldNotifier =
|
||||
PublishNotifier();
|
||||
DatabaseNotificationListener? _listener;
|
||||
DatabaseGroupListener(this.viewId);
|
||||
|
||||
void start({
|
||||
required void Function(GroupUpdateValue) onNumOfGroupsChanged,
|
||||
|
@ -4,10 +4,10 @@ import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
|
||||
class GroupBackendService {
|
||||
final String viewId;
|
||||
|
||||
GroupBackendService(this.viewId);
|
||||
|
||||
final String viewId;
|
||||
|
||||
Future<Either<Unit, FlowyError>> groupByField({
|
||||
required String fieldId,
|
||||
}) {
|
||||
|
@ -8,11 +8,13 @@ import 'package:dartz/dartz.dart';
|
||||
|
||||
/// Listener for database layout changes.
|
||||
class DatabaseLayoutListener {
|
||||
DatabaseLayoutListener(this.viewId);
|
||||
|
||||
final String viewId;
|
||||
|
||||
PublishNotifier<Either<DatabaseLayoutPB, FlowyError>>? _layoutNotifier =
|
||||
PublishNotifier();
|
||||
DatabaseNotificationListener? _listener;
|
||||
DatabaseLayoutListener(this.viewId);
|
||||
|
||||
void start({
|
||||
required void Function(Either<DatabaseLayoutPB, FlowyError>)
|
||||
|
@ -9,11 +9,13 @@ import 'package:dartz/dartz.dart';
|
||||
typedef LayoutSettingsValue<T> = Either<T, FlowyError>;
|
||||
|
||||
class DatabaseLayoutSettingListener {
|
||||
DatabaseLayoutSettingListener(this.viewId);
|
||||
|
||||
final String viewId;
|
||||
|
||||
PublishNotifier<LayoutSettingsValue<DatabaseLayoutSettingPB>>?
|
||||
_settingNotifier = PublishNotifier();
|
||||
DatabaseNotificationListener? _listener;
|
||||
DatabaseLayoutSettingListener(this.viewId);
|
||||
|
||||
void start({
|
||||
required void Function(LayoutSettingsValue<DatabaseLayoutSettingPB>)
|
||||
|
@ -11,17 +11,30 @@ import 'row_meta_listener.dart';
|
||||
part 'row_banner_bloc.freezed.dart';
|
||||
|
||||
class RowBannerBloc extends Bloc<RowBannerEvent, RowBannerState> {
|
||||
final String viewId;
|
||||
final RowBackendService _rowBackendSvc;
|
||||
final RowMetaListener _metaListener;
|
||||
SingleFieldListener? _fieldListener;
|
||||
|
||||
RowBannerBloc({
|
||||
required this.viewId,
|
||||
required RowMetaPB rowMeta,
|
||||
}) : _rowBackendSvc = RowBackendService(viewId: viewId),
|
||||
_metaListener = RowMetaListener(rowMeta.id),
|
||||
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>(
|
||||
(event, emit) {
|
||||
event.when(
|
||||
@ -32,12 +45,8 @@ class RowBannerBloc extends Bloc<RowBannerEvent, RowBannerState> {
|
||||
didReceiveRowMeta: (RowMetaPB rowMeta) {
|
||||
emit(state.copyWith(rowMeta: rowMeta));
|
||||
},
|
||||
setCover: (String coverURL) {
|
||||
_updateMeta(coverURL: coverURL);
|
||||
},
|
||||
setIcon: (String iconURL) {
|
||||
_updateMeta(iconURL: iconURL);
|
||||
},
|
||||
setCover: (String coverURL) => _updateMeta(coverURL: coverURL),
|
||||
setIcon: (String iconURL) => _updateMeta(iconURL: iconURL),
|
||||
didReceiveFieldUpdate: (updatedField) {
|
||||
emit(
|
||||
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 {
|
||||
final fieldOrError =
|
||||
await FieldBackendService.getPrimaryField(viewId: viewId);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user