mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: revamp mobile database toolbar (#4579)
* chore: revamp mobile database toolbar * chore: code cleanup
This commit is contained in:
parent
8c1d0106dd
commit
ca93cb20ec
@ -81,6 +81,7 @@ class _MobileRowDetailPageState extends State<MobileRowDetailPage> {
|
||||
child: Scaffold(
|
||||
appBar: FlowyAppBar(
|
||||
leadingType: FlowyAppBarLeadingType.close,
|
||||
showDivider: false,
|
||||
actions: [
|
||||
AppBarMoreButton(
|
||||
onTap: (_) => _showCardActions(context),
|
||||
|
@ -22,15 +22,18 @@ class MobileDatabaseFieldList extends StatelessWidget {
|
||||
const MobileDatabaseFieldList({
|
||||
super.key,
|
||||
required this.databaseController,
|
||||
required this.canCreate,
|
||||
});
|
||||
|
||||
final DatabaseController databaseController;
|
||||
final bool canCreate;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return _MobileDatabaseFieldListBody(
|
||||
databaseController: databaseController,
|
||||
viewId: context.read<ViewBloc>().state.view.id,
|
||||
canCreate: canCreate,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -39,10 +42,12 @@ class _MobileDatabaseFieldListBody extends StatelessWidget {
|
||||
const _MobileDatabaseFieldListBody({
|
||||
required this.databaseController,
|
||||
required this.viewId,
|
||||
required this.canCreate,
|
||||
});
|
||||
|
||||
final DatabaseController databaseController;
|
||||
final String viewId;
|
||||
final bool canCreate;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -113,13 +118,15 @@ class _MobileDatabaseFieldListBody extends StatelessWidget {
|
||||
.add(DatabasePropertyEvent.moveField(from, to));
|
||||
},
|
||||
header: firstCell,
|
||||
footer: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
_divider(),
|
||||
_NewDatabaseFieldTile(viewId: viewId),
|
||||
],
|
||||
),
|
||||
footer: canCreate
|
||||
? Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
_divider(),
|
||||
_NewDatabaseFieldTile(viewId: viewId),
|
||||
],
|
||||
)
|
||||
: null,
|
||||
itemCount: cells.length,
|
||||
itemBuilder: (context, index) => cells[index],
|
||||
);
|
||||
|
@ -240,6 +240,7 @@ class DatabaseViewSettingTile extends StatelessWidget {
|
||||
value: context.read<ViewBloc>(),
|
||||
child: MobileDatabaseFieldList(
|
||||
databaseController: databaseController,
|
||||
canCreate: true,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
@ -1,7 +1,11 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/mobile/presentation/bottom_sheet/show_mobile_bottom_sheet.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/view/database_view_list.dart';
|
||||
import 'package:appflowy/plugins/base/emoji/emoji_text.dart';
|
||||
import 'package:appflowy/plugins/database/application/tab_bar_bloc.dart';
|
||||
import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.dart';
|
||||
import 'package:appflowy/plugins/database/widgets/setting/mobile_database_controls.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_ext.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
@ -24,10 +28,11 @@ class _MobileTabBarHeaderState extends State<MobileTabBarHeader> {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 14),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Expanded(child: _DatabaseViewList()),
|
||||
const HSpace(10),
|
||||
HSpace(GridSize.leadingHeaderPadding),
|
||||
const _DatabaseViewSelectorButton(),
|
||||
const Spacer(),
|
||||
BlocBuilder<DatabaseTabBarBloc, DatabaseTabBarState>(
|
||||
builder: (context, state) {
|
||||
final currentView = state.tabBars.firstWhereIndexedOrNull(
|
||||
@ -51,134 +56,80 @@ class _MobileTabBarHeaderState extends State<MobileTabBarHeader> {
|
||||
}
|
||||
}
|
||||
|
||||
class _DatabaseViewList extends StatelessWidget {
|
||||
const _DatabaseViewList();
|
||||
class _DatabaseViewSelectorButton extends StatelessWidget {
|
||||
const _DatabaseViewSelectorButton();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<DatabaseTabBarBloc, DatabaseTabBarState>(
|
||||
builder: (context, state) {
|
||||
final currentView = state.tabBars.firstWhereIndexedOrNull(
|
||||
final tabBar = state.tabBars.firstWhereIndexedOrNull(
|
||||
(index, tabBar) => index == state.selectedIndex,
|
||||
);
|
||||
|
||||
if (currentView == null) {
|
||||
if (tabBar == null) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
final children = state.tabBars.mapIndexed<Widget>((index, tabBar) {
|
||||
return Padding(
|
||||
padding: EdgeInsetsDirectional.only(
|
||||
start: index == 0 ? 0 : 2,
|
||||
end: 2,
|
||||
return TextButton(
|
||||
style: ButtonStyle(
|
||||
padding: const MaterialStatePropertyAll(
|
||||
EdgeInsets.fromLTRB(12, 8, 8, 8),
|
||||
),
|
||||
child: _DatabaseViewListItem(
|
||||
tabBar: tabBar,
|
||||
isSelected: currentView.viewId == tabBar.viewId,
|
||||
maximumSize: const MaterialStatePropertyAll(Size(200, 48)),
|
||||
minimumSize: const MaterialStatePropertyAll(Size(48, 0)),
|
||||
shape: const MaterialStatePropertyAll(
|
||||
RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(12)),
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList();
|
||||
|
||||
children.insert(0, HSpace(GridSize.leadingHeaderPadding));
|
||||
|
||||
return SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(children: children),
|
||||
backgroundColor: const MaterialStatePropertyAll(Color(0x0F212729)),
|
||||
overlayColor: MaterialStatePropertyAll(
|
||||
Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
_buildViewIconButton(context, tabBar.view),
|
||||
const HSpace(6),
|
||||
Flexible(
|
||||
child: FlowyText.medium(
|
||||
tabBar.view.name,
|
||||
fontSize: 13,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
const HSpace(8),
|
||||
const FlowySvg(
|
||||
FlowySvgs.arrow_tight_s,
|
||||
size: Size.square(10),
|
||||
),
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
showMobileBottomSheet(
|
||||
context,
|
||||
showDivider: false,
|
||||
builder: (_) {
|
||||
return MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider<ViewBloc>.value(
|
||||
value: context.read<ViewBloc>(),
|
||||
),
|
||||
BlocProvider<DatabaseTabBarBloc>.value(
|
||||
value: context.read<DatabaseTabBarBloc>(),
|
||||
),
|
||||
],
|
||||
child: const MobileDatabaseViewList(),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _DatabaseViewListItem extends StatefulWidget {
|
||||
const _DatabaseViewListItem({
|
||||
required this.tabBar,
|
||||
required this.isSelected,
|
||||
});
|
||||
|
||||
final DatabaseTabBar tabBar;
|
||||
final bool isSelected;
|
||||
|
||||
@override
|
||||
State<_DatabaseViewListItem> createState() => _DatabaseViewListItemState();
|
||||
}
|
||||
|
||||
class _DatabaseViewListItemState extends State<_DatabaseViewListItem> {
|
||||
late final MaterialStatesController statesController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
statesController = MaterialStatesController(
|
||||
<MaterialState>{if (widget.isSelected) MaterialState.selected},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
if (widget.isSelected != oldWidget.isSelected) {
|
||||
statesController.update(MaterialState.selected, widget.isSelected);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TextButton(
|
||||
statesController: statesController,
|
||||
style: ButtonStyle(
|
||||
padding: const MaterialStatePropertyAll(
|
||||
EdgeInsets.symmetric(horizontal: 12, vertical: 7),
|
||||
),
|
||||
maximumSize: MaterialStateProperty.resolveWith((states) {
|
||||
if (states.contains(MaterialState.selected)) {
|
||||
return const Size(150, 48);
|
||||
}
|
||||
return const Size(120, 48);
|
||||
}),
|
||||
minimumSize: const MaterialStatePropertyAll(Size(48, 0)),
|
||||
shape: const MaterialStatePropertyAll(
|
||||
RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(12)),
|
||||
),
|
||||
),
|
||||
backgroundColor: MaterialStateProperty.resolveWith((states) {
|
||||
if (states.contains(MaterialState.selected)) {
|
||||
return const Color(0x0F212729);
|
||||
}
|
||||
return Colors.transparent;
|
||||
}),
|
||||
overlayColor: MaterialStateProperty.resolveWith((states) {
|
||||
if (states.contains(MaterialState.selected)) {
|
||||
return Colors.transparent;
|
||||
}
|
||||
return Theme.of(context).colorScheme.secondary;
|
||||
}),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
_buildViewIconButton(context, widget.tabBar.view),
|
||||
const HSpace(6),
|
||||
Flexible(
|
||||
child: FlowyText(
|
||||
widget.tabBar.view.name,
|
||||
fontSize: 14,
|
||||
fontWeight: widget.isSelected ? FontWeight.w500 : FontWeight.w400,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
if (!widget.isSelected) {
|
||||
context
|
||||
.read<DatabaseTabBarBloc>()
|
||||
.add(DatabaseTabBarEvent.selectView(widget.tabBar.viewId));
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildViewIconButton(BuildContext context, ViewPB view) {
|
||||
return view.icon.value.isNotEmpty
|
||||
|
@ -1,10 +1,8 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/view/database_view_list.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/view/edit_database_view_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/view/database_field_list.dart';
|
||||
import 'package:appflowy/plugins/database/application/database_controller.dart';
|
||||
import 'package:appflowy/plugins/database/application/tab_bar_bloc.dart';
|
||||
import 'package:appflowy/plugins/database/grid/application/filter/filter_menu_bloc.dart';
|
||||
import 'package:appflowy/plugins/database/grid/application/sort/sort_menu_bloc.dart';
|
||||
import 'package:appflowy/plugins/database/grid/presentation/grid_page.dart';
|
||||
@ -58,62 +56,26 @@ class MobileDatabaseControls extends StatelessWidget {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
return Row(
|
||||
children: [
|
||||
_DatabaseControlButton(
|
||||
icon: FlowySvgs.settings_s,
|
||||
onTap: () {
|
||||
showMobileBottomSheet(
|
||||
context,
|
||||
showHeader: true,
|
||||
showDoneButton: true,
|
||||
title: LocaleKeys.grid_settings_editView.tr(),
|
||||
enableDraggableScrollable: true,
|
||||
initialChildSize: 0.98,
|
||||
minChildSize: 0.98,
|
||||
maxChildSize: 0.98,
|
||||
builder: (_) {
|
||||
return BlocProvider<ViewBloc>(
|
||||
create: (_) {
|
||||
return ViewBloc(
|
||||
view: context
|
||||
.read<DatabaseTabBarBloc>()
|
||||
.state
|
||||
.tabBarControllerByViewId[controller.viewId]!
|
||||
.view,
|
||||
)..add(const ViewEvent.initial());
|
||||
},
|
||||
child: MobileEditDatabaseViewScreen(
|
||||
databaseController: controller,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
_DatabaseControlButton(
|
||||
icon: FlowySvgs.align_left_s,
|
||||
onTap: () {
|
||||
showMobileBottomSheet(
|
||||
context,
|
||||
showDivider: false,
|
||||
builder: (_) {
|
||||
return MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider<ViewBloc>.value(
|
||||
value: context.read<ViewBloc>(),
|
||||
),
|
||||
BlocProvider<DatabaseTabBarBloc>.value(
|
||||
value: context.read<DatabaseTabBarBloc>(),
|
||||
),
|
||||
],
|
||||
child: const MobileDatabaseViewList(),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
return _DatabaseControlButton(
|
||||
icon: FlowySvgs.m_field_hide_s,
|
||||
onTap: () => showMobileBottomSheet(
|
||||
context,
|
||||
resizeToAvoidBottomInset: false,
|
||||
showDragHandle: true,
|
||||
showHeader: true,
|
||||
showBackButton: true,
|
||||
title: LocaleKeys.grid_settings_properties.tr(),
|
||||
showDivider: true,
|
||||
builder: (_) {
|
||||
return BlocProvider.value(
|
||||
value: context.read<ViewBloc>(),
|
||||
child: MobileDatabaseFieldList(
|
||||
databaseController: controller,
|
||||
canCreate: false,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
5
frontend/resources/flowy_icons/16x/arrow_tight.svg
Normal file
5
frontend/resources/flowy_icons/16x/arrow_tight.svg
Normal file
@ -0,0 +1,5 @@
|
||||
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g opacity="0.9">
|
||||
<path d="M1.59505 3.16079C1.40444 2.97017 1.0954 2.97017 0.904783 3.16079C0.71417 3.3514 0.71417 3.66044 0.904783 3.85106L4.36016 7.30643C4.71349 7.65976 5.28635 7.65976 5.63968 7.30643L9.09505 3.85106C9.28567 3.66044 9.28567 3.3514 9.09505 3.16079C8.90444 2.97017 8.5954 2.97017 8.40478 3.16079L4.99992 6.56565L1.59505 3.16079Z" fill="#2B2F36" stroke="black" stroke-width="0.142857" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 559 B |
Loading…
Reference in New Issue
Block a user