feat: disable publish in non-apppflowy-cloud user mode

This commit is contained in:
Lucas.Xu 2024-07-03 13:43:59 +08:00
parent bec7227cff
commit f96218820d
6 changed files with 61 additions and 28 deletions

View File

@ -1,5 +1,6 @@
import 'dart:io'; import 'dart:io';
import 'package:appflowy/user/application/user_service.dart';
import 'package:appflowy/workspace/application/export/document_exporter.dart'; import 'package:appflowy/workspace/application/export/document_exporter.dart';
import 'package:appflowy/workspace/application/view/view_listener.dart'; import 'package:appflowy/workspace/application/view/view_listener.dart';
import 'package:appflowy/workspace/application/view/view_service.dart'; import 'package:appflowy/workspace/application/view/view_service.dart';
@ -7,6 +8,7 @@ import 'package:appflowy_backend/log.dart';
import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.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-error/errors.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
import 'package:appflowy_result/appflowy_result.dart'; import 'package:appflowy_result/appflowy_result.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';
@ -31,12 +33,18 @@ class DocumentShareBloc extends Bloc<DocumentShareEvent, DocumentShareState> {
); );
final publishInfo = await ViewBackendService.getPublishInfo(view); final publishInfo = await ViewBackendService.getPublishInfo(view);
final enablePublish =
await UserBackendService.getCurrentUserProfile().fold(
(v) => v.authenticator == AuthenticatorPB.AppFlowyCloud,
(p) => false,
);
publishInfo.fold((s) { publishInfo.fold((s) {
emit( emit(
state.copyWith( state.copyWith(
isPublished: true, isPublished: true,
url: '$_url/${s.namespace}/${s.publishName}', url: '$_url/${s.namespace}/${s.publishName}',
viewName: view.name, viewName: view.name,
enablePublish: enablePublish,
), ),
); );
}, (f) { }, (f) {
@ -45,6 +53,7 @@ class DocumentShareBloc extends Bloc<DocumentShareEvent, DocumentShareState> {
isPublished: false, isPublished: false,
url: '', url: '',
viewName: view.name, viewName: view.name,
enablePublish: enablePublish,
), ),
); );
}); });
@ -220,18 +229,20 @@ class DocumentShareEvent with _$DocumentShareEvent {
@freezed @freezed
class DocumentShareState with _$DocumentShareState { class DocumentShareState with _$DocumentShareState {
const factory DocumentShareState({ const factory DocumentShareState({
required bool isLoading,
FlowyResult<ExportDataPB, FlowyError>? exportResult,
required bool isPublished, required bool isPublished,
FlowyResult<void, FlowyError>? publishResult, required bool isLoading,
FlowyResult<void, FlowyError>? unpublishResult,
required String url, required String url,
required String viewName, required String viewName,
required bool enablePublish,
FlowyResult<ExportDataPB, FlowyError>? exportResult,
FlowyResult<void, FlowyError>? publishResult,
FlowyResult<void, FlowyError>? unpublishResult,
}) = _DocumentShareState; }) = _DocumentShareState;
factory DocumentShareState.initial() => const DocumentShareState( factory DocumentShareState.initial() => const DocumentShareState(
isLoading: false, isLoading: false,
isPublished: false, isPublished: false,
enablePublish: true,
url: '', url: '',
viewName: '', viewName: '',
); );

View File

@ -6,7 +6,7 @@ import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/util/string_extension.dart'; import 'package:appflowy/util/string_extension.dart';
import 'package:appflowy/util/theme_extension.dart'; import 'package:appflowy/util/theme_extension.dart';
import 'package:appflowy/workspace/application/export/document_exporter.dart'; import 'package:appflowy/workspace/application/export/document_exporter.dart';
import 'package:appflowy/workspace/presentation/home/toast.dart'; import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/file_picker/file_picker_service.dart'; import 'package:flowy_infra/file_picker/file_picker_service.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart';
@ -81,9 +81,16 @@ class ExportTab extends StatelessWidget {
DocumentExporter(context.read<DocumentShareBloc>().view); DocumentExporter(context.read<DocumentShareBloc>().view);
final result = await documentExporter.export(DocumentExportType.markdown); final result = await documentExporter.export(DocumentExportType.markdown);
result.fold( result.fold(
(markdown) => getIt<ClipboardService>() (markdown) {
.setData(ClipboardServiceData(plainText: markdown)), getIt<ClipboardService>().setData(
(error) => showMessageToast(error.msg), ClipboardServiceData(plainText: markdown),
);
showToastNotification(
context,
message: LocaleKeys.grid_url_copiedNotification.tr(),
);
},
(error) => showToastNotification(context, message: error.msg),
); );
} }
} }

View File

@ -43,6 +43,10 @@ class DocumentShareButton extends StatelessWidget {
}, },
child: BlocBuilder<DocumentShareBloc, DocumentShareState>( child: BlocBuilder<DocumentShareBloc, DocumentShareState>(
builder: (context, state) { builder: (context, state) {
final tabs = [
if (state.enablePublish) ShareMenuTab.publish,
ShareMenuTab.exportAs,
];
final shareBloc = context.read<DocumentShareBloc>(); final shareBloc = context.read<DocumentShareBloc>();
return SizedBox( return SizedBox(
height: 32.0, height: 32.0,
@ -55,12 +59,18 @@ class DocumentShareButton extends StatelessWidget {
offset: const Offset(0, 8), offset: const Offset(0, 8),
popupBuilder: (context) => BlocProvider.value( popupBuilder: (context) => BlocProvider.value(
value: shareBloc, value: shareBloc,
child: const ShareMenu(), child: ShareMenu(
tabs: tabs,
),
), ),
child: RoundedTextButton( child: RoundedTextButton(
title: LocaleKeys.shareAction_buttonText.tr(), title: LocaleKeys.shareAction_buttonText.tr(),
padding: const EdgeInsets.symmetric(horizontal: 12.0), padding: const EdgeInsets.symmetric(horizontal: 14.0),
fontSize: 14.0, fontSize: 14.0,
fontWeight: FontWeight.w500,
borderRadius: const BorderRadius.all(
Radius.circular(10.0),
),
textColor: Theme.of(context).colorScheme.onPrimary, textColor: Theme.of(context).colorScheme.onPrimary,
), ),
), ),

View File

@ -12,26 +12,25 @@ enum ShareMenuTab {
publish, publish,
exportAs; exportAs;
static List<ShareMenuTab> supportedTabs = [
// ShareMenuTab.share,
ShareMenuTab.publish,
ShareMenuTab.exportAs,
];
String get i18n { String get i18n {
switch (this) { switch (this) {
case ShareMenuTab.share: case ShareMenuTab.share:
return 'Share'; return LocaleKeys.shareAction_shareTab.tr();
case ShareMenuTab.publish: case ShareMenuTab.publish:
return LocaleKeys.shareAction_publish; return LocaleKeys.shareAction_publishTab.tr();
case ShareMenuTab.exportAs: case ShareMenuTab.exportAs:
return 'Export as'; return LocaleKeys.shareAction_exportAsTab.tr();
} }
} }
} }
class ShareMenu extends StatefulWidget { class ShareMenu extends StatefulWidget {
const ShareMenu({super.key}); const ShareMenu({
super.key,
required this.tabs,
});
final List<ShareMenuTab> tabs;
@override @override
State<ShareMenu> createState() => _ShareMenuState(); State<ShareMenu> createState() => _ShareMenuState();
@ -39,15 +38,19 @@ class ShareMenu extends StatefulWidget {
class _ShareMenuState extends State<ShareMenu> class _ShareMenuState extends State<ShareMenu>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
ShareMenuTab selectedTab = ShareMenuTab.publish; late ShareMenuTab selectedTab = widget.tabs.first;
late final tabController = TabController( late final tabController = TabController(
length: ShareMenuTab.supportedTabs.length, length: widget.tabs.length,
vsync: this, vsync: this,
initialIndex: ShareMenuTab.supportedTabs.indexOf(selectedTab), initialIndex: widget.tabs.indexOf(selectedTab),
); );
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (widget.tabs.isEmpty) {
return const SizedBox.shrink();
}
return Column( return Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
@ -79,7 +82,7 @@ class _ShareMenuState extends State<ShareMenu>
Widget _buildTabBar(BuildContext context) { Widget _buildTabBar(BuildContext context) {
final children = [ final children = [
for (final tab in ShareMenuTab.supportedTabs) for (final tab in widget.tabs)
Padding( Padding(
padding: const EdgeInsets.only(bottom: 10), padding: const EdgeInsets.only(bottom: 10),
child: _Segment( child: _Segment(
@ -103,7 +106,7 @@ class _ShareMenuState extends State<ShareMenu>
tabs: children, tabs: children,
onTap: (index) { onTap: (index) {
setState(() { setState(() {
selectedTab = ShareMenuTab.supportedTabs[index]; selectedTab = widget.tabs[index];
}); });
}, },
); );

View File

@ -304,11 +304,10 @@ void showToastNotification(
) )
: null, : null,
alignment: Alignment.bottomCenter, alignment: Alignment.bottomCenter,
autoCloseDuration: const Duration(seconds: 4), autoCloseDuration: const Duration(milliseconds: 3000),
showProgressBar: false, showProgressBar: false,
backgroundColor: Theme.of(context).colorScheme.surface, backgroundColor: Theme.of(context).colorScheme.surface,
borderSide: BorderSide( borderSide: BorderSide(
width: 1.5,
color: Colors.grey.withOpacity(0.4), color: Colors.grey.withOpacity(0.4),
), ),
); );

View File

@ -111,7 +111,10 @@
"publishToTheWebHint": "Create a website with AppFlowy", "publishToTheWebHint": "Create a website with AppFlowy",
"publish": "Publish", "publish": "Publish",
"unPublish": "Unpublish", "unPublish": "Unpublish",
"visitSite": "Visit site" "visitSite": "Visit site",
"exportAsTab": "Export as",
"publishTab": "Publish",
"shareTab": "Share"
}, },
"moreAction": { "moreAction": {
"small": "small", "small": "small",