fix: settings changes + ai layout improvements (#5656)

* fix: settings changes

* fix: improve chat layout
This commit is contained in:
Mathias Mogensen 2024-06-28 16:54:54 +02:00 committed by GitHub
parent b09ff040f1
commit 3bcadff152
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 155 additions and 143 deletions

View File

@ -71,7 +71,6 @@ class AIChatPagePlugin extends Plugin {
void dispose() { void dispose() {
_viewInfoBloc.close(); _viewInfoBloc.close();
notifier.dispose(); notifier.dispose();
super.dispose();
} }
} }
@ -119,4 +118,7 @@ class AIChatPagePluginWidgetBuilder extends PluginWidgetBuilder
@override @override
List<NavigationItem> get navigationItems => [this]; List<NavigationItem> get navigationItems => [this];
@override
EdgeInsets get contentPadding => EdgeInsets.zero;
} }

View File

@ -1,3 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/plugins/ai_chat/application/chat_bloc.dart'; import 'package:appflowy/plugins/ai_chat/application/chat_bloc.dart';
import 'package:appflowy/plugins/ai_chat/presentation/ai_message_bubble.dart'; import 'package:appflowy/plugins/ai_chat/presentation/ai_message_bubble.dart';
@ -10,12 +13,10 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra/theme_extension.dart';
import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_chat_types/flutter_chat_types.dart'; import 'package:flutter_chat_types/flutter_chat_types.dart';
import 'package:flutter_chat_ui/flutter_chat_ui.dart' show Chat;
import 'package:flutter_chat_types/flutter_chat_types.dart' as types; import 'package:flutter_chat_types/flutter_chat_types.dart' as types;
import 'package:flutter_chat_ui/flutter_chat_ui.dart' show Chat;
import 'presentation/chat_input.dart'; import 'presentation/chat_input.dart';
import 'presentation/chat_popmenu.dart'; import 'presentation/chat_popmenu.dart';
@ -27,11 +28,11 @@ import 'presentation/message/user_text_message.dart';
class AIChatUILayout { class AIChatUILayout {
static EdgeInsets get chatPadding => static EdgeInsets get chatPadding =>
isMobile ? EdgeInsets.zero : const EdgeInsets.symmetric(horizontal: 70); isMobile ? EdgeInsets.zero : const EdgeInsets.symmetric(horizontal: 20);
static EdgeInsets get welcomePagePadding => isMobile static EdgeInsets get welcomePagePadding => isMobile
? const EdgeInsets.symmetric(horizontal: 20) ? const EdgeInsets.symmetric(horizontal: 20)
: const EdgeInsets.symmetric(horizontal: 100); : const EdgeInsets.symmetric(horizontal: 50);
static double get messageWidthRatio => 0.85; static double get messageWidthRatio => 0.85;
@ -44,7 +45,8 @@ class AIChatUILayout {
query.padding.right, query.padding.right,
query.viewInsets.bottom + query.padding.bottom, query.viewInsets.bottom + query.padding.bottom,
) )
: const EdgeInsets.symmetric(horizontal: 70); : const EdgeInsets.symmetric(horizontal: 50) +
const EdgeInsets.only(bottom: 20);
} }
} }
@ -77,92 +79,89 @@ class _AIChatPageState extends State<AIChatPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (widget.userProfile.authenticator == AuthenticatorPB.AppFlowyCloud) { if (widget.userProfile.authenticator == AuthenticatorPB.AppFlowyCloud) {
return buildChatWidget(); return buildChatWidget();
} else {
return Center(
child: FlowyText(
LocaleKeys.chat_unsupportedCloudPrompt.tr(),
fontSize: 20,
),
);
} }
return Center(
child: FlowyText(
LocaleKeys.chat_unsupportedCloudPrompt.tr(),
fontSize: 20,
),
);
} }
Widget buildChatWidget() { Widget buildChatWidget() {
return SizedBox.expand( return Row(
child: Padding( mainAxisAlignment: MainAxisAlignment.center,
padding: AIChatUILayout.chatPadding, children: [
child: BlocProvider( Flexible(
create: (context) => ChatBloc( child: ConstrainedBox(
view: widget.view, constraints: const BoxConstraints(maxWidth: 784),
userProfile: widget.userProfile, child: BlocProvider(
)..add(const ChatEvent.initialLoad()), create: (_) => ChatBloc(
child: BlocBuilder<ChatBloc, ChatState>( view: widget.view,
builder: (blocContext, state) { userProfile: widget.userProfile,
return Chat( )..add(const ChatEvent.initialLoad()),
messages: state.messages, child: BlocBuilder<ChatBloc, ChatState>(
onAttachmentPressed: () {}, builder: (blocContext, state) => Chat(
onSendPressed: (types.PartialText message) { messages: state.messages,
// We use custom bottom widget for chat input, so onSendPressed: (_) {
// do not need to handle this event. // We use custom bottom widget for chat input, so
}, // do not need to handle this event.
customBottomWidget: buildChatInput(blocContext), },
user: _user, customBottomWidget: buildChatInput(blocContext),
theme: buildTheme(context), user: _user,
onEndReached: () async { theme: buildTheme(context),
if (state.hasMorePrevMessage && onEndReached: () async {
state.loadingPreviousStatus != if (state.hasMorePrevMessage &&
const LoadingState.loading()) { state.loadingPreviousStatus !=
blocContext const LoadingState.loading()) {
.read<ChatBloc>() blocContext
.add(const ChatEvent.startLoadingPrevMessage()); .read<ChatBloc>()
} .add(const ChatEvent.startLoadingPrevMessage());
}, }
emptyState: BlocBuilder<ChatBloc, ChatState>( },
builder: (context, state) { emptyState: BlocBuilder<ChatBloc, ChatState>(
return state.initialLoadingStatus == builder: (_, state) => state.initialLoadingStatus ==
const LoadingState.finish() const LoadingState.finish()
? Padding( ? Padding(
padding: AIChatUILayout.welcomePagePadding, padding: AIChatUILayout.welcomePagePadding,
child: ChatWelcomePage( child: ChatWelcomePage(
onSelectedQuestion: (question) { onSelectedQuestion: (question) => blocContext
blocContext .read<ChatBloc>()
.read<ChatBloc>() .add(ChatEvent.sendMessage(question)),
.add(ChatEvent.sendMessage(question));
},
), ),
) )
: const Center( : const Center(
child: CircularProgressIndicator.adaptive(), child: CircularProgressIndicator.adaptive(),
); ),
),
messageWidthRatio: AIChatUILayout.messageWidthRatio,
textMessageBuilder: (
textMessage, {
required messageWidth,
required showName,
}) =>
_buildAITextMessage(blocContext, textMessage),
bubbleBuilder: (
child, {
required message,
required nextMessageInGroup,
}) {
if (message.author.id == _user.id) {
return ChatUserMessageBubble(
message: message,
child: child,
);
}
return _buildAIBubble(message, blocContext, state, child);
}, },
), ),
messageWidthRatio: AIChatUILayout.messageWidthRatio, ),
textMessageBuilder: ( ),
textMessage, {
required messageWidth,
required showName,
}) {
return _buildAITextMessage(blocContext, textMessage);
},
bubbleBuilder: (
child, {
required message,
required nextMessageInGroup,
}) {
if (message.author.id == _user.id) {
return ChatUserMessageBubble(
message: message,
child: child,
);
} else {
return _buildAIBubble(message, blocContext, state, child);
}
},
);
},
), ),
), ),
), ],
); );
} }

View File

@ -1,9 +1,10 @@
import 'package:flutter/material.dart';
import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart';
import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flutter/material.dart';
import 'chat_input.dart'; import 'chat_input.dart';
@ -31,19 +32,15 @@ class ChatWelcomePage extends StatelessWidget {
size: Size.square(44), size: Size.square(44),
), ),
const SizedBox(height: 40), const SizedBox(height: 40),
GridView.builder( Wrap(
shrinkWrap: true, children: items
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( .map(
crossAxisCount: isMobile ? 2 : 4, (i) => WelcomeQuestion(
crossAxisSpacing: 6, question: i,
mainAxisSpacing: 6, onSelected: onSelectedQuestion,
childAspectRatio: 16.0 / 9.0, ),
), )
itemCount: items.length, .toList(),
itemBuilder: (context, index) => WelcomeQuestion(
question: items[index],
onSelected: onSelectedQuestion,
),
), ),
], ],
), ),

View File

@ -70,7 +70,6 @@ class UserWorkspaceBloc extends Bloc<UserWorkspaceEvent, UserWorkspaceState> {
final workspaceMemberResult = final workspaceMemberResult =
await _userService.getWorkspaceMember(); await _userService.getWorkspaceMember();
final workspaceMember = workspaceMemberResult.toNullable(); final workspaceMember = workspaceMemberResult.toNullable();
emit(state.copyWith(currentWorkspaceMember: workspaceMember)); emit(state.copyWith(currentWorkspaceMember: workspaceMember));
}, },
fetchWorkspaces: () async { fetchWorkspaces: () async {
@ -510,6 +509,7 @@ class UserWorkspaceState with _$UserWorkspaceState {
if (identical(this, other)) return true; if (identical(this, other)) return true;
return other is UserWorkspaceState && return other is UserWorkspaceState &&
other.currentWorkspaceMember == currentWorkspaceMember &&
other.currentWorkspace == currentWorkspace && other.currentWorkspace == currentWorkspace &&
_deepCollectionEquality.equals(other.workspaces, workspaces) && _deepCollectionEquality.equals(other.workspaces, workspaces) &&
identical(other.actionResult, actionResult); identical(other.actionResult, actionResult);

View File

@ -1,5 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart';
import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/plugins/blank/blank.dart'; import 'package:appflowy/plugins/blank/blank.dart';
@ -34,7 +36,6 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
/// Home Sidebar is the left side bar of the home page. /// Home Sidebar is the left side bar of the home page.

View File

@ -10,7 +10,6 @@ import 'package:appflowy_backend/log.dart';
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
class AIFeatureOnlySupportedWhenUsingAppFlowyCloud extends StatelessWidget { class AIFeatureOnlySupportedWhenUsingAppFlowyCloud extends StatelessWidget {
@ -31,30 +30,25 @@ class AIFeatureOnlySupportedWhenUsingAppFlowyCloud extends StatelessWidget {
} }
class SettingsAIView extends StatelessWidget { class SettingsAIView extends StatelessWidget {
const SettingsAIView({ const SettingsAIView({super.key, required this.userProfile});
super.key,
required this.userProfile,
});
final UserProfilePB userProfile; final UserProfilePB userProfile;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider<SettingsAIBloc>( return BlocProvider<SettingsAIBloc>(
create: (context) => create: (_) =>
SettingsAIBloc(userProfile)..add(const SettingsAIEvent.started()), SettingsAIBloc(userProfile)..add(const SettingsAIEvent.started()),
child: BlocBuilder<SettingsAIBloc, SettingsAIState>( child: BlocBuilder<SettingsAIBloc, SettingsAIState>(
builder: (context, state) { builder: (_, __) => SettingsBody(
return SettingsBody( title: LocaleKeys.settings_aiPage_title.tr(),
title: LocaleKeys.settings_aiPage_title.tr(), description:
description: LocaleKeys.settings_aiPage_keys_aiSettingsDescription.tr(),
LocaleKeys.settings_aiPage_keys_aiSettingsDescription.tr(), children: const [
children: const [ AIModelSeclection(),
AIModelSeclection(), _AISearchToggle(value: false),
_AISearchToggle(value: false), ],
], ),
);
},
), ),
); );
} }
@ -66,23 +60,22 @@ class AIModelSeclection extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
FlowyText( Flexible(
LocaleKeys.settings_aiPage_keys_llmModel.tr(), child: FlowyText.medium(
fontSize: 14, LocaleKeys.settings_aiPage_keys_llmModel.tr(),
),
), ),
const Spacer(), const Spacer(),
BlocBuilder<SettingsAIBloc, SettingsAIState>( Flexible(
builder: (context, state) { child: BlocBuilder<SettingsAIBloc, SettingsAIState>(
return Expanded( builder: (context, state) {
child: SettingsDropdown<AIModelPB>( return SettingsDropdown<AIModelPB>(
key: const Key('AIModelDropdown'), key: const Key('AIModelDropdown'),
expandWidth: false, onChanged: (model) => context
onChanged: (format) { .read<SettingsAIBloc>()
context.read<SettingsAIBloc>().add( .add(SettingsAIEvent.selectModel(model)),
SettingsAIEvent.selectModel(format),
);
},
selectedOption: state.userProfile.aiModel, selectedOption: state.userProfile.aiModel,
options: _availableModels options: _availableModels
.map( .map(
@ -93,9 +86,9 @@ class AIModelSeclection extends StatelessWidget {
), ),
) )
.toList(), .toList(),
), );
); },
}, ),
), ),
], ],
); );
@ -139,17 +132,21 @@ class _AISearchToggle extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Row( return Row(
children: [ children: [
Expanded( FlowyText.medium(
child: FlowyText.regular( LocaleKeys.settings_aiPage_keys_enableAISearchTitle.tr(),
LocaleKeys.settings_aiPage_keys_enableAISearchTitle.tr(),
fontSize: 16,
),
), ),
const HSpace(16), const Spacer(),
BlocBuilder<SettingsAIBloc, SettingsAIState>( BlocBuilder<SettingsAIBloc, SettingsAIState>(
builder: (context, state) { builder: (context, state) {
if (state.aiSettings == null) { if (state.aiSettings == null) {
return const CircularProgressIndicator.adaptive(); return const Padding(
padding: EdgeInsets.only(top: 6),
child: SizedBox(
height: 26,
width: 26,
child: CircularProgressIndicator.adaptive(),
),
);
} else { } else {
return Toggle( return Toggle(
value: state.enableSearchIndexing, value: state.enableSearchIndexing,

View File

@ -494,6 +494,7 @@ class _ActionButton extends StatelessWidget {
? SystemMouseCursors.click ? SystemMouseCursors.click
: MouseCursor.defer, : MouseCursor.defer,
child: _drawBorder( child: _drawBorder(
context,
isLM: isLM, isLM: isLM,
isUpgrade: isUpgrade, isUpgrade: isUpgrade,
child: Container( child: Container(
@ -544,7 +545,8 @@ class _ActionButton extends StatelessWidget {
); );
} }
Widget _drawBorder({ Widget _drawBorder(
BuildContext context, {
required bool isLM, required bool isLM,
required bool isUpgrade, required bool isUpgrade,
required Widget child, required Widget child,
@ -562,7 +564,7 @@ class _ActionButton extends StatelessWidget {
], ],
) )
: null, : null,
border: isUpgrade ? null : Border.all(), border: isUpgrade ? null : Border.all(color: const Color(0xFF333333)),
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
), ),
child: child, child: child,

View File

@ -70,6 +70,7 @@ class SettingsPlanView extends StatelessWidget {
usage: state.workspaceUsage, usage: state.workspaceUsage,
subscription: state.subscription, subscription: state.subscription,
), ),
const VSpace(16),
_CurrentPlanBox(subscription: state.subscription), _CurrentPlanBox(subscription: state.subscription),
], ],
), ),

View File

@ -490,14 +490,11 @@ class KeyBadge extends StatelessWidget {
), ),
child: Center( child: Center(
child: iconData != null child: iconData != null
? FlowySvg( ? FlowySvg(iconData!, color: Colors.black)
iconData!,
color: AFThemeExtension.of(context).strongText,
)
: FlowyText.medium( : FlowyText.medium(
keyLabel.toLowerCase(), keyLabel.toLowerCase(),
fontSize: 12, fontSize: 12,
color: AFThemeExtension.of(context).strongText, color: Colors.black,
), ),
), ),
); );

View File

@ -24,6 +24,7 @@ import 'package:appflowy/workspace/presentation/settings/shared/setting_list_til
import 'package:appflowy/workspace/presentation/settings/shared/settings_alert_dialog.dart'; import 'package:appflowy/workspace/presentation/settings/shared/settings_alert_dialog.dart';
import 'package:appflowy/workspace/presentation/settings/shared/settings_body.dart'; import 'package:appflowy/workspace/presentation/settings/shared/settings_body.dart';
import 'package:appflowy/workspace/presentation/settings/shared/settings_category.dart'; import 'package:appflowy/workspace/presentation/settings/shared/settings_category.dart';
import 'package:appflowy/workspace/presentation/settings/shared/settings_category_spacer.dart';
import 'package:appflowy/workspace/presentation/settings/shared/settings_dashed_divider.dart'; import 'package:appflowy/workspace/presentation/settings/shared/settings_dashed_divider.dart';
import 'package:appflowy/workspace/presentation/settings/shared/settings_dropdown.dart'; import 'package:appflowy/workspace/presentation/settings/shared/settings_dropdown.dart';
import 'package:appflowy/workspace/presentation/settings/shared/settings_input_field.dart'; import 'package:appflowy/workspace/presentation/settings/shared/settings_input_field.dart';
@ -85,6 +86,7 @@ class SettingsWorkspaceView extends StatelessWidget {
return SettingsBody( return SettingsBody(
title: LocaleKeys.settings_workspacePage_title.tr(), title: LocaleKeys.settings_workspacePage_title.tr(),
description: LocaleKeys.settings_workspacePage_description.tr(), description: LocaleKeys.settings_workspacePage_description.tr(),
autoSeparate: false,
children: [ children: [
// We don't allow changing workspace name/icon for local/offline // We don't allow changing workspace name/icon for local/offline
if (userProfile.authenticator != AuthenticatorPB.Local) ...[ if (userProfile.authenticator != AuthenticatorPB.Local) ...[
@ -93,6 +95,7 @@ class SettingsWorkspaceView extends StatelessWidget {
.tr(), .tr(),
children: [_WorkspaceNameSetting(member: workspaceMember)], children: [_WorkspaceNameSetting(member: workspaceMember)],
), ),
const SettingsCategorySpacer(),
SettingsCategory( SettingsCategory(
title: LocaleKeys.settings_workspacePage_workspaceIcon_title title: LocaleKeys.settings_workspacePage_workspaceIcon_title
.tr(), .tr(),
@ -106,11 +109,14 @@ class SettingsWorkspaceView extends StatelessWidget {
), ),
], ],
), ),
const SettingsCategorySpacer(),
], ],
SettingsCategory( SettingsCategory(
title: LocaleKeys.settings_workspacePage_appearance_title.tr(), title: LocaleKeys.settings_workspacePage_appearance_title.tr(),
children: const [AppearanceSelector()], children: const [AppearanceSelector()],
), ),
const VSpace(16),
// const SettingsCategorySpacer(),
SettingsCategory( SettingsCategory(
title: LocaleKeys.settings_workspacePage_theme_title.tr(), title: LocaleKeys.settings_workspacePage_theme_title.tr(),
description: description:
@ -121,6 +127,7 @@ class SettingsWorkspaceView extends StatelessWidget {
_DocumentSelectionColorSetting(), _DocumentSelectionColorSetting(),
], ],
), ),
const SettingsCategorySpacer(),
SettingsCategory( SettingsCategory(
title: title:
LocaleKeys.settings_workspacePage_workspaceFont_title.tr(), LocaleKeys.settings_workspacePage_workspaceFont_title.tr(),
@ -129,7 +136,9 @@ class SettingsWorkspaceView extends StatelessWidget {
currentFont: currentFont:
context.read<AppearanceSettingsCubit>().state.font, context.read<AppearanceSettingsCubit>().state.font,
), ),
const SettingsDashedDivider(), SettingsDashedDivider(
color: Theme.of(context).colorScheme.outline,
),
SettingsCategory( SettingsCategory(
title: LocaleKeys.settings_workspacePage_textDirection_title title: LocaleKeys.settings_workspacePage_textDirection_title
.tr(), .tr(),
@ -140,11 +149,14 @@ class SettingsWorkspaceView extends StatelessWidget {
), ),
], ],
), ),
const VSpace(16),
SettingsCategory( SettingsCategory(
title: LocaleKeys.settings_workspacePage_layoutDirection_title title: LocaleKeys.settings_workspacePage_layoutDirection_title
.tr(), .tr(),
children: const [_LayoutDirectionSelect()], children: const [_LayoutDirectionSelect()],
), ),
const SettingsCategorySpacer(),
SettingsCategory( SettingsCategory(
title: LocaleKeys.settings_workspacePage_dateTime_title.tr(), title: LocaleKeys.settings_workspacePage_dateTime_title.tr(),
children: [ children: [
@ -156,10 +168,14 @@ class SettingsWorkspaceView extends StatelessWidget {
const _DateFormatDropdown(), const _DateFormatDropdown(),
], ],
), ),
const SettingsCategorySpacer(),
SettingsCategory( SettingsCategory(
title: LocaleKeys.settings_workspacePage_language_title.tr(), title: LocaleKeys.settings_workspacePage_language_title.tr(),
children: const [LanguageDropdown()], children: const [LanguageDropdown()],
), ),
const SettingsCategorySpacer(),
if (userProfile.authenticator != AuthenticatorPB.Local) ...[ if (userProfile.authenticator != AuthenticatorPB.Local) ...[
SingleSettingAction( SingleSettingAction(
label: LocaleKeys.settings_workspacePage_manageWorkspace_title label: LocaleKeys.settings_workspacePage_manageWorkspace_title

View File

@ -1,4 +1,3 @@
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/startup/startup.dart';
@ -15,6 +14,7 @@ import 'package:appflowy/workspace/presentation/settings/widgets/feature_flags/f
import 'package:appflowy/workspace/presentation/settings/widgets/members/workspace_member_page.dart'; import 'package:appflowy/workspace/presentation/settings/widgets/members/workspace_member_page.dart';
import 'package:appflowy/workspace/presentation/settings/widgets/settings_menu.dart'; import 'package:appflowy/workspace/presentation/settings/widgets/settings_menu.dart';
import 'package:appflowy/workspace/presentation/settings/widgets/settings_notifications_view.dart'; import 'package:appflowy/workspace/presentation/settings/widgets/settings_notifications_view.dart';
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';

View File

@ -33,7 +33,7 @@ class SettingsBody extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
separatorBuilder: () => autoSeparate separatorBuilder: () => autoSeparate
? const SettingsCategorySpacer() ? const SettingsCategorySpacer()
: const VSpace(16), : const SizedBox.shrink(),
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: children, children: children,
), ),