feat: show notes icon when notes is not empty (#3893)

* feat: show notes icon when notes is not empty

* fix: redundant clone

* chore: update collab and fix after merging main
This commit is contained in:
Mathias Mogensen 2023-11-09 00:30:50 +01:00 committed by GitHub
parent 73f1c211c2
commit 17651bf64c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 249 additions and 156 deletions

View File

@ -40,6 +40,7 @@ class RowBackendService {
required String rowId, required String rowId,
String? iconURL, String? iconURL,
String? coverURL, String? coverURL,
bool? isDocumentEmpty,
}) { }) {
final payload = UpdateRowMetaChangesetPB.create() final payload = UpdateRowMetaChangesetPB.create()
..viewId = viewId ..viewId = viewId
@ -52,6 +53,10 @@ class RowBackendService {
payload.coverUrl = coverURL; payload.coverUrl = coverURL;
} }
if (isDocumentEmpty != null) {
payload.isDocumentEmpty = isDocumentEmpty;
}
return DatabaseEventUpdateRowMeta(payload).send(); return DatabaseEventUpdateRowMeta(payload).send();
} }

View File

@ -115,9 +115,9 @@ class BoardPage extends StatelessWidget {
class BoardContent extends StatefulWidget { class BoardContent extends StatefulWidget {
const BoardContent({ const BoardContent({
Key? key, super.key,
this.onEditStateChanged, this.onEditStateChanged,
}) : super(key: key); });
final VoidCallback? onEditStateChanged; final VoidCallback? onEditStateChanged;
@ -275,6 +275,7 @@ class _BoardContentState extends State<BoardContent> {
boardBloc.state.editingRow?.row.id == groupItem.row.id; boardBloc.state.editingRow?.row.id == groupItem.row.id;
final groupItemId = groupItem.row.id + groupData.group.groupId; final groupItemId = groupItem.row.id + groupData.group.groupId;
return AppFlowyGroupCard( return AppFlowyGroupCard(
key: ValueKey(groupItemId), key: ValueKey(groupItemId),
margin: config.cardPadding, margin: config.cardPadding,

View File

@ -228,6 +228,7 @@ class UngroupedItem extends StatelessWidget {
text: cellBuilder.buildCell( text: cellBuilder.buildCell(
cellContext: cellContext, cellContext: cellContext,
renderHook: renderHook, renderHook: renderHook,
hasNotes: false,
), ),
onTap: onPressed, onTap: onPressed,
), ),

View File

@ -5,6 +5,7 @@ import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
import 'package:appflowy_backend/protobuf/flowy-error/code.pbenum.dart'; import 'package:appflowy_backend/protobuf/flowy-error/code.pbenum.dart';
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
@ -43,6 +44,14 @@ class RowDocumentBloc extends Bloc<RowDocumentEvent, RowDocumentState> {
), ),
); );
}, },
updateIsEmpty: (isEmpty) async {
final unitOrFailure = await _rowBackendSvc.updateMeta(
rowId: rowId,
isDocumentEmpty: isEmpty,
);
unitOrFailure.fold((l) => null, (err) => Log.error(err));
},
); );
}, },
); );
@ -104,6 +113,8 @@ class RowDocumentEvent with _$RowDocumentEvent {
_DidReceiveRowDocument; _DidReceiveRowDocument;
const factory RowDocumentEvent.didReceiveError(FlowyError error) = const factory RowDocumentEvent.didReceiveError(FlowyError error) =
_DidReceiveError; _DidReceiveError;
const factory RowDocumentEvent.updateIsEmpty(bool isDocumentEmpty) =
_UpdateIsEmpty;
} }
@freezed @freezed

View File

@ -48,23 +48,23 @@ class RowCard<CustomCardData> extends StatefulWidget {
final RowCardStyleConfiguration styleConfiguration; final RowCardStyleConfiguration styleConfiguration;
const RowCard({ const RowCard({
super.key,
required this.rowMeta, required this.rowMeta,
required this.viewId, required this.viewId,
this.groupingFieldId,
this.groupId,
required this.isEditing, required this.isEditing,
required this.rowCache, required this.rowCache,
required this.cellBuilder, required this.cellBuilder,
required this.openCard, required this.openCard,
required this.onStartEditing, required this.onStartEditing,
required this.onEndEditing, required this.onEndEditing,
this.groupingFieldId,
this.groupId,
this.cardData, this.cardData,
this.styleConfiguration = const RowCardStyleConfiguration( this.styleConfiguration = const RowCardStyleConfiguration(
showAccessory: true, showAccessory: true,
), ),
this.renderHook, this.renderHook,
Key? key, });
}) : super(key: key);
@override @override
State<RowCard<CustomCardData>> createState() => State<RowCard<CustomCardData>> createState() =>
@ -79,6 +79,7 @@ class _RowCardState<T> extends State<RowCard<T>> {
@override @override
void initState() { void initState() {
super.initState();
rowNotifier = EditableRowNotifier(isEditing: widget.isEditing); rowNotifier = EditableRowNotifier(isEditing: widget.isEditing);
_cardBloc = CardBloc( _cardBloc = CardBloc(
viewId: widget.viewId, viewId: widget.viewId,
@ -100,7 +101,6 @@ class _RowCardState<T> extends State<RowCard<T>> {
}); });
popoverController = PopoverController(); popoverController = PopoverController();
super.initState();
} }
@override @override
@ -197,21 +197,22 @@ class _RowCardState<T> extends State<RowCard<T>> {
} }
class _CardContent<CustomCardData> extends StatelessWidget { class _CardContent<CustomCardData> extends StatelessWidget {
final CardCellBuilder<CustomCardData> cellBuilder;
final EditableRowNotifier rowNotifier;
final List<DatabaseCellContext> cells;
final RowCardRenderHook<CustomCardData>? renderHook;
final CustomCardData? cardData;
final RowCardStyleConfiguration styleConfiguration;
const _CardContent({ const _CardContent({
super.key,
required this.rowNotifier, required this.rowNotifier,
required this.cellBuilder, required this.cellBuilder,
required this.cells, required this.cells,
required this.cardData, required this.cardData,
required this.styleConfiguration, required this.styleConfiguration,
this.renderHook, this.renderHook,
Key? key, });
}) : super(key: key);
final CardCellBuilder<CustomCardData> cellBuilder;
final EditableRowNotifier rowNotifier;
final List<DatabaseCellContext> cells;
final RowCardRenderHook<CustomCardData>? renderHook;
final CustomCardData? cardData;
final RowCardStyleConfiguration styleConfiguration;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -244,8 +245,7 @@ class _CardContent<CustomCardData> extends StatelessWidget {
// Remove all the cell listeners. // Remove all the cell listeners.
rowNotifier.unbind(); rowNotifier.unbind();
cells.asMap().forEach( cells.asMap().forEach((int index, DatabaseCellContext cellContext) {
(int index, DatabaseCellContext cellContext) {
final isEditing = index == 0 ? rowNotifier.isEditing.value : false; final isEditing = index == 0 ? rowNotifier.isEditing.value : false;
final cellNotifier = EditableCardNotifier(isEditing: isEditing); final cellNotifier = EditableCardNotifier(isEditing: isEditing);
@ -263,12 +263,12 @@ class _CardContent<CustomCardData> extends StatelessWidget {
cellNotifier: cellNotifier, cellNotifier: cellNotifier,
renderHook: renderHook, renderHook: renderHook,
cardData: cardData, cardData: cardData,
hasNotes: !cellContext.rowMeta.isDocumentEmpty,
), ),
); );
children.add(child); children.add(child);
}, });
);
return children; return children;
} }
} }

View File

@ -1,4 +1,5 @@
import 'dart:collection'; import 'dart:collection';
import 'package:appflowy/plugins/database_view/application/row/row_listener.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/row_entities.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/row_entities.pb.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
@ -16,8 +17,10 @@ class CardBloc extends Bloc<RowCardEvent, RowCardState> {
final String? groupFieldId; final String? groupFieldId;
final RowBackendService _rowBackendSvc; final RowBackendService _rowBackendSvc;
final RowCache _rowCache; final RowCache _rowCache;
VoidCallback? _rowCallback;
final String viewId; final String viewId;
final RowListener _rowListener;
VoidCallback? _rowCallback;
CardBloc({ CardBloc({
required this.rowMeta, required this.rowMeta,
@ -26,6 +29,7 @@ class CardBloc extends Bloc<RowCardEvent, RowCardState> {
required RowCache rowCache, required RowCache rowCache,
required bool isEditing, required bool isEditing,
}) : _rowBackendSvc = RowBackendService(viewId: viewId), }) : _rowBackendSvc = RowBackendService(viewId: viewId),
_rowListener = RowListener(rowMeta.id),
_rowCache = rowCache, _rowCache = rowCache,
super( super(
RowCardState.initial( RowCardState.initial(
@ -50,6 +54,16 @@ class CardBloc extends Bloc<RowCardEvent, RowCardState> {
setIsEditing: (bool isEditing) { setIsEditing: (bool isEditing) {
emit(state.copyWith(isEditing: isEditing)); emit(state.copyWith(isEditing: isEditing));
}, },
didReceiveRowMeta: (rowMeta) {
final cells = state.cells
.map(
(cell) => cell.rowMeta.id == rowMeta.id
? cell.copyWith(rowMeta: rowMeta)
: cell,
)
.toList();
emit(state.copyWith(cells: cells));
},
); );
}, },
); );
@ -85,6 +99,14 @@ class CardBloc extends Bloc<RowCardEvent, RowCardState> {
} }
}, },
); );
_rowListener.start(
onMetaChanged: (meta) {
if (!isClosed) {
add(RowCardEvent.didReceiveRowMeta(meta));
}
},
);
} }
} }
@ -116,6 +138,9 @@ class RowCardEvent with _$RowCardEvent {
List<DatabaseCellContext> cells, List<DatabaseCellContext> cells,
ChangedReason reason, ChangedReason reason,
) = _DidReceiveCells; ) = _DidReceiveCells;
const factory RowCardEvent.didReceiveRowMeta(
RowMetaPB meta,
) = _DidReceiveRowMeta;
} }
@freezed @freezed

View File

@ -25,6 +25,7 @@ class CardCellBuilder<CustomCardData> {
required DatabaseCellContext cellContext, required DatabaseCellContext cellContext,
EditableCardNotifier? cellNotifier, EditableCardNotifier? cellNotifier,
RowCardRenderHook<CustomCardData>? renderHook, RowCardRenderHook<CustomCardData>? renderHook,
required bool hasNotes,
}) { }) {
final cellControllerBuilder = CellControllerBuilder( final cellControllerBuilder = CellControllerBuilder(
cellContext: cellContext, cellContext: cellContext,
@ -86,12 +87,13 @@ class CardCellBuilder<CustomCardData> {
); );
case FieldType.RichText: case FieldType.RichText:
return TextCardCell<CustomCardData>( return TextCardCell<CustomCardData>(
key: key,
style: isStyleOrNull<TextCardCellStyle>(style),
cardData: cardData,
renderHook: renderHook?.renderHook[FieldType.RichText], renderHook: renderHook?.renderHook[FieldType.RichText],
cellControllerBuilder: cellControllerBuilder, cellControllerBuilder: cellControllerBuilder,
editableNotifier: cellNotifier, editableNotifier: cellNotifier,
cardData: cardData, showNotes: cellContext.fieldInfo.isPrimary && hasNotes,
style: isStyleOrNull<TextCardCellStyle>(style),
key: key,
); );
case FieldType.URL: case FieldType.URL:
return URLCardCell<CustomCardData>( return URLCardCell<CustomCardData>(

View File

@ -1,6 +1,8 @@
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart'; import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart';
import 'package:appflowy/plugins/database_view/widgets/row/cells/text_cell/text_cell_bloc.dart'; import 'package:appflowy/plugins/database_view/widgets/row/cells/text_cell/text_cell_bloc.dart';
import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import '../../row/cell_builder.dart'; import '../../row/cell_builder.dart';
@ -15,19 +17,21 @@ class TextCardCellStyle extends CardCellStyle {
class TextCardCell<CustomCardData> class TextCardCell<CustomCardData>
extends CardCell<CustomCardData, TextCardCellStyle> with EditableCell { extends CardCell<CustomCardData, TextCardCellStyle> with EditableCell {
const TextCardCell({
super.key,
super.cardData,
super.style,
required this.cellControllerBuilder,
this.editableNotifier,
this.renderHook,
this.showNotes = false,
});
@override @override
final EditableCardNotifier? editableNotifier; final EditableCardNotifier? editableNotifier;
final CellControllerBuilder cellControllerBuilder; final CellControllerBuilder cellControllerBuilder;
final CellRenderHook<String, CustomCardData>? renderHook; final CellRenderHook<String, CustomCardData>? renderHook;
final bool showNotes;
const TextCardCell({
required this.cellControllerBuilder,
required CustomCardData? cardData,
this.editableNotifier,
this.renderHook,
TextCardCellStyle? style,
Key? key,
}) : super(key: key, style: style, cardData: cardData);
@override @override
State<TextCardCell> createState() => _TextCellState(); State<TextCardCell> createState() => _TextCellState();
@ -122,14 +126,19 @@ class _TextCellState extends State<TextCardCell> {
return const SizedBox(); return const SizedBox();
} }
// final child = state.enableEdit || focusWhenInit
Widget child; ? _buildTextField()
if (state.enableEdit || focusWhenInit) { : _buildText(state);
child = _buildTextField();
} else { return Row(
child = _buildText(state); children: [
} if (widget.showNotes) ...[
return Align(alignment: Alignment.centerLeft, child: child); const FlowySvg(FlowySvgs.notes_s),
const HSpace(4),
],
Expanded(child: child),
],
);
}, },
), ),
), ),
@ -151,9 +160,9 @@ class _TextCellState extends State<TextCardCell> {
double _fontSize() { double _fontSize() {
if (widget.style != null) { if (widget.style != null) {
return widget.style!.fontSize; return widget.style!.fontSize;
} else {
return 14;
} }
return 14;
} }
Widget _buildText(TextCellState state) { Widget _buildText(TextCellState state) {

View File

@ -15,10 +15,10 @@ class RowDetailPage extends StatefulWidget with FlowyOverlayDelegate {
final GridCellBuilder cellBuilder; final GridCellBuilder cellBuilder;
const RowDetailPage({ const RowDetailPage({
super.key,
required this.rowController, required this.rowController,
required this.cellBuilder, required this.cellBuilder,
Key? key, });
}) : super(key: key);
@override @override
State<RowDetailPage> createState() => _RowDetailPageState(); State<RowDetailPage> createState() => _RowDetailPageState();

View File

@ -24,12 +24,8 @@ class RowDocument extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider<RowDocumentBloc>( return BlocProvider<RowDocumentBloc>(
create: (context) => RowDocumentBloc( create: (context) => RowDocumentBloc(viewId: viewId, rowId: rowId)
viewId: viewId, ..add(const RowDocumentEvent.initial()),
rowId: rowId,
)..add(
const RowDocumentEvent.initial(),
),
child: BlocBuilder<RowDocumentBloc, RowDocumentState>( child: BlocBuilder<RowDocumentBloc, RowDocumentState>(
builder: (context, state) { builder: (context, state) {
return state.loadingState.when( return state.loadingState.when(
@ -43,6 +39,9 @@ class RowDocument extends StatelessWidget {
finish: () => RowEditor( finish: () => RowEditor(
viewPB: state.viewPB!, viewPB: state.viewPB!,
scrollController: scrollController, scrollController: scrollController,
onIsEmptyChanged: (isEmpty) => context
.read<RowDocumentBloc>()
.add(RowDocumentEvent.updateIsEmpty(isEmpty)),
), ),
); );
}, },
@ -56,10 +55,12 @@ class RowEditor extends StatefulWidget {
super.key, super.key,
required this.viewPB, required this.viewPB,
required this.scrollController, required this.scrollController,
this.onIsEmptyChanged,
}); });
final ViewPB viewPB; final ViewPB viewPB;
final ScrollController scrollController; final ScrollController scrollController;
final void Function(bool)? onIsEmptyChanged;
@override @override
State<RowEditor> createState() => _RowEditorState(); State<RowEditor> createState() => _RowEditorState();
@ -87,6 +88,14 @@ class _RowEditorState extends State<RowEditor> {
providers: [ providers: [
BlocProvider.value(value: documentBloc), BlocProvider.value(value: documentBloc),
], ],
child: BlocListener<DocumentBloc, DocumentState>(
listenWhen: (previous, current) =>
previous.isDocumentEmpty != current.isDocumentEmpty,
listener: (context, state) {
if (state.isDocumentEmpty != null) {
widget.onIsEmptyChanged?.call(state.isDocumentEmpty!);
}
},
child: BlocBuilder<DocumentBloc, DocumentState>( child: BlocBuilder<DocumentBloc, DocumentState>(
builder: (context, state) { builder: (context, state) {
return state.loadingState.when( return state.loadingState.when(
@ -129,6 +138,7 @@ class _RowEditorState extends State<RowEditor> {
); );
}, },
), ),
),
); );
} }
} }

View File

@ -31,13 +31,7 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
required this.view, required this.view,
}) : _documentListener = DocumentListener(id: view.id), }) : _documentListener = DocumentListener(id: view.id),
_viewListener = ViewListener(viewId: view.id), _viewListener = ViewListener(viewId: view.id),
_documentService = DocumentService(),
_trashService = TrashService(),
super(DocumentState.initial()) { super(DocumentState.initial()) {
_transactionAdapter = TransactionAdapter(
documentId: view.id,
documentService: _documentService,
);
on<DocumentEvent>(_onDocumentEvent); on<DocumentEvent>(_onDocumentEvent);
} }
@ -46,10 +40,13 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
final DocumentListener _documentListener; final DocumentListener _documentListener;
final ViewListener _viewListener; final ViewListener _viewListener;
final DocumentService _documentService; final DocumentService _documentService = DocumentService();
final TrashService _trashService; final TrashService _trashService = TrashService();
late final TransactionAdapter _transactionAdapter; late final TransactionAdapter _transactionAdapter = TransactionAdapter(
documentId: view.id,
documentService: _documentService,
);
EditorState? editorState; EditorState? editorState;
StreamSubscription? _subscription; StreamSubscription? _subscription;
@ -158,6 +155,11 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
// check if the document is empty. // check if the document is empty.
applyRules(); applyRules();
if (!isClosed) {
// ignore: invalid_use_of_visible_for_testing_member
emit(state.copyWith(isDocumentEmpty: editorState.document.isEmpty));
}
}); });
// output the log from the editor when debug mode // output the log from the editor when debug mode
@ -240,6 +242,7 @@ class DocumentState with _$DocumentState {
required DocumentLoadingState loadingState, required DocumentLoadingState loadingState,
required bool isDeleted, required bool isDeleted,
required bool forceClose, required bool forceClose,
bool? isDocumentEmpty,
UserProfilePB? userProfilePB, UserProfilePB? userProfilePB,
}) = _DocumentState; }) = _DocumentState;
@ -247,6 +250,7 @@ class DocumentState with _$DocumentState {
loadingState: _Loading(), loadingState: _Loading(),
isDeleted: false, isDeleted: false,
forceClose: false, forceClose: false,
isDocumentEmpty: null,
userProfilePB: null, userProfilePB: null,
); );
} }

View File

@ -460,7 +460,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b"
dependencies = [ dependencies = [
"borsh-derive", "borsh-derive",
"hashbrown 0.13.2", "hashbrown 0.12.3",
] ]
[[package]] [[package]]
@ -863,7 +863,7 @@ dependencies = [
[[package]] [[package]]
name = "collab" name = "collab"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=68459c6c501cd6d69deda04605839db1b442bb01#68459c6c501cd6d69deda04605839db1b442bb01" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6e30a5b9#6e30a5b9415dc934c845047730a3df6988b864ba"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -883,7 +883,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-database" name = "collab-database"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=68459c6c501cd6d69deda04605839db1b442bb01#68459c6c501cd6d69deda04605839db1b442bb01" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6e30a5b9#6e30a5b9415dc934c845047730a3df6988b864ba"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -913,7 +913,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-derive" name = "collab-derive"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=68459c6c501cd6d69deda04605839db1b442bb01#68459c6c501cd6d69deda04605839db1b442bb01" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6e30a5b9#6e30a5b9415dc934c845047730a3df6988b864ba"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -925,7 +925,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-document" name = "collab-document"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=68459c6c501cd6d69deda04605839db1b442bb01#68459c6c501cd6d69deda04605839db1b442bb01" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6e30a5b9#6e30a5b9415dc934c845047730a3df6988b864ba"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"collab", "collab",
@ -945,7 +945,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-entity" name = "collab-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=68459c6c501cd6d69deda04605839db1b442bb01#68459c6c501cd6d69deda04605839db1b442bb01" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6e30a5b9#6e30a5b9415dc934c845047730a3df6988b864ba"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytes", "bytes",
@ -959,7 +959,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-folder" name = "collab-folder"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=68459c6c501cd6d69deda04605839db1b442bb01#68459c6c501cd6d69deda04605839db1b442bb01" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6e30a5b9#6e30a5b9415dc934c845047730a3df6988b864ba"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",
@ -1001,7 +1001,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-persistence" name = "collab-persistence"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=68459c6c501cd6d69deda04605839db1b442bb01#68459c6c501cd6d69deda04605839db1b442bb01" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6e30a5b9#6e30a5b9415dc934c845047730a3df6988b864ba"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"bincode", "bincode",
@ -1022,7 +1022,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-plugins" name = "collab-plugins"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=68459c6c501cd6d69deda04605839db1b442bb01#68459c6c501cd6d69deda04605839db1b442bb01" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6e30a5b9#6e30a5b9415dc934c845047730a3df6988b864ba"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -1049,7 +1049,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-user" name = "collab-user"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=68459c6c501cd6d69deda04605839db1b442bb01#68459c6c501cd6d69deda04605839db1b442bb01" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6e30a5b9#6e30a5b9415dc934c845047730a3df6988b864ba"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"collab", "collab",
@ -5594,9 +5594,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.107" version = "1.0.108"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
dependencies = [ dependencies = [
"itoa 1.0.6", "itoa 1.0.6",
"ryu", "ryu",

View File

@ -48,14 +48,14 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d37
# To switch to the local path, run: # To switch to the local path, run:
# scripts/tool/update_collab_source.sh # scripts/tool/update_collab_source.sh
# ⚠️⚠️⚠️️ # ⚠️⚠️⚠️️
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "68459c6c501cd6d69deda04605839db1b442bb01" } collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6e30a5b9" }
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "68459c6c501cd6d69deda04605839db1b442bb01" } collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6e30a5b9" }
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "68459c6c501cd6d69deda04605839db1b442bb01" } collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6e30a5b9" }
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "68459c6c501cd6d69deda04605839db1b442bb01" } collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6e30a5b9" }
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "68459c6c501cd6d69deda04605839db1b442bb01" } collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6e30a5b9" }
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "68459c6c501cd6d69deda04605839db1b442bb01" } collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6e30a5b9" }
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "68459c6c501cd6d69deda04605839db1b442bb01" } collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6e30a5b9" }
collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "68459c6c501cd6d69deda04605839db1b442bb01" } collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6e30a5b9" }

View File

@ -0,0 +1,11 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Icons 16 / docs">
<g id="Group 1321314145">
<path id="Vector" d="M9.08889 2V5.81818C9.08889 6.42067 9.5764 6.90909 10.1778 6.90909H12.3556M4.18889 14H11.8111C12.4125 14 12.9 13.5116 12.9 12.9091V7.09091C12.9 6.61883 12.7472 6.15948 12.4644 5.78182L10.2867 2.87273C9.87538 2.32333 9.22991 2 8.54444 2H4.18889C3.58751 2 3.1 2.48842 3.1 3.09091V12.9091C3.1 13.5116 3.58751 14 4.18889 14Z" stroke="#747B84" stroke-width="1.09091"/>
<g id="Vector_2">
<path d="M5.27777 10.7273C4.97708 10.7273 4.73332 10.9715 4.73332 11.2727C4.73332 11.574 4.97708 11.8182 5.27777 11.8182H7.45554C7.75623 11.8182 7.99999 11.574 7.99999 11.2727C7.99999 10.9715 7.75623 10.7273 7.45554 10.7273H5.27777Z" fill="#747B84"/>
<path d="M4.73332 9.09091C4.73332 8.78966 4.97708 8.54546 5.27777 8.54546H9.63332C9.93401 8.54546 10.1778 8.78966 10.1778 9.09091C10.1778 9.39216 9.93401 9.63637 9.63332 9.63637H5.27777C4.97708 9.63637 4.73332 9.39216 4.73332 9.09091Z" fill="#747B84"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -467,7 +467,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b"
dependencies = [ dependencies = [
"borsh-derive", "borsh-derive",
"hashbrown 0.13.2", "hashbrown 0.12.3",
] ]
[[package]] [[package]]
@ -730,7 +730,7 @@ dependencies = [
[[package]] [[package]]
name = "collab" name = "collab"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=68459c6c501cd6d69deda04605839db1b442bb01#68459c6c501cd6d69deda04605839db1b442bb01" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6e30a5b9#6e30a5b9415dc934c845047730a3df6988b864ba"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -750,7 +750,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-database" name = "collab-database"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=68459c6c501cd6d69deda04605839db1b442bb01#68459c6c501cd6d69deda04605839db1b442bb01" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6e30a5b9#6e30a5b9415dc934c845047730a3df6988b864ba"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -780,7 +780,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-derive" name = "collab-derive"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=68459c6c501cd6d69deda04605839db1b442bb01#68459c6c501cd6d69deda04605839db1b442bb01" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6e30a5b9#6e30a5b9415dc934c845047730a3df6988b864ba"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -792,7 +792,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-document" name = "collab-document"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=68459c6c501cd6d69deda04605839db1b442bb01#68459c6c501cd6d69deda04605839db1b442bb01" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6e30a5b9#6e30a5b9415dc934c845047730a3df6988b864ba"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"collab", "collab",
@ -812,7 +812,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-entity" name = "collab-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=68459c6c501cd6d69deda04605839db1b442bb01#68459c6c501cd6d69deda04605839db1b442bb01" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6e30a5b9#6e30a5b9415dc934c845047730a3df6988b864ba"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytes", "bytes",
@ -826,7 +826,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-folder" name = "collab-folder"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=68459c6c501cd6d69deda04605839db1b442bb01#68459c6c501cd6d69deda04605839db1b442bb01" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6e30a5b9#6e30a5b9415dc934c845047730a3df6988b864ba"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",
@ -868,7 +868,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-persistence" name = "collab-persistence"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=68459c6c501cd6d69deda04605839db1b442bb01#68459c6c501cd6d69deda04605839db1b442bb01" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6e30a5b9#6e30a5b9415dc934c845047730a3df6988b864ba"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"bincode", "bincode",
@ -889,7 +889,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-plugins" name = "collab-plugins"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=68459c6c501cd6d69deda04605839db1b442bb01#68459c6c501cd6d69deda04605839db1b442bb01" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6e30a5b9#6e30a5b9415dc934c845047730a3df6988b864ba"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -916,7 +916,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-user" name = "collab-user"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=68459c6c501cd6d69deda04605839db1b442bb01#68459c6c501cd6d69deda04605839db1b442bb01" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6e30a5b9#6e30a5b9415dc934c845047730a3df6988b864ba"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"collab", "collab",

View File

@ -93,11 +93,11 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d37
# To switch to the local path, run: # To switch to the local path, run:
# scripts/tool/update_collab_source.sh # scripts/tool/update_collab_source.sh
# ⚠️⚠️⚠️️ # ⚠️⚠️⚠️️
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "68459c6c501cd6d69deda04605839db1b442bb01" } collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6e30a5b9" }
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "68459c6c501cd6d69deda04605839db1b442bb01" } collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6e30a5b9" }
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "68459c6c501cd6d69deda04605839db1b442bb01" } collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6e30a5b9" }
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "68459c6c501cd6d69deda04605839db1b442bb01" } collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6e30a5b9" }
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "68459c6c501cd6d69deda04605839db1b442bb01" } collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6e30a5b9" }
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "68459c6c501cd6d69deda04605839db1b442bb01" } collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6e30a5b9" }
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "68459c6c501cd6d69deda04605839db1b442bb01" } collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6e30a5b9" }
collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "68459c6c501cd6d69deda04605839db1b442bb01" } collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6e30a5b9" }

View File

@ -265,6 +265,7 @@ async fn update_row_meta_event_with_url_test() {
view_id: grid_view.id.clone(), view_id: grid_view.id.clone(),
icon_url: Some("icon_url".to_owned()), icon_url: Some("icon_url".to_owned()),
cover_url: None, cover_url: None,
is_document_empty: None,
}; };
let error = test.update_row_meta(changeset).await; let error = test.update_row_meta(changeset).await;
assert!(error.is_none()); assert!(error.is_none());
@ -293,6 +294,7 @@ async fn update_row_meta_event_with_cover_test() {
view_id: grid_view.id.clone(), view_id: grid_view.id.clone(),
cover_url: Some("cover url".to_owned()), cover_url: Some("cover url".to_owned()),
icon_url: None, icon_url: None,
is_document_empty: None,
}; };
let error = test.update_row_meta(changeset).await; let error = test.update_row_meta(changeset).await;
assert!(error.is_none()); assert!(error.is_none());

View File

@ -59,6 +59,9 @@ pub struct RowMetaPB {
#[pb(index = 4, one_of)] #[pb(index = 4, one_of)]
pub cover: Option<String>, pub cover: Option<String>,
#[pb(index = 5)]
pub is_document_empty: bool,
} }
impl std::convert::From<&RowDetail> for RowMetaPB { impl std::convert::From<&RowDetail> for RowMetaPB {
@ -68,6 +71,7 @@ impl std::convert::From<&RowDetail> for RowMetaPB {
document_id: row_detail.document_id.clone(), document_id: row_detail.document_id.clone(),
icon: row_detail.meta.icon_url.clone(), icon: row_detail.meta.icon_url.clone(),
cover: row_detail.meta.cover_url.clone(), cover: row_detail.meta.cover_url.clone(),
is_document_empty: row_detail.meta.is_document_empty.clone(),
} }
} }
} }
@ -78,6 +82,7 @@ impl std::convert::From<RowDetail> for RowMetaPB {
document_id: row_detail.document_id, document_id: row_detail.document_id,
icon: row_detail.meta.icon_url, icon: row_detail.meta.icon_url,
cover: row_detail.meta.cover_url, cover: row_detail.meta.cover_url,
is_document_empty: row_detail.meta.is_document_empty,
} }
} }
} }
@ -96,6 +101,9 @@ pub struct UpdateRowMetaChangesetPB {
#[pb(index = 4, one_of)] #[pb(index = 4, one_of)]
pub cover_url: Option<String>, pub cover_url: Option<String>,
#[pb(index = 5, one_of)]
pub is_document_empty: Option<bool>,
} }
#[derive(Debug)] #[derive(Debug)]
@ -104,6 +112,7 @@ pub struct UpdateRowMetaParams {
pub view_id: String, pub view_id: String,
pub icon_url: Option<String>, pub icon_url: Option<String>,
pub cover_url: Option<String>, pub cover_url: Option<String>,
pub is_document_empty: Option<bool>,
} }
impl TryInto<UpdateRowMetaParams> for UpdateRowMetaChangesetPB { impl TryInto<UpdateRowMetaParams> for UpdateRowMetaChangesetPB {
@ -122,6 +131,7 @@ impl TryInto<UpdateRowMetaParams> for UpdateRowMetaChangesetPB {
view_id, view_id,
icon_url: self.icon_url, icon_url: self.icon_url,
cover_url: self.cover_url, cover_url: self.cover_url,
is_document_empty: self.is_document_empty,
}) })
} }
} }

View File

@ -546,6 +546,7 @@ impl DatabaseEditor {
document_id: row_document_id, document_id: row_document_id,
icon: row_meta.icon_url, icon: row_meta.icon_url,
cover: row_meta.cover_url, cover: row_meta.cover_url,
is_document_empty: row_meta.is_document_empty,
}) })
} else { } else {
warn!("the row:{} is exist in view:{}", row_id.as_str(), view_id); warn!("the row:{} is exist in view:{}", row_id.as_str(), view_id);
@ -577,7 +578,8 @@ impl DatabaseEditor {
self.database.lock().update_row_meta(row_id, |meta_update| { self.database.lock().update_row_meta(row_id, |meta_update| {
meta_update meta_update
.insert_cover_if_not_none(changeset.cover_url) .insert_cover_if_not_none(changeset.cover_url)
.insert_icon_if_not_none(changeset.icon_url); .insert_icon_if_not_none(changeset.icon_url)
.update_is_document_empty_if_not_none(changeset.is_document_empty);
}); });
// Use the temporary row meta to get rid of the lock that not implement the `Send` or 'Sync' trait. // Use the temporary row meta to get rid of the lock that not implement the `Send` or 'Sync' trait.