mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-12-28 05:34:41 +00:00
chore: show document icon or emoji (#6144)
Some checks are pending
Commit messages lint / commitlint (push) Waiting to run
Docker-CI / build-app (push) Waiting to run
Flutter-CI / prepare-linux (development-linux-x86_64, ubuntu-latest, x86_64-unknown-linux-gnu) (push) Waiting to run
Flutter-CI / prepare-windows (development-windows-x86, windows-latest, x86_64-pc-windows-msvc) (push) Waiting to run
Flutter-CI / prepare-macos (development-mac-x86_64, macos-latest, x86_64-apple-darwin) (push) Waiting to run
Flutter-CI / unit_test (development-linux-x86_64, ubuntu-latest, x86_64-unknown-linux-gnu) (push) Blocked by required conditions
Flutter-CI / cloud_integration_test (development-linux-x86_64, ubuntu-latest, x86_64-unknown-linux-gnu) (push) Blocked by required conditions
Flutter-CI / integration_test_1 (ubuntu-latest, x86_64-unknown-linux-gnu) (push) Blocked by required conditions
Flutter-CI / integration_test_2 (ubuntu-latest, x86_64-unknown-linux-gnu) (push) Blocked by required conditions
Flutter-CI / integration_test_3 (ubuntu-latest, x86_64-unknown-linux-gnu) (push) Blocked by required conditions
iOS CI / build-self-hosted (push) Waiting to run
iOS CI / build-macos (push) Waiting to run
Rust-CI / self-hosted-job (push) Waiting to run
Rust-CI / ubuntu-job (push) Waiting to run
Rust code coverage / tests (push) Waiting to run
Some checks are pending
Commit messages lint / commitlint (push) Waiting to run
Docker-CI / build-app (push) Waiting to run
Flutter-CI / prepare-linux (development-linux-x86_64, ubuntu-latest, x86_64-unknown-linux-gnu) (push) Waiting to run
Flutter-CI / prepare-windows (development-windows-x86, windows-latest, x86_64-pc-windows-msvc) (push) Waiting to run
Flutter-CI / prepare-macos (development-mac-x86_64, macos-latest, x86_64-apple-darwin) (push) Waiting to run
Flutter-CI / unit_test (development-linux-x86_64, ubuntu-latest, x86_64-unknown-linux-gnu) (push) Blocked by required conditions
Flutter-CI / cloud_integration_test (development-linux-x86_64, ubuntu-latest, x86_64-unknown-linux-gnu) (push) Blocked by required conditions
Flutter-CI / integration_test_1 (ubuntu-latest, x86_64-unknown-linux-gnu) (push) Blocked by required conditions
Flutter-CI / integration_test_2 (ubuntu-latest, x86_64-unknown-linux-gnu) (push) Blocked by required conditions
Flutter-CI / integration_test_3 (ubuntu-latest, x86_64-unknown-linux-gnu) (push) Blocked by required conditions
iOS CI / build-self-hosted (push) Waiting to run
iOS CI / build-macos (push) Waiting to run
Rust-CI / self-hosted-job (push) Waiting to run
Rust-CI / ubuntu-job (push) Waiting to run
Rust code coverage / tests (push) Waiting to run
* chore: show icon * chore: rename * chore: adjust UI * chore: remove unused property * chore: update test * chore: fix test * chore: fix test
This commit is contained in:
parent
d264f3dbde
commit
01d7d6e900
2
.github/workflows/flutter_ci.yaml
vendored
2
.github/workflows/flutter_ci.yaml
vendored
@ -246,7 +246,7 @@ jobs:
|
||||
- name: Run Docker-Compose
|
||||
working-directory: AppFlowy-Cloud
|
||||
env:
|
||||
BACKEND_VERSION: 0.3.24-amd64
|
||||
BACKEND_VERSION: 0.6.4-amd64
|
||||
run: |
|
||||
if [ "$(docker ps --filter name=appflowy-cloud -q)" == "" ]; then
|
||||
docker compose pull
|
||||
|
||||
2
.github/workflows/rust_ci.yaml
vendored
2
.github/workflows/rust_ci.yaml
vendored
@ -106,6 +106,8 @@ jobs:
|
||||
|
||||
- name: Run Docker-Compose
|
||||
working-directory: AppFlowy-Cloud
|
||||
env:
|
||||
BACKEND_VERSION: 0.6.4-amd64
|
||||
run: |
|
||||
if [ "$(docker ps --filter name=appflowy-cloud -q)" == "" ]; then
|
||||
docker compose pull
|
||||
|
||||
@ -2,6 +2,7 @@ import 'dart:async';
|
||||
|
||||
import 'package:appflowy/plugins/database/application/cell/cell_controller_builder.dart';
|
||||
import 'package:appflowy/plugins/database/application/field/field_info.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
@ -42,8 +43,8 @@ class TextCellBloc extends Bloc<TextCellEvent, TextCellState> {
|
||||
emit(state.copyWith(wrap: wrap));
|
||||
}
|
||||
},
|
||||
didUpdateEmoji: (String emoji) {
|
||||
emit(state.copyWith(emoji: emoji));
|
||||
didUpdateEmoji: (String emoji, bool hasDocument) {
|
||||
// emit(state.copyWith(emoji: emoji, hasDocument: hasDocument));
|
||||
},
|
||||
updateText: (String text) {
|
||||
if (state.content != text) {
|
||||
@ -66,13 +67,6 @@ class TextCellBloc extends Bloc<TextCellEvent, TextCellState> {
|
||||
}
|
||||
},
|
||||
onFieldChanged: _onFieldChangedListener,
|
||||
onRowMetaChanged: cellController.fieldInfo.isPrimary
|
||||
? () {
|
||||
if (!isClosed) {
|
||||
add(TextCellEvent.didUpdateEmoji(cellController.icon ?? ""));
|
||||
}
|
||||
}
|
||||
: null,
|
||||
);
|
||||
}
|
||||
|
||||
@ -91,14 +85,18 @@ class TextCellEvent with _$TextCellEvent {
|
||||
_DidUpdateField;
|
||||
const factory TextCellEvent.updateText(String text) = _UpdateText;
|
||||
const factory TextCellEvent.enableEdit(bool enabled) = _EnableEdit;
|
||||
const factory TextCellEvent.didUpdateEmoji(String emoji) = _UpdateEmoji;
|
||||
const factory TextCellEvent.didUpdateEmoji(
|
||||
String emoji,
|
||||
bool hasDocument,
|
||||
) = _UpdateEmoji;
|
||||
}
|
||||
|
||||
@freezed
|
||||
class TextCellState with _$TextCellState {
|
||||
const factory TextCellState({
|
||||
required String content,
|
||||
required String emoji,
|
||||
required ValueNotifier<String>? emoji,
|
||||
required ValueNotifier<bool>? hasDocument,
|
||||
required bool enableEdit,
|
||||
required bool wrap,
|
||||
}) = _TextCellState;
|
||||
@ -106,13 +104,16 @@ class TextCellState with _$TextCellState {
|
||||
factory TextCellState.initial(TextCellController cellController) {
|
||||
final cellData = cellController.getCellData() ?? "";
|
||||
final wrap = cellController.fieldInfo.wrapCellContent ?? true;
|
||||
final emoji =
|
||||
cellController.fieldInfo.isPrimary ? cellController.icon ?? "" : "";
|
||||
ValueNotifier<String>? emoji;
|
||||
if (cellController.fieldInfo.isPrimary) {
|
||||
emoji = cellController.icon;
|
||||
}
|
||||
|
||||
return TextCellState(
|
||||
content: cellData,
|
||||
emoji: emoji,
|
||||
enableEdit: false,
|
||||
hasDocument: cellController.hasDocument,
|
||||
wrap: wrap,
|
||||
);
|
||||
}
|
||||
|
||||
@ -5,7 +5,6 @@ import 'package:appflowy/plugins/database/application/field/field_info.dart';
|
||||
import 'package:appflowy/plugins/database/domain/cell_listener.dart';
|
||||
import 'package:appflowy/plugins/database/application/field/type_option/type_option_data_parser.dart';
|
||||
import 'package:appflowy/plugins/database/application/row/row_cache.dart';
|
||||
import 'package:appflowy/plugins/database/domain/row_meta_listener.dart';
|
||||
import 'package:appflowy/plugins/database/application/row/row_service.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||
@ -61,10 +60,8 @@ class CellController<T, D> {
|
||||
final CellDataPersistence<D> _cellDataPersistence;
|
||||
|
||||
CellListener? _cellListener;
|
||||
RowMetaListener? _rowMetaListener;
|
||||
CellDataNotifier<T?>? _cellDataNotifier;
|
||||
|
||||
VoidCallback? _onRowMetaChanged;
|
||||
Timer? _loadDataOperation;
|
||||
Timer? _saveDataOperation;
|
||||
|
||||
@ -75,8 +72,9 @@ class CellController<T, D> {
|
||||
FieldInfo get fieldInfo => _fieldController.getField(_cellContext.fieldId)!;
|
||||
FieldType get fieldType =>
|
||||
_fieldController.getField(_cellContext.fieldId)!.fieldType;
|
||||
RowMetaPB? get rowMeta => _rowCache.getRow(rowId)?.rowMeta;
|
||||
String? get icon => rowMeta?.icon;
|
||||
ValueNotifier<String>? get icon => _rowCache.getRow(rowId)?.rowIconNotifier;
|
||||
ValueNotifier<bool>? get hasDocument =>
|
||||
_rowCache.getRow(rowId)?.rowDocumentNotifier;
|
||||
CellMemCache get _cellCache => _rowCache.cellCache;
|
||||
|
||||
/// casting method for painless type coersion
|
||||
@ -89,15 +87,6 @@ class CellController<T, D> {
|
||||
fieldId: _cellContext.fieldId,
|
||||
);
|
||||
|
||||
_rowCache.addListener(
|
||||
rowId: rowId,
|
||||
onRowChanged: (context, reason) {
|
||||
if (reason == const ChangedReason.didFetchRow()) {
|
||||
_onRowMetaChanged?.call();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// 1. Listen on user edit event and load the new cell data if needed.
|
||||
// For example:
|
||||
// user input: 12
|
||||
@ -116,23 +105,12 @@ class CellController<T, D> {
|
||||
fieldId,
|
||||
onFieldChanged: _onFieldChangedListener,
|
||||
);
|
||||
|
||||
// 3. If the field is primary listen to row meta changes.
|
||||
if (fieldInfo.field.isPrimary) {
|
||||
_rowMetaListener = RowMetaListener(_cellContext.rowId);
|
||||
_rowMetaListener?.start(
|
||||
callback: (newRowMeta) {
|
||||
_onRowMetaChanged?.call();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Add a new listener
|
||||
VoidCallback? addListener({
|
||||
required void Function(T?) onCellChanged,
|
||||
void Function(FieldInfo fieldInfo)? onFieldChanged,
|
||||
VoidCallback? onRowMetaChanged,
|
||||
}) {
|
||||
/// an adaptor for the onCellChanged listener
|
||||
void onCellChangedFn() => onCellChanged(_cellDataNotifier?.value);
|
||||
@ -145,8 +123,6 @@ class CellController<T, D> {
|
||||
);
|
||||
}
|
||||
|
||||
_onRowMetaChanged = onRowMetaChanged;
|
||||
|
||||
// Return the function pointer that can be used when calling removeListener.
|
||||
return onCellChangedFn;
|
||||
}
|
||||
@ -242,9 +218,6 @@ class CellController<T, D> {
|
||||
}
|
||||
|
||||
Future<void> dispose() async {
|
||||
await _rowMetaListener?.stop();
|
||||
_rowMetaListener = null;
|
||||
|
||||
await _cellListener?.stop();
|
||||
_cellListener = null;
|
||||
|
||||
@ -258,7 +231,6 @@ class CellController<T, D> {
|
||||
_saveDataOperation?.cancel();
|
||||
_cellDataNotifier?.dispose();
|
||||
_cellDataNotifier = null;
|
||||
_onRowMetaChanged = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -92,12 +92,19 @@ class RowCache {
|
||||
}
|
||||
|
||||
void setRowMeta(RowMetaPB rowMeta) {
|
||||
final rowInfo = buildGridRow(rowMeta);
|
||||
_rowList.add(rowInfo);
|
||||
var rowInfo = _rowList.get(rowMeta.id);
|
||||
if (rowInfo != null) {
|
||||
rowInfo.updateRowMeta(rowMeta);
|
||||
} else {
|
||||
rowInfo = buildGridRow(rowMeta);
|
||||
_rowList.add(rowInfo);
|
||||
}
|
||||
|
||||
_changedNotifier?.receive(const ChangedReason.didFetchRow());
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
_rowList.dispose();
|
||||
_rowLifeCycle.onRowDisposed();
|
||||
_changedNotifier?.dispose();
|
||||
_changedNotifier = null;
|
||||
@ -176,8 +183,10 @@ class RowCache {
|
||||
}
|
||||
}
|
||||
|
||||
final updatedIndexs =
|
||||
_rowList.updateRows(updatedList, (rowId) => buildGridRow(rowId));
|
||||
final updatedIndexs = _rowList.updateRows(
|
||||
rowMetas: updatedList,
|
||||
builder: (rowId) => buildGridRow(rowId),
|
||||
);
|
||||
|
||||
if (updatedIndexs.isNotEmpty) {
|
||||
_changedNotifier?.receive(ChangedReason.update(updatedIndexs));
|
||||
@ -251,9 +260,7 @@ class RowCache {
|
||||
final rowInfo = _rowList.get(rowMetaPB.id);
|
||||
final rowIndex = _rowList.indexOfRow(rowMetaPB.id);
|
||||
if (rowInfo != null && rowIndex != null) {
|
||||
final updatedRowInfo = rowInfo.copyWith(rowMeta: rowMetaPB);
|
||||
_rowList.remove(rowMetaPB.id);
|
||||
_rowList.insert(rowIndex, updatedRowInfo);
|
||||
rowInfo.rowMetaNotifier.value = rowMetaPB;
|
||||
|
||||
final UpdatedIndexMap updatedIndexs = UpdatedIndexMap();
|
||||
updatedIndexs[rowMetaPB.id] = UpdatedIndex(
|
||||
@ -308,15 +315,38 @@ class RowChangesetNotifier extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
@unfreezed
|
||||
class RowInfo with _$RowInfo {
|
||||
const RowInfo._();
|
||||
factory RowInfo({
|
||||
required UnmodifiableListView<FieldInfo> fields,
|
||||
class RowInfo {
|
||||
RowInfo({
|
||||
required this.fields,
|
||||
required RowMetaPB rowMeta,
|
||||
}) = _RowInfo;
|
||||
}) : rowMetaNotifier = ValueNotifier<RowMetaPB>(rowMeta),
|
||||
rowIconNotifier = ValueNotifier<String>(rowMeta.icon),
|
||||
rowDocumentNotifier = ValueNotifier<bool>(
|
||||
!(rowMeta.hasIsDocumentEmpty() ? rowMeta.isDocumentEmpty : true),
|
||||
);
|
||||
|
||||
String get rowId => rowMeta.id;
|
||||
final UnmodifiableListView<FieldInfo> fields;
|
||||
final ValueNotifier<RowMetaPB> rowMetaNotifier;
|
||||
final ValueNotifier<String> rowIconNotifier;
|
||||
final ValueNotifier<bool> rowDocumentNotifier;
|
||||
|
||||
String get rowId => rowMetaNotifier.value.id;
|
||||
|
||||
RowMetaPB get rowMeta => rowMetaNotifier.value;
|
||||
|
||||
/// Updates the RowMeta and automatically updates the related notifiers.
|
||||
void updateRowMeta(RowMetaPB newMeta) {
|
||||
rowMetaNotifier.value = newMeta;
|
||||
rowIconNotifier.value = newMeta.icon;
|
||||
rowDocumentNotifier.value = !newMeta.isDocumentEmpty;
|
||||
}
|
||||
|
||||
/// Dispose of the notifiers when they are no longer needed.
|
||||
void dispose() {
|
||||
rowMetaNotifier.dispose();
|
||||
rowIconNotifier.dispose();
|
||||
rowDocumentNotifier.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
typedef InsertedIndexs = List<InsertedIndex>;
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'dart:collection';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/row_entities.pb.dart';
|
||||
|
||||
@ -117,20 +118,23 @@ class RowList {
|
||||
return deletedIndex;
|
||||
}
|
||||
|
||||
UpdatedIndexMap updateRows(
|
||||
List<RowMetaPB> rowMetas,
|
||||
RowInfo Function(RowMetaPB) builder,
|
||||
) {
|
||||
UpdatedIndexMap updateRows({
|
||||
required List<RowMetaPB> rowMetas,
|
||||
required RowInfo Function(RowMetaPB) builder,
|
||||
}) {
|
||||
final UpdatedIndexMap updatedIndexs = UpdatedIndexMap();
|
||||
for (final rowMeta in rowMetas) {
|
||||
final index = _rowInfos.indexWhere(
|
||||
(rowInfo) => rowInfo.rowId == rowMeta.id,
|
||||
);
|
||||
if (index != -1) {
|
||||
rowInfoByRowId[rowMeta.id]?.updateRowMeta(rowMeta);
|
||||
} else {
|
||||
final insertIndex = max(index, _rowInfos.length);
|
||||
final rowInfo = builder(rowMeta);
|
||||
insert(index, rowInfo);
|
||||
insert(insertIndex, rowInfo);
|
||||
updatedIndexs[rowMeta.id] = UpdatedIndex(
|
||||
index: index,
|
||||
index: insertIndex,
|
||||
rowId: rowMeta.id,
|
||||
);
|
||||
}
|
||||
@ -162,4 +166,11 @@ class RowList {
|
||||
bool contains(RowId rowId) {
|
||||
return rowInfoByRowId[rowId] != null;
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
for (final rowInfo in _rowInfos) {
|
||||
rowInfo.dispose();
|
||||
}
|
||||
_rowInfos.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ class RowBackendService {
|
||||
}
|
||||
|
||||
Future<FlowyResult<void, FlowyError>> initRow(RowId rowId) async {
|
||||
final payload = RowIdPB()
|
||||
final payload = DatabaseViewRowIdPB()
|
||||
..viewId = viewId
|
||||
..rowId = rowId;
|
||||
|
||||
@ -65,7 +65,7 @@ class RowBackendService {
|
||||
required String viewId,
|
||||
required String rowId,
|
||||
}) {
|
||||
final payload = RowIdPB()
|
||||
final payload = DatabaseViewRowIdPB()
|
||||
..viewId = viewId
|
||||
..rowId = rowId;
|
||||
|
||||
@ -73,7 +73,7 @@ class RowBackendService {
|
||||
}
|
||||
|
||||
Future<FlowyResult<RowMetaPB, FlowyError>> getRowMeta(RowId rowId) {
|
||||
final payload = RowIdPB.create()
|
||||
final payload = DatabaseViewRowIdPB.create()
|
||||
..viewId = viewId
|
||||
..rowId = rowId;
|
||||
|
||||
@ -119,7 +119,7 @@ class RowBackendService {
|
||||
String viewId,
|
||||
RowId rowId,
|
||||
) {
|
||||
final payload = RowIdPB(
|
||||
final payload = DatabaseViewRowIdPB(
|
||||
viewId: viewId,
|
||||
rowId: rowId,
|
||||
);
|
||||
|
||||
@ -220,7 +220,7 @@ class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
|
||||
}
|
||||
|
||||
Future<CalendarEventData<CalendarDayEvent>?> _loadEvent(RowId rowId) async {
|
||||
final payload = RowIdPB(viewId: viewId, rowId: rowId);
|
||||
final payload = DatabaseViewRowIdPB(viewId: viewId, rowId: rowId);
|
||||
return DatabaseEventGetCalendarEvent(payload).send().then((result) {
|
||||
return result.fold(
|
||||
(eventPB) => _calendarEventDataFromEventPB(eventPB),
|
||||
|
||||
@ -77,7 +77,7 @@ class UnscheduleEventsBloc
|
||||
Future<CalendarEventPB?> _loadEvent(
|
||||
RowId rowId,
|
||||
) async {
|
||||
final payload = RowIdPB(viewId: viewId, rowId: rowId);
|
||||
final payload = DatabaseViewRowIdPB(viewId: viewId, rowId: rowId);
|
||||
return DatabaseEventGetCalendarEvent(payload).send().then(
|
||||
(result) => result.fold(
|
||||
(eventPB) => eventPB,
|
||||
|
||||
@ -140,12 +140,13 @@ class _TextCellState extends State<TextCardCell> {
|
||||
}
|
||||
|
||||
Widget? _buildIcon(TextCellState state) {
|
||||
if (state.emoji.isNotEmpty) {
|
||||
if (state.emoji?.value.isNotEmpty ?? false) {
|
||||
return Text(
|
||||
state.emoji,
|
||||
state.emoji?.value ?? '',
|
||||
style: widget.style.titleTextStyle,
|
||||
);
|
||||
}
|
||||
|
||||
if (widget.showNotes) {
|
||||
return FlowyTooltip(
|
||||
message: LocaleKeys.board_notesTooltip.tr(),
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/plugins/database/application/cell/bloc/text_cell_bloc.dart';
|
||||
import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.dart';
|
||||
import 'package:appflowy/plugins/database/widgets/row/cells/cell_container.dart';
|
||||
@ -20,26 +21,7 @@ class DesktopGridTextCellSkin extends IEditableTextCellSkin {
|
||||
padding: GridSize.cellContentInsets,
|
||||
child: Row(
|
||||
children: [
|
||||
BlocBuilder<TextCellBloc, TextCellState>(
|
||||
buildWhen: (p, c) => p.emoji != c.emoji,
|
||||
builder: (context, state) {
|
||||
if (state.emoji.isEmpty) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return Center(
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
FlowyText(
|
||||
state.emoji,
|
||||
fontSize: 16,
|
||||
),
|
||||
const HSpace(6),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
const _IconOrEmoji(),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: textEditingController,
|
||||
@ -62,3 +44,49 @@ class DesktopGridTextCellSkin extends IEditableTextCellSkin {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _IconOrEmoji extends StatelessWidget {
|
||||
const _IconOrEmoji();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<TextCellBloc, TextCellState>(
|
||||
builder: (context, state) {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (state.emoji != null)
|
||||
ValueListenableBuilder<String>(
|
||||
valueListenable: state.emoji!,
|
||||
builder: (context, value, child) {
|
||||
if (value.isEmpty) {
|
||||
return const SizedBox.shrink();
|
||||
} else {
|
||||
return FlowyText(
|
||||
value,
|
||||
fontSize: 16,
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
if (state.hasDocument != null)
|
||||
ValueListenableBuilder<bool>(
|
||||
valueListenable: state.hasDocument!,
|
||||
builder: (context, hasDocument, child) {
|
||||
if ((state.emoji?.value.isEmpty ?? true) && hasDocument) {
|
||||
return FlowySvg(
|
||||
FlowySvgs.notes_s,
|
||||
color: Theme.of(context).hintColor,
|
||||
);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
},
|
||||
),
|
||||
const HSpace(6),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ class MobileGridTextCellSkin extends IEditableTextCellSkin {
|
||||
buildWhen: (p, c) => p.emoji != c.emoji,
|
||||
builder: (context, state) => Center(
|
||||
child: FlowyText.emoji(
|
||||
state.emoji,
|
||||
state.emoji?.value ?? "",
|
||||
fontSize: 15,
|
||||
optimizeEmojiAlign: true,
|
||||
),
|
||||
|
||||
@ -3,12 +3,13 @@ import {
|
||||
MoveGroupRowPayloadPB,
|
||||
MoveRowPayloadPB,
|
||||
OrderObjectPositionTypePB,
|
||||
RepeatedRowIdPB,
|
||||
RowIdPB,
|
||||
UpdateRowMetaChangesetPB,
|
||||
} from '@/services/backend';
|
||||
import {
|
||||
DatabaseEventCreateRow,
|
||||
DatabaseEventDeleteRow,
|
||||
DatabaseEventDeleteRows,
|
||||
DatabaseEventDuplicateRow,
|
||||
DatabaseEventGetRowMeta,
|
||||
DatabaseEventMoveGroupRow,
|
||||
@ -51,13 +52,12 @@ export async function duplicateRow(viewId: string, rowId: string, groupId?: stri
|
||||
}
|
||||
|
||||
export async function deleteRow(viewId: string, rowId: string, groupId?: string): Promise<void> {
|
||||
const payload = RowIdPB.fromObject({
|
||||
const payload = RepeatedRowIdPB.fromObject({
|
||||
view_id: viewId,
|
||||
row_id: rowId,
|
||||
group_id: groupId,
|
||||
row_ids: [rowId],
|
||||
});
|
||||
|
||||
const result = await DatabaseEventDeleteRow(payload);
|
||||
const result = await DatabaseEventDeleteRows(payload);
|
||||
|
||||
return result.unwrap();
|
||||
}
|
||||
|
||||
@ -262,7 +262,7 @@ impl EventIntegrationTest {
|
||||
pub async fn get_row(&self, view_id: &str, row_id: &str) -> OptionalRowPB {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(DatabaseEvent::GetRow)
|
||||
.payload(RowIdPB {
|
||||
.payload(DatabaseViewRowIdPB {
|
||||
view_id: view_id.to_string(),
|
||||
row_id: row_id.to_string(),
|
||||
group_id: None,
|
||||
@ -275,7 +275,7 @@ impl EventIntegrationTest {
|
||||
pub async fn get_row_meta(&self, view_id: &str, row_id: &str) -> RowMetaPB {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(DatabaseEvent::GetRowMeta)
|
||||
.payload(RowIdPB {
|
||||
.payload(DatabaseViewRowIdPB {
|
||||
view_id: view_id.to_string(),
|
||||
row_id: row_id.to_string(),
|
||||
group_id: None,
|
||||
@ -297,7 +297,7 @@ impl EventIntegrationTest {
|
||||
pub async fn duplicate_row(&self, view_id: &str, row_id: &str) -> Option<FlowyError> {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(DatabaseEvent::DuplicateRow)
|
||||
.payload(RowIdPB {
|
||||
.payload(DatabaseViewRowIdPB {
|
||||
view_id: view_id.to_string(),
|
||||
row_id: row_id.to_string(),
|
||||
group_id: None,
|
||||
|
||||
@ -288,14 +288,14 @@ async fn update_row_meta_event_with_cover_test() {
|
||||
|
||||
// By default the row icon is None.
|
||||
let row = test.get_row_meta(&grid_view.id, &database.rows[0].id).await;
|
||||
assert_eq!(row.cover, None);
|
||||
assert_eq!(row.icon, None);
|
||||
|
||||
// Insert cover to the row.
|
||||
let changeset = UpdateRowMetaChangesetPB {
|
||||
id: database.rows[0].id.clone(),
|
||||
view_id: grid_view.id.clone(),
|
||||
cover_url: Some("cover url".to_owned()),
|
||||
icon_url: None,
|
||||
icon_url: Some("cover url".to_owned()),
|
||||
cover_url: None,
|
||||
is_document_empty: None,
|
||||
};
|
||||
let error = test.update_row_meta(changeset).await;
|
||||
@ -303,7 +303,7 @@ async fn update_row_meta_event_with_cover_test() {
|
||||
|
||||
// Check if the icon is updated.
|
||||
let row = test.get_row_meta(&grid_view.id, &database.rows[0].id).await;
|
||||
assert_eq!(row.cover, Some("cover url".to_owned()));
|
||||
assert_eq!(row.icon, Some("cover url".to_owned()));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
@ -55,8 +55,8 @@ async fn af_cloud_sync_anon_user_document_test() {
|
||||
// workspace:
|
||||
// view: SyncDocument
|
||||
let views = test.get_all_workspace_views().await;
|
||||
assert_eq!(views.len(), 2);
|
||||
let document_id = views[1].id.clone();
|
||||
assert_eq!(views.len(), 3);
|
||||
let document_id = views[2].id.clone();
|
||||
test.open_document(document_id.clone()).await;
|
||||
|
||||
// wait all update are send to the remote
|
||||
|
||||
@ -77,11 +77,11 @@ async fn migrate_anon_user_data_to_af_cloud_test() {
|
||||
assert_eq!(user.authenticator, AuthenticatorPB::AppFlowyCloud);
|
||||
|
||||
let user_first_level_views = test.get_all_workspace_views().await;
|
||||
assert_eq!(user_first_level_views.len(), 2);
|
||||
assert_eq!(user_first_level_views.len(), 3);
|
||||
|
||||
println!("user first level views: {:?}", user_first_level_views);
|
||||
let user_second_level_views = test
|
||||
.get_view(&user_first_level_views[1].id)
|
||||
.get_view(&user_first_level_views[2].id)
|
||||
.await
|
||||
.child_views;
|
||||
println!("user second level views: {:?}", user_second_level_views);
|
||||
@ -95,11 +95,11 @@ async fn migrate_anon_user_data_to_af_cloud_test() {
|
||||
assert_eq!(anon_first_level_views.len(), 1);
|
||||
|
||||
// the first view of user_first_level_views is the default get started view
|
||||
assert_eq!(user_first_level_views.len(), 2);
|
||||
assert_eq!(user_first_level_views.len(), 3);
|
||||
assert_ne!(anon_first_level_views[0].id, user_first_level_views[1].id);
|
||||
assert_eq!(
|
||||
anon_first_level_views[0].name,
|
||||
user_first_level_views[1].name
|
||||
user_first_level_views[2].name
|
||||
);
|
||||
|
||||
// check second level
|
||||
|
||||
@ -28,17 +28,18 @@ async fn import_appflowy_data_need_migration_test() {
|
||||
.unwrap();
|
||||
// after import, the structure is:
|
||||
// workspace:
|
||||
// view: Getting Started
|
||||
// view: Generate
|
||||
// view: Shared
|
||||
// view: 037_local
|
||||
// view: Getting Started
|
||||
// view: Document1
|
||||
// view: Document2
|
||||
|
||||
let views = test.get_all_workspace_views().await;
|
||||
assert_eq!(views.len(), 2);
|
||||
assert_eq!(views[1].name, import_container_name);
|
||||
assert_eq!(views.len(), 3);
|
||||
assert_eq!(views[2].name, import_container_name);
|
||||
|
||||
let child_views = test.get_view(&views[1].id).await.child_views;
|
||||
let child_views = test.get_view(&views[2].id).await.child_views;
|
||||
assert_eq!(child_views.len(), 1);
|
||||
|
||||
let child_views = test.get_view(&child_views[0].id).await.child_views;
|
||||
@ -81,13 +82,13 @@ async fn import_appflowy_data_folder_into_new_view_test() {
|
||||
// view: Grid1
|
||||
// view: Grid2
|
||||
let views = test.get_all_workspace_views().await;
|
||||
assert_eq!(views.len(), 2);
|
||||
assert_eq!(views[1].name, import_container_name);
|
||||
assert_eq!(views.len(), 3);
|
||||
assert_eq!(views[2].name, import_container_name);
|
||||
|
||||
// the 040_local should be an empty document, so try to get the document data
|
||||
let _ = test.get_document_data(&views[1].id).await;
|
||||
let _ = test.get_document_data(&views[2].id).await;
|
||||
|
||||
let local_child_views = test.get_view(&views[1].id).await.child_views;
|
||||
let local_child_views = test.get_view(&views[2].id).await.child_views;
|
||||
assert_eq!(local_child_views.len(), 1);
|
||||
assert_eq!(local_child_views[0].name, "Document1");
|
||||
|
||||
@ -139,16 +140,17 @@ async fn import_appflowy_data_folder_into_current_workspace_test() {
|
||||
.unwrap();
|
||||
// after import, the structure is:
|
||||
// workspace:
|
||||
// view: Getting Started
|
||||
// view: General
|
||||
// view: Shared
|
||||
// view: Document1
|
||||
// view: Document2
|
||||
// view: Grid1
|
||||
// view: Grid2
|
||||
let views = test.get_all_workspace_views().await;
|
||||
assert_eq!(views.len(), 2);
|
||||
assert_eq!(views[1].name, "Document1");
|
||||
assert_eq!(views.len(), 3);
|
||||
assert_eq!(views[2].name, "Document1");
|
||||
|
||||
let document_1_child_views = test.get_view(&views[1].id).await.child_views;
|
||||
let document_1_child_views = test.get_view(&views[2].id).await.child_views;
|
||||
assert_eq!(document_1_child_views.len(), 1);
|
||||
assert_eq!(document_1_child_views[0].name, "Document2");
|
||||
|
||||
@ -179,9 +181,9 @@ async fn import_appflowy_data_folder_into_new_view_test2() {
|
||||
.unwrap();
|
||||
|
||||
let views = test.get_all_workspace_views().await;
|
||||
assert_eq!(views.len(), 2);
|
||||
assert_eq!(views[1].name, import_container_name);
|
||||
assert_040_local_2_import_content(&test, &views[1].id).await;
|
||||
assert_eq!(views.len(), 3);
|
||||
assert_eq!(views[2].name, import_container_name);
|
||||
assert_040_local_2_import_content(&test, &views[2].id).await;
|
||||
|
||||
drop(cleaner);
|
||||
}
|
||||
@ -226,13 +228,14 @@ async fn import_appflowy_data_folder_multiple_times_test() {
|
||||
.await
|
||||
.unwrap();
|
||||
// after import, the structure is:
|
||||
// Getting Started
|
||||
// General
|
||||
// Shared
|
||||
// 040_local_2
|
||||
|
||||
let views = test.get_all_workspace_views().await;
|
||||
assert_eq!(views.len(), 2);
|
||||
assert_eq!(views[1].name, import_container_name);
|
||||
assert_040_local_2_import_content(&test, &views[1].id).await;
|
||||
assert_eq!(views.len(), 3);
|
||||
assert_eq!(views[2].name, import_container_name);
|
||||
assert_040_local_2_import_content(&test, &views[2].id).await;
|
||||
|
||||
test
|
||||
.import_appflowy_data(
|
||||
@ -242,16 +245,17 @@ async fn import_appflowy_data_folder_multiple_times_test() {
|
||||
.await
|
||||
.unwrap();
|
||||
// after import, the structure is:
|
||||
// Getting Started
|
||||
// Generate
|
||||
// Shared
|
||||
// 040_local_2
|
||||
// Getting started
|
||||
// 040_local_2
|
||||
// Getting started
|
||||
let views = test.get_all_workspace_views().await;
|
||||
assert_eq!(views.len(), 3);
|
||||
assert_eq!(views[2].name, import_container_name);
|
||||
assert_040_local_2_import_content(&test, &views[1].id).await;
|
||||
assert_eq!(views.len(), 4);
|
||||
assert_eq!(views[3].name, import_container_name);
|
||||
assert_040_local_2_import_content(&test, &views[2].id).await;
|
||||
assert_040_local_2_import_content(&test, &views[3].id).await;
|
||||
drop(cleaner);
|
||||
}
|
||||
|
||||
|
||||
@ -101,16 +101,17 @@ async fn af_cloud_open_workspace_test() {
|
||||
user_localhost_af_cloud().await;
|
||||
let test = EventIntegrationTest::new().await;
|
||||
let _ = test.af_cloud_sign_up().await;
|
||||
let default_document_name = "Getting started";
|
||||
let default_document_name = "General";
|
||||
|
||||
test.create_document("A").await;
|
||||
test.create_document("B").await;
|
||||
let first_workspace = test.get_current_workspace().await;
|
||||
let views = test.get_all_workspace_views().await;
|
||||
assert_eq!(views.len(), 3);
|
||||
assert_eq!(views.len(), 4);
|
||||
assert_eq!(views[0].name, default_document_name);
|
||||
assert_eq!(views[1].name, "A");
|
||||
assert_eq!(views[2].name, "B");
|
||||
assert_eq!(views[1].name, "Shared");
|
||||
assert_eq!(views[2].name, "A");
|
||||
assert_eq!(views[3].name, "B");
|
||||
|
||||
let user_workspace = test.create_workspace("second workspace").await;
|
||||
test.open_workspace(&user_workspace.workspace_id).await;
|
||||
@ -119,10 +120,11 @@ async fn af_cloud_open_workspace_test() {
|
||||
test.create_document("D").await;
|
||||
|
||||
let views = test.get_all_workspace_views().await;
|
||||
assert_eq!(views.len(), 3);
|
||||
assert_eq!(views.len(), 4);
|
||||
assert_eq!(views[0].name, default_document_name);
|
||||
assert_eq!(views[1].name, "C");
|
||||
assert_eq!(views[2].name, "D");
|
||||
assert_eq!(views[1].name, "Shared");
|
||||
assert_eq!(views[2].name, "C");
|
||||
assert_eq!(views[3].name, "D");
|
||||
|
||||
// simulate open workspace and check if the views are correct
|
||||
for i in 0..10 {
|
||||
@ -144,14 +146,16 @@ async fn af_cloud_open_workspace_test() {
|
||||
test.open_workspace(&first_workspace.id).await;
|
||||
let views_1 = test.get_all_workspace_views().await;
|
||||
assert_eq!(views_1[0].name, default_document_name);
|
||||
assert_eq!(views_1[1].name, "A");
|
||||
assert_eq!(views_1[2].name, "B");
|
||||
assert_eq!(views_1[1].name, "Shared");
|
||||
assert_eq!(views_1[2].name, "A");
|
||||
assert_eq!(views_1[3].name, "B");
|
||||
|
||||
test.open_workspace(&second_workspace.id).await;
|
||||
let views_2 = test.get_all_workspace_views().await;
|
||||
assert_eq!(views_2[0].name, default_document_name);
|
||||
assert_eq!(views_2[1].name, "C");
|
||||
assert_eq!(views_2[2].name, "D");
|
||||
assert_eq!(views_2[1].name, "Shared");
|
||||
assert_eq!(views_2[2].name, "C");
|
||||
assert_eq!(views_2[3].name, "D");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@ -174,7 +178,7 @@ async fn af_cloud_different_open_same_workspace_test() {
|
||||
|
||||
let views = client.get_all_workspace_views().await;
|
||||
// only the getting started view should be present
|
||||
assert_eq!(views.len(), 1);
|
||||
assert_eq!(views.len(), 2);
|
||||
for view in views {
|
||||
client.delete_view(&view.id).await;
|
||||
}
|
||||
@ -205,7 +209,7 @@ async fn af_cloud_different_open_same_workspace_test() {
|
||||
client.open_workspace(iter_workspace_id).await;
|
||||
if iter_workspace_id == &cloned_shared_workspace_id {
|
||||
let views = client.get_all_workspace_views().await;
|
||||
assert_eq!(views.len(), 1);
|
||||
assert_eq!(views.len(), 2);
|
||||
sleep(Duration::from_millis(300)).await;
|
||||
} else {
|
||||
let views = client.get_all_workspace_views().await;
|
||||
@ -242,6 +246,6 @@ async fn af_cloud_different_open_same_workspace_test() {
|
||||
let folder_workspace_id = folder.get_workspace_id();
|
||||
assert_eq!(folder_workspace_id, Some(shared_workspace_id));
|
||||
|
||||
assert_eq!(views.len(), 1, "only get: {:?}", views); // Expecting two views.
|
||||
assert_eq!(views[0].name, "Getting started");
|
||||
assert_eq!(views.len(), 2, "only get: {:?}", views); // Expecting two views.
|
||||
assert_eq!(views[0].name, "General");
|
||||
}
|
||||
|
||||
@ -62,9 +62,6 @@ pub struct RowMetaPB {
|
||||
pub icon: Option<String>,
|
||||
|
||||
#[pb(index = 4, one_of)]
|
||||
pub cover: Option<String>,
|
||||
|
||||
#[pb(index = 5, one_of)]
|
||||
pub is_document_empty: Option<bool>,
|
||||
}
|
||||
|
||||
@ -80,7 +77,6 @@ impl From<RowOrder> for RowMetaPB {
|
||||
id: data.id.into_inner(),
|
||||
document_id: None,
|
||||
icon: None,
|
||||
cover: None,
|
||||
is_document_empty: None,
|
||||
}
|
||||
}
|
||||
@ -92,7 +88,6 @@ impl From<Row> for RowMetaPB {
|
||||
id: data.id.into_inner(),
|
||||
document_id: None,
|
||||
icon: None,
|
||||
cover: None,
|
||||
is_document_empty: None,
|
||||
}
|
||||
}
|
||||
@ -104,7 +99,6 @@ impl From<RowDetail> for RowMetaPB {
|
||||
id: row_detail.row.id.to_string(),
|
||||
document_id: Some(row_detail.document_id),
|
||||
icon: row_detail.meta.icon_url,
|
||||
cover: row_detail.meta.cover_url,
|
||||
is_document_empty: Some(row_detail.meta.is_document_empty),
|
||||
}
|
||||
}
|
||||
@ -305,7 +299,7 @@ impl From<UpdatedRow> for UpdatedRowPB {
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, ProtoBuf)]
|
||||
pub struct RowIdPB {
|
||||
pub struct DatabaseViewRowIdPB {
|
||||
#[pb(index = 1)]
|
||||
pub view_id: String,
|
||||
|
||||
@ -322,7 +316,7 @@ pub struct RowIdParams {
|
||||
pub group_id: Option<String>,
|
||||
}
|
||||
|
||||
impl TryInto<RowIdParams> for RowIdPB {
|
||||
impl TryInto<RowIdParams> for DatabaseViewRowIdPB {
|
||||
type Error = ErrorCode;
|
||||
|
||||
fn try_into(self) -> Result<RowIdParams, Self::Error> {
|
||||
|
||||
@ -404,7 +404,7 @@ pub(crate) async fn move_field_handler(
|
||||
|
||||
// #[tracing::instrument(level = "debug", skip(data, manager), err)]
|
||||
pub(crate) async fn get_row_handler(
|
||||
data: AFPluginData<RowIdPB>,
|
||||
data: AFPluginData<DatabaseViewRowIdPB>,
|
||||
manager: AFPluginState<Weak<DatabaseManager>>,
|
||||
) -> DataResult<OptionalRowPB, FlowyError> {
|
||||
let manager = upgrade_manager(manager)?;
|
||||
@ -420,7 +420,7 @@ pub(crate) async fn get_row_handler(
|
||||
}
|
||||
|
||||
pub(crate) async fn init_row_handler(
|
||||
data: AFPluginData<RowIdPB>,
|
||||
data: AFPluginData<DatabaseViewRowIdPB>,
|
||||
manager: AFPluginState<Weak<DatabaseManager>>,
|
||||
) -> Result<(), FlowyError> {
|
||||
let manager = upgrade_manager(manager)?;
|
||||
@ -433,7 +433,7 @@ pub(crate) async fn init_row_handler(
|
||||
}
|
||||
|
||||
pub(crate) async fn get_row_meta_handler(
|
||||
data: AFPluginData<RowIdPB>,
|
||||
data: AFPluginData<DatabaseViewRowIdPB>,
|
||||
manager: AFPluginState<Weak<DatabaseManager>>,
|
||||
) -> DataResult<RowMetaPB, FlowyError> {
|
||||
let manager = upgrade_manager(manager)?;
|
||||
@ -487,7 +487,7 @@ pub(crate) async fn delete_rows_handler(
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(data, manager), err)]
|
||||
pub(crate) async fn duplicate_row_handler(
|
||||
data: AFPluginData<RowIdPB>,
|
||||
data: AFPluginData<DatabaseViewRowIdPB>,
|
||||
manager: AFPluginState<Weak<DatabaseManager>>,
|
||||
) -> Result<(), FlowyError> {
|
||||
let manager = upgrade_manager(manager)?;
|
||||
@ -960,7 +960,7 @@ pub(crate) async fn get_no_date_calendar_events_handler(
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(data, manager), err)]
|
||||
pub(crate) async fn get_calendar_event_handler(
|
||||
data: AFPluginData<RowIdPB>,
|
||||
data: AFPluginData<DatabaseViewRowIdPB>,
|
||||
manager: AFPluginState<Weak<DatabaseManager>>,
|
||||
) -> DataResult<CalendarEventPB, FlowyError> {
|
||||
let manager = upgrade_manager(manager)?;
|
||||
|
||||
@ -14,7 +14,6 @@ pub fn init(database_manager: Weak<DatabaseManager>) -> AFPlugin {
|
||||
.state(database_manager);
|
||||
plugin
|
||||
.event(DatabaseEvent::GetDatabase, get_database_data_handler)
|
||||
.event(DatabaseEvent::GetAllRows, get_all_rows_handler)
|
||||
.event(DatabaseEvent::GetDatabaseData, get_database_data_handler)
|
||||
.event(DatabaseEvent::GetDatabaseId, get_database_id_handler)
|
||||
.event(DatabaseEvent::GetDatabaseSetting, get_database_setting_handler)
|
||||
@ -224,19 +223,19 @@ pub enum DatabaseEvent {
|
||||
|
||||
/// [GetRow] event is used to get the row data,[RowPB]. [OptionalRowPB] is a wrapper that enables
|
||||
/// to return a nullable row data.
|
||||
#[event(input = "RowIdPB", output = "OptionalRowPB")]
|
||||
#[event(input = "DatabaseViewRowIdPB", output = "OptionalRowPB")]
|
||||
GetRow = 51,
|
||||
|
||||
#[event(input = "RepeatedRowIdPB")]
|
||||
DeleteRows = 52,
|
||||
|
||||
#[event(input = "RowIdPB")]
|
||||
#[event(input = "DatabaseViewRowIdPB")]
|
||||
DuplicateRow = 53,
|
||||
|
||||
#[event(input = "MoveRowPayloadPB")]
|
||||
MoveRow = 54,
|
||||
|
||||
#[event(input = "RowIdPB", output = "RowMetaPB")]
|
||||
#[event(input = "DatabaseViewRowIdPB", output = "RowMetaPB")]
|
||||
GetRowMeta = 55,
|
||||
|
||||
#[event(input = "UpdateRowMetaChangesetPB")]
|
||||
@ -321,7 +320,7 @@ pub enum DatabaseEvent {
|
||||
)]
|
||||
GetNoDateCalendarEvents = 124,
|
||||
|
||||
#[event(input = "RowIdPB", output = "CalendarEventPB")]
|
||||
#[event(input = "DatabaseViewRowIdPB", output = "CalendarEventPB")]
|
||||
GetCalendarEvent = 125,
|
||||
|
||||
#[event(input = "MoveCalendarEventPB")]
|
||||
@ -381,12 +380,9 @@ pub enum DatabaseEvent {
|
||||
#[event(input = "TranslateRowPB")]
|
||||
TranslateRow = 175,
|
||||
|
||||
#[event(input = "RowIdPB")]
|
||||
#[event(input = "DatabaseViewRowIdPB")]
|
||||
InitRow = 176,
|
||||
|
||||
#[event(input = "DatabaseViewIdPB", output = "RepeatedRowMetaPB")]
|
||||
GetAllRows = 177,
|
||||
|
||||
#[event(input = "DatabaseViewIdPB", output = "DatabaseExportDataPB")]
|
||||
ExportRawDatabaseData = 178,
|
||||
}
|
||||
|
||||
@ -750,7 +750,6 @@ impl DatabaseEditor {
|
||||
id: row_id.clone().into_inner(),
|
||||
document_id: Some(row_document_id),
|
||||
icon: row_meta.icon_url,
|
||||
cover: row_meta.cover_url,
|
||||
is_document_empty: Some(row_meta.is_document_empty),
|
||||
})
|
||||
} else {
|
||||
@ -1522,6 +1521,7 @@ impl DatabaseEditor {
|
||||
Ok(type_option.database_id)
|
||||
}
|
||||
|
||||
/// TODO(nathan): lazy load database rows
|
||||
pub async fn get_related_rows(
|
||||
&self,
|
||||
row_ids: Option<&Vec<String>>,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user