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
- 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

View File

@ -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();

View File

@ -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);

View File

@ -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();

View File

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

View File

@ -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

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/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,
);

View File

@ -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);

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/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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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(

View File

@ -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);

View File

@ -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 {

View File

@ -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 {

View File

@ -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();

View File

@ -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);

View File

@ -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);

View File

@ -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(

View File

@ -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();

View File

@ -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 {

View File

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

View File

@ -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

View File

@ -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);

View File

@ -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();

View File

@ -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();

View File

@ -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) {

View File

@ -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();

View File

@ -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() {

View File

@ -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 {

View File

@ -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,

View File

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

View File

@ -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(

View File

@ -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(

View File

@ -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(

View File

@ -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

View File

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

View File

@ -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>(

View File

@ -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();

View File

@ -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(

View File

@ -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();

View File

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

View File

@ -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) {

View File

@ -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();

View File

@ -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(

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';
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(

View File

@ -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++;

View File

@ -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,

View File

@ -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,

View File

@ -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(

View File

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

View File

@ -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),

View File

@ -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),
);
}),
},
);
}

View File

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

View File

@ -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,

View File

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

View File

@ -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;
}
}),
},
);
}

View File

@ -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,

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();
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) {

View File

@ -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 {

View File

@ -30,7 +30,7 @@ class UserSessionSettingGroup extends StatelessWidget {
() => null,
(result) => result.fold(
(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),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
emoji ??

View File

@ -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(),

View File

@ -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,

View File

@ -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(

View File

@ -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,

View File

@ -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(

View File

@ -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(),
),
),
);

View File

@ -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);
}

View File

@ -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) {

View File

@ -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,

View File

@ -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);

View File

@ -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,
}) {

View File

@ -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,

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';
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,

View File

@ -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;
}

View File

@ -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 {

View File

@ -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;
}

View File

@ -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 =>

View File

@ -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

View File

@ -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:

View File

@ -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,

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
/// 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);
}

View File

@ -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

View File

@ -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,

View File

@ -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> {

View File

@ -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(

View File

@ -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,

View File

@ -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,
}) {

View File

@ -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,
}) {

View File

@ -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,

View File

@ -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;

View File

@ -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,

View File

@ -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,
}) {

View File

@ -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>)

View File

@ -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>)

View File

@ -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