mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
Merge branch 'publish' into feat/support-get-encoded-collab-event
This commit is contained in:
commit
628eace341
@ -26,7 +26,7 @@ CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
|
||||
CARGO_MAKE_CRATE_FS_NAME = "dart_ffi"
|
||||
CARGO_MAKE_CRATE_NAME = "dart-ffi"
|
||||
LIB_NAME = "dart_ffi"
|
||||
APPFLOWY_VERSION = "0.6.0"
|
||||
APPFLOWY_VERSION = "0.6.1"
|
||||
FLUTTER_DESKTOP_FEATURES = "dart"
|
||||
PRODUCT_NAME = "AppFlowy"
|
||||
MACOSX_DEPLOYMENT_TARGET = "11.0"
|
||||
|
@ -4,6 +4,7 @@ import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
|
||||
import 'package:appflowy/mobile/presentation/home/space/mobile_space_header.dart';
|
||||
import 'package:appflowy/mobile/presentation/home/space/mobile_space_menu.dart';
|
||||
import 'package:appflowy/mobile/presentation/page_item/mobile_view_item.dart';
|
||||
import 'package:appflowy/mobile/presentation/presentation.dart';
|
||||
import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/sidebar/space/space_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_bloc.dart';
|
||||
@ -22,6 +23,18 @@ class MobileSpace extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _MobileSpaceState extends State<MobileSpace> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
createNewPageNotifier.addListener(_createNewPage);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
createNewPageNotifier.removeListener(_createNewPage);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<SpaceBloc, SpaceState>(
|
||||
@ -81,6 +94,14 @@ class _MobileSpaceState extends State<MobileSpace> {
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _createNewPage() {
|
||||
context.read<SpaceBloc>().add(
|
||||
SpaceEvent.createPage(
|
||||
name: LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _Pages extends StatelessWidget {
|
||||
|
@ -1,18 +1,15 @@
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/mobile/application/mobile_router.dart';
|
||||
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
|
||||
import 'package:appflowy/util/theme_extension.dart';
|
||||
import 'package:appflowy/workspace/application/workspace/workspace_service.dart';
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
final PropertyValueNotifier<ViewLayoutPB?> createNewPageNotifier =
|
||||
PropertyValueNotifier(null);
|
||||
|
||||
const _homeLabel = 'home';
|
||||
const _addLabel = 'add';
|
||||
const _notificationLabel = 'notification';
|
||||
@ -93,7 +90,7 @@ class MobileBottomNavigationBar extends StatelessWidget {
|
||||
void _onTap(BuildContext context, int bottomBarIndex) {
|
||||
if (_items[bottomBarIndex].label == _addLabel) {
|
||||
// show an add dialog
|
||||
_showCreatePageBottomSheet(context);
|
||||
createNewPageNotifier.value = ViewLayoutPB.Document;
|
||||
return;
|
||||
}
|
||||
// When navigating to a new branch, it's recommended to use the goBranch
|
||||
@ -108,40 +105,4 @@ class MobileBottomNavigationBar extends StatelessWidget {
|
||||
initialLocation: bottomBarIndex == navigationShell.currentIndex,
|
||||
);
|
||||
}
|
||||
|
||||
void _showCreatePageBottomSheet(BuildContext context) {
|
||||
showMobileBottomSheet(
|
||||
context,
|
||||
showHeader: true,
|
||||
title: LocaleKeys.sideBar_addAPage.tr(),
|
||||
showDragHandle: true,
|
||||
showCloseButton: true,
|
||||
useRootNavigator: true,
|
||||
builder: (sheetContext) {
|
||||
return AddNewPageWidgetBottomSheet(
|
||||
view: ViewPB(),
|
||||
onAction: (layout) async {
|
||||
Navigator.of(sheetContext).pop();
|
||||
final currentWorkspaceId =
|
||||
await FolderEventReadCurrentWorkspace().send();
|
||||
await currentWorkspaceId.fold((s) async {
|
||||
final workspaceService = WorkspaceService(workspaceId: s.id);
|
||||
final result = await workspaceService.createView(
|
||||
name: LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
|
||||
viewSection: ViewSectionPB.Private,
|
||||
layout: layout,
|
||||
);
|
||||
result.fold((s) {
|
||||
context.pushView(s);
|
||||
}, (e) {
|
||||
Log.error('Failed to create new page: $e');
|
||||
});
|
||||
}, (e) {
|
||||
Log.error('Failed to read current workspace: $e');
|
||||
});
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ part 'document_share_bloc.freezed.dart';
|
||||
class DocumentShareBloc extends Bloc<DocumentShareEvent, DocumentShareState> {
|
||||
DocumentShareBloc({
|
||||
required this.view,
|
||||
}) : super(const DocumentShareState.initial()) {
|
||||
}) : super(DocumentShareState.initial()) {
|
||||
on<DocumentShareEvent>((event, emit) async {
|
||||
await event.when(
|
||||
share: (type, path) async {
|
||||
@ -23,36 +23,52 @@ class DocumentShareBloc extends Bloc<DocumentShareEvent, DocumentShareState> {
|
||||
return;
|
||||
}
|
||||
|
||||
emit(const DocumentShareState.loading());
|
||||
emit(state.copyWith(isLoading: true));
|
||||
|
||||
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),
|
||||
);
|
||||
});
|
||||
final result = await _export(type, path);
|
||||
|
||||
emit(DocumentShareState.finish(result));
|
||||
emit(
|
||||
state.copyWith(
|
||||
isLoading: false,
|
||||
exportResult: result,
|
||||
),
|
||||
);
|
||||
},
|
||||
publish: (url) async {
|
||||
emit(state.copyWith(isPublished: true));
|
||||
},
|
||||
unPublish: () async {
|
||||
emit(state.copyWith(isPublished: false));
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
final ViewPB view;
|
||||
late final exporter = DocumentExporter(view);
|
||||
|
||||
Future<FlowyResult<ExportDataPB, FlowyError>> _export(
|
||||
DocumentShareType type,
|
||||
String? path,
|
||||
) async {
|
||||
final result = await exporter.export(type.exportType);
|
||||
return result.fold(
|
||||
(s) {
|
||||
if (path != null) {
|
||||
switch (type) {
|
||||
case DocumentShareType.markdown:
|
||||
return FlowySuccess(_saveMarkdownToPath(s, path));
|
||||
case DocumentShareType.html:
|
||||
return FlowySuccess(_saveHTMLToPath(s, path));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return FlowyResult.failure(FlowyError());
|
||||
},
|
||||
(f) => FlowyResult.failure(f),
|
||||
);
|
||||
}
|
||||
|
||||
ExportDataPB _saveMarkdownToPath(String markdown, String path) {
|
||||
File(path).writeAsStringSync(markdown);
|
||||
@ -93,15 +109,25 @@ enum DocumentShareType {
|
||||
|
||||
@freezed
|
||||
class DocumentShareEvent with _$DocumentShareEvent {
|
||||
const factory DocumentShareEvent.share(DocumentShareType type, String? path) =
|
||||
Share;
|
||||
const factory DocumentShareEvent.share(
|
||||
DocumentShareType type,
|
||||
String? path,
|
||||
) = _Share;
|
||||
const factory DocumentShareEvent.publish(String url) = _Publish;
|
||||
const factory DocumentShareEvent.unPublish() = _UnPublish;
|
||||
}
|
||||
|
||||
@freezed
|
||||
class DocumentShareState with _$DocumentShareState {
|
||||
const factory DocumentShareState.initial() = _Initial;
|
||||
const factory DocumentShareState.loading() = _Loading;
|
||||
const factory DocumentShareState.finish(
|
||||
FlowyResult<ExportDataPB, FlowyError> successOrFail,
|
||||
) = _Finish;
|
||||
const factory DocumentShareState({
|
||||
required bool isLoading,
|
||||
FlowyResult<ExportDataPB, FlowyError>? exportResult,
|
||||
required bool isPublished,
|
||||
FlowyResult<void, FlowyError>? publishResult,
|
||||
}) = _DocumentShareState;
|
||||
|
||||
factory DocumentShareState.initial() => const DocumentShareState(
|
||||
isLoading: false,
|
||||
isPublished: false,
|
||||
);
|
||||
}
|
||||
|
@ -73,8 +73,7 @@ class _AppFlowyMobileToolbarState extends State<AppFlowyMobileToolbar> {
|
||||
ValueListenableBuilder(
|
||||
valueListenable: isKeyboardShow,
|
||||
builder: (context, isKeyboardShow, __) {
|
||||
return AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 110),
|
||||
return SizedBox(
|
||||
// only adding padding when the keyboard is triggered by editor
|
||||
height: isKeyboardShow && widget.editorState.selection != null
|
||||
? widget.toolbarHeight
|
||||
@ -383,37 +382,26 @@ class _MobileToolbarState extends State<_MobileToolbar>
|
||||
return ValueListenableBuilder(
|
||||
valueListenable: cachedKeyboardHeight,
|
||||
builder: (_, height, ___) {
|
||||
var paddingHeight = height;
|
||||
if (Platform.isAndroid) {
|
||||
// use the viewInsets to get the keyboard height on Android
|
||||
paddingHeight = MediaQuery.of(context).viewInsets.bottom;
|
||||
// if the padding height is 0 and the keyboard height is not 0,
|
||||
// use the keyboard height
|
||||
if (paddingHeight == 0 && height != 0) {
|
||||
paddingHeight = height + MediaQuery.of(context).viewPadding.bottom;
|
||||
}
|
||||
}
|
||||
debugPrint('Keyboard height: $paddingHeight');
|
||||
return AnimatedContainer(
|
||||
duration: const Duration(microseconds: 110),
|
||||
height: paddingHeight,
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: showMenuNotifier,
|
||||
builder: (_, showingMenu, __) {
|
||||
return AnimatedContainer(
|
||||
duration: const Duration(microseconds: 110),
|
||||
height: height,
|
||||
child: (showingMenu && selectedMenuIndex != null)
|
||||
? widget.toolbarItems[selectedMenuIndex!].menuBuilder?.call(
|
||||
context,
|
||||
widget.editorState,
|
||||
this,
|
||||
) ??
|
||||
const SizedBox.shrink()
|
||||
: const SizedBox.shrink(),
|
||||
);
|
||||
},
|
||||
),
|
||||
return ValueListenableBuilder(
|
||||
valueListenable: showMenuNotifier,
|
||||
builder: (_, showingMenu, __) {
|
||||
var paddingHeight = height;
|
||||
if (Platform.isAndroid) {
|
||||
paddingHeight =
|
||||
height + MediaQuery.of(context).viewPadding.bottom;
|
||||
}
|
||||
return SizedBox(
|
||||
height: paddingHeight,
|
||||
child: (showingMenu && selectedMenuIndex != null)
|
||||
? widget.toolbarItems[selectedMenuIndex!].menuBuilder?.call(
|
||||
context,
|
||||
widget.editorState,
|
||||
this,
|
||||
) ??
|
||||
const SizedBox.shrink()
|
||||
: const SizedBox.shrink(),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
|
@ -0,0 +1,221 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/document/application/document_share_bloc.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flowy_infra_ui/widget/rounded_button.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class PublishTab extends StatelessWidget {
|
||||
const PublishTab({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return context.watch<DocumentShareBloc>().state.isPublished
|
||||
? _PublishedWidget(
|
||||
onUnPublish: () {
|
||||
context
|
||||
.read<DocumentShareBloc>()
|
||||
.add(const DocumentShareEvent.unPublish());
|
||||
},
|
||||
onVisitSite: () {},
|
||||
)
|
||||
: _UnPublishWidget(
|
||||
onPublish: () => context
|
||||
.read<DocumentShareBloc>()
|
||||
.add(const DocumentShareEvent.publish('')),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _PublishedWidget extends StatefulWidget {
|
||||
const _PublishedWidget({
|
||||
required this.onVisitSite,
|
||||
required this.onUnPublish,
|
||||
});
|
||||
|
||||
final VoidCallback onVisitSite;
|
||||
final VoidCallback onUnPublish;
|
||||
|
||||
@override
|
||||
State<_PublishedWidget> createState() => _PublishedWidgetState();
|
||||
}
|
||||
|
||||
class _PublishedWidgetState extends State<_PublishedWidget> {
|
||||
final controller = TextEditingController();
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const VSpace(16),
|
||||
const _PublishTabHeader(),
|
||||
const VSpace(16),
|
||||
_PublishUrl(
|
||||
controller: controller,
|
||||
onCopy: (url) {},
|
||||
onSubmitted: (url) {},
|
||||
),
|
||||
const VSpace(16),
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
_buildButton(
|
||||
context,
|
||||
name: LocaleKeys.shareAction_unPublish.tr(),
|
||||
borderColor: const Color(0x1E14171B),
|
||||
onTap: widget.onUnPublish,
|
||||
),
|
||||
const Spacer(),
|
||||
_buildButton(
|
||||
context,
|
||||
name: LocaleKeys.shareAction_visitSite.tr(),
|
||||
backgroundColor: Theme.of(context).colorScheme.primary,
|
||||
textColor: Colors.white,
|
||||
onTap: () {},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildButton(
|
||||
BuildContext context, {
|
||||
required String name,
|
||||
Color? backgroundColor,
|
||||
Color borderColor = Colors.transparent,
|
||||
Color? textColor,
|
||||
required VoidCallback onTap,
|
||||
}) {
|
||||
return SizedBox(
|
||||
height: 36,
|
||||
width: 189,
|
||||
child: FlowyButton(
|
||||
decoration: BoxDecoration(
|
||||
color: backgroundColor,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
border: Border.all(color: borderColor),
|
||||
),
|
||||
text: FlowyText.regular(
|
||||
name,
|
||||
textAlign: TextAlign.center,
|
||||
color: textColor,
|
||||
),
|
||||
onTap: onTap,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _UnPublishWidget extends StatelessWidget {
|
||||
const _UnPublishWidget({
|
||||
required this.onPublish,
|
||||
});
|
||||
|
||||
final VoidCallback onPublish;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const VSpace(16),
|
||||
const _PublishTabHeader(),
|
||||
const VSpace(16),
|
||||
RoundedTextButton(
|
||||
height: 36,
|
||||
title: LocaleKeys.shareAction_publish.tr(),
|
||||
padding: const EdgeInsets.symmetric(vertical: 9.0),
|
||||
fontSize: 14.0,
|
||||
textColor: Theme.of(context).colorScheme.onPrimary,
|
||||
onPressed: onPublish,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _PublishTabHeader extends StatelessWidget {
|
||||
const _PublishTabHeader();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const FlowySvg(FlowySvgs.share_publish_s),
|
||||
const HSpace(6),
|
||||
FlowyText(LocaleKeys.shareAction_publishToTheWeb.tr()),
|
||||
],
|
||||
),
|
||||
const VSpace(4),
|
||||
FlowyText.regular(
|
||||
LocaleKeys.shareAction_publishToTheWebHint.tr(),
|
||||
fontSize: 12,
|
||||
maxLines: 3,
|
||||
color: Theme.of(context).hintColor,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _PublishUrl extends StatelessWidget {
|
||||
const _PublishUrl({
|
||||
required this.controller,
|
||||
required this.onCopy,
|
||||
required this.onSubmitted,
|
||||
});
|
||||
|
||||
final TextEditingController controller;
|
||||
final void Function(String url) onCopy;
|
||||
final void Function(String url) onSubmitted;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
height: 36,
|
||||
child: FlowyTextField(
|
||||
autoFocus: false,
|
||||
controller: controller,
|
||||
text: 'http:/appflowy.com/vinh/open-positions',
|
||||
suffixIcon: _buildCopyLinkIcon(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildCopyLinkIcon() {
|
||||
return MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
onTap: () => onCopy(controller.text),
|
||||
child: Container(
|
||||
width: 36,
|
||||
height: 36,
|
||||
alignment: Alignment.center,
|
||||
padding: const EdgeInsets.all(10),
|
||||
decoration: const BoxDecoration(
|
||||
border: Border(left: BorderSide(color: Color(0x141F2329))),
|
||||
),
|
||||
child: const FlowySvg(
|
||||
FlowySvgs.m_toolbar_link_m,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
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/plugins/document/presentation/share/share_menu.dart';
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/util/string_extension.dart';
|
||||
import 'package:appflowy/workspace/application/export/document_exporter.dart';
|
||||
@ -13,6 +14,7 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:easy_localization/easy_localization.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/widget/rounded_button.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
@ -31,20 +33,40 @@ class DocumentShareButton extends StatelessWidget {
|
||||
create: (context) => getIt<DocumentShareBloc>(param1: view),
|
||||
child: BlocListener<DocumentShareBloc, DocumentShareState>(
|
||||
listener: (context, state) {
|
||||
state.mapOrNull(
|
||||
finish: (state) {
|
||||
state.successOrFail.fold(
|
||||
(data) => _handleExportData(context, data),
|
||||
_handleExportError,
|
||||
);
|
||||
},
|
||||
);
|
||||
if (state.isLoading == false && state.exportResult != null) {
|
||||
state.exportResult!.fold(
|
||||
(data) => _handleExportData(context, data),
|
||||
_handleExportError,
|
||||
);
|
||||
}
|
||||
},
|
||||
child: BlocBuilder<DocumentShareBloc, DocumentShareState>(
|
||||
builder: (context, state) => SizedBox(
|
||||
height: 32.0,
|
||||
child: IntrinsicWidth(child: ShareActionList(view: view)),
|
||||
),
|
||||
builder: (context, state) {
|
||||
final shareBloc = context.read<DocumentShareBloc>();
|
||||
return SizedBox(
|
||||
height: 32.0,
|
||||
child: IntrinsicWidth(
|
||||
child: AppFlowyPopover(
|
||||
direction: PopoverDirection.bottomWithRightAligned,
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: 422,
|
||||
),
|
||||
margin: const EdgeInsets.all(16),
|
||||
offset: const Offset(0, 8),
|
||||
popupBuilder: (context) => BlocProvider.value(
|
||||
value: shareBloc,
|
||||
child: const ShareMenu(),
|
||||
),
|
||||
child: RoundedTextButton(
|
||||
title: LocaleKeys.shareAction_buttonText.tr(),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12.0),
|
||||
fontSize: 14.0,
|
||||
textColor: Theme.of(context).colorScheme.onPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -0,0 +1,121 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:custom_sliding_segmented_control/custom_sliding_segmented_control.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'publish_tab.dart';
|
||||
|
||||
enum ShareMenuTab {
|
||||
share,
|
||||
publish,
|
||||
exportAs;
|
||||
|
||||
static List<ShareMenuTab> supportedTabs = [
|
||||
ShareMenuTab.share,
|
||||
ShareMenuTab.publish,
|
||||
ShareMenuTab.exportAs,
|
||||
];
|
||||
|
||||
String get i18n {
|
||||
switch (this) {
|
||||
case ShareMenuTab.share:
|
||||
return 'Share';
|
||||
case ShareMenuTab.publish:
|
||||
return LocaleKeys.shareAction_publish;
|
||||
case ShareMenuTab.exportAs:
|
||||
return 'Export as';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ShareMenu extends StatefulWidget {
|
||||
const ShareMenu({super.key});
|
||||
|
||||
@override
|
||||
State<ShareMenu> createState() => _ShareMenuState();
|
||||
}
|
||||
|
||||
class _ShareMenuState extends State<ShareMenu> {
|
||||
ShareMenuTab selectedTab = ShareMenuTab.publish;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final children = {
|
||||
for (final tab in ShareMenuTab.supportedTabs)
|
||||
tab: _Segment(
|
||||
title: tab.i18n.tr(),
|
||||
isSelected: selectedTab == tab,
|
||||
),
|
||||
};
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 34,
|
||||
child: CustomSlidingSegmentedControl<ShareMenuTab>(
|
||||
initialValue: selectedTab,
|
||||
curve: Curves.linear,
|
||||
padding: 0,
|
||||
fixedWidth: 128,
|
||||
innerPadding: const EdgeInsets.all(3.0),
|
||||
children: children,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFEEF0F3),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
thumbDecoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
boxShadow: const [
|
||||
BoxShadow(
|
||||
color: Color(0x141F2225),
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
],
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
onValueChanged: (v) {
|
||||
setState(() {
|
||||
selectedTab = v;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
_buildTab(context),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildTab(BuildContext context) {
|
||||
switch (selectedTab) {
|
||||
case ShareMenuTab.publish:
|
||||
return const PublishTab();
|
||||
|
||||
default:
|
||||
return const Center(
|
||||
child: FlowyText('coming soon'),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class _Segment extends StatelessWidget {
|
||||
const _Segment({
|
||||
required this.title,
|
||||
required this.isSelected,
|
||||
});
|
||||
|
||||
final String title;
|
||||
final bool isSelected;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final textColor = isSelected ? null : Theme.of(context).hintColor;
|
||||
return FlowyText(
|
||||
title,
|
||||
textAlign: TextAlign.center,
|
||||
color: textColor,
|
||||
);
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@ import 'package:appflowy_editor/appflowy_editor.dart' hide Log;
|
||||
import 'package:appflowy_result/appflowy_result.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/uuid.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:protobuf/protobuf.dart';
|
||||
@ -257,6 +258,10 @@ class SpaceBloc extends Bloc<SpaceEvent, SpaceState> {
|
||||
);
|
||||
},
|
||||
reset: (userProfile, workspaceId) async {
|
||||
if (workspaceId == _workspaceId) {
|
||||
return;
|
||||
}
|
||||
|
||||
_reset(userProfile, workspaceId);
|
||||
|
||||
add(
|
||||
@ -321,6 +326,7 @@ class SpaceBloc extends Bloc<SpaceEvent, SpaceState> {
|
||||
required String icon,
|
||||
required String iconColor,
|
||||
required SpacePermission permission,
|
||||
String? viewId,
|
||||
}) async {
|
||||
final section = switch (permission) {
|
||||
SpacePermission.publicToAll => ViewSectionPB.Public,
|
||||
@ -331,6 +337,7 @@ class SpaceBloc extends Bloc<SpaceEvent, SpaceState> {
|
||||
name: name,
|
||||
viewSection: section,
|
||||
setAsCurrent: false,
|
||||
viewId: viewId,
|
||||
);
|
||||
return await result.fold((space) async {
|
||||
Log.info('Space created: $space');
|
||||
@ -476,56 +483,82 @@ class SpaceBloc extends Bloc<SpaceEvent, SpaceState> {
|
||||
if (members.items.length == 1 || isOwner) {
|
||||
// create a new public space and a new private space
|
||||
// move all the views in the workspace to the new public/private space
|
||||
final publicViews =
|
||||
await _workspaceService.getPublicViews().getOrThrow();
|
||||
// only migrate the public space if there are any public views
|
||||
if (publicViews.isNotEmpty) {
|
||||
final publicSpace = await _createSpace(
|
||||
name: 'Shared',
|
||||
icon: builtInSpaceIcons.first,
|
||||
iconColor: builtInSpaceColors.first,
|
||||
permission: SpacePermission.publicToAll,
|
||||
);
|
||||
|
||||
if (publicSpace != null) {
|
||||
for (final view in publicViews.reversed) {
|
||||
if (view.isSpace) {
|
||||
continue;
|
||||
}
|
||||
await ViewBackendService.moveViewV2(
|
||||
viewId: view.id,
|
||||
newParentId: publicSpace.id,
|
||||
prevViewId: view.parentViewId,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// create a new private space
|
||||
final privateViews =
|
||||
await _workspaceService.getPrivateViews().getOrThrow();
|
||||
// only migrate the private space if there are any private views
|
||||
if (privateViews.isNotEmpty) {
|
||||
final privateSpace = await _createSpace(
|
||||
name: 'Private',
|
||||
icon: builtInSpaceIcons.last,
|
||||
iconColor: builtInSpaceColors.last,
|
||||
permission: SpacePermission.private,
|
||||
var publicViews = await _workspaceService.getPublicViews().getOrThrow();
|
||||
final containsPublicSpace = publicViews.any(
|
||||
(e) => e.isSpace && e.spacePermission == SpacePermission.publicToAll,
|
||||
);
|
||||
if (privateSpace != null) {
|
||||
for (final view in privateViews.reversed) {
|
||||
publicViews = publicViews.where((e) => !e.isSpace).toList();
|
||||
// if there is already a public space, don't migrate the public space
|
||||
// only migrate the public space if there are any public views
|
||||
if (publicViews.isEmpty || containsPublicSpace) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final viewId = fixedUuid(user.id.toInt(), UuidType.publicSpace);
|
||||
final publicSpace = await _createSpace(
|
||||
name: 'Shared',
|
||||
icon: builtInSpaceIcons.first,
|
||||
iconColor: builtInSpaceColors.first,
|
||||
permission: SpacePermission.publicToAll,
|
||||
viewId: viewId,
|
||||
);
|
||||
|
||||
Log.info('migrating: created a new public space: ${publicSpace?.id}');
|
||||
|
||||
if (publicSpace != null) {
|
||||
for (final view in publicViews.reversed) {
|
||||
if (view.isSpace) {
|
||||
continue;
|
||||
}
|
||||
await ViewBackendService.moveViewV2(
|
||||
viewId: view.id,
|
||||
newParentId: privateSpace.id,
|
||||
prevViewId: view.parentViewId,
|
||||
newParentId: publicSpace.id,
|
||||
prevViewId: null,
|
||||
);
|
||||
Log.info(
|
||||
'migrating: migrate ${view.name}(${view.id}) to public space(${publicSpace.id})',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create a new private space
|
||||
final viewId = fixedUuid(user.id.toInt(), UuidType.privateSpace);
|
||||
var privateViews = await _workspaceService.getPrivateViews().getOrThrow();
|
||||
// if there is already a private space, don't migrate the private space
|
||||
final containsPrivateSpace = privateViews.any(
|
||||
(e) => e.isSpace && e.spacePermission == SpacePermission.private,
|
||||
);
|
||||
privateViews = privateViews.where((e) => !e.isSpace).toList();
|
||||
if (privateViews.isEmpty || containsPrivateSpace) {
|
||||
return true;
|
||||
}
|
||||
// only migrate the private space if there are any private views
|
||||
final privateSpace = await _createSpace(
|
||||
name: 'Private',
|
||||
icon: builtInSpaceIcons.last,
|
||||
iconColor: builtInSpaceColors.last,
|
||||
permission: SpacePermission.private,
|
||||
viewId: viewId,
|
||||
);
|
||||
Log.info('migrating: created a new private space: ${privateSpace?.id}');
|
||||
|
||||
if (privateSpace != null) {
|
||||
for (final view in privateViews.reversed) {
|
||||
if (view.isSpace) {
|
||||
continue;
|
||||
}
|
||||
await ViewBackendService.moveViewV2(
|
||||
viewId: view.id,
|
||||
newParentId: privateSpace.id,
|
||||
prevViewId: null,
|
||||
);
|
||||
Log.info(
|
||||
'migrating: migrate ${view.name}(${view.id}) to private space(${privateSpace.id})',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (e) {
|
||||
Log.error('migrate space error: $e');
|
||||
@ -538,14 +571,16 @@ class SpaceBloc extends Bloc<SpaceEvent, SpaceState> {
|
||||
required List<ViewPB> publicViews,
|
||||
required List<ViewPB> privateViews,
|
||||
}) async {
|
||||
final publicSpaces =
|
||||
spaces.where((e) => e.spacePermission == SpacePermission.publicToAll);
|
||||
final publicSpaces = spaces.where(
|
||||
(e) => e.spacePermission == SpacePermission.publicToAll,
|
||||
);
|
||||
if (publicSpaces.isEmpty && publicViews.isNotEmpty) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final privateSpaces =
|
||||
spaces.where((e) => e.spacePermission == SpacePermission.private);
|
||||
final privateSpaces = spaces.where(
|
||||
(e) => e.spacePermission == SpacePermission.private,
|
||||
);
|
||||
if (privateSpaces.isEmpty && privateViews.isNotEmpty) {
|
||||
return true;
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ class ViewBackendService {
|
||||
/// If the index is null, the view will be added to the end of the list.
|
||||
int? index,
|
||||
ViewSectionPB? section,
|
||||
final String? viewId,
|
||||
}) {
|
||||
final payload = CreateViewPayloadPB.create()
|
||||
..parentViewId = parentViewId
|
||||
@ -63,6 +64,10 @@ class ViewBackendService {
|
||||
payload.section = section;
|
||||
}
|
||||
|
||||
if (viewId != null) {
|
||||
payload.viewId = viewId;
|
||||
}
|
||||
|
||||
return FolderEventCreateView(payload).send();
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ class WorkspaceService {
|
||||
int? index,
|
||||
ViewLayoutPB? layout,
|
||||
bool? setAsCurrent,
|
||||
String? viewId,
|
||||
}) {
|
||||
final payload = CreateViewPayloadPB.create()
|
||||
..parentViewId = workspaceId
|
||||
@ -37,6 +38,10 @@ class WorkspaceService {
|
||||
payload.setAsCurrent = setAsCurrent;
|
||||
}
|
||||
|
||||
if (viewId != null) {
|
||||
payload.viewId = viewId;
|
||||
}
|
||||
|
||||
return FolderEventCreateView(payload).send();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,19 @@
|
||||
import 'package:uuid/data.dart';
|
||||
import 'package:uuid/rng.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
const _uuid = Uuid();
|
||||
|
||||
String uuid() {
|
||||
return const Uuid().v4();
|
||||
return _uuid.v4();
|
||||
}
|
||||
|
||||
String fixedUuid(int seed, UuidType type) {
|
||||
return _uuid.v4(config: V4Options(null, MathRNG(seed: seed + type.index)));
|
||||
}
|
||||
|
||||
enum UuidType {
|
||||
// 0.6.0
|
||||
publicSpace,
|
||||
privateSpace,
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ class RoundedTextButton extends StatelessWidget {
|
||||
final Color? hoverColor;
|
||||
final Color? textColor;
|
||||
final double? fontSize;
|
||||
final FontWeight? fontWeight;
|
||||
final EdgeInsets padding;
|
||||
|
||||
const RoundedTextButton({
|
||||
@ -27,6 +28,7 @@ class RoundedTextButton extends StatelessWidget {
|
||||
this.hoverColor,
|
||||
this.textColor,
|
||||
this.fontSize,
|
||||
this.fontWeight,
|
||||
this.padding = const EdgeInsets.symmetric(horizontal: 8, vertical: 6),
|
||||
});
|
||||
|
||||
@ -42,6 +44,7 @@ class RoundedTextButton extends StatelessWidget {
|
||||
child: SizedBox.expand(
|
||||
child: FlowyTextButton(
|
||||
title ?? '',
|
||||
fontWeight: fontWeight,
|
||||
onPressed: onPressed,
|
||||
fontSize: fontSize,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
|
@ -394,6 +394,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
custom_sliding_segmented_control:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: custom_sliding_segmented_control
|
||||
sha256: "53c3e931c3ae1f696085d1ec70ac8e934da836595a9b7d9b88fdd0fcbf2a5574"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.8.3"
|
||||
dart_style:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -2174,10 +2182,10 @@ packages:
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
name: uuid
|
||||
sha256: cd210a09f7c18cbe5a02511718e0334de6559871052c90a90c0cca46a4aa81c8
|
||||
sha256: "814e9e88f21a176ae1359149021870e87f7cddaf633ab678a5d2b0bff7fd1ba8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.3.3"
|
||||
version: "4.4.0"
|
||||
value_layout_builder:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||
# Read more about iOS versioning at
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
version: 0.6.0
|
||||
version: 0.6.1
|
||||
|
||||
environment:
|
||||
flutter: ">=3.22.0"
|
||||
@ -149,6 +149,7 @@ dependencies:
|
||||
bitsdojo_window: ^0.1.6
|
||||
|
||||
flutter_highlight: ^0.7.0
|
||||
custom_sliding_segmented_control: ^1.8.3
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: ^3.0.1
|
||||
@ -199,7 +200,7 @@ dependency_overrides:
|
||||
ref: e44458d
|
||||
path: sheet
|
||||
|
||||
uuid: ^4.1.0
|
||||
uuid: ^4.4.0
|
||||
|
||||
flutter_cache_manager:
|
||||
git:
|
||||
|
3
frontend/resources/flowy_icons/16x/share_publish.svg
Normal file
3
frontend/resources/flowy_icons/16x/share_publish.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9 1.6875C13.0387 1.6875 16.3125 4.96125 16.3125 9C16.3125 13.0387 13.0387 16.3125 9 16.3125C4.96125 16.3125 1.6875 13.0387 1.6875 9C1.6875 4.96125 4.96125 1.6875 9 1.6875ZM8.4375 9.5625L6.1995 9.56288C6.21525 9.92288 6.24563 10.2731 6.2895 10.6117L6.32438 10.863L6.36787 11.1311C6.71512 13.1156 7.52325 14.607 8.43787 15.051L8.4375 9.5625ZM11.8005 9.56288L9.5625 9.5625V15.051C10.4565 14.6164 11.2489 13.1813 11.6081 11.2628L11.6321 11.1311L11.6756 10.8634C11.7402 10.4324 11.7819 9.99828 11.8005 9.56288ZM5.07337 9.56288H2.83763C3.04238 11.8316 4.47225 13.7479 6.4605 14.6441C6.07163 14.0415 5.751 13.3009 5.5155 12.4639L5.46225 12.2689L5.40038 12.0199L5.34337 11.7656C5.19117 11.0403 5.10084 10.3034 5.07337 9.56288ZM15.1624 9.56288H12.9262C12.9014 10.2245 12.827 10.8834 12.7035 11.5339L12.6562 11.7656L12.5992 12.0199L12.5374 12.2692C12.2974 13.1858 11.958 13.9954 11.5391 14.6441C13.5274 13.7479 14.9573 11.8316 15.1616 9.56288H15.1624ZM6.4605 3.3555L6.41025 3.37838C4.4475 4.28437 3.0405 6.1875 2.83763 8.4375H5.07337C5.10037 7.75125 5.1765 7.08938 5.29613 6.46613L5.34337 6.23438L5.40038 5.98012L5.46225 5.73075C5.70225 4.81425 6.04163 4.00463 6.4605 3.35588V3.3555ZM8.4375 2.949C7.54612 3.38175 6.75562 4.8105 6.39488 6.72113L6.36787 6.86888L6.32438 7.13662C6.25977 7.56774 6.21809 8.00197 6.1995 8.4375H8.4375V2.949ZM11.5395 3.35588L11.5845 3.42712C11.952 4.01475 12.2565 4.72762 12.4826 5.52863L12.5378 5.73112L12.5996 5.98012L12.6566 6.23438C12.8036 6.92438 12.8963 7.66538 12.9266 8.4375H15.1624C14.958 6.16838 13.5281 4.25213 11.5395 3.35625V3.35588ZM9.5625 2.949V8.4375H11.8005C11.7849 8.07668 11.7537 7.71672 11.7067 7.35862L11.6756 7.13662L11.6321 6.86888C11.2849 4.88475 10.4771 3.39338 9.56288 2.949H9.5625Z" fill="#171717"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
@ -106,7 +106,12 @@
|
||||
"html": "HTML",
|
||||
"clipboard": "Copy to clipboard",
|
||||
"csv": "CSV",
|
||||
"copyLink": "Copy Link"
|
||||
"copyLink": "Copy Link",
|
||||
"publishToTheWeb": "Publish to the web",
|
||||
"publishToTheWebHint": "Publish a static website of this page and control who see it",
|
||||
"publish": "Publish",
|
||||
"unPublish": "UnPublish",
|
||||
"visitSite": "Visit site"
|
||||
},
|
||||
"moreAction": {
|
||||
"small": "small",
|
||||
|
@ -21,6 +21,7 @@ impl EventIntegrationTest {
|
||||
set_as_current: true,
|
||||
index: None,
|
||||
section: None,
|
||||
view_id: None,
|
||||
};
|
||||
EventBuilder::new(self.clone())
|
||||
.event(FolderEvent::CreateView)
|
||||
|
@ -45,6 +45,7 @@ impl EventIntegrationTest {
|
||||
set_as_current: true,
|
||||
index: None,
|
||||
section: None,
|
||||
view_id: None,
|
||||
};
|
||||
EventBuilder::new(self.clone())
|
||||
.event(FolderEvent::CreateView)
|
||||
@ -76,6 +77,7 @@ impl EventIntegrationTest {
|
||||
set_as_current: true,
|
||||
index: None,
|
||||
section: None,
|
||||
view_id: None,
|
||||
};
|
||||
EventBuilder::new(self.clone())
|
||||
.event(FolderEvent::CreateView)
|
||||
@ -102,6 +104,7 @@ impl EventIntegrationTest {
|
||||
set_as_current: true,
|
||||
index: None,
|
||||
section: None,
|
||||
view_id: None,
|
||||
};
|
||||
EventBuilder::new(self.clone())
|
||||
.event(FolderEvent::CreateView)
|
||||
|
@ -78,6 +78,7 @@ impl DocumentEventTest {
|
||||
set_as_current: true,
|
||||
index: None,
|
||||
section: None,
|
||||
view_id: None,
|
||||
};
|
||||
EventBuilder::new(core.clone())
|
||||
.event(FolderEvent::CreateView)
|
||||
|
@ -42,6 +42,7 @@ impl EventIntegrationTest {
|
||||
set_as_current: true,
|
||||
index: None,
|
||||
section: None,
|
||||
view_id: None,
|
||||
};
|
||||
let view = EventBuilder::new(self.clone())
|
||||
.event(FolderEvent::CreateView)
|
||||
|
@ -250,6 +250,7 @@ impl EventIntegrationTest {
|
||||
set_as_current: false,
|
||||
index: None,
|
||||
section: None,
|
||||
view_id: None,
|
||||
};
|
||||
EventBuilder::new(self.clone())
|
||||
.event(FolderEvent::CreateView)
|
||||
@ -313,6 +314,7 @@ impl ViewTest {
|
||||
set_as_current: true,
|
||||
index: None,
|
||||
section: None,
|
||||
view_id: None,
|
||||
};
|
||||
|
||||
let view = EventBuilder::new(sdk.clone())
|
||||
|
@ -252,6 +252,7 @@ pub async fn create_view(
|
||||
set_as_current: true,
|
||||
index: None,
|
||||
section: None,
|
||||
view_id: None,
|
||||
};
|
||||
EventBuilder::new(sdk.clone())
|
||||
.event(CreateView)
|
||||
|
@ -258,6 +258,9 @@ pub struct CreateViewPayloadPB {
|
||||
// The view in private section will only be shown in the user's private view list.
|
||||
#[pb(index = 10, one_of)]
|
||||
pub section: Option<ViewSectionPB>,
|
||||
|
||||
#[pb(index = 11, one_of)]
|
||||
pub view_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Hash, Debug, ProtoBuf_Enum, Clone, Default)]
|
||||
@ -313,7 +316,8 @@ impl TryInto<CreateViewParams> for CreateViewPayloadPB {
|
||||
fn try_into(self) -> Result<CreateViewParams, Self::Error> {
|
||||
let name = ViewName::parse(self.name)?.0;
|
||||
let parent_view_id = ViewIdentify::parse(self.parent_view_id)?.0;
|
||||
let view_id = gen_view_id().to_string();
|
||||
// if view_id is not provided, generate a new view_id
|
||||
let view_id = self.view_id.unwrap_or_else(|| gen_view_id().to_string());
|
||||
|
||||
Ok(CreateViewParams {
|
||||
parent_view_id,
|
||||
|
@ -59,8 +59,6 @@ AppDir:
|
||||
- libwayland-cursor0:amd64
|
||||
- libwayland-client0:amd64
|
||||
- libwayland-egl1:amd64
|
||||
- libmpv-dev:amd64
|
||||
- mpv:amd64
|
||||
files:
|
||||
include: []
|
||||
exclude:
|
||||
|
Loading…
Reference in New Issue
Block a user