mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: support creating database at the first level (#5627)
* feat: support creating database at the first level * chore: add loading indicator when importing file
This commit is contained in:
parent
7d96c2dfd4
commit
f812040f04
@ -54,6 +54,7 @@ class _MobileSpaceState extends State<MobileSpace> {
|
||||
context.read<SpaceBloc>().add(
|
||||
SpaceEvent.createPage(
|
||||
name: LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
|
||||
layout: ViewLayoutPB.Document,
|
||||
index: 0,
|
||||
),
|
||||
);
|
||||
@ -99,6 +100,7 @@ class _MobileSpaceState extends State<MobileSpace> {
|
||||
context.read<SpaceBloc>().add(
|
||||
SpaceEvent.createPage(
|
||||
name: LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
|
||||
layout: ViewLayoutPB.Document,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -124,6 +124,7 @@ class SpaceBloc extends Bloc<SpaceEvent, SpaceState> {
|
||||
SpaceEvent.createPage(
|
||||
name: LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
|
||||
index: 0,
|
||||
layout: ViewLayoutPB.Document,
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -216,7 +217,7 @@ class SpaceBloc extends Bloc<SpaceEvent, SpaceState> {
|
||||
await _setSpaceExpandStatus(space, isExpanded);
|
||||
emit(state.copyWith(isExpanded: isExpanded));
|
||||
},
|
||||
createPage: (name, index) async {
|
||||
createPage: (name, layout, index) async {
|
||||
final parentViewId = state.currentSpace?.id;
|
||||
if (parentViewId == null) {
|
||||
return;
|
||||
@ -224,7 +225,7 @@ class SpaceBloc extends Bloc<SpaceEvent, SpaceState> {
|
||||
|
||||
final result = await ViewBackendService.createView(
|
||||
name: name,
|
||||
layoutType: ViewLayoutPB.Document,
|
||||
layoutType: layout,
|
||||
parentViewId: parentViewId,
|
||||
index: index,
|
||||
);
|
||||
@ -631,6 +632,7 @@ class SpaceEvent with _$SpaceEvent {
|
||||
const factory SpaceEvent.expand(ViewPB space, bool isExpanded) = _Expand;
|
||||
const factory SpaceEvent.createPage({
|
||||
required String name,
|
||||
required ViewLayoutPB layout,
|
||||
int? index,
|
||||
}) = _CreatePage;
|
||||
const factory SpaceEvent.delete(ViewPB? space) = _Delete;
|
||||
|
@ -158,7 +158,7 @@ class DesktopHomeScreen extends StatelessWidget {
|
||||
delegate: DesktopHomeScreenStackAdaptor(context),
|
||||
userProfile: userProfile,
|
||||
);
|
||||
final menu = _buildHomeSidebar(
|
||||
final sidebar = _buildHomeSidebar(
|
||||
context,
|
||||
layout: layout,
|
||||
userProfile: userProfile,
|
||||
@ -170,7 +170,7 @@ class DesktopHomeScreen extends StatelessWidget {
|
||||
return _layoutWidgets(
|
||||
layout: layout,
|
||||
homeStack: homeStack,
|
||||
homeMenu: menu,
|
||||
sidebar: sidebar,
|
||||
editPanel: editPanel,
|
||||
bubble: const QuestionBubble(),
|
||||
homeMenuResizer: homeMenuResizer,
|
||||
@ -253,7 +253,7 @@ class DesktopHomeScreen extends StatelessWidget {
|
||||
|
||||
Widget _layoutWidgets({
|
||||
required HomeLayout layout,
|
||||
required Widget homeMenu,
|
||||
required Widget sidebar,
|
||||
required Widget homeStack,
|
||||
required Widget editPanel,
|
||||
required Widget bubble,
|
||||
@ -287,7 +287,7 @@ class DesktopHomeScreen extends StatelessWidget {
|
||||
bottom: 0,
|
||||
width: layout.editPanelWidth,
|
||||
),
|
||||
homeMenu
|
||||
sidebar
|
||||
.animatedPanelX(
|
||||
closeX: -layout.menuWidth,
|
||||
isClosed: !layout.showMenu,
|
||||
|
@ -1,19 +1,21 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/document/application/document_data_pb_extension.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/migration/editor_migration.dart';
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/workspace/application/settings/share/import_service.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/import/import_type.dart';
|
||||
|
||||
import 'package:appflowy/workspace/presentation/home/toast.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart' hide Log;
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/file_picker/file_picker_service.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/container.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
|
||||
@ -67,10 +69,12 @@ class ImportPanel extends StatefulWidget {
|
||||
|
||||
class _ImportPanelState extends State<ImportPanel> {
|
||||
final flowyContainerFocusNode = FocusNode();
|
||||
final ValueNotifier<bool> showLoading = ValueNotifier(false);
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
flowyContainerFocusNode.dispose();
|
||||
showLoading.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@ -87,37 +91,52 @@ class _ImportPanelState extends State<ImportPanel> {
|
||||
FlowyOverlay.pop(context);
|
||||
}
|
||||
},
|
||||
child: FlowyContainer(
|
||||
Theme.of(context).colorScheme.surface,
|
||||
height: height,
|
||||
width: width,
|
||||
child: GridView.count(
|
||||
childAspectRatio: 1 / .2,
|
||||
crossAxisCount: 2,
|
||||
children: ImportType.values
|
||||
.where((element) => element.enableOnRelease)
|
||||
.map(
|
||||
(e) => Card(
|
||||
child: FlowyButton(
|
||||
leftIcon: e.icon(context),
|
||||
leftIconSize: const Size.square(20),
|
||||
text: FlowyText.medium(
|
||||
e.toString(),
|
||||
fontSize: 15,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
color: Theme.of(context).colorScheme.tertiary,
|
||||
child: Stack(
|
||||
children: [
|
||||
FlowyContainer(
|
||||
Theme.of(context).colorScheme.surface,
|
||||
height: height,
|
||||
width: width,
|
||||
child: GridView.count(
|
||||
childAspectRatio: 1 / .2,
|
||||
crossAxisCount: 2,
|
||||
children: ImportType.values
|
||||
.where((element) => element.enableOnRelease)
|
||||
.map(
|
||||
(e) => Card(
|
||||
child: FlowyButton(
|
||||
leftIcon: e.icon(context),
|
||||
leftIconSize: const Size.square(20),
|
||||
text: FlowyText.medium(
|
||||
e.toString(),
|
||||
fontSize: 15,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
color: Theme.of(context).colorScheme.tertiary,
|
||||
),
|
||||
onTap: () async {
|
||||
await _importFile(widget.parentViewId, e);
|
||||
if (context.mounted) {
|
||||
FlowyOverlay.pop(context);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
onTap: () async {
|
||||
await _importFile(widget.parentViewId, e);
|
||||
if (context.mounted) {
|
||||
FlowyOverlay.pop(context);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
ValueListenableBuilder(
|
||||
valueListenable: showLoading,
|
||||
builder: (context, showLoading, child) {
|
||||
if (!showLoading) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -132,6 +151,8 @@ class _ImportPanelState extends State<ImportPanel> {
|
||||
return;
|
||||
}
|
||||
|
||||
showLoading.value = true;
|
||||
|
||||
for (final file in result.files) {
|
||||
final path = file.path;
|
||||
if (path == null) {
|
||||
@ -145,43 +166,60 @@ class _ImportPanelState extends State<ImportPanel> {
|
||||
case ImportType.historyDocument:
|
||||
final bytes = _documentDataFrom(importType, data);
|
||||
if (bytes != null) {
|
||||
await ImportBackendService.importData(
|
||||
final result = await ImportBackendService.importData(
|
||||
bytes,
|
||||
name,
|
||||
parentViewId,
|
||||
ImportTypePB.HistoryDocument,
|
||||
);
|
||||
result.onFailure((error) {
|
||||
showSnackBarMessage(context, error.msg);
|
||||
Log.error('Failed to import markdown $error');
|
||||
});
|
||||
}
|
||||
break;
|
||||
case ImportType.historyDatabase:
|
||||
await ImportBackendService.importData(
|
||||
final result = await ImportBackendService.importData(
|
||||
utf8.encode(data),
|
||||
name,
|
||||
parentViewId,
|
||||
ImportTypePB.HistoryDatabase,
|
||||
);
|
||||
result.onFailure((error) {
|
||||
showSnackBarMessage(context, error.msg);
|
||||
Log.error('Failed to import history database $error');
|
||||
});
|
||||
break;
|
||||
case ImportType.databaseRawData:
|
||||
await ImportBackendService.importData(
|
||||
final result = await ImportBackendService.importData(
|
||||
utf8.encode(data),
|
||||
name,
|
||||
parentViewId,
|
||||
ImportTypePB.RawDatabase,
|
||||
);
|
||||
result.onFailure((error) {
|
||||
showSnackBarMessage(context, error.msg);
|
||||
Log.error('Failed to import database raw data $error');
|
||||
});
|
||||
break;
|
||||
case ImportType.databaseCSV:
|
||||
await ImportBackendService.importData(
|
||||
final result = await ImportBackendService.importData(
|
||||
utf8.encode(data),
|
||||
name,
|
||||
parentViewId,
|
||||
ImportTypePB.CSV,
|
||||
);
|
||||
result.onFailure((error) {
|
||||
showSnackBarMessage(context, error.msg);
|
||||
Log.error('Failed to import CSV $error');
|
||||
});
|
||||
break;
|
||||
default:
|
||||
assert(false, 'Unsupported Type $importType');
|
||||
}
|
||||
}
|
||||
|
||||
showLoading.value = false;
|
||||
widget.importCallback(importType, '', null);
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ class SidebarNewPageButton extends StatelessWidget {
|
||||
SpaceEvent.createPage(
|
||||
name: viewName,
|
||||
index: 0,
|
||||
layout: ViewLayoutPB.Document,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
|
@ -6,7 +6,6 @@ import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/hotkeys.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/menu_shared_state.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/favorites/favorite_folder.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/shared/rename_view_dialog.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/create_space_popup.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/shared_widget.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/sidebar_space_header.dart';
|
||||
@ -103,7 +102,11 @@ class _SpaceState extends State<_Space> {
|
||||
SidebarSpaceHeader(
|
||||
isExpanded: state.isExpanded,
|
||||
space: currentSpace,
|
||||
onAdded: () => _showCreatePagePopup(context, currentSpace),
|
||||
onAdded: (layout) => _showCreatePagePopup(
|
||||
context,
|
||||
currentSpace,
|
||||
layout,
|
||||
),
|
||||
onCreateNewSpace: () => _showCreateSpaceDialog(context),
|
||||
onCollapseAllPages: () => isExpandedNotifier.value = true,
|
||||
),
|
||||
@ -150,23 +153,20 @@ class _SpaceState extends State<_Space> {
|
||||
);
|
||||
}
|
||||
|
||||
void _showCreatePagePopup(BuildContext context, ViewPB space) {
|
||||
createViewAndShowRenameDialogIfNeeded(
|
||||
context,
|
||||
LocaleKeys.newPageText.tr(),
|
||||
(viewName, _) {
|
||||
if (viewName.isNotEmpty) {
|
||||
context.read<SpaceBloc>().add(
|
||||
SpaceEvent.createPage(
|
||||
name: viewName,
|
||||
index: 0,
|
||||
),
|
||||
);
|
||||
void _showCreatePagePopup(
|
||||
BuildContext context,
|
||||
ViewPB space,
|
||||
ViewLayoutPB layout,
|
||||
) {
|
||||
context.read<SpaceBloc>().add(
|
||||
SpaceEvent.createPage(
|
||||
name: LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
|
||||
layout: layout,
|
||||
index: 0,
|
||||
),
|
||||
);
|
||||
|
||||
context.read<SpaceBloc>().add(SpaceEvent.expand(space, true));
|
||||
}
|
||||
},
|
||||
);
|
||||
context.read<SpaceBloc>().add(SpaceEvent.expand(space, true));
|
||||
}
|
||||
|
||||
void _switchToNextSpace() {
|
||||
|
@ -1,6 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/util/theme_extension.dart';
|
||||
import 'package:appflowy/workspace/application/sidebar/space/space_bloc.dart';
|
||||
@ -9,6 +8,7 @@ import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/manage_s
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/shared_widget.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/space_action_type.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/space_more_popup.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/view/view_add_button.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
@ -29,7 +29,7 @@ class SidebarSpaceHeader extends StatefulWidget {
|
||||
});
|
||||
|
||||
final ViewPB space;
|
||||
final VoidCallback onAdded;
|
||||
final void Function(ViewLayoutPB layout) onAdded;
|
||||
final VoidCallback onCreateNewSpace;
|
||||
final VoidCallback onCollapseAllPages;
|
||||
final bool isExpanded;
|
||||
@ -87,7 +87,7 @@ class _SidebarSpaceHeaderState extends State<SidebarSpaceHeader> {
|
||||
left: 3,
|
||||
top: 3,
|
||||
bottom: 3,
|
||||
right: isHovered.value || onEditing ? 66 : 0,
|
||||
right: isHovered.value || onEditing ? 88 : 0,
|
||||
child: SpacePopup(
|
||||
child: _buildChild(),
|
||||
),
|
||||
@ -144,12 +144,20 @@ class _SidebarSpaceHeaderState extends State<SidebarSpaceHeader> {
|
||||
onAction: _onAction,
|
||||
),
|
||||
const HSpace(8.0),
|
||||
FlowyIconButton(
|
||||
width: 24,
|
||||
tooltipText: LocaleKeys.sideBar_addAPage.tr(),
|
||||
iconPadding: const EdgeInsets.all(4.0),
|
||||
icon: const FlowySvg(FlowySvgs.view_item_add_s),
|
||||
onPressed: widget.onAdded,
|
||||
ViewAddButton(
|
||||
parentViewId: widget.space.id,
|
||||
onEditing: (_) {},
|
||||
onSelected: (
|
||||
pluginBuilder,
|
||||
name,
|
||||
initialDataBytes,
|
||||
openAfterCreated,
|
||||
createNewView,
|
||||
) {
|
||||
if (createNewView) {
|
||||
widget.onAdded(pluginBuilder.layoutType!);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
|
Loading…
Reference in New Issue
Block a user