mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: code cleanup (#4129)
This commit is contained in:
parent
81e09ae72e
commit
b7b8713cd9
@ -1,60 +0,0 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_property_edit/mobile_field_editor.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_controller.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class MobileCreateRowFieldScreen extends StatefulWidget {
|
||||
static const routeName = '/MobileCreateRowFieldScreen';
|
||||
static const argViewId = 'viewId';
|
||||
static const argFieldController = 'fieldController';
|
||||
static const argTypeOption = 'typeOption';
|
||||
|
||||
const MobileCreateRowFieldScreen({
|
||||
super.key,
|
||||
required this.viewId,
|
||||
required this.typeOption,
|
||||
required this.fieldController,
|
||||
});
|
||||
|
||||
final String viewId;
|
||||
final FieldController fieldController;
|
||||
final TypeOptionPB typeOption;
|
||||
|
||||
@override
|
||||
State<MobileCreateRowFieldScreen> createState() =>
|
||||
_MobileCreateRowFieldScreenState();
|
||||
}
|
||||
|
||||
class _MobileCreateRowFieldScreenState
|
||||
extends State<MobileCreateRowFieldScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(LocaleKeys.grid_field_newProperty.tr()),
|
||||
actions: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 16),
|
||||
child: TextButton(
|
||||
onPressed: () => context.pop(),
|
||||
child: Text(
|
||||
LocaleKeys.button_done.tr(),
|
||||
style: Theme.of(context).textTheme.labelMedium?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onBackground,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
body: MobileFieldEditor(
|
||||
viewId: widget.viewId,
|
||||
fieldController: widget.fieldController,
|
||||
field: widget.typeOption.field_2,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_property_edit/widgets/widgets.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_editor_bloc.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class MobileFieldNameTextField extends StatefulWidget {
|
||||
const MobileFieldNameTextField({
|
||||
super.key,
|
||||
this.text,
|
||||
});
|
||||
|
||||
final String? text;
|
||||
|
||||
@override
|
||||
State<MobileFieldNameTextField> createState() =>
|
||||
_MobileFieldNameTextFieldState();
|
||||
}
|
||||
|
||||
class _MobileFieldNameTextFieldState extends State<MobileFieldNameTextField> {
|
||||
final controller = TextEditingController();
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (widget.text != null) {
|
||||
controller.text = widget.text!;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PropertyEditContainer(
|
||||
padding: EdgeInsets.zero,
|
||||
child: TextField(
|
||||
controller: controller,
|
||||
decoration: InputDecoration(
|
||||
hintText: LocaleKeys.board_propertyName.tr(),
|
||||
enabledBorder: InputBorder.none,
|
||||
focusedBorder: InputBorder.none,
|
||||
),
|
||||
onChanged: (newName) {
|
||||
context
|
||||
.read<FieldEditorBloc>()
|
||||
.add(FieldEditorEvent.renameField(newName));
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
export 'mobile_create_field_button.dart';
|
||||
export 'mobile_field_name_text_field.dart';
|
||||
export 'mobile_row_property_list.dart';
|
||||
export 'option_text_field.dart';
|
||||
|
@ -1,64 +0,0 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_property_edit/mobile_field_editor.dart';
|
||||
import 'package:appflowy/mobile/presentation/widgets/show_flowy_mobile_confirm_dialog.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/cell/cell_service.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_controller.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/application/row/row_detail_bloc.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class CardPropertyEditScreen extends StatelessWidget {
|
||||
const CardPropertyEditScreen({
|
||||
super.key,
|
||||
required this.cellContext,
|
||||
required this.fieldController,
|
||||
});
|
||||
|
||||
static const routeName = '/CardPropertyEditScreen';
|
||||
static const argCellContext = 'cellContext';
|
||||
static const argFieldController = 'fieldController';
|
||||
static const argRowDetailBloc = 'rowDetailBloc';
|
||||
|
||||
final DatabaseCellContext cellContext;
|
||||
final FieldController fieldController;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(LocaleKeys.grid_field_editProperty.tr()),
|
||||
actions: [
|
||||
// show delete button when this field is not used to group cards
|
||||
if (!cellContext.fieldInfo.isGroupField)
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
showFlowyMobileConfirmDialog(
|
||||
context,
|
||||
title: LocaleKeys.grid_field_deleteFieldPromptMessage.tr(),
|
||||
actionButtonTitle: LocaleKeys.button_delete.tr(),
|
||||
actionButtonColor: Theme.of(context).colorScheme.error,
|
||||
onActionButtonPressed: () {
|
||||
context.read<RowDetailBloc>().add(
|
||||
RowDetailEvent.deleteField(
|
||||
cellContext.fieldInfo.field.id,
|
||||
),
|
||||
);
|
||||
context.pop();
|
||||
},
|
||||
);
|
||||
},
|
||||
icon: const FlowySvg(FlowySvgs.m_delete_m),
|
||||
),
|
||||
],
|
||||
),
|
||||
body: MobileFieldEditor(
|
||||
viewId: cellContext.viewId,
|
||||
fieldController: fieldController,
|
||||
field: cellContext.fieldInfo.field,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,130 +0,0 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_detail/widgets/widgets.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_property_edit/mobile_field_type_option_editor.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_property_edit/widgets/widgets.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_controller.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_editor_bloc.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/type_option/type_option_context.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/application/row/row_detail_bloc.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/setting/field_visibility_extension.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
// Used in [CardPropertyEditScreen] and [MobileCreateRowFieldScreen]
|
||||
class MobileFieldEditor extends StatelessWidget {
|
||||
const MobileFieldEditor({
|
||||
super.key,
|
||||
required this.viewId,
|
||||
required this.field,
|
||||
required this.fieldController,
|
||||
});
|
||||
|
||||
final String viewId;
|
||||
final FieldController fieldController;
|
||||
final FieldPB field;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final typeOptionLoader = FieldTypeOptionLoader(
|
||||
viewId: viewId,
|
||||
field: field,
|
||||
);
|
||||
|
||||
return BlocProvider(
|
||||
create: (context) {
|
||||
return FieldEditorBloc(
|
||||
viewId: viewId,
|
||||
loader: typeOptionLoader,
|
||||
field: field,
|
||||
fieldController: fieldController,
|
||||
)..add(const FieldEditorEvent.initial());
|
||||
},
|
||||
child: BlocBuilder<FieldEditorBloc, FieldEditorState>(
|
||||
builder: (context, state) {
|
||||
// for field type edit option
|
||||
final dataController =
|
||||
context.read<FieldEditorBloc>().typeOptionController;
|
||||
final fieldInfoVisibility =
|
||||
fieldController.getField(field.id)?.visibility;
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
PropertyEditGroupTitle(LocaleKeys.settings_user_name.tr()),
|
||||
BlocSelector<FieldEditorBloc, FieldEditorState, String>(
|
||||
selector: (state) => state.field.name,
|
||||
builder: (context, fieldName) =>
|
||||
MobileFieldNameTextField(text: fieldName),
|
||||
),
|
||||
const VSpace(16),
|
||||
PropertyEditGroupTitle(LocaleKeys.grid_field_visibility.tr()),
|
||||
PropertyEditContainer(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
PropertyTitle(
|
||||
LocaleKeys.board_showOnCard.tr(),
|
||||
),
|
||||
VisibilitySwitch(
|
||||
isFieldHidden: !(fieldInfoVisibility != null
|
||||
? fieldInfoVisibility.isVisibleState()
|
||||
: field.visibility),
|
||||
onChanged: () => context.read<RowDetailBloc>().add(
|
||||
RowDetailEvent.toggleFieldVisibility(
|
||||
state.field.id,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const VSpace(16),
|
||||
PropertyEditGroupTitle(LocaleKeys.board_setting.tr()),
|
||||
// edit property type and settings
|
||||
if (!typeOptionLoader.field.isPrimary)
|
||||
MobileFieldTypeOptionEditor(dataController: dataController),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class VisibilitySwitch extends StatefulWidget {
|
||||
const VisibilitySwitch({
|
||||
super.key,
|
||||
required this.isFieldHidden,
|
||||
this.onChanged,
|
||||
});
|
||||
|
||||
final bool isFieldHidden;
|
||||
final Function? onChanged;
|
||||
|
||||
@override
|
||||
State<VisibilitySwitch> createState() => _VisibilitySwitchState();
|
||||
}
|
||||
|
||||
class _VisibilitySwitchState extends State<VisibilitySwitch> {
|
||||
late bool _isFieldHidden = widget.isFieldHidden;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Switch.adaptive(
|
||||
value: !_isFieldHidden,
|
||||
activeColor: Theme.of(context).colorScheme.primary,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
_isFieldHidden = !_isFieldHidden;
|
||||
widget.onChanged?.call();
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_type_option_edit_bloc.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/field_type_extension.dart';
|
||||
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
typedef SelectFieldCallback = void Function(FieldType);
|
||||
|
||||
class MobileFieldTypeList extends StatelessWidget {
|
||||
const MobileFieldTypeList({
|
||||
super.key,
|
||||
required this.onSelectField,
|
||||
required this.bloc,
|
||||
});
|
||||
|
||||
final FieldTypeOptionEditBloc bloc;
|
||||
final SelectFieldCallback onSelectField;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
const allFieldTypes = FieldType.values;
|
||||
return BlocProvider.value(
|
||||
value: bloc,
|
||||
child: ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: allFieldTypes.length,
|
||||
itemBuilder: (_, index) {
|
||||
return MobileFieldTypeCell(
|
||||
fieldType: allFieldTypes[index],
|
||||
onSelectField: onSelectField,
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MobileFieldTypeCell extends StatelessWidget {
|
||||
const MobileFieldTypeCell({
|
||||
super.key,
|
||||
required this.fieldType,
|
||||
required this.onSelectField,
|
||||
});
|
||||
|
||||
final FieldType fieldType;
|
||||
final SelectFieldCallback onSelectField;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RadioListTile<FieldType>(
|
||||
dense: true,
|
||||
controlAffinity: ListTileControlAffinity.trailing,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
value: fieldType,
|
||||
groupValue: context.select(
|
||||
(FieldTypeOptionEditBloc bloc) => bloc.state.field.fieldType,
|
||||
),
|
||||
onChanged: (value) {
|
||||
if (value != null) {
|
||||
onSelectField(value);
|
||||
}
|
||||
},
|
||||
title: Row(
|
||||
children: [
|
||||
FlowySvg(
|
||||
fieldType.icon(),
|
||||
),
|
||||
const HSpace(8),
|
||||
Text(
|
||||
fieldType.title(),
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onBackground,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,193 +0,0 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_property_edit/type_option_widget_builder/type_option_widget_builder.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_property_edit/widgets/widgets.dart';
|
||||
import 'package:appflowy/mobile/presentation/widgets/show_flowy_mobile_bottom_sheet.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_type_option_edit_bloc.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/type_option/type_option_data_controller.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/field_type_extension.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/type_option/builder.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'mobile_field_type_list.dart';
|
||||
|
||||
class MobileFieldTypeOptionEditor extends StatelessWidget {
|
||||
const MobileFieldTypeOptionEditor({
|
||||
super.key,
|
||||
required TypeOptionController dataController,
|
||||
}) : _dataController = dataController;
|
||||
|
||||
final TypeOptionController _dataController;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider<FieldTypeOptionEditBloc>(
|
||||
create: (_) => FieldTypeOptionEditBloc(_dataController)
|
||||
..add(const FieldTypeOptionEditEvent.initial()),
|
||||
child: BlocBuilder<FieldTypeOptionEditBloc, FieldTypeOptionEditState>(
|
||||
builder: (context, state) {
|
||||
final typeOptionWidget = _makeTypeOptionMobileWidget(
|
||||
context: context,
|
||||
dataController: _dataController,
|
||||
);
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
const _MobileSwitchFieldButton(),
|
||||
if (typeOptionWidget != null) ...[
|
||||
const VSpace(8),
|
||||
typeOptionWidget,
|
||||
],
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _MobileSwitchFieldButton extends StatelessWidget {
|
||||
const _MobileSwitchFieldButton();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final fieldType = context.select(
|
||||
(FieldTypeOptionEditBloc bloc) => bloc.state.field.fieldType,
|
||||
);
|
||||
return GestureDetector(
|
||||
child: PropertyEditContainer(
|
||||
child: Row(
|
||||
children: [
|
||||
PropertyTitle(
|
||||
LocaleKeys.grid_field_propertyType.tr(),
|
||||
),
|
||||
const Spacer(),
|
||||
FlowySvg(fieldType.icon()),
|
||||
const HSpace(4),
|
||||
Text(
|
||||
fieldType.title(),
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
Icon(
|
||||
Icons.arrow_forward_ios_sharp,
|
||||
color: Theme.of(context).hintColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onTap: () => showFlowyMobileBottomSheet(
|
||||
context,
|
||||
isScrollControlled: true,
|
||||
title: LocaleKeys.grid_field_propertyType.tr(),
|
||||
builder: (_) => MobileFieldTypeList(
|
||||
bloc: context.read<FieldTypeOptionEditBloc>(),
|
||||
onSelectField: (newFieldType) {
|
||||
context.read<FieldTypeOptionEditBloc>().add(
|
||||
FieldTypeOptionEditEvent.switchToField(newFieldType),
|
||||
);
|
||||
context.pop();
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget? _makeTypeOptionMobileWidget({
|
||||
required BuildContext context,
|
||||
required TypeOptionController dataController,
|
||||
}) =>
|
||||
_makeTypeOptionMobileWidgetBuilder(
|
||||
dataController: dataController,
|
||||
).build(context);
|
||||
|
||||
TypeOptionWidgetBuilder _makeTypeOptionMobileWidgetBuilder({
|
||||
required TypeOptionController dataController,
|
||||
}) {
|
||||
final viewId = dataController.loader.viewId;
|
||||
final fieldType = dataController.field.fieldType;
|
||||
|
||||
switch (dataController.field.fieldType) {
|
||||
case FieldType.Checkbox:
|
||||
return CheckboxTypeOptionMobileWidgetBuilder(
|
||||
makeTypeOptionContextWithDataController<CheckboxTypeOptionPB>(
|
||||
viewId: viewId,
|
||||
fieldType: fieldType,
|
||||
dataController: dataController,
|
||||
),
|
||||
);
|
||||
case FieldType.DateTime:
|
||||
return DateTypeOptionMobileWidgetBuilder(
|
||||
makeTypeOptionContextWithDataController<DateTypeOptionPB>(
|
||||
viewId: viewId,
|
||||
fieldType: fieldType,
|
||||
dataController: dataController,
|
||||
),
|
||||
);
|
||||
case FieldType.LastEditedTime:
|
||||
case FieldType.CreatedTime:
|
||||
return TimestampTypeOptionMobileWidgetBuilder(
|
||||
makeTypeOptionContextWithDataController<TimestampTypeOptionPB>(
|
||||
viewId: viewId,
|
||||
fieldType: fieldType,
|
||||
dataController: dataController,
|
||||
),
|
||||
);
|
||||
case FieldType.SingleSelect:
|
||||
return SingleSelectTypeOptionMobileWidgetBuilder(
|
||||
makeTypeOptionContextWithDataController<SingleSelectTypeOptionPB>(
|
||||
viewId: viewId,
|
||||
fieldType: fieldType,
|
||||
dataController: dataController,
|
||||
),
|
||||
);
|
||||
case FieldType.MultiSelect:
|
||||
return MultiSelectTypeOptionMobileWidgetBuilder(
|
||||
makeTypeOptionContextWithDataController<MultiSelectTypeOptionPB>(
|
||||
viewId: viewId,
|
||||
fieldType: fieldType,
|
||||
dataController: dataController,
|
||||
),
|
||||
);
|
||||
case FieldType.Number:
|
||||
return NumberTypeOptionMobileWidgetBuilder(
|
||||
makeTypeOptionContextWithDataController<NumberTypeOptionPB>(
|
||||
viewId: viewId,
|
||||
fieldType: fieldType,
|
||||
dataController: dataController,
|
||||
),
|
||||
);
|
||||
case FieldType.RichText:
|
||||
return RichTextTypeOptionMobileWidgetBuilder(
|
||||
makeTypeOptionContextWithDataController<RichTextTypeOptionPB>(
|
||||
viewId: viewId,
|
||||
fieldType: fieldType,
|
||||
dataController: dataController,
|
||||
),
|
||||
);
|
||||
|
||||
case FieldType.URL:
|
||||
return URLTypeOptionMobileWidgetBuilder(
|
||||
makeTypeOptionContextWithDataController<URLTypeOptionPB>(
|
||||
viewId: viewId,
|
||||
fieldType: fieldType,
|
||||
dataController: dataController,
|
||||
),
|
||||
);
|
||||
|
||||
case FieldType.Checklist:
|
||||
return ChecklistTypeOptionMobileWidgetBuilder(
|
||||
makeTypeOptionContextWithDataController<ChecklistTypeOptionPB>(
|
||||
viewId: viewId,
|
||||
fieldType: fieldType,
|
||||
dataController: dataController,
|
||||
),
|
||||
);
|
||||
}
|
||||
throw UnimplementedError;
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
import 'package:appflowy/plugins/database_view/application/field/type_option/type_option_context.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/type_option/builder.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CheckboxTypeOptionMobileWidgetBuilder extends TypeOptionWidgetBuilder {
|
||||
CheckboxTypeOptionMobileWidgetBuilder(
|
||||
CheckboxTypeOptionContext typeOptionContext,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget? build(BuildContext context) => null;
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
import 'package:appflowy/plugins/database_view/application/field/type_option/type_option_context.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/type_option/builder.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ChecklistTypeOptionMobileWidgetBuilder extends TypeOptionWidgetBuilder {
|
||||
ChecklistTypeOptionMobileWidgetBuilder(
|
||||
ChecklistTypeOptionContext typeOptionContext,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget? build(BuildContext context) => const Text('Under Construction');
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_property_edit/widgets/widgets.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/row/cells/date_cell/widgets/widgets.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/type_option/date_bloc.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/type_option/type_option_context.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/field_type_option_editor.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/type_option/builder.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/type_option/date.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class DateTypeOptionMobileWidgetBuilder extends TypeOptionWidgetBuilder {
|
||||
final DateTypeOptionMobileWidget _widget;
|
||||
DateTypeOptionMobileWidgetBuilder(
|
||||
DateTypeOptionContext typeOptionContext,
|
||||
) : _widget = DateTypeOptionMobileWidget(
|
||||
typeOptionContext: typeOptionContext,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget? build(BuildContext context) => _widget;
|
||||
}
|
||||
|
||||
class DateTypeOptionMobileWidget extends TypeOptionWidget {
|
||||
const DateTypeOptionMobileWidget({
|
||||
super.key,
|
||||
required this.typeOptionContext,
|
||||
});
|
||||
|
||||
final DateTypeOptionContext typeOptionContext;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) =>
|
||||
DateTypeOptionBloc(typeOptionContext: typeOptionContext),
|
||||
child: BlocConsumer<DateTypeOptionBloc, DateTypeOptionState>(
|
||||
listener: (context, state) =>
|
||||
typeOptionContext.typeOption = state.typeOption,
|
||||
builder: (context, state) {
|
||||
final List<Widget> children = [
|
||||
PropertyEditContainer(
|
||||
child: DateFormatListTile(
|
||||
currentFormatStr: state.typeOption.dateFormat.title(),
|
||||
groupValue: context
|
||||
.watch<DateTypeOptionBloc>()
|
||||
.state
|
||||
.typeOption
|
||||
.dateFormat,
|
||||
onChanged: (newFormat) {
|
||||
if (newFormat != null) {
|
||||
context.read<DateTypeOptionBloc>().add(
|
||||
DateTypeOptionEvent.didSelectDateFormat(
|
||||
newFormat,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
PropertyEditContainer(
|
||||
child: TimeFormatListTile(
|
||||
currentFormatStr: state.typeOption.timeFormat.title(),
|
||||
groupValue: context
|
||||
.watch<DateTypeOptionBloc>()
|
||||
.state
|
||||
.typeOption
|
||||
.timeFormat,
|
||||
onChanged: (newFormat) {
|
||||
if (newFormat != null) {
|
||||
context.read<DateTypeOptionBloc>().add(
|
||||
DateTypeOptionEvent.didSelectTimeFormat(
|
||||
newFormat,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
];
|
||||
|
||||
return ListView.separated(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
separatorBuilder: (_, index) => const VSpace(8),
|
||||
itemCount: children.length,
|
||||
itemBuilder: (_, index) => children[index],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
import 'package:appflowy/plugins/database_view/application/field/type_option/type_option_context.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/type_option/builder.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MultiSelectTypeOptionMobileWidgetBuilder extends TypeOptionWidgetBuilder {
|
||||
MultiSelectTypeOptionMobileWidgetBuilder(
|
||||
MultiSelectTypeOptionContext typeOptionContext,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget? build(BuildContext context) => const Text('Under Construction');
|
||||
}
|
@ -1,156 +0,0 @@
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_property_edit/widgets/widgets.dart';
|
||||
import 'package:appflowy/mobile/presentation/widgets/widgets.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/type_option/number_bloc.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/type_option/number_format_bloc.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/type_option/type_option_context.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/field_type_option_editor.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/type_option/builder.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/number_entities.pbenum.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class NumberTypeOptionMobileWidgetBuilder extends TypeOptionWidgetBuilder {
|
||||
final NumberTypeOptionMobileWidget _widget;
|
||||
|
||||
NumberTypeOptionMobileWidgetBuilder(
|
||||
NumberTypeOptionContext typeOptionContext,
|
||||
) : _widget = NumberTypeOptionMobileWidget(
|
||||
typeOptionContext: typeOptionContext,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget? build(BuildContext context) {
|
||||
return _widget;
|
||||
}
|
||||
}
|
||||
|
||||
class NumberTypeOptionMobileWidget extends TypeOptionWidget {
|
||||
final NumberTypeOptionContext typeOptionContext;
|
||||
|
||||
const NumberTypeOptionMobileWidget({
|
||||
super.key,
|
||||
required this.typeOptionContext,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) =>
|
||||
NumberTypeOptionBloc(typeOptionContext: typeOptionContext),
|
||||
child: BlocConsumer<NumberTypeOptionBloc, NumberTypeOptionState>(
|
||||
listener: (context, state) =>
|
||||
typeOptionContext.typeOption = state.typeOption,
|
||||
builder: (context, state) {
|
||||
return GestureDetector(
|
||||
child: PropertyEditContainer(
|
||||
child: Row(
|
||||
children: [
|
||||
PropertyTitle(LocaleKeys.grid_field_numberFormat.tr()),
|
||||
const Spacer(),
|
||||
const HSpace(4),
|
||||
Text(
|
||||
state.typeOption.format.title(),
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
color: Theme.of(context).hintColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onTap: () => showFlowyMobileBottomSheet(
|
||||
context,
|
||||
isScrollControlled: true,
|
||||
title: LocaleKeys.grid_field_numberFormat.tr(),
|
||||
builder: (bottomsheetContext) => GestureDetector(
|
||||
child: NumberFormatList(
|
||||
onSelected: (format) {
|
||||
context
|
||||
.read<NumberTypeOptionBloc>()
|
||||
.add(NumberTypeOptionEvent.didSelectFormat(format));
|
||||
bottomsheetContext.pop();
|
||||
},
|
||||
selectedFormat: state.typeOption.format,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
typedef SelectNumberFormatCallback = Function(NumberFormatPB format);
|
||||
|
||||
class NumberFormatList extends StatelessWidget {
|
||||
const NumberFormatList({
|
||||
super.key,
|
||||
required this.selectedFormat,
|
||||
required this.onSelected,
|
||||
});
|
||||
|
||||
final SelectNumberFormatCallback onSelected;
|
||||
final NumberFormatPB selectedFormat;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => NumberFormatBloc(),
|
||||
child: Column(
|
||||
children: [
|
||||
const _FilterTextField(),
|
||||
const VSpace(16),
|
||||
SizedBox(
|
||||
height: 300,
|
||||
child: BlocBuilder<NumberFormatBloc, NumberFormatState>(
|
||||
builder: (context, state) {
|
||||
final List<NumberFormatPB> formatList = state.formats;
|
||||
return ListView.builder(
|
||||
itemCount: formatList.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final format = formatList[index];
|
||||
return RadioListTile<NumberFormatPB>(
|
||||
controlAffinity: ListTileControlAffinity.trailing,
|
||||
visualDensity: VisualDensity.compact,
|
||||
value: format,
|
||||
groupValue: selectedFormat,
|
||||
onChanged: (format) => onSelected(format!),
|
||||
title: Text(format.title()),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _FilterTextField extends StatelessWidget {
|
||||
const _FilterTextField();
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
child: TextField(
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: const Icon(Icons.search),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
onChanged: (text) => context
|
||||
.read<NumberFormatBloc>()
|
||||
.add(NumberFormatEvent.setFilter(text)),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
import 'package:appflowy/plugins/database_view/application/field/type_option/type_option_context.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/type_option/builder.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class RichTextTypeOptionMobileWidgetBuilder extends TypeOptionWidgetBuilder {
|
||||
RichTextTypeOptionMobileWidgetBuilder(
|
||||
RichTextTypeOptionContext typeOptionContext,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget? build(BuildContext context) => null;
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
import 'package:appflowy/plugins/database_view/application/field/type_option/type_option_context.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/type_option/builder.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SingleSelectTypeOptionMobileWidgetBuilder
|
||||
extends TypeOptionWidgetBuilder {
|
||||
SingleSelectTypeOptionMobileWidgetBuilder(
|
||||
SingleSelectTypeOptionContext typeOptionContext,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget? build(BuildContext context) => const Text('Under Construction');
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_property_edit/widgets/widgets.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/row/cells/date_cell/widgets/widgets.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/type_option/timestamp_bloc.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/type_option/type_option_context.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/field_type_option_editor.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/type_option/builder.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/type_option/date.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class TimestampTypeOptionMobileWidgetBuilder extends TypeOptionWidgetBuilder {
|
||||
final TimestampTypeOptionMobileWidget _widget;
|
||||
|
||||
TimestampTypeOptionMobileWidgetBuilder(
|
||||
TimestampTypeOptionContext typeOptionContext,
|
||||
) : _widget = TimestampTypeOptionMobileWidget(
|
||||
typeOptionContext: typeOptionContext,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget? build(BuildContext context) => _widget;
|
||||
}
|
||||
|
||||
class TimestampTypeOptionMobileWidget extends TypeOptionWidget {
|
||||
const TimestampTypeOptionMobileWidget({
|
||||
super.key,
|
||||
required this.typeOptionContext,
|
||||
});
|
||||
|
||||
final TimestampTypeOptionContext typeOptionContext;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) =>
|
||||
TimestampTypeOptionBloc(typeOptionContext: typeOptionContext),
|
||||
child: BlocConsumer<TimestampTypeOptionBloc, TimestampTypeOptionState>(
|
||||
listener: (context, state) =>
|
||||
typeOptionContext.typeOption = state.typeOption,
|
||||
builder: (context, state) {
|
||||
final List<Widget> children = [
|
||||
PropertyEditContainer(
|
||||
child: DateFormatListTile(
|
||||
currentFormatStr: state.typeOption.dateFormat.title(),
|
||||
groupValue: context
|
||||
.watch<TimestampTypeOptionBloc>()
|
||||
.state
|
||||
.typeOption
|
||||
.dateFormat,
|
||||
onChanged: (newFormat) {
|
||||
if (newFormat != null) {
|
||||
context.read<TimestampTypeOptionBloc>().add(
|
||||
TimestampTypeOptionEvent.didSelectDateFormat(
|
||||
newFormat,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
PropertyEditContainer(
|
||||
child: IncludeTimeSwitch(
|
||||
switchValue: state.typeOption.includeTime,
|
||||
onChanged: (value) => context
|
||||
.read<TimestampTypeOptionBloc>()
|
||||
.add(TimestampTypeOptionEvent.includeTime(value)),
|
||||
),
|
||||
),
|
||||
if (state.typeOption.includeTime)
|
||||
PropertyEditContainer(
|
||||
child: TimeFormatListTile(
|
||||
currentFormatStr: state.typeOption.timeFormat.title(),
|
||||
groupValue: context
|
||||
.watch<TimestampTypeOptionBloc>()
|
||||
.state
|
||||
.typeOption
|
||||
.timeFormat,
|
||||
onChanged: (newFormat) {
|
||||
if (newFormat != null) {
|
||||
context.read<TimestampTypeOptionBloc>().add(
|
||||
TimestampTypeOptionEvent.didSelectTimeFormat(
|
||||
newFormat,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
];
|
||||
|
||||
return ListView.separated(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
separatorBuilder: (context, index) => const VSpace(8),
|
||||
itemCount: children.length,
|
||||
itemBuilder: (BuildContext context, int index) => children[index],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
export 'checklist.dart';
|
||||
export 'checkbox.dart';
|
||||
export 'date.dart';
|
||||
export 'multi_select.dart';
|
||||
export 'number.dart';
|
||||
export 'rich_text.dart';
|
||||
export 'single_select.dart';
|
||||
export 'timestamp.dart';
|
||||
export 'url.dart';
|
@ -1,12 +0,0 @@
|
||||
import 'package:appflowy/plugins/database_view/application/field/type_option/type_option_context.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/type_option/builder.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class URLTypeOptionMobileWidgetBuilder extends TypeOptionWidgetBuilder {
|
||||
URLTypeOptionMobileWidgetBuilder(
|
||||
URLTypeOptionContext typeOptionContext,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget? build(BuildContext context) => null;
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class PropertyEditContainer extends StatelessWidget {
|
||||
const PropertyEditContainer({
|
||||
super.key,
|
||||
required this.child,
|
||||
this.padding,
|
||||
});
|
||||
|
||||
final Widget child;
|
||||
final EdgeInsets? padding;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: 50,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: padding ?? const EdgeInsets.symmetric(horizontal: 8),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class PropertyEditGroupTitle extends StatelessWidget {
|
||||
const PropertyEditGroupTitle(this.name, {super.key});
|
||||
|
||||
final String name;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: Text(
|
||||
name,
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class PropertyTitle extends StatelessWidget {
|
||||
const PropertyTitle(this.name, {super.key});
|
||||
|
||||
final String name;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: Text(
|
||||
name,
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onBackground,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
export 'property_edit_group_title.dart';
|
||||
export 'property_title.dart';
|
||||
export 'property_edit_container.dart';
|
@ -1,142 +0,0 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/row/cells/date_cell/date_cal_bloc.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/date_entities.pbenum.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class DateAndTimeDisplay extends StatelessWidget {
|
||||
const DateAndTimeDisplay(this.state, {super.key});
|
||||
final DateCellCalendarState state;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
// date/start date and time
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
_DateEditButton(
|
||||
dateStr: state.isRange
|
||||
? _formatDateByDateFormatPB(
|
||||
state.startDay,
|
||||
state.dateTypeOptionPB.dateFormat,
|
||||
)
|
||||
: state.dateStr,
|
||||
initialDate: state.isRange ? state.startDay : state.dateTime,
|
||||
onDaySelected: (newDate) {
|
||||
context.read<DateCellCalendarBloc>().add(
|
||||
state.isRange
|
||||
? DateCellCalendarEvent.setStartDay(newDate)
|
||||
: DateCellCalendarEvent.selectDay(newDate),
|
||||
);
|
||||
},
|
||||
),
|
||||
const HSpace(8),
|
||||
if (state.includeTime)
|
||||
Expanded(child: _TimeEditButton(state.timeStr)),
|
||||
],
|
||||
),
|
||||
const VSpace(8),
|
||||
// end date and time
|
||||
if (state.isRange) ...[
|
||||
_DateEditButton(
|
||||
dateStr: state.endDay != null ? state.endDateStr : null,
|
||||
initialDate: state.endDay,
|
||||
onDaySelected: (newDate) {
|
||||
context.read<DateCellCalendarBloc>().add(
|
||||
DateCellCalendarEvent.setEndDay(newDate),
|
||||
);
|
||||
},
|
||||
),
|
||||
const HSpace(8),
|
||||
if (state.includeTime)
|
||||
Expanded(child: _TimeEditButton(state.endTimeStr)),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _DateEditButton extends StatelessWidget {
|
||||
const _DateEditButton({
|
||||
required this.dateStr,
|
||||
required this.initialDate,
|
||||
required this.onDaySelected,
|
||||
});
|
||||
|
||||
final String? dateStr;
|
||||
|
||||
/// initial date for date picker, if null, use DateTime.now()
|
||||
final DateTime? initialDate;
|
||||
final void Function(DateTime)? onDaySelected;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final size = MediaQuery.of(context).size;
|
||||
|
||||
return SizedBox(
|
||||
// share space with TimeEditButton
|
||||
width: (size.width - 8) / 2,
|
||||
child: OutlinedButton(
|
||||
onPressed: () async {
|
||||
final DateTime? newDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: initialDate ?? DateTime.now(),
|
||||
firstDate: DateTime(1900),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
if (newDate != null) {
|
||||
onDaySelected?.call(newDate);
|
||||
}
|
||||
},
|
||||
child: Text(
|
||||
dateStr ?? LocaleKeys.grid_field_selectDate.tr(),
|
||||
style: Theme.of(context).textTheme.labelMedium,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _TimeEditButton extends StatelessWidget {
|
||||
const _TimeEditButton(
|
||||
this.timeStr,
|
||||
);
|
||||
|
||||
final String? timeStr;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return OutlinedButton(
|
||||
// TODO(yijing): implement time picker
|
||||
onPressed: null,
|
||||
child: Text(
|
||||
timeStr ?? LocaleKeys.grid_field_selectTime.tr(),
|
||||
style: Theme.of(context).textTheme.labelMedium,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
String? _formatDateByDateFormatPB(DateTime? date, DateFormatPB dateFormatPB) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
switch (dateFormatPB) {
|
||||
case DateFormatPB.Local:
|
||||
return DateFormat('MM/dd/yyyy').format(date);
|
||||
case DateFormatPB.US:
|
||||
return DateFormat('yyyy/MM/dd').format(date);
|
||||
case DateFormatPB.ISO:
|
||||
return DateFormat('yyyy-MM-dd').format(date);
|
||||
case DateFormatPB.Friendly:
|
||||
return DateFormat('MMM dd, yyyy').format(date);
|
||||
case DateFormatPB.DayMonthYear:
|
||||
return DateFormat('dd/MM/yyyy').format(date);
|
||||
default:
|
||||
return 'Unavailable date format';
|
||||
}
|
||||
}
|
@ -1,141 +0,0 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_property_edit/widgets/widgets.dart';
|
||||
import 'package:appflowy/mobile/presentation/widgets/widgets.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/date_entities.pb.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class DateFormatListTile extends StatelessWidget {
|
||||
const DateFormatListTile({
|
||||
super.key,
|
||||
required this.currentFormatStr,
|
||||
this.groupValue,
|
||||
this.onChanged,
|
||||
});
|
||||
|
||||
final String currentFormatStr;
|
||||
|
||||
/// The group value for the radio list tile.
|
||||
final DateFormatPB? groupValue;
|
||||
|
||||
/// The Function for the radio list tile.
|
||||
final void Function(DateFormatPB?)? onChanged;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final style = Theme.of(context);
|
||||
return Row(
|
||||
children: [
|
||||
PropertyTitle(
|
||||
LocaleKeys.grid_field_dateFormat.tr(),
|
||||
),
|
||||
const Spacer(),
|
||||
GestureDetector(
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
currentFormatStr,
|
||||
style: style.textTheme.titleMedium,
|
||||
),
|
||||
const HSpace(4),
|
||||
Icon(
|
||||
Icons.arrow_forward_ios_sharp,
|
||||
color: style.hintColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
onTap: () => showFlowyMobileBottomSheet(
|
||||
context,
|
||||
title: LocaleKeys.grid_field_dateFormat.tr(),
|
||||
builder: (_) {
|
||||
return Column(
|
||||
children: [
|
||||
_DateFormatRadioListTile(
|
||||
title: LocaleKeys.grid_field_dateFormatLocal.tr(),
|
||||
dateFormatPB: DateFormatPB.Local,
|
||||
groupValue: groupValue,
|
||||
onChanged: (newFormat) {
|
||||
onChanged?.call(newFormat);
|
||||
context.pop();
|
||||
},
|
||||
),
|
||||
_DateFormatRadioListTile(
|
||||
title: LocaleKeys.grid_field_dateFormatUS.tr(),
|
||||
dateFormatPB: DateFormatPB.US,
|
||||
groupValue: groupValue,
|
||||
onChanged: (newFormat) {
|
||||
onChanged?.call(newFormat);
|
||||
context.pop();
|
||||
},
|
||||
),
|
||||
_DateFormatRadioListTile(
|
||||
title: LocaleKeys.grid_field_dateFormatISO.tr(),
|
||||
dateFormatPB: DateFormatPB.ISO,
|
||||
groupValue: groupValue,
|
||||
onChanged: (newFormat) {
|
||||
onChanged?.call(newFormat);
|
||||
context.pop();
|
||||
},
|
||||
),
|
||||
_DateFormatRadioListTile(
|
||||
title: LocaleKeys.grid_field_dateFormatFriendly.tr(),
|
||||
dateFormatPB: DateFormatPB.Friendly,
|
||||
groupValue: groupValue,
|
||||
onChanged: (newFormat) {
|
||||
onChanged?.call(newFormat);
|
||||
context.pop();
|
||||
},
|
||||
),
|
||||
_DateFormatRadioListTile(
|
||||
title: LocaleKeys.grid_field_dateFormatDayMonthYear.tr(),
|
||||
dateFormatPB: DateFormatPB.DayMonthYear,
|
||||
groupValue: groupValue,
|
||||
onChanged: (newFormat) {
|
||||
onChanged?.call(newFormat);
|
||||
context.pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _DateFormatRadioListTile extends StatelessWidget {
|
||||
const _DateFormatRadioListTile({
|
||||
required this.title,
|
||||
required this.dateFormatPB,
|
||||
required this.groupValue,
|
||||
required this.onChanged,
|
||||
});
|
||||
|
||||
final String title;
|
||||
final DateFormatPB dateFormatPB;
|
||||
final DateFormatPB? groupValue;
|
||||
final void Function(DateFormatPB?)? onChanged;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final style = Theme.of(context);
|
||||
return RadioListTile<DateFormatPB>(
|
||||
dense: true,
|
||||
contentPadding: const EdgeInsets.fromLTRB(0, 0, 4, 0),
|
||||
controlAffinity: ListTileControlAffinity.trailing,
|
||||
title: Text(
|
||||
title,
|
||||
style: style.textTheme.bodyMedium?.copyWith(
|
||||
color: style.colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
groupValue: groupValue,
|
||||
value: dateFormatPB,
|
||||
onChanged: onChanged,
|
||||
);
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_property_edit/widgets/property_title.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class IncludeTimeSwitch extends StatelessWidget {
|
||||
const IncludeTimeSwitch({
|
||||
super.key,
|
||||
required this.switchValue,
|
||||
required this.onChanged,
|
||||
});
|
||||
|
||||
final bool switchValue;
|
||||
final void Function(bool)? onChanged;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
PropertyTitle(
|
||||
LocaleKeys.grid_field_includeTime.tr(),
|
||||
),
|
||||
const Spacer(),
|
||||
Switch.adaptive(
|
||||
value: switchValue,
|
||||
activeColor: Theme.of(context).colorScheme.primary,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -1,115 +0,0 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_property_edit/widgets/widgets.dart';
|
||||
import 'package:appflowy/mobile/presentation/widgets/widgets.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/date_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/date_entities.pbenum.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class TimeFormatListTile extends StatelessWidget {
|
||||
const TimeFormatListTile({
|
||||
super.key,
|
||||
required this.currentFormatStr,
|
||||
required this.groupValue,
|
||||
required this.onChanged,
|
||||
});
|
||||
|
||||
final String currentFormatStr;
|
||||
|
||||
/// The group value for the radio list tile.
|
||||
final TimeFormatPB? groupValue;
|
||||
|
||||
/// The Function for the radio list tile.
|
||||
final void Function(TimeFormatPB?)? onChanged;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final style = Theme.of(context);
|
||||
return Row(
|
||||
children: [
|
||||
PropertyTitle(
|
||||
LocaleKeys.grid_field_timeFormat.tr(),
|
||||
),
|
||||
const Spacer(),
|
||||
GestureDetector(
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
currentFormatStr,
|
||||
style: style.textTheme.titleMedium,
|
||||
),
|
||||
const HSpace(4),
|
||||
Icon(
|
||||
Icons.arrow_forward_ios_sharp,
|
||||
color: style.hintColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
onTap: () => showFlowyMobileBottomSheet(
|
||||
context,
|
||||
title: LocaleKeys.grid_field_timeFormat.tr(),
|
||||
builder: (context) {
|
||||
return Column(
|
||||
children: [
|
||||
_TimeFormatRadioListTile(
|
||||
title: LocaleKeys.grid_field_timeFormatTwelveHour.tr(),
|
||||
timeFormatPB: TimeFormatPB.TwelveHour,
|
||||
groupValue: groupValue,
|
||||
onChanged: (newFormat) {
|
||||
onChanged?.call(newFormat);
|
||||
context.pop();
|
||||
},
|
||||
),
|
||||
_TimeFormatRadioListTile(
|
||||
title: LocaleKeys.grid_field_timeFormatTwentyFourHour.tr(),
|
||||
timeFormatPB: TimeFormatPB.TwentyFourHour,
|
||||
groupValue: groupValue,
|
||||
onChanged: (newFormat) {
|
||||
onChanged?.call(newFormat);
|
||||
context.pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _TimeFormatRadioListTile extends StatelessWidget {
|
||||
const _TimeFormatRadioListTile({
|
||||
required this.title,
|
||||
required this.timeFormatPB,
|
||||
required this.groupValue,
|
||||
required this.onChanged,
|
||||
});
|
||||
|
||||
final String title;
|
||||
final TimeFormatPB timeFormatPB;
|
||||
final TimeFormatPB? groupValue;
|
||||
final void Function(TimeFormatPB?)? onChanged;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final style = Theme.of(context);
|
||||
return RadioListTile<TimeFormatPB>(
|
||||
dense: true,
|
||||
contentPadding: const EdgeInsets.fromLTRB(0, 0, 4, 0),
|
||||
controlAffinity: ListTileControlAffinity.trailing,
|
||||
title: Text(
|
||||
title,
|
||||
style: style.textTheme.bodyMedium?.copyWith(
|
||||
color: style.colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
groupValue: groupValue,
|
||||
value: timeFormatPB,
|
||||
onChanged: onChanged,
|
||||
);
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
export 'date_and_time_display.dart';
|
||||
export 'date_format_list_tile.dart';
|
||||
export 'time_format_list_tile.dart';
|
||||
export 'include_time_switch.dart';
|
@ -1,9 +1,7 @@
|
||||
import 'package:appflowy/mobile/presentation/database/board/mobile_board_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_detail/mobile_create_field_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_detail/mobile_create_row_field_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_detail/mobile_edit_field_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_property_edit/card_property_edit_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/date_picker/mobile_date_picker_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/mobile_calendar_events_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/mobile_calendar_screen.dart';
|
||||
@ -16,7 +14,6 @@ import 'package:appflowy/mobile/presentation/setting/font/font_picker_screen.dar
|
||||
import 'package:appflowy/mobile/presentation/setting/language/language_picker_screen.dart';
|
||||
import 'package:appflowy/plugins/base/color/color_picker_screen.dart';
|
||||
import 'package:appflowy/plugins/base/emoji/emoji_picker_screen.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/application/row/row_detail_bloc.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/code_block/code_language_screen.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/image/image_picker_screen.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_item/mobile_block_settings_screen.dart';
|
||||
@ -29,7 +26,6 @@ import 'package:appflowy/workspace/presentation/home/desktop_home_screen.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||
import 'package:flowy_infra/time/duration.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
GoRouter generateRouter(Widget child) {
|
||||
@ -62,9 +58,7 @@ GoRouter generateRouter(Widget child) {
|
||||
_mobileCalendarScreenRoute(),
|
||||
// card detail page
|
||||
_mobileCardDetailScreenRoute(),
|
||||
_mobileCardPropertyEditScreenRoute(),
|
||||
_mobileDateCellEditScreenRoute(),
|
||||
_mobileCreateRowFieldScreenRoute(),
|
||||
_mobileNewPropertyPageRoute(),
|
||||
_mobileEditPropertyPageRoute(),
|
||||
|
||||
@ -557,29 +551,6 @@ GoRoute _mobileCardDetailScreenRoute() {
|
||||
);
|
||||
}
|
||||
|
||||
GoRoute _mobileCardPropertyEditScreenRoute() {
|
||||
return GoRoute(
|
||||
parentNavigatorKey: AppGlobals.rootNavKey,
|
||||
path: CardPropertyEditScreen.routeName,
|
||||
pageBuilder: (context, state) {
|
||||
final args = state.extra as Map<String, dynamic>;
|
||||
final cellContext = args[CardPropertyEditScreen.argCellContext];
|
||||
final fieldController = args[CardPropertyEditScreen.argFieldController];
|
||||
final rowDetailBloc = args[CardPropertyEditScreen.argRowDetailBloc];
|
||||
|
||||
return MaterialPage(
|
||||
child: BlocProvider.value(
|
||||
value: rowDetailBloc as RowDetailBloc,
|
||||
child: CardPropertyEditScreen(
|
||||
cellContext: cellContext,
|
||||
fieldController: fieldController,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
GoRoute _mobileDateCellEditScreenRoute() {
|
||||
return GoRoute(
|
||||
parentNavigatorKey: AppGlobals.rootNavKey,
|
||||
@ -603,29 +574,6 @@ GoRoute _mobileDateCellEditScreenRoute() {
|
||||
);
|
||||
}
|
||||
|
||||
GoRoute _mobileCreateRowFieldScreenRoute() {
|
||||
return GoRoute(
|
||||
parentNavigatorKey: AppGlobals.rootNavKey,
|
||||
path: MobileCreateRowFieldScreen.routeName,
|
||||
pageBuilder: (context, state) {
|
||||
final args = state.extra as Map<String, dynamic>;
|
||||
final viewId = args[MobileCreateRowFieldScreen.argViewId];
|
||||
final fieldController =
|
||||
args[MobileCreateRowFieldScreen.argFieldController];
|
||||
final typeOption = args[MobileCreateRowFieldScreen.argTypeOption];
|
||||
|
||||
return MaterialPage(
|
||||
child: MobileCreateRowFieldScreen(
|
||||
viewId: viewId,
|
||||
typeOption: typeOption,
|
||||
fieldController: fieldController,
|
||||
),
|
||||
fullscreenDialog: true,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
GoRoute _rootRoute(Widget child) {
|
||||
return GoRoute(
|
||||
path: '/',
|
||||
|
Loading…
Reference in New Issue
Block a user