mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: expand share option (#5021)
* feat: expand share option * chore: optimize the code --------- Co-authored-by: Lucas.Xu <lucas.xu@appflowy.io>
This commit is contained in:
parent
1597f7d94c
commit
a50918fa6a
@ -1,6 +1,7 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:appflowy/workspace/application/export/document_exporter.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
@ -11,45 +12,89 @@ import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
part 'document_share_bloc.freezed.dart';
|
||||
|
||||
class DocumentShareBloc extends Bloc<DocumentShareEvent, DocumentShareState> {
|
||||
DocumentShareBloc({required this.view})
|
||||
: super(const DocumentShareState.initial()) {
|
||||
on<ShareMarkdown>(_onShareMarkdown);
|
||||
DocumentShareBloc({
|
||||
required this.view,
|
||||
}) : super(const DocumentShareState.initial()) {
|
||||
on<DocumentShareEvent>((event, emit) async {
|
||||
await event.when(
|
||||
share: (type, path) async {
|
||||
if (DocumentShareType.unimplemented.contains(type)) {
|
||||
Log.error('DocumentShareType $type is not implemented');
|
||||
return;
|
||||
}
|
||||
|
||||
emit(const DocumentShareState.loading());
|
||||
|
||||
final exporter = DocumentExporter(view);
|
||||
final FlowyResult<ExportDataPB, FlowyError> result =
|
||||
await exporter.export(type.exportType).then((value) {
|
||||
return value.fold(
|
||||
(s) {
|
||||
if (path != null) {
|
||||
switch (type) {
|
||||
case DocumentShareType.markdown:
|
||||
return FlowyResult.success(_saveMarkdownToPath(s, path));
|
||||
case DocumentShareType.html:
|
||||
return FlowyResult.success(_saveHTMLToPath(s, path));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return FlowyResult.failure(FlowyError());
|
||||
},
|
||||
(f) => FlowyResult.failure(f),
|
||||
);
|
||||
});
|
||||
|
||||
emit(DocumentShareState.finish(result));
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
final ViewPB view;
|
||||
|
||||
Future<void> _onShareMarkdown(
|
||||
ShareMarkdown event,
|
||||
Emitter<DocumentShareState> emit,
|
||||
) async {
|
||||
emit(const DocumentShareState.loading());
|
||||
|
||||
final documentExporter = DocumentExporter(view);
|
||||
final result = await documentExporter.export(DocumentExportType.markdown);
|
||||
emit(
|
||||
DocumentShareState.finish(
|
||||
result.fold(
|
||||
(markdown) =>
|
||||
FlowyResult.success(_saveMarkdownToPath(markdown, event.path)),
|
||||
(error) => FlowyResult.failure(error),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
ExportDataPB _saveMarkdownToPath(String markdown, String path) {
|
||||
File(path).writeAsStringSync(markdown);
|
||||
return ExportDataPB()
|
||||
..data = markdown
|
||||
..exportType = ExportType.Markdown;
|
||||
}
|
||||
|
||||
ExportDataPB _saveHTMLToPath(String html, String path) {
|
||||
File(path).writeAsStringSync(html);
|
||||
return ExportDataPB()
|
||||
..data = html
|
||||
..exportType = ExportType.HTML;
|
||||
}
|
||||
}
|
||||
|
||||
enum DocumentShareType {
|
||||
markdown,
|
||||
html,
|
||||
text,
|
||||
link;
|
||||
|
||||
static List<DocumentShareType> get unimplemented => [text, link];
|
||||
|
||||
DocumentExportType get exportType {
|
||||
switch (this) {
|
||||
case DocumentShareType.markdown:
|
||||
return DocumentExportType.markdown;
|
||||
case DocumentShareType.html:
|
||||
return DocumentExportType.html;
|
||||
case DocumentShareType.text:
|
||||
return DocumentExportType.text;
|
||||
case DocumentShareType.link:
|
||||
throw UnsupportedError('DocumentShareType.link is not supported');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@freezed
|
||||
class DocumentShareEvent with _$DocumentShareEvent {
|
||||
const factory DocumentShareEvent.shareMarkdown(String path) = ShareMarkdown;
|
||||
const factory DocumentShareEvent.shareText() = ShareText;
|
||||
const factory DocumentShareEvent.shareLink() = ShareLink;
|
||||
const factory DocumentShareEvent.share(DocumentShareType type, String? path) =
|
||||
Share;
|
||||
}
|
||||
|
||||
@freezed
|
||||
|
@ -1,7 +1,9 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/document/application/document_share_bloc.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/copy_and_paste/clipboard_service.dart';
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/util/string_extension.dart';
|
||||
import 'package:appflowy/workspace/application/export/document_exporter.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_listener.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/toast.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart';
|
||||
@ -62,6 +64,12 @@ class DocumentShareButton extends StatelessWidget {
|
||||
case ExportType.Link:
|
||||
case ExportType.Text:
|
||||
break;
|
||||
case ExportType.HTML:
|
||||
showSnackBarMessage(
|
||||
context,
|
||||
LocaleKeys.settings_files_exportFileSuccess.tr(),
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,9 +133,38 @@ class ShareActionListState extends State<ShareActionList> {
|
||||
fileName: '${name.toFileName()}.md',
|
||||
);
|
||||
if (exportPath != null) {
|
||||
docShareBloc.add(DocumentShareEvent.shareMarkdown(exportPath));
|
||||
docShareBloc.add(
|
||||
DocumentShareEvent.share(
|
||||
DocumentShareType.markdown,
|
||||
exportPath,
|
||||
),
|
||||
);
|
||||
}
|
||||
break;
|
||||
case ShareAction.html:
|
||||
final exportPath = await getIt<FilePickerService>().saveFile(
|
||||
dialogTitle: '',
|
||||
fileName: '${name.toFileName()}.html',
|
||||
);
|
||||
if (exportPath != null) {
|
||||
docShareBloc.add(
|
||||
DocumentShareEvent.share(
|
||||
DocumentShareType.html,
|
||||
exportPath,
|
||||
),
|
||||
);
|
||||
}
|
||||
break;
|
||||
case ShareAction.clipboard:
|
||||
final documentExporter = DocumentExporter(widget.view);
|
||||
final result =
|
||||
await documentExporter.export(DocumentExportType.markdown);
|
||||
result.fold(
|
||||
(markdown) => getIt<ClipboardService>()
|
||||
.setData(ClipboardServiceData(plainText: markdown)),
|
||||
(error) => showMessageToast(error.msg),
|
||||
);
|
||||
break;
|
||||
}
|
||||
controller.close();
|
||||
},
|
||||
@ -146,6 +183,8 @@ class ShareActionListState extends State<ShareActionList> {
|
||||
|
||||
enum ShareAction {
|
||||
markdown,
|
||||
html,
|
||||
clipboard,
|
||||
}
|
||||
|
||||
class ShareActionWrapper extends ActionCell {
|
||||
@ -160,6 +199,10 @@ class ShareActionWrapper extends ActionCell {
|
||||
switch (inner) {
|
||||
case ShareAction.markdown:
|
||||
return LocaleKeys.shareAction_markdown.tr();
|
||||
case ShareAction.html:
|
||||
return LocaleKeys.shareAction_html.tr();
|
||||
case ShareAction.clipboard:
|
||||
return LocaleKeys.shareAction_clipboard.tr();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ enum DocumentExportType {
|
||||
json,
|
||||
markdown,
|
||||
text,
|
||||
html,
|
||||
}
|
||||
|
||||
class DocumentExporter {
|
||||
@ -56,6 +57,11 @@ class DocumentExporter {
|
||||
return FlowyResult.success(markdown);
|
||||
case DocumentExportType.text:
|
||||
throw UnimplementedError();
|
||||
case DocumentExportType.html:
|
||||
final html = documentToHTML(
|
||||
document,
|
||||
);
|
||||
return FlowyResult.success(html);
|
||||
}
|
||||
},
|
||||
(error) => FlowyResult.failure(error),
|
||||
|
@ -92,6 +92,8 @@
|
||||
"buttonText": "Share",
|
||||
"workInProgress": "Coming soon",
|
||||
"markdown": "Markdown",
|
||||
"html": "HTML",
|
||||
"clipboard": "Copy to clipboard",
|
||||
"csv": "CSV",
|
||||
"copyLink": "Copy Link"
|
||||
},
|
||||
|
@ -70,6 +70,8 @@
|
||||
"buttonText": "分享",
|
||||
"workInProgress": "敬请期待",
|
||||
"markdown": "Markdown",
|
||||
"html": "HTML",
|
||||
"clipboard": "拷贝到剪贴板",
|
||||
"csv": "CSV",
|
||||
"copyLink": "复制链接"
|
||||
},
|
||||
|
@ -339,6 +339,7 @@ pub enum ExportType {
|
||||
Text = 0,
|
||||
Markdown = 1,
|
||||
Link = 2,
|
||||
HTML = 3,
|
||||
}
|
||||
|
||||
impl From<i32> for ExportType {
|
||||
@ -347,6 +348,7 @@ impl From<i32> for ExportType {
|
||||
0 => ExportType::Text,
|
||||
1 => ExportType::Markdown,
|
||||
2 => ExportType::Link,
|
||||
3 => ExportType::HTML,
|
||||
_ => {
|
||||
tracing::error!("🔴Invalid export type: {}", val);
|
||||
ExportType::Text
|
||||
|
Loading…
x
Reference in New Issue
Block a user