mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: add cover migration for document (#1929)
* feat: add cover migration for document * fix: should not delete the cover when selecting all * fix: chinese characters for openai
This commit is contained in:
parent
675c833f07
commit
7ff4cecd09
@ -1,15 +1,18 @@
|
||||
import 'dart:convert';
|
||||
import 'package:appflowy/plugins/document/presentation/plugins/cover/cover_node_widget.dart';
|
||||
import 'package:appflowy/plugins/trash/application/trash_service.dart';
|
||||
import 'package:appflowy/user/application/user_service.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_listener.dart';
|
||||
import 'package:appflowy/plugins/document/application/doc_service.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pbserver.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart'
|
||||
show EditorState, Document, Transaction;
|
||||
show EditorState, Document, Transaction, Node;
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/trash.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
@ -78,29 +81,27 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
|
||||
Future<void> _initial(Initial value, Emitter<DocumentState> emit) async {
|
||||
final userProfile = await UserBackendService.getCurrentUserProfile();
|
||||
if (userProfile.isRight()) {
|
||||
emit(
|
||||
return emit(
|
||||
state.copyWith(
|
||||
loadingState: DocumentLoadingState.finish(
|
||||
right(userProfile.asRight()),
|
||||
),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
final result = await _documentService.openDocument(view: view);
|
||||
result.fold(
|
||||
(documentData) {
|
||||
final document = Document.fromJson(jsonDecode(documentData.content));
|
||||
editorState = EditorState(document: document);
|
||||
_listenOnDocumentChange();
|
||||
return result.fold(
|
||||
(documentData) async {
|
||||
await _initEditorState(documentData).whenComplete(() {
|
||||
emit(
|
||||
state.copyWith(
|
||||
loadingState: DocumentLoadingState.finish(left(unit)),
|
||||
userProfilePB: userProfile.asLeft(),
|
||||
),
|
||||
);
|
||||
});
|
||||
},
|
||||
(err) {
|
||||
(err) async {
|
||||
emit(
|
||||
state.copyWith(
|
||||
loadingState: DocumentLoadingState.finish(right(err)),
|
||||
@ -127,8 +128,13 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
|
||||
);
|
||||
}
|
||||
|
||||
void _listenOnDocumentChange() {
|
||||
_subscription = editorState?.transactionStream.listen((transaction) {
|
||||
Future<void> _initEditorState(DocumentDataPB documentData) async {
|
||||
final document = Document.fromJson(jsonDecode(documentData.content));
|
||||
final editorState = EditorState(document: document);
|
||||
this.editorState = editorState;
|
||||
|
||||
// listen on document change
|
||||
_subscription = editorState.transactionStream.listen((transaction) {
|
||||
final json = jsonEncode(TransactionAdaptor(transaction).toJson());
|
||||
_documentService
|
||||
.applyEdit(docId: view.id, operations: json)
|
||||
@ -139,6 +145,15 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
|
||||
);
|
||||
});
|
||||
});
|
||||
// log
|
||||
if (kDebugMode) {
|
||||
editorState.logConfiguration.handler = (log) {
|
||||
Log.debug(log);
|
||||
};
|
||||
}
|
||||
// migration
|
||||
final migration = DocumentMigration(editorState: editorState);
|
||||
await migration.apply();
|
||||
}
|
||||
}
|
||||
|
||||
@ -215,3 +230,33 @@ class TransactionAdaptor {
|
||||
return json;
|
||||
}
|
||||
}
|
||||
|
||||
class DocumentMigration {
|
||||
const DocumentMigration({
|
||||
required this.editorState,
|
||||
});
|
||||
|
||||
final EditorState editorState;
|
||||
|
||||
/// Migrate the document to the latest version.
|
||||
Future<void> apply() async {
|
||||
final transaction = editorState.transaction;
|
||||
|
||||
// A temporary solution to migrate the document to the latest version.
|
||||
// Once the editor is stable, we can remove this.
|
||||
|
||||
// cover plugin
|
||||
if (editorState.document.nodeAtPath([0])?.type != kCoverType) {
|
||||
transaction.insertNode(
|
||||
[0],
|
||||
Node(type: kCoverType),
|
||||
);
|
||||
}
|
||||
|
||||
transaction.afterSelection = null;
|
||||
|
||||
if (transaction.operations.isNotEmpty) {
|
||||
editorState.apply(transaction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +91,13 @@ class HttpOpenAIRepository implements OpenAIRepository {
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
return Right(TextCompletionResponse.fromJson(json.decode(response.body)));
|
||||
return Right(
|
||||
TextCompletionResponse.fromJson(
|
||||
json.decode(
|
||||
utf8.decode(response.bodyBytes),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Left(OpenAIError.fromJson(json.decode(response.body)['error']));
|
||||
}
|
||||
@ -119,7 +125,13 @@ class HttpOpenAIRepository implements OpenAIRepository {
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
return Right(TextEditResponse.fromJson(json.decode(response.body)));
|
||||
return Right(
|
||||
TextEditResponse.fromJson(
|
||||
json.decode(
|
||||
utf8.decode(response.bodyBytes),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Left(OpenAIError.fromJson(json.decode(response.body)['error']));
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
import 'package:appflowy/plugins/document/document.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/plugins/cover/cover_node_widget.dart';
|
||||
import 'package:appflowy/startup/plugin/plugin.dart';
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/app/header/import/import_panel.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart' show Document, Node;
|
||||
import 'package:appflowy_editor/appflowy_editor.dart' show Document;
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:flowy_infra/image.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/icon_button.dart';
|
||||
@ -61,12 +60,7 @@ class AddButton extends StatelessWidget {
|
||||
},
|
||||
onSelected: (action, controller) {
|
||||
if (action is AddButtonActionWrapper) {
|
||||
Document? document;
|
||||
if (action.pluginType == PluginType.editor) {
|
||||
// initialize the document if needed.
|
||||
document = buildInitialDocument();
|
||||
}
|
||||
onSelected(action.pluginBuilder, document);
|
||||
onSelected(action.pluginBuilder, null);
|
||||
}
|
||||
if (action is ImportActionWrapper) {
|
||||
showImportPanel(context, (document) {
|
||||
@ -80,12 +74,6 @@ class AddButton extends StatelessWidget {
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Document buildInitialDocument() {
|
||||
final document = Document.empty();
|
||||
document.insert([0], [Node(type: kCoverType)]);
|
||||
return document;
|
||||
}
|
||||
}
|
||||
|
||||
class AddButtonActionWrapper extends ActionCell {
|
||||
|
@ -12,8 +12,9 @@ ShortcutEventHandler backspaceEventHandler = (editorState, event) {
|
||||
nodes = selection.isBackward ? nodes : nodes.reversed.toList(growable: false);
|
||||
selection = selection.isBackward ? selection : selection.reversed;
|
||||
final textNodes = nodes.whereType<TextNode>().toList();
|
||||
final List<Node> nonTextNodes =
|
||||
nodes.where((node) => node is! TextNode).toList(growable: false);
|
||||
final List<Node> nonTextNodes = nodes
|
||||
.where((node) => node is! TextNode && node.selectable != null)
|
||||
.toList(growable: false);
|
||||
|
||||
final transaction = editorState.transaction;
|
||||
List<int>? cancelNumberListPath;
|
||||
|
Loading…
Reference in New Issue
Block a user