mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
fix: cell focus issue on windows (#2880)
* fix: cell focus issue on windows * fix: try to fix * fix: cell focus not working on Windows platform there are multiple text cells * docs: add documentation * chore: adjust row detail page ui * test: add test * test: fix test --------- Co-authored-by: vedon <vedon.fu@gmail.com>
This commit is contained in:
parent
f1bfcb6066
commit
a29c8ab27a
frontend
appflowy_flutter
integration_test
lib/plugins/database_view
grid/presentation
widgets/row
cell_builder.dart
cells
row_property.dartappflowy_tauri/src-tauri
@ -1,4 +1,5 @@
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/protobuf.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
@ -47,6 +48,44 @@ void main() {
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
// Makesure the text cells are filled with the right content when there are
|
||||
// multiple text cell
|
||||
testWidgets('edit multiple text cells', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
await tester.createNewPageWithName(ViewLayoutPB.Grid, 'my grid');
|
||||
await tester.createField(FieldType.RichText, 'description');
|
||||
|
||||
await tester.editCell(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.RichText,
|
||||
input: 'hello',
|
||||
);
|
||||
|
||||
await tester.editCell(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.RichText,
|
||||
input: 'world',
|
||||
cellIndex: 1,
|
||||
);
|
||||
|
||||
await tester.assertCellContent(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.RichText,
|
||||
content: 'hello',
|
||||
cellIndex: 0,
|
||||
);
|
||||
|
||||
await tester.assertCellContent(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.RichText,
|
||||
content: 'world',
|
||||
cellIndex: 1,
|
||||
);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('edit number cell', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
@ -108,22 +108,26 @@ extension AppFlowyDatabaseTest on WidgetTester {
|
||||
required int rowIndex,
|
||||
required FieldType fieldType,
|
||||
required String input,
|
||||
int cellIndex = 0,
|
||||
}) async {
|
||||
final cell = cellFinder(rowIndex, fieldType);
|
||||
final cell = cellFinder(rowIndex, fieldType, cellIndex: cellIndex);
|
||||
|
||||
expect(cell, findsOneWidget);
|
||||
await enterText(cell, input);
|
||||
await pumpAndSettle();
|
||||
}
|
||||
|
||||
Finder cellFinder(int rowIndex, FieldType fieldType) {
|
||||
///
|
||||
Finder cellFinder(int rowIndex, FieldType fieldType, {int cellIndex = 0}) {
|
||||
final findRow = find.byType(GridRow, skipOffstage: false);
|
||||
final findCell = finderForFieldType(fieldType);
|
||||
return find.descendant(
|
||||
of: findRow.at(rowIndex),
|
||||
matching: findCell,
|
||||
skipOffstage: false,
|
||||
);
|
||||
return find
|
||||
.descendant(
|
||||
of: findRow.at(rowIndex),
|
||||
matching: findCell,
|
||||
skipOffstage: false,
|
||||
)
|
||||
.at(cellIndex);
|
||||
}
|
||||
|
||||
Future<void> tapCheckboxCellInGrid({
|
||||
@ -173,8 +177,9 @@ extension AppFlowyDatabaseTest on WidgetTester {
|
||||
required int rowIndex,
|
||||
required FieldType fieldType,
|
||||
required String content,
|
||||
int cellIndex = 0,
|
||||
}) async {
|
||||
final findCell = cellFinder(rowIndex, fieldType);
|
||||
final findCell = cellFinder(rowIndex, fieldType, cellIndex: cellIndex);
|
||||
final findContent = find.descendant(
|
||||
of: findCell,
|
||||
matching: find.text(content),
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/row/row_service.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/toolbar/grid_setting_bar.dart';
|
||||
@ -241,41 +243,7 @@ class _GridRows extends StatelessWidget {
|
||||
);
|
||||
return ScrollConfiguration(
|
||||
behavior: behavior,
|
||||
child: ReorderableListView.builder(
|
||||
/// TODO(Xazin): Resolve inconsistent scrollbar behavior
|
||||
/// This is a workaround related to
|
||||
/// https://github.com/flutter/flutter/issues/25652
|
||||
cacheExtent: 5000,
|
||||
scrollController: scrollController.verticalController,
|
||||
buildDefaultDragHandles: false,
|
||||
proxyDecorator: (child, index, animation) => Material(
|
||||
color: Colors.white.withOpacity(.1),
|
||||
child: Opacity(opacity: .5, child: child),
|
||||
),
|
||||
onReorder: (fromIndex, newIndex) {
|
||||
final toIndex =
|
||||
newIndex > fromIndex ? newIndex - 1 : newIndex;
|
||||
if (fromIndex == toIndex) {
|
||||
return;
|
||||
}
|
||||
context
|
||||
.read<GridBloc>()
|
||||
.add(GridEvent.moveRow(fromIndex, toIndex));
|
||||
},
|
||||
itemCount: rowInfos.length + 1, // the extra item is the footer
|
||||
itemBuilder: (context, index) {
|
||||
if (index < rowInfos.length) {
|
||||
final rowInfo = rowInfos[index];
|
||||
return _renderRow(
|
||||
context,
|
||||
rowInfo.rowId,
|
||||
isDraggable: state.reorderable,
|
||||
index: index,
|
||||
);
|
||||
}
|
||||
return const GridRowBottomBar(key: Key('gridFooter'));
|
||||
},
|
||||
),
|
||||
child: _renderList(context, state, rowInfos),
|
||||
);
|
||||
},
|
||||
),
|
||||
@ -283,6 +251,66 @@ class _GridRows extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _renderList(
|
||||
BuildContext context,
|
||||
GridState state,
|
||||
List<RowInfo> rowInfos,
|
||||
) {
|
||||
if (Platform.isWindows) {
|
||||
// Workaround: On Windows, the focusing of the text cell is not working
|
||||
// properly when the list is reorderable. So using the ListView instead.
|
||||
return ListView.builder(
|
||||
controller: scrollController.verticalController,
|
||||
itemCount: rowInfos.length + 1, // the extra item is the footer
|
||||
itemBuilder: (context, index) {
|
||||
if (index < rowInfos.length) {
|
||||
final rowInfo = rowInfos[index];
|
||||
return _renderRow(
|
||||
context,
|
||||
rowInfo.rowId,
|
||||
isDraggable: false,
|
||||
index: index,
|
||||
);
|
||||
}
|
||||
return const GridRowBottomBar(key: Key('gridFooter'));
|
||||
},
|
||||
);
|
||||
} else {
|
||||
return ReorderableListView.builder(
|
||||
/// TODO(Xazin): Resolve inconsistent scrollbar behavior
|
||||
/// This is a workaround related to
|
||||
/// https://github.com/flutter/flutter/issues/25652
|
||||
cacheExtent: 5000,
|
||||
scrollController: scrollController.verticalController,
|
||||
buildDefaultDragHandles: false,
|
||||
proxyDecorator: (child, index, animation) => Material(
|
||||
color: Colors.white.withOpacity(.1),
|
||||
child: Opacity(opacity: .5, child: child),
|
||||
),
|
||||
onReorder: (fromIndex, newIndex) {
|
||||
final toIndex = newIndex > fromIndex ? newIndex - 1 : newIndex;
|
||||
if (fromIndex == toIndex) {
|
||||
return;
|
||||
}
|
||||
context.read<GridBloc>().add(GridEvent.moveRow(fromIndex, toIndex));
|
||||
},
|
||||
itemCount: rowInfos.length + 1, // the extra item is the footer
|
||||
itemBuilder: (context, index) {
|
||||
if (index < rowInfos.length) {
|
||||
final rowInfo = rowInfos[index];
|
||||
return _renderRow(
|
||||
context,
|
||||
rowInfo.rowId,
|
||||
isDraggable: state.reorderable,
|
||||
index: index,
|
||||
);
|
||||
}
|
||||
return const GridRowBottomBar(key: Key('gridFooter'));
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget _renderRow(
|
||||
BuildContext context,
|
||||
RowId rowId, {
|
||||
|
@ -138,7 +138,6 @@ class _OptionNameTextField extends StatelessWidget {
|
||||
return FlowyTextField(
|
||||
autoFocus: autoFocus,
|
||||
text: name,
|
||||
maxLength: 30,
|
||||
submitOnLeave: true,
|
||||
onSubmitted: (newName) {
|
||||
if (name != newName) {
|
||||
|
@ -103,11 +103,11 @@ class BlankCell extends StatelessWidget {
|
||||
}
|
||||
|
||||
abstract class CellEditable {
|
||||
GridCellFocusListener get beginFocus;
|
||||
RequestFocusListener get requestFocus;
|
||||
|
||||
ValueNotifier<bool> get onCellFocus;
|
||||
|
||||
ValueNotifier<bool> get onCellEditing;
|
||||
// ValueNotifier<bool> get onCellEditing;
|
||||
}
|
||||
|
||||
typedef AccessoryBuilder = List<GridCellAccessoryBuilder> Function(
|
||||
@ -125,11 +125,7 @@ abstract class CellAccessory extends Widget {
|
||||
|
||||
abstract class GridCellWidget extends StatefulWidget
|
||||
implements CellAccessory, CellEditable, CellShortcuts {
|
||||
GridCellWidget({Key? key}) : super(key: key) {
|
||||
onCellEditing.addListener(() {
|
||||
onCellFocus.value = onCellEditing.value;
|
||||
});
|
||||
}
|
||||
GridCellWidget({super.key});
|
||||
|
||||
@override
|
||||
final ValueNotifier<bool> onCellFocus = ValueNotifier<bool>(false);
|
||||
@ -138,8 +134,8 @@ abstract class GridCellWidget extends StatefulWidget
|
||||
@override
|
||||
ValueNotifier<bool> get onAccessoryHover => onCellFocus;
|
||||
|
||||
@override
|
||||
final ValueNotifier<bool> onCellEditing = ValueNotifier<bool>(false);
|
||||
// @override
|
||||
// final ValueNotifier<bool> onCellEditing = ValueNotifier<bool>(false);
|
||||
|
||||
@override
|
||||
List<GridCellAccessoryBuilder> Function(
|
||||
@ -147,7 +143,7 @@ abstract class GridCellWidget extends StatefulWidget
|
||||
)? get accessoryBuilder => null;
|
||||
|
||||
@override
|
||||
final GridCellFocusListener beginFocus = GridCellFocusListener();
|
||||
final RequestFocusListener requestFocus = RequestFocusListener();
|
||||
|
||||
@override
|
||||
final Map<CellKeyboardKey, CellKeyboardAction> shortcutHandlers = {};
|
||||
@ -156,7 +152,7 @@ abstract class GridCellWidget extends StatefulWidget
|
||||
abstract class GridCellState<T extends GridCellWidget> extends State<T> {
|
||||
@override
|
||||
void initState() {
|
||||
widget.beginFocus.setListener(() => requestBeginFocus());
|
||||
widget.requestFocus.setListener(requestBeginFocus);
|
||||
widget.shortcutHandlers[CellKeyboardKey.onCopy] = () => onCopy();
|
||||
widget.shortcutHandlers[CellKeyboardKey.onInsert] = () {
|
||||
Clipboard.getData("text/plain").then((data) {
|
||||
@ -172,17 +168,18 @@ abstract class GridCellState<T extends GridCellWidget> extends State<T> {
|
||||
@override
|
||||
void didUpdateWidget(covariant T oldWidget) {
|
||||
if (oldWidget != this) {
|
||||
widget.beginFocus.setListener(() => requestBeginFocus());
|
||||
widget.requestFocus.setListener(requestBeginFocus);
|
||||
}
|
||||
super.didUpdateWidget(oldWidget);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
widget.beginFocus.removeAllListener();
|
||||
widget.requestFocus.removeAllListener();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
/// Subclass can override this method to request focus.
|
||||
void requestBeginFocus();
|
||||
|
||||
String? onCopy() => null;
|
||||
@ -190,9 +187,9 @@ abstract class GridCellState<T extends GridCellWidget> extends State<T> {
|
||||
void onInsert(String value) {}
|
||||
}
|
||||
|
||||
abstract class GridFocusNodeCellState<T extends GridCellWidget>
|
||||
abstract class GridEditableTextCell<T extends GridCellWidget>
|
||||
extends GridCellState<T> {
|
||||
SingleListenerFocusNode focusNode = SingleListenerFocusNode();
|
||||
SingleListenerFocusNode get focusNode;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -226,9 +223,9 @@ abstract class GridFocusNodeCellState<T extends GridCellWidget>
|
||||
}
|
||||
|
||||
void _listenOnFocusNodeChanged() {
|
||||
widget.onCellEditing.value = focusNode.hasFocus;
|
||||
widget.onCellFocus.value = focusNode.hasFocus;
|
||||
focusNode.setListener(() {
|
||||
widget.onCellEditing.value = focusNode.hasFocus;
|
||||
widget.onCellFocus.value = focusNode.hasFocus;
|
||||
focusChanged();
|
||||
});
|
||||
}
|
||||
@ -236,7 +233,7 @@ abstract class GridFocusNodeCellState<T extends GridCellWidget>
|
||||
Future<void> focusChanged() async {}
|
||||
}
|
||||
|
||||
class GridCellFocusListener extends ChangeNotifier {
|
||||
class RequestFocusListener extends ChangeNotifier {
|
||||
VoidCallback? _listener;
|
||||
|
||||
void setListener(VoidCallback listener) {
|
||||
|
@ -51,8 +51,8 @@ class CellContainer extends StatelessWidget {
|
||||
}
|
||||
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onTap: () => child.beginFocus.notify(),
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () => child.requestFocus.notify(),
|
||||
child: Container(
|
||||
constraints: BoxConstraints(maxWidth: width, minHeight: 46),
|
||||
decoration: _makeBoxDecoration(context, isFocus),
|
||||
|
@ -45,14 +45,14 @@ class GridChecklistCellState extends GridCellState<GridChecklistCell> {
|
||||
triggerActions: PopoverTriggerFlags.none,
|
||||
popupBuilder: (BuildContext context) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
widget.onCellEditing.value = true;
|
||||
widget.onCellFocus.value = true;
|
||||
});
|
||||
return GridChecklistCellEditor(
|
||||
cellController:
|
||||
widget.cellControllerBuilder.build() as ChecklistCellController,
|
||||
);
|
||||
},
|
||||
onClose: () => widget.onCellEditing.value = false,
|
||||
onClose: () => widget.onCellFocus.value = false,
|
||||
child: Padding(
|
||||
padding: GridSize.cellContentInsets,
|
||||
child: BlocBuilder<ChecklistCardCellBloc, ChecklistCellState>(
|
||||
|
@ -90,11 +90,11 @@ class _DateCellState extends GridCellState<GridDateCell> {
|
||||
return DateCellEditor(
|
||||
cellController: widget.cellControllerBuilder.build()
|
||||
as DateCellController,
|
||||
onDismissed: () => widget.onCellEditing.value = false,
|
||||
onDismissed: () => widget.onCellFocus.value = false,
|
||||
);
|
||||
},
|
||||
onClose: () {
|
||||
widget.onCellEditing.value = false;
|
||||
widget.onCellFocus.value = false;
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -115,7 +115,7 @@ class _DateCellState extends GridCellState<GridDateCell> {
|
||||
_popover.show();
|
||||
|
||||
if (widget.editable) {
|
||||
widget.onCellEditing.value = true;
|
||||
widget.onCellFocus.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,13 +16,16 @@ class GridNumberCell extends GridCellWidget {
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
GridFocusNodeCellState<GridNumberCell> createState() => _NumberCellState();
|
||||
GridEditableTextCell<GridNumberCell> createState() => _NumberCellState();
|
||||
}
|
||||
|
||||
class _NumberCellState extends GridFocusNodeCellState<GridNumberCell> {
|
||||
class _NumberCellState extends GridEditableTextCell<GridNumberCell> {
|
||||
late NumberCellBloc _cellBloc;
|
||||
late TextEditingController _controller;
|
||||
|
||||
@override
|
||||
SingleListenerFocusNode focusNode = SingleListenerFocusNode();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
final cellController =
|
||||
|
@ -62,7 +62,7 @@ class _SingleSelectCellState extends GridCellState<GridSingleSelectCell> {
|
||||
return SelectOptionWrap(
|
||||
selectOptions: state.selectedOptions,
|
||||
cellStyle: widget.cellStyle,
|
||||
onCellEditing: widget.onCellEditing,
|
||||
onCellEditing: widget.onCellFocus,
|
||||
popoverController: _popover,
|
||||
cellControllerBuilder: widget.cellControllerBuilder,
|
||||
);
|
||||
@ -125,7 +125,7 @@ class _MultiSelectCellState extends GridCellState<GridMultiSelectCell> {
|
||||
return SelectOptionWrap(
|
||||
selectOptions: state.selectedOptions,
|
||||
cellStyle: widget.cellStyle,
|
||||
onCellEditing: widget.onCellEditing,
|
||||
onCellEditing: widget.onCellFocus,
|
||||
popoverController: _popover,
|
||||
cellControllerBuilder: widget.cellControllerBuilder,
|
||||
);
|
||||
|
@ -157,7 +157,6 @@ class _TextField extends StatelessWidget {
|
||||
options: state.options,
|
||||
selectedOptionMap: optionMap,
|
||||
distanceToText: _editorPanelWidth * 0.7,
|
||||
maxLength: 30,
|
||||
tagController: tagController,
|
||||
textSeparators: const [','],
|
||||
onClick: () => popoverMutex.close(),
|
||||
|
@ -41,13 +41,16 @@ class GridTextCell extends GridCellWidget {
|
||||
}
|
||||
|
||||
@override
|
||||
GridFocusNodeCellState<GridTextCell> createState() => _GridTextCellState();
|
||||
GridEditableTextCell<GridTextCell> createState() => _GridTextCellState();
|
||||
}
|
||||
|
||||
class _GridTextCellState extends GridFocusNodeCellState<GridTextCell> {
|
||||
class _GridTextCellState extends GridEditableTextCell<GridTextCell> {
|
||||
late TextCellBloc _cellBloc;
|
||||
late TextEditingController _controller;
|
||||
|
||||
@override
|
||||
SingleListenerFocusNode focusNode = SingleListenerFocusNode();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
final cellController =
|
||||
|
@ -108,11 +108,14 @@ class GridURLCell extends GridCellWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _GridURLCellState extends GridFocusNodeCellState<GridURLCell> {
|
||||
class _GridURLCellState extends GridEditableTextCell<GridURLCell> {
|
||||
final _popoverController = PopoverController();
|
||||
late final URLCellBloc _cellBloc;
|
||||
late final TextEditingController _controller;
|
||||
|
||||
@override
|
||||
SingleListenerFocusNode focusNode = SingleListenerFocusNode();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
@ -182,7 +185,7 @@ class _GridURLCellState extends GridFocusNodeCellState<GridURLCell> {
|
||||
|
||||
@override
|
||||
void requestBeginFocus() {
|
||||
widget.onCellEditing.value = true;
|
||||
widget.onCellFocus.value = true;
|
||||
_popoverController.show();
|
||||
}
|
||||
|
||||
|
@ -85,8 +85,8 @@ class _PropertyCellState extends State<_PropertyCell> {
|
||||
final cell = widget.cellBuilder.build(widget.cellContext, style: style);
|
||||
|
||||
final gesture = GestureDetector(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onTap: () => cell.beginFocus.notify(),
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () => cell.requestFocus.notify(),
|
||||
child: AccessoryHover(
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 3, vertical: 3),
|
||||
child: cell,
|
||||
@ -97,8 +97,8 @@ class _PropertyCellState extends State<_PropertyCell> {
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(minHeight: 30),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
AppFlowyPopover(
|
||||
controller: popover,
|
||||
@ -108,6 +108,7 @@ class _PropertyCellState extends State<_PropertyCell> {
|
||||
popupBuilder: (popoverContext) => buildFieldEditor(),
|
||||
child: SizedBox(
|
||||
width: 150,
|
||||
height: 40,
|
||||
child: FieldCellButton(
|
||||
field: widget.cellContext.fieldInfo.field,
|
||||
onTap: () => popover.show(),
|
||||
|
20
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
20
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
@ -105,7 +105,7 @@ checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
|
||||
[[package]]
|
||||
name = "appflowy-integrate"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e9f7fc#e9f7fc76192f2dbb2379f1a02310047763bd4426"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=06e942#06e942cb6433c94b5ecfe1d431b64bba625fc09c"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@ -1030,7 +1030,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e9f7fc#e9f7fc76192f2dbb2379f1a02310047763bd4426"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=06e942#06e942cb6433c94b5ecfe1d431b64bba625fc09c"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@ -1048,7 +1048,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-client-ws"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e9f7fc#e9f7fc76192f2dbb2379f1a02310047763bd4426"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=06e942#06e942cb6433c94b5ecfe1d431b64bba625fc09c"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"collab-sync",
|
||||
@ -1066,7 +1066,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-database"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e9f7fc#e9f7fc76192f2dbb2379f1a02310047763bd4426"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=06e942#06e942cb6433c94b5ecfe1d431b64bba625fc09c"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -1092,7 +1092,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-derive"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e9f7fc#e9f7fc76192f2dbb2379f1a02310047763bd4426"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=06e942#06e942cb6433c94b5ecfe1d431b64bba625fc09c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -1104,7 +1104,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-document"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e9f7fc#e9f7fc76192f2dbb2379f1a02310047763bd4426"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=06e942#06e942cb6433c94b5ecfe1d431b64bba625fc09c"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@ -1122,7 +1122,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-folder"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e9f7fc#e9f7fc76192f2dbb2379f1a02310047763bd4426"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=06e942#06e942cb6433c94b5ecfe1d431b64bba625fc09c"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
@ -1142,7 +1142,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-persistence"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e9f7fc#e9f7fc76192f2dbb2379f1a02310047763bd4426"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=06e942#06e942cb6433c94b5ecfe1d431b64bba625fc09c"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"chrono",
|
||||
@ -1162,7 +1162,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-plugins"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e9f7fc#e9f7fc76192f2dbb2379f1a02310047763bd4426"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=06e942#06e942cb6433c94b5ecfe1d431b64bba625fc09c"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -1193,7 +1193,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-sync"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e9f7fc#e9f7fc76192f2dbb2379f1a02310047763bd4426"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=06e942#06e942cb6433c94b5ecfe1d431b64bba625fc09c"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"collab",
|
||||
|
Loading…
Reference in New Issue
Block a user