chore: lazy load database row (#6001)

* chore: fix potential load database rows fail

* chore: fix layout padding
This commit is contained in:
Nathan.fooo 2024-08-18 18:44:32 +08:00 committed by GitHub
parent fd5299a13d
commit 5878379b2e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 204 additions and 134 deletions

View File

@ -23,9 +23,9 @@ class RelatedRowDetailPageBloc
@override
Future<void> close() {
state.whenOrNull(
ready: (databaseController, rowController) {
rowController.dispose();
databaseController.dispose();
ready: (databaseController, rowController) async {
await rowController.dispose();
await databaseController.dispose();
},
);
return super.close();
@ -36,8 +36,8 @@ class RelatedRowDetailPageBloc
event.when(
didInitialize: (databaseController, rowController) {
state.maybeWhen(
ready: (_, oldRowController) {
oldRowController.dispose();
ready: (_, oldRowController) async {
await oldRowController.dispose();
emit(
RelatedRowDetailPageState.ready(
databaseController: databaseController,

View File

@ -81,6 +81,12 @@ class RowCache {
_changedNotifier.receive(const ChangedReason.setInitialRows());
}
void setRowMeta(RowMetaPB rowMeta) {
final rowInfo = buildGridRow(rowMeta);
_rowList.add(rowInfo);
_changedNotifier.receive(const ChangedReason.didFetchRow());
}
void dispose() {
_rowLifeCycle.onRowDisposed();
_changedNotifier.dispose();
@ -215,7 +221,8 @@ class RowCache {
if (rowInfo == null) {
_loadRow(rowMeta.id);
}
return _makeCells(rowMeta);
final cells = _makeCells(rowMeta);
return cells;
}
Future<void> _loadRow(RowId rowId) async {
@ -277,6 +284,7 @@ class RowChangesetNotifier extends ChangeNotifier {
reorderRows: (_) => notifyListeners(),
reorderSingleRow: (_) => notifyListeners(),
setInitialRows: (_) => notifyListeners(),
didFetchRow: (_) => notifyListeners(),
);
}
}
@ -305,6 +313,7 @@ class ChangedReason with _$ChangedReason {
const factory ChangedReason.update(UpdatedIndexMap indexs) = _Update;
const factory ChangedReason.fieldDidChange() = _FieldDidChange;
const factory ChangedReason.initial() = InitialListState;
const factory ChangedReason.didFetchRow() = _DidFetchRow;
const factory ChangedReason.reorderRows() = _ReorderRows;
const factory ChangedReason.reorderSingleRow(
ReorderSingleRowPB reorderRow,

View File

@ -1,3 +1,5 @@
import 'package:appflowy/plugins/database/application/row/row_service.dart';
import 'package:appflowy/plugins/database/domain/row_listener.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/row_entities.pb.dart';
import 'package:flutter/material.dart';
@ -9,35 +11,60 @@ typedef OnRowChanged = void Function(List<CellContext>, ChangedReason);
class RowController {
RowController({
required this.rowMeta,
required RowMetaPB rowMeta,
required this.viewId,
required RowCache rowCache,
this.groupId,
}) : _rowCache = rowCache;
}) : _rowMeta = rowMeta,
_rowCache = rowCache,
_rowBackendSvc = RowBackendService(viewId: viewId),
_rowListener = RowListener(rowMeta.id) {
_rowBackendSvc.initRow(rowMeta.id);
_rowListener.start(
onMetaChanged: (newRowMeta) {
if (_isDisposed) {
return;
}
_rowMeta = newRowMeta;
_rowCache.setRowMeta(newRowMeta);
},
);
}
final RowMetaPB rowMeta;
RowMetaPB _rowMeta;
final String? groupId;
final String viewId;
final List<VoidCallback> _onRowChangedListeners = [];
final RowCache _rowCache;
final RowListener _rowListener;
final RowBackendService _rowBackendSvc;
bool _isDisposed = false;
CellMemCache get cellCache => _rowCache.cellCache;
String get rowId => rowMeta.id;
RowMetaPB get rowMeta => _rowMeta;
List<CellContext> loadData() => _rowCache.loadCells(rowMeta);
List<CellContext> loadCells() => _rowCache.loadCells(rowMeta);
void addListener({OnRowChanged? onRowChanged}) {
final fn = _rowCache.addListener(
rowId: rowMeta.id,
onRowChanged: onRowChanged,
onRowChanged: (context, reasons) {
if (_isDisposed) {
return;
}
onRowChanged?.call(context, reasons);
},
);
// Add the listener to the list so that we can remove it later.
_onRowChangedListeners.add(fn);
}
void dispose() {
Future<void> dispose() async {
_isDisposed = true;
await _rowListener.stop();
for (final fn in _onRowChangedListeners) {
_rowCache.removeRowListener(fn);
}

View File

@ -34,7 +34,7 @@ class CalendarEventEditorBloc
.firstWhere((fieldInfo) => fieldInfo.isPrimary)
.id;
final cells = rowController
.loadData()
.loadCells()
.where(
(cellContext) =>
_filterCellContext(cellContext, primaryFieldId),
@ -88,7 +88,7 @@ class CalendarEventEditorBloc
@override
Future<void> close() async {
rowController.dispose();
await rowController.dispose();
return super.close();
}
}

View File

@ -23,8 +23,6 @@ class RowBloc extends Bloc<RowEvent, RowState> {
}) : _rowBackendSvc = RowBackendService(viewId: viewId),
_rowController = rowController,
super(RowState.initial()) {
_rowBackendSvc.initRow(rowId);
_dispatch();
_startListening();
_init();
@ -38,7 +36,7 @@ class RowBloc extends Bloc<RowEvent, RowState> {
@override
Future<void> close() async {
_rowController.dispose();
await _rowController.dispose();
return super.close();
}
@ -84,7 +82,7 @@ class RowBloc extends Bloc<RowEvent, RowState> {
void _init() {
add(
RowEvent.didReceiveCells(
_rowController.loadData(),
_rowController.loadCells(),
const ChangedReason.setInitialRows(),
),
);

View File

@ -29,7 +29,7 @@ class RowDetailBloc extends Bloc<RowDetailEvent, RowDetailState> {
@override
Future<void> close() async {
rowController.dispose();
await rowController.dispose();
return super.close();
}
@ -125,7 +125,7 @@ class RowDetailBloc extends Bloc<RowDetailEvent, RowDetailState> {
}
void _init() {
allCells.addAll(rowController.loadData());
allCells.addAll(rowController.loadCells());
int numHiddenFields = 0;
final visibleCells = <CellContext>[];
for (final cell in allCells) {

View File

@ -9,7 +9,6 @@ import 'package:appflowy/workspace/application/action_navigation/navigation_acti
import 'package:appflowy/workspace/application/view/view_bloc.dart';
import 'package:appflowy_backend/log.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:collection/collection.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/scrolling/styled_scrollview.dart';
@ -154,6 +153,7 @@ class _GridPageState extends State<GridPage> {
finish: (result) => result.successOrFail.fold(
(_) => GridShortcuts(
child: GridPageContent(
key: ValueKey(widget.view.id),
view: widget.view,
),
),
@ -331,33 +331,10 @@ class _GridRowsState extends State<_GridRows> {
BuildContext context,
GridState state,
) {
final children = state.rowInfos.mapIndexed((index, rowInfo) {
return _renderRow(
context,
rowInfo.rowId,
isDraggable: state.reorderable,
index: index,
);
}).toList()
..add(const GridRowBottomBar(key: Key('grid_footer')));
if (showFloatingCalculations) {
children.add(
const SizedBox(
key: Key('calculations_bottom_padding'),
height: 36,
),
);
} else {
children.add(
GridCalculationsRow(
key: const Key('grid_calculations'),
viewId: widget.viewId,
),
);
}
children.add(const SizedBox(key: Key('footer_padding'), height: 10));
// 1. GridRowBottomBar
// 2. GridCalculationsRow
// 3. Footer Padding
final itemCount = state.rowInfos.length + 3;
return Stack(
children: [
@ -381,8 +358,37 @@ class _GridRowsState extends State<_GridRows> {
.add(GridEvent.moveRow(fromIndex, toIndex));
}
},
itemCount: children.length,
itemBuilder: (context, index) => children[index],
itemCount: itemCount,
itemBuilder: (context, index) {
if (index < state.rowInfos.length) {
return _renderRow(
context,
state.rowInfos[index].rowId,
isDraggable: state.reorderable,
index: index,
);
}
if (index == state.rowInfos.length) {
return const GridRowBottomBar(key: Key('grid_footer'));
}
if (index == state.rowInfos.length + 1) {
if (showFloatingCalculations) {
return const SizedBox(
key: Key('calculations_bottom_padding'),
height: 36,
);
} else {
return GridCalculationsRow(
key: const Key('grid_calculations'),
viewId: widget.viewId,
);
}
}
return const SizedBox(key: Key('footer_padding'), height: 10);
},
),
),
if (showFloatingCalculations) ...[

View File

@ -81,7 +81,7 @@ class _MobileGridRowState extends State<MobileGridRow> {
@override
Future<void> dispose() async {
_rowController.dispose();
await _rowController.dispose();
super.dispose();
}
}

View File

@ -57,7 +57,7 @@ class _DatabaseViewSettingContent extends StatelessWidget {
builder: (context, state) {
return Padding(
padding: EdgeInsets.symmetric(
horizontal: GridSize.horizontalHeaderPadding,
horizontal: GridSize.horizontalHeaderPadding + 40,
),
child: DecoratedBox(
decoration: BoxDecoration(

View File

@ -963,7 +963,7 @@ dependencies = [
[[package]]
name = "collab"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d03bd474e551ab5583780abe051a85b8063e6aa9#d03bd474e551ab5583780abe051a85b8063e6aa9"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0af7f361d52611842a862b982b2c72e4fa12cda1#0af7f361d52611842a862b982b2c72e4fa12cda1"
dependencies = [
"anyhow",
"arc-swap",
@ -988,7 +988,7 @@ dependencies = [
[[package]]
name = "collab-database"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d03bd474e551ab5583780abe051a85b8063e6aa9#d03bd474e551ab5583780abe051a85b8063e6aa9"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0af7f361d52611842a862b982b2c72e4fa12cda1#0af7f361d52611842a862b982b2c72e4fa12cda1"
dependencies = [
"anyhow",
"async-trait",
@ -1018,7 +1018,7 @@ dependencies = [
[[package]]
name = "collab-document"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d03bd474e551ab5583780abe051a85b8063e6aa9#d03bd474e551ab5583780abe051a85b8063e6aa9"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0af7f361d52611842a862b982b2c72e4fa12cda1#0af7f361d52611842a862b982b2c72e4fa12cda1"
dependencies = [
"anyhow",
"arc-swap",
@ -1038,7 +1038,7 @@ dependencies = [
[[package]]
name = "collab-entity"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d03bd474e551ab5583780abe051a85b8063e6aa9#d03bd474e551ab5583780abe051a85b8063e6aa9"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0af7f361d52611842a862b982b2c72e4fa12cda1#0af7f361d52611842a862b982b2c72e4fa12cda1"
dependencies = [
"anyhow",
"bytes",
@ -1057,7 +1057,7 @@ dependencies = [
[[package]]
name = "collab-folder"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d03bd474e551ab5583780abe051a85b8063e6aa9#d03bd474e551ab5583780abe051a85b8063e6aa9"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0af7f361d52611842a862b982b2c72e4fa12cda1#0af7f361d52611842a862b982b2c72e4fa12cda1"
dependencies = [
"anyhow",
"arc-swap",
@ -1100,7 +1100,7 @@ dependencies = [
[[package]]
name = "collab-plugins"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d03bd474e551ab5583780abe051a85b8063e6aa9#d03bd474e551ab5583780abe051a85b8063e6aa9"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0af7f361d52611842a862b982b2c72e4fa12cda1#0af7f361d52611842a862b982b2c72e4fa12cda1"
dependencies = [
"anyhow",
"async-stream",
@ -1180,7 +1180,7 @@ dependencies = [
[[package]]
name = "collab-user"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d03bd474e551ab5583780abe051a85b8063e6aa9#d03bd474e551ab5583780abe051a85b8063e6aa9"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0af7f361d52611842a862b982b2c72e4fa12cda1#0af7f361d52611842a862b982b2c72e4fa12cda1"
dependencies = [
"anyhow",
"collab",

View File

@ -116,13 +116,13 @@ custom-protocol = ["tauri/custom-protocol"]
# To switch to the local path, run:
# scripts/tool/update_collab_source.sh
# ⚠️⚠️⚠️️
collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d03bd474e551ab5583780abe051a85b8063e6aa9" }
collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d03bd474e551ab5583780abe051a85b8063e6aa9" }
collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d03bd474e551ab5583780abe051a85b8063e6aa9" }
collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d03bd474e551ab5583780abe051a85b8063e6aa9" }
collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d03bd474e551ab5583780abe051a85b8063e6aa9" }
collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d03bd474e551ab5583780abe051a85b8063e6aa9" }
collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d03bd474e551ab5583780abe051a85b8063e6aa9" }
collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0af7f361d52611842a862b982b2c72e4fa12cda1" }
collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0af7f361d52611842a862b982b2c72e4fa12cda1" }
collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0af7f361d52611842a862b982b2c72e4fa12cda1" }
collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0af7f361d52611842a862b982b2c72e4fa12cda1" }
collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0af7f361d52611842a862b982b2c72e4fa12cda1" }
collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0af7f361d52611842a862b982b2c72e4fa12cda1" }
collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0af7f361d52611842a862b982b2c72e4fa12cda1" }
# Working directory: frontend
# To update the commit ID, run:

View File

@ -946,7 +946,7 @@ dependencies = [
[[package]]
name = "collab"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d03bd474e551ab5583780abe051a85b8063e6aa9#d03bd474e551ab5583780abe051a85b8063e6aa9"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0af7f361d52611842a862b982b2c72e4fa12cda1#0af7f361d52611842a862b982b2c72e4fa12cda1"
dependencies = [
"anyhow",
"arc-swap",
@ -971,7 +971,7 @@ dependencies = [
[[package]]
name = "collab-database"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d03bd474e551ab5583780abe051a85b8063e6aa9#d03bd474e551ab5583780abe051a85b8063e6aa9"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0af7f361d52611842a862b982b2c72e4fa12cda1#0af7f361d52611842a862b982b2c72e4fa12cda1"
dependencies = [
"anyhow",
"async-trait",
@ -1001,7 +1001,7 @@ dependencies = [
[[package]]
name = "collab-document"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d03bd474e551ab5583780abe051a85b8063e6aa9#d03bd474e551ab5583780abe051a85b8063e6aa9"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0af7f361d52611842a862b982b2c72e4fa12cda1#0af7f361d52611842a862b982b2c72e4fa12cda1"
dependencies = [
"anyhow",
"arc-swap",
@ -1021,7 +1021,7 @@ dependencies = [
[[package]]
name = "collab-entity"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d03bd474e551ab5583780abe051a85b8063e6aa9#d03bd474e551ab5583780abe051a85b8063e6aa9"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0af7f361d52611842a862b982b2c72e4fa12cda1#0af7f361d52611842a862b982b2c72e4fa12cda1"
dependencies = [
"anyhow",
"bytes",
@ -1040,7 +1040,7 @@ dependencies = [
[[package]]
name = "collab-folder"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d03bd474e551ab5583780abe051a85b8063e6aa9#d03bd474e551ab5583780abe051a85b8063e6aa9"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0af7f361d52611842a862b982b2c72e4fa12cda1#0af7f361d52611842a862b982b2c72e4fa12cda1"
dependencies = [
"anyhow",
"arc-swap",
@ -1083,7 +1083,7 @@ dependencies = [
[[package]]
name = "collab-plugins"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d03bd474e551ab5583780abe051a85b8063e6aa9#d03bd474e551ab5583780abe051a85b8063e6aa9"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0af7f361d52611842a862b982b2c72e4fa12cda1#0af7f361d52611842a862b982b2c72e4fa12cda1"
dependencies = [
"anyhow",
"async-stream",
@ -1163,7 +1163,7 @@ dependencies = [
[[package]]
name = "collab-user"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d03bd474e551ab5583780abe051a85b8063e6aa9#d03bd474e551ab5583780abe051a85b8063e6aa9"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0af7f361d52611842a862b982b2c72e4fa12cda1#0af7f361d52611842a862b982b2c72e4fa12cda1"
dependencies = [
"anyhow",
"collab",

View File

@ -116,13 +116,13 @@ custom-protocol = ["tauri/custom-protocol"]
# To switch to the local path, run:
# scripts/tool/update_collab_source.sh
# ⚠️⚠️⚠️️
collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d03bd474e551ab5583780abe051a85b8063e6aa9" }
collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d03bd474e551ab5583780abe051a85b8063e6aa9" }
collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d03bd474e551ab5583780abe051a85b8063e6aa9" }
collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d03bd474e551ab5583780abe051a85b8063e6aa9" }
collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d03bd474e551ab5583780abe051a85b8063e6aa9" }
collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d03bd474e551ab5583780abe051a85b8063e6aa9" }
collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d03bd474e551ab5583780abe051a85b8063e6aa9" }
collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0af7f361d52611842a862b982b2c72e4fa12cda1" }
collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0af7f361d52611842a862b982b2c72e4fa12cda1" }
collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0af7f361d52611842a862b982b2c72e4fa12cda1" }
collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0af7f361d52611842a862b982b2c72e4fa12cda1" }
collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0af7f361d52611842a862b982b2c72e4fa12cda1" }
collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0af7f361d52611842a862b982b2c72e4fa12cda1" }
collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0af7f361d52611842a862b982b2c72e4fa12cda1" }
# Working directory: frontend
# To update the commit ID, run:

View File

@ -824,7 +824,7 @@ dependencies = [
[[package]]
name = "collab"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d03bd474e551ab5583780abe051a85b8063e6aa9#d03bd474e551ab5583780abe051a85b8063e6aa9"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0af7f361d52611842a862b982b2c72e4fa12cda1#0af7f361d52611842a862b982b2c72e4fa12cda1"
dependencies = [
"anyhow",
"arc-swap",
@ -849,7 +849,7 @@ dependencies = [
[[package]]
name = "collab-database"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d03bd474e551ab5583780abe051a85b8063e6aa9#d03bd474e551ab5583780abe051a85b8063e6aa9"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0af7f361d52611842a862b982b2c72e4fa12cda1#0af7f361d52611842a862b982b2c72e4fa12cda1"
dependencies = [
"anyhow",
"async-trait",
@ -879,7 +879,7 @@ dependencies = [
[[package]]
name = "collab-document"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d03bd474e551ab5583780abe051a85b8063e6aa9#d03bd474e551ab5583780abe051a85b8063e6aa9"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0af7f361d52611842a862b982b2c72e4fa12cda1#0af7f361d52611842a862b982b2c72e4fa12cda1"
dependencies = [
"anyhow",
"arc-swap",
@ -899,7 +899,7 @@ dependencies = [
[[package]]
name = "collab-entity"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d03bd474e551ab5583780abe051a85b8063e6aa9#d03bd474e551ab5583780abe051a85b8063e6aa9"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0af7f361d52611842a862b982b2c72e4fa12cda1#0af7f361d52611842a862b982b2c72e4fa12cda1"
dependencies = [
"anyhow",
"bytes",
@ -918,7 +918,7 @@ dependencies = [
[[package]]
name = "collab-folder"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d03bd474e551ab5583780abe051a85b8063e6aa9#d03bd474e551ab5583780abe051a85b8063e6aa9"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0af7f361d52611842a862b982b2c72e4fa12cda1#0af7f361d52611842a862b982b2c72e4fa12cda1"
dependencies = [
"anyhow",
"arc-swap",
@ -961,7 +961,7 @@ dependencies = [
[[package]]
name = "collab-plugins"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d03bd474e551ab5583780abe051a85b8063e6aa9#d03bd474e551ab5583780abe051a85b8063e6aa9"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0af7f361d52611842a862b982b2c72e4fa12cda1#0af7f361d52611842a862b982b2c72e4fa12cda1"
dependencies = [
"anyhow",
"async-stream",
@ -1041,7 +1041,7 @@ dependencies = [
[[package]]
name = "collab-user"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d03bd474e551ab5583780abe051a85b8063e6aa9#d03bd474e551ab5583780abe051a85b8063e6aa9"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0af7f361d52611842a862b982b2c72e4fa12cda1#0af7f361d52611842a862b982b2c72e4fa12cda1"
dependencies = [
"anyhow",
"collab",

View File

@ -136,13 +136,13 @@ rocksdb = { git = "https://github.com/rust-rocksdb/rust-rocksdb", rev = "1710120
# To switch to the local path, run:
# scripts/tool/update_collab_source.sh
# ⚠️⚠️⚠️️
collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d03bd474e551ab5583780abe051a85b8063e6aa9" }
collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d03bd474e551ab5583780abe051a85b8063e6aa9" }
collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d03bd474e551ab5583780abe051a85b8063e6aa9" }
collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d03bd474e551ab5583780abe051a85b8063e6aa9" }
collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d03bd474e551ab5583780abe051a85b8063e6aa9" }
collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d03bd474e551ab5583780abe051a85b8063e6aa9" }
collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d03bd474e551ab5583780abe051a85b8063e6aa9" }
collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0af7f361d52611842a862b982b2c72e4fa12cda1" }
collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0af7f361d52611842a862b982b2c72e4fa12cda1" }
collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0af7f361d52611842a862b982b2c72e4fa12cda1" }
collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0af7f361d52611842a862b982b2c72e4fa12cda1" }
collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0af7f361d52611842a862b982b2c72e4fa12cda1" }
collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0af7f361d52611842a862b982b2c72e4fa12cda1" }
collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0af7f361d52611842a862b982b2c72e4fa12cda1" }
# Working directory: frontend
# To update the commit ID, run:

View File

@ -279,6 +279,7 @@ impl DatabaseManager {
self.open_database(database_id).await
}
#[instrument(level = "trace", skip_all, err)]
pub async fn open_database(&self, database_id: &str) -> FlowyResult<Arc<DatabaseEditor>> {
trace!("open database editor:{}", database_id);
let lock = self.workspace_database()?;

View File

@ -37,7 +37,7 @@ use lib_infra::util::timestamp;
use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::{broadcast, RwLock};
use tracing::{error, event, instrument, trace, warn};
use tracing::{debug, error, event, instrument, trace, warn};
#[derive(Clone)]
pub struct DatabaseEditor {
@ -66,7 +66,7 @@ impl DatabaseEditor {
// observe_view_change(&database_id, &database).await;
// observe_field_change(&database_id, &database).await;
observe_rows_change(&database_id, &database, &notification_sender).await;
// observe_block_event(&database_id, &database).await;
observe_block_event(&database_id, &database).await;
// Used to cache the view of the database for fast access.
let editor_by_view_id = Arc::new(RwLock::new(EditorByViewId::default()));
@ -119,7 +119,7 @@ impl DatabaseEditor {
.database
.read()
.await
.get_database_rows()
.get_all_row_orders()
.await
.into_iter()
.map(|entry| entry.id)
@ -509,16 +509,28 @@ impl DatabaseEditor {
.ok_or_else(|| FlowyError::internal().with_context("error while copying row"))?;
let (index, row_order) = database.create_row_in_view(view_id, params);
tracing::trace!("duplicated row: {:?} at {}", row_order, index);
trace!(
"duplicate row: {:?} at index:{}, new row:{:?}",
row_id,
index,
row_order
);
let row_detail = database.get_row_detail(&row_order.id).await;
(row_detail, index)
};
if let Some(row_detail) = row_detail {
for view in self.database_views.editors().await {
view.v_did_create_row(&row_detail, index).await;
}
match row_detail {
None => {
error!(
"Failed to duplicate row: {:?}. Row is not exist before duplicating",
row_id
);
},
Some(row_detail) => {
for view in self.database_views.editors().await {
view.v_did_create_row(&row_detail, index).await;
}
},
}
Ok(())
@ -654,9 +666,9 @@ impl DatabaseEditor {
Ok(())
}
pub async fn get_rows(&self, view_id: &str) -> FlowyResult<Vec<Arc<RowDetail>>> {
pub async fn get_row_details(&self, view_id: &str) -> FlowyResult<Vec<Arc<RowDetail>>> {
let view_editor = self.database_views.get_view_editor(view_id).await?;
Ok(view_editor.v_get_rows().await)
Ok(view_editor.v_get_row_details().await)
}
pub async fn get_row(&self, view_id: &str, row_id: &RowId) -> Option<Row> {
@ -669,11 +681,22 @@ impl DatabaseEditor {
}
pub async fn init_database_row(&self, row_id: &RowId) -> FlowyResult<()> {
if self
.database
.read()
.await
.get_database_row(row_id)
.is_some()
{
return Ok(());
}
debug!("Init database row: {}", row_id);
let database_row = self
.database
.read()
.await
.get_row_collab(row_id)
.create_database_row(row_id)
.ok_or_else(|| {
FlowyError::record_not_found()
.with_context(format!("The row:{} in database not found", row_id))
@ -1143,7 +1166,7 @@ impl DatabaseEditor {
let to_row = if to_row.is_some() {
to_row
} else {
let row_details = self.get_rows(view_id).await?;
let row_details = self.get_row_details(view_id).await?;
row_details
.last()
.map(|row_detail| row_detail.row.id.clone())
@ -1275,7 +1298,8 @@ impl DatabaseEditor {
.v_get_view()
.await
.ok_or_else(FlowyError::record_not_found)?;
let rows = database_view.v_get_rows().await;
let row_orders = self.database.read().await.get_row_orders_for_view(&view_id);
let (database_id, fields, is_linked) = {
let database = self.database.read().await;
let database_id = database.get_database_id();
@ -1288,9 +1312,15 @@ impl DatabaseEditor {
(database_id, fields, is_linked)
};
let rows = rows
let rows = row_orders
.into_iter()
.map(|row_detail| RowMetaPB::from(row_detail.as_ref()))
.map(|row_order| RowMetaPB {
id: row_order.id.to_string(),
document_id: "".to_string(),
icon: None,
cover: None,
is_document_empty: false,
})
.collect::<Vec<RowMetaPB>>();
Ok(DatabasePB {
id: database_id,
@ -1374,7 +1404,7 @@ impl DatabaseEditor {
.ok_or(FlowyError::internal())?;
let row_data = {
let mut rows = database.get_database_rows().await;
let mut rows = database.get_all_rows().await;
if let Some(row_ids) = row_ids {
rows.retain(|row| row_ids.contains(&row.id));
}
@ -1504,7 +1534,7 @@ impl DatabaseViewOperation for DatabaseViewOperationImpl {
self.database.read().await.index_of_row(view_id, row_id)
}
async fn get_row(&self, view_id: &str, row_id: &RowId) -> Option<(usize, Arc<RowDetail>)> {
async fn get_row_detail(&self, view_id: &str, row_id: &RowId) -> Option<(usize, Arc<RowDetail>)> {
let database = self.database.read().await;
let index = database.index_of_row(view_id, row_id);
let row_detail = database.get_row_detail(row_id).await;
@ -1514,7 +1544,7 @@ impl DatabaseViewOperation for DatabaseViewOperationImpl {
}
}
async fn get_rows(&self, view_id: &str) -> Vec<Arc<RowDetail>> {
async fn get_row_details(&self, view_id: &str) -> Vec<Arc<RowDetail>> {
let view_id = view_id.to_string();
let row_orders = self.database.read().await.get_row_orders_for_view(&view_id);
trace!("total row orders: {}", row_orders.len());

View File

@ -136,7 +136,6 @@ pub(crate) async fn observe_view_change(database_id: &str, database: &Arc<RwLock
});
}
#[allow(dead_code)]
pub(crate) async fn observe_block_event(database_id: &str, database: &Arc<RwLock<Database>>) {
let database_id = database_id.to_string();
let weak_database = Arc::downgrade(database);

View File

@ -314,8 +314,8 @@ impl DatabaseViewEditor {
}
#[instrument(level = "info", skip(self))]
pub async fn v_get_rows(&self) -> Vec<Arc<RowDetail>> {
let mut rows = self.delegate.get_rows(&self.view_id).await;
pub async fn v_get_row_details(&self) -> Vec<Arc<RowDetail>> {
let mut rows = self.delegate.get_row_details(&self.view_id).await;
self.v_filter_rows(&mut rows).await;
self.v_sort_rows(&mut rows).await;
rows
@ -937,7 +937,7 @@ impl DatabaseViewEditor {
.timestamp
.unwrap_or_default();
let (_, row_detail) = self.delegate.get_row(&self.view_id, &row_id).await?;
let (_, row_detail) = self.delegate.get_row_detail(&self.view_id, &row_id).await?;
Some(CalendarEventPB {
row_meta: RowMetaPB::from(row_detail.as_ref()),
date_field_id: date_field.id.clone(),
@ -1000,7 +1000,7 @@ impl DatabaseViewEditor {
.unwrap_or_default()
.into();
let (_, row_detail) = self.delegate.get_row(&self.view_id, &row_id).await?;
let (_, row_detail) = self.delegate.get_row_detail(&self.view_id, &row_id).await?;
let event = CalendarEventPB {
row_meta: RowMetaPB::from(row_detail.as_ref()),
date_field_id: calendar_setting.field_id.clone(),

View File

@ -53,11 +53,11 @@ impl FilterDelegate for DatabaseViewFilterDelegateImpl {
}
async fn get_rows(&self, view_id: &str) -> Vec<Arc<RowDetail>> {
self.0.get_rows(view_id).await
self.0.get_row_details(view_id).await
}
async fn get_row(&self, view_id: &str, rows_id: &RowId) -> Option<(usize, Arc<RowDetail>)> {
self.0.get_row(view_id, rows_id).await
self.0.get_row_detail(view_id, rows_id).await
}
async fn get_all_filters(&self, view_id: &str) -> Vec<Filter> {

View File

@ -97,7 +97,7 @@ impl GroupControllerDelegate for GroupControllerDelegateImpl {
}
async fn get_all_rows(&self, view_id: &str) -> Vec<Arc<RowDetail>> {
let mut row_details = self.delegate.get_rows(view_id).await;
let mut row_details = self.delegate.get_row_details(view_id).await;
self.filter_controller.filter_rows(&mut row_details).await;
row_details
}

View File

@ -53,10 +53,10 @@ pub trait DatabaseViewOperation: Send + Sync + 'static {
async fn index_of_row(&self, view_id: &str, row_id: &RowId) -> Option<usize>;
/// Returns the `index` and `RowRevision` with row_id
async fn get_row(&self, view_id: &str, row_id: &RowId) -> Option<(usize, Arc<RowDetail>)>;
async fn get_row_detail(&self, view_id: &str, row_id: &RowId) -> Option<(usize, Arc<RowDetail>)>;
/// Returns all the rows in the view
async fn get_rows(&self, view_id: &str) -> Vec<Arc<RowDetail>>;
async fn get_row_details(&self, view_id: &str) -> Vec<Arc<RowDetail>>;
async fn remove_row(&self, row_id: &RowId) -> Option<Row>;

View File

@ -61,7 +61,7 @@ impl SortDelegate for DatabaseViewSortDelegateImpl {
async fn get_rows(&self, view_id: &str) -> Vec<Arc<RowDetail>> {
let view_id = view_id.to_string();
let mut row_details = self.delegate.get_rows(&view_id).await;
let mut row_details = self.delegate.get_row_details(&view_id).await;
self.filter_controller.filter_rows(&mut row_details).await;
row_details
}

View File

@ -86,7 +86,7 @@ impl DatabaseEditorTest {
.map(Arc::new)
.collect();
let rows = editor
.get_rows(&test.child_view.id)
.get_row_details(&test.child_view.id)
.await
.unwrap()
.into_iter()
@ -109,7 +109,7 @@ impl DatabaseEditorTest {
}
pub async fn get_rows(&self) -> Vec<Arc<RowDetail>> {
self.editor.get_rows(&self.view_id).await.unwrap()
self.editor.get_row_details(&self.view_id).await.unwrap()
}
pub async fn get_field(&self, field_id: &str, field_type: FieldType) -> Field {

View File

@ -121,7 +121,7 @@ impl DatabaseFieldTest {
} => {
let field = self.editor.get_field(&field_id).await.unwrap();
let rows = self.editor.get_rows(&self.view_id()).await.unwrap();
let rows = self.editor.get_row_details(&self.view_id()).await.unwrap();
let row_detail = rows.get(row_index).unwrap();
let cell = row_detail.row.cells.get(&field_id).unwrap().clone();

View File

@ -86,7 +86,7 @@ impl DatabasePreFillRowCellTest {
.await
.unwrap(),
PreFillRowCellTestScript::AssertRowCount(expected_row_count) => {
let rows = self.editor.get_rows(&self.view_id).await.unwrap();
let rows = self.editor.get_row_details(&self.view_id).await.unwrap();
assert_eq!(expected_row_count, rows.len());
},
PreFillRowCellTestScript::AssertCellExistence {
@ -94,7 +94,7 @@ impl DatabasePreFillRowCellTest {
row_index,
exists,
} => {
let rows = self.editor.get_rows(&self.view_id).await.unwrap();
let rows = self.editor.get_row_details(&self.view_id).await.unwrap();
let row_detail = rows.get(row_index).unwrap();
let cell = row_detail.row.cells.get(&field_id).cloned();
@ -108,7 +108,7 @@ impl DatabasePreFillRowCellTest {
} => {
let field = self.editor.get_field(&field_id).await.unwrap();
let rows = self.editor.get_rows(&self.view_id).await.unwrap();
let rows = self.editor.get_row_details(&self.view_id).await.unwrap();
let row_detail = rows.get(row_index).unwrap();
let cell = row_detail
@ -125,7 +125,7 @@ impl DatabasePreFillRowCellTest {
row_index,
expected_content,
} => {
let rows = self.editor.get_rows(&self.view_id).await.unwrap();
let rows = self.editor.get_row_details(&self.view_id).await.unwrap();
let row_detail = rows.get(row_index).unwrap();
let cell = row_detail

View File

@ -33,7 +33,7 @@ async fn export_and_then_import_meta_csv_test() {
let database = test.get_database(&result.database_id).await.unwrap();
let fields = database.get_fields(&result.view_id, None).await;
let rows = database.get_rows(&result.view_id).await.unwrap();
let rows = database.get_row_details(&result.view_id).await.unwrap();
assert_eq!(fields[0].field_type, 0);
assert_eq!(fields[1].field_type, 1);
assert_eq!(fields[2].field_type, 2);
@ -112,7 +112,7 @@ async fn history_database_import_test() {
let database = test.get_database(&result.database_id).await.unwrap();
let fields = database.get_fields(&result.view_id, None).await;
let rows = database.get_rows(&result.view_id).await.unwrap();
let rows = database.get_row_details(&result.view_id).await.unwrap();
assert_eq!(fields[0].field_type, 0);
assert_eq!(fields[1].field_type, 1);
assert_eq!(fields[2].field_type, 2);

View File

@ -117,7 +117,7 @@ impl DatabaseSortTest {
},
SortScript::AssertCellContentOrder { field_id, orders } => {
let mut cells = vec![];
let rows = self.editor.get_rows(&self.view_id).await.unwrap();
let rows = self.editor.get_row_details(&self.view_id).await.unwrap();
let field = self.editor.get_field(&field_id).await.unwrap();
for row_detail in rows {
if let Some(cell) = row_detail.row.cells.get(&field_id) {