| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 | import 'package:app_flowy/generated/locale_keys.g.dart';import 'package:app_flowy/plugins/board/application/toolbar/board_setting_bloc.dart';import 'package:app_flowy/plugins/grid/application/field/field_controller.dart';import 'package:app_flowy/plugins/grid/presentation/layout/sizes.dart';import 'package:app_flowy/plugins/grid/presentation/widgets/toolbar/grid_group.dart';import 'package:app_flowy/plugins/grid/presentation/widgets/toolbar/grid_property.dart';import 'package:appflowy_popover/appflowy_popover.dart';import 'package:easy_localization/easy_localization.dart';import 'package:flowy_infra/image.dart';import 'package:flowy_infra/theme.dart';import 'package:flowy_infra_ui/style_widget/button.dart';import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';import 'package:flowy_infra_ui/style_widget/text.dart';import 'package:flowy_infra_ui/widget/spacing.dart';import 'package:flutter/material.dart';import 'package:flutter_bloc/flutter_bloc.dart';import 'board_toolbar.dart';class BoardSettingContext {  final String viewId;  final GridFieldController fieldController;  BoardSettingContext({    required this.viewId,    required this.fieldController,  });  factory BoardSettingContext.from(BoardToolbarContext toolbarContext) =>      BoardSettingContext(        viewId: toolbarContext.viewId,        fieldController: toolbarContext.fieldController,      );}class BoardSettingList extends StatelessWidget {  final BoardSettingContext settingContext;  final Function(BoardSettingAction, BoardSettingContext) onAction;  const BoardSettingList({    required this.settingContext,    required this.onAction,    Key? key,  }) : super(key: key);  @override  Widget build(BuildContext context) {    return BlocProvider(      create: (context) => BoardSettingBloc(gridId: settingContext.viewId),      child: BlocListener<BoardSettingBloc, BoardSettingState>(        listenWhen: (previous, current) =>            previous.selectedAction != current.selectedAction,        listener: (context, state) {          state.selectedAction.foldLeft(null, (_, action) {            onAction(action, settingContext);          });        },        child: BlocBuilder<BoardSettingBloc, BoardSettingState>(          builder: (context, state) {            return _renderList();          },        ),      ),    );  }  Widget _renderList() {    final cells = BoardSettingAction.values.map((action) {      return _SettingItem(action: action);    }).toList();    return SizedBox(      width: 140,      child: ListView.separated(        shrinkWrap: true,        controller: ScrollController(),        itemCount: cells.length,        separatorBuilder: (context, index) {          return VSpace(GridSize.typeOptionSeparatorHeight);        },        physics: StyledScrollPhysics(),        itemBuilder: (BuildContext context, int index) {          return cells[index];        },      ),    );  }}class _SettingItem extends StatelessWidget {  final BoardSettingAction action;  const _SettingItem({    required this.action,    Key? key,  }) : super(key: key);  @override  Widget build(BuildContext context) {    final theme = context.read<AppTheme>();    final isSelected = context        .read<BoardSettingBloc>()        .state        .selectedAction        .foldLeft(false, (_, selectedAction) => selectedAction == action);    return SizedBox(      height: 30,      child: FlowyButton(        isSelected: isSelected,        text: FlowyText.medium(          action.title(),          fontSize: 12,          color: theme.textColor,        ),        hoverColor: theme.hover,        onTap: () {          context              .read<BoardSettingBloc>()              .add(BoardSettingEvent.performAction(action));        },        leftIcon: svgWidget(action.iconName(), color: theme.iconColor),      ),    );  }}extension _GridSettingExtension on BoardSettingAction {  String iconName() {    switch (this) {      case BoardSettingAction.properties:        return 'grid/setting/properties';      case BoardSettingAction.groups:        return 'grid/setting/group';    }  }  String title() {    switch (this) {      case BoardSettingAction.properties:        return LocaleKeys.grid_settings_Properties.tr();      case BoardSettingAction.groups:        return LocaleKeys.grid_settings_group.tr();    }  }}class BoardSettingListPopover extends StatefulWidget {  final PopoverController popoverController;  final BoardSettingContext settingContext;  const BoardSettingListPopover({    Key? key,    required this.popoverController,    required this.settingContext,  }) : super(key: key);  @override  State<StatefulWidget> createState() => _BoardSettingListPopoverState();}class _BoardSettingListPopoverState extends State<BoardSettingListPopover> {  BoardSettingAction? _action;  @override  Widget build(BuildContext context) {    if (_action != null) {      switch (_action!) {        case BoardSettingAction.groups:          return GridGroupList(            viewId: widget.settingContext.viewId,            fieldController: widget.settingContext.fieldController,            onDismissed: () {              widget.popoverController.close();            },          );        case BoardSettingAction.properties:          return GridPropertyList(            gridId: widget.settingContext.viewId,            fieldController: widget.settingContext.fieldController,          );      }    }    return BoardSettingList(      settingContext: widget.settingContext,      onAction: (action, settingContext) {        setState(() => _action = action);      },    );  }}
 |