feat: upgrade to flutter 3.16 (#4119)

* feat: upgrade to flutter 3.16

* chore: adjust flutter 3.16 new api

* chore: code format

* fix: ci lint

* chore: code format

* chore: dart format
This commit is contained in:
Lucas.Xu 2023-12-08 20:01:54 +07:00 committed by GitHub
parent 6338ca1417
commit ef49cb6577
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
140 changed files with 575 additions and 605 deletions

View File

@ -3,7 +3,7 @@ name: Build AppFlowy Release APK
on: workflow_dispatch
env:
FLUTTER_VERSION: "3.13.9"
FLUTTER_VERSION: "3.16.2"
RUST_TOOLCHAIN: "1.70"
jobs:

View File

@ -23,7 +23,7 @@ on:
env:
CARGO_TERM_COLOR: always
FLUTTER_VERSION: "3.13.9"
FLUTTER_VERSION: "3.16.2"
RUST_TOOLCHAIN: "1.70"
CARGO_MAKE_VERSION: "0.36.6"

View File

@ -18,7 +18,7 @@ on:
- "!frontend/appflowy_tauri/**"
env:
FLUTTER_VERSION: "3.13.9"
FLUTTER_VERSION: "3.16.2"
RUST_TOOLCHAIN: "1.70"
concurrency:

View File

@ -6,7 +6,7 @@ on:
- "*"
env:
FLUTTER_VERSION: "3.13.9"
FLUTTER_VERSION: "3.16.2"
RUST_TOOLCHAIN: "1.70"
jobs:

View File

@ -11,7 +11,7 @@ on:
env:
CARGO_TERM_COLOR: always
FLUTTER_VERSION: "3.13.9"
FLUTTER_VERSION: "3.16.2"
RUST_TOOLCHAIN: "1.70"
jobs:

View File

@ -34,6 +34,13 @@ linter:
- prefer_final_in_for_each
- prefer_final_locals
- sized_box_for_whitespace
- avoid_unnecessary_containers
- always_declare_return_types
- unnecessary_raw_strings
- use_decorated_box
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

View File

@ -19,7 +19,7 @@ void main() {
await tester.createNewPageWithName(layout: ViewLayoutPB.Board);
final card1 = find.ancestor(
of: find.findTextInFlowyText(card1Name),
of: find.findTextInFlowyText(card1Name),
matching: find.byType(AppFlowyGroupCard),
);
final doingGroup = find.findTextInFlowyText('Doing');
@ -27,7 +27,7 @@ void main() {
final card1Center = tester.getCenter(card1);
await tester.timedDrag(
card1,
card1,
doingGroupCenter.translate(-card1Center.dx, -card1Center.dy),
const Duration(seconds: 1),
);
@ -36,9 +36,9 @@ void main() {
await tester.pumpAndSettle();
final card1StatusFinder = find.descendant(
of: find.byType(RowPropertyList),
of: find.byType(RowPropertyList),
matching: find.descendant(
of: find.byType(SelectOptionTag),
of: find.byType(SelectOptionTag),
matching: find.byType(FlowyText),
),
);

View File

@ -104,7 +104,7 @@ void main() {
});
}
const _sample = r'''
const _sample = '''
# Heading 1
## Heading 2
### Heading 3

View File

@ -26,7 +26,7 @@ class CocoaWindowChannel {
}
class MoveWindowDetector extends StatefulWidget {
const MoveWindowDetector({Key? key, this.child}) : super(key: key);
const MoveWindowDetector({super.key, this.child});
final Widget? child;

View File

@ -13,11 +13,9 @@ typedef DocumentNotificationCallback = void Function(
class DocumentNotificationParser
extends NotificationParser<DocumentNotification, FlowyError> {
DocumentNotificationParser({
String? id,
required DocumentNotificationCallback callback,
super.id,
required super.callback,
}) : super(
id: id,
callback: callback,
tyParser: (ty) => DocumentNotification.valueOf(ty),
errorParser: (bytes) => FlowyError.fromBuffer(bytes),
);

View File

@ -17,11 +17,9 @@ typedef FolderNotificationCallback = void Function(
class FolderNotificationParser
extends NotificationParser<FolderNotification, FlowyError> {
FolderNotificationParser({
String? id,
required FolderNotificationCallback callback,
super.id,
required super.callback,
}) : super(
id: id,
callback: callback,
tyParser: (ty) => FolderNotification.valueOf(ty),
errorParser: (bytes) => FlowyError.fromBuffer(bytes),
);

View File

@ -17,11 +17,9 @@ typedef DatabaseNotificationCallback = void Function(
class DatabaseNotificationParser
extends NotificationParser<DatabaseNotification, FlowyError> {
DatabaseNotificationParser({
String? id,
required DatabaseNotificationCallback callback,
super.id,
required super.callback,
}) : super(
id: id,
callback: callback,
tyParser: (ty) => DatabaseNotification.valueOf(ty),
errorParser: (bytes) => FlowyError.fromBuffer(bytes),
);

View File

@ -17,11 +17,9 @@ typedef UserNotificationCallback = void Function(
class UserNotificationParser
extends NotificationParser<UserNotification, FlowyError> {
UserNotificationParser({
required String id,
required UserNotificationCallback callback,
required String super.id,
required super.callback,
}) : super(
id: id,
callback: callback,
tyParser: (ty) => UserNotification.valueOf(ty),
errorParser: (bytes) => FlowyError.fromBuffer(bytes),
);

View File

@ -146,7 +146,7 @@ enum AuthenticatorType {
}
}
static fromValue(int value) {
static AuthenticatorType fromValue(int value) {
switch (value) {
case 0:
return AuthenticatorType.local;

View File

@ -31,7 +31,7 @@ class _MobileViewItemBottomSheetState extends State<MobileViewItemBottomSheet> {
MobileBottomSheetType type = MobileBottomSheetType.view;
@override
initState() {
void initState() {
super.initState();
type = widget.defaultType;

View File

@ -76,7 +76,7 @@ class _MobileRecentViewState extends State<MobileRecentView> {
onTap: () => context.pushView(view),
child: Stack(
children: [
Container(
DecoratedBox(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
border: Border.all(color: theme.colorScheme.outline),

View File

@ -37,7 +37,7 @@ class _LanguagePickerPageState extends State<LanguagePickerPage> {
late List<String> availableFonts;
@override
initState() {
void initState() {
super.initState();
availableFonts = _availableFonts;

View File

@ -1,10 +1,10 @@
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/startup/plugin/plugin.dart';
import 'package:appflowy/workspace/presentation/home/home_stack.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flutter/material.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/startup/plugin/plugin.dart';
class BlankPluginBuilder extends PluginBuilder {
@override
@ -55,7 +55,7 @@ class BlankPagePluginWidgetBuilder extends PluginWidgetBuilder
}
class BlankPage extends StatefulWidget {
const BlankPage({Key? key}) : super(key: key);
const BlankPage({super.key});
@override
State<BlankPage> createState() => _BlankPageState();

View File

@ -124,7 +124,7 @@ class CellController<T, D> extends Equatable {
_onRowMetaChanged = onRowMetaChanged;
/// Notify the listener, the cell data was changed.
onCellChangedFn() => onCellChanged(_cellDataNotifier?.value);
void onCellChangedFn() => onCellChanged(_cellDataNotifier?.value);
_cellDataNotifier?.addListener(onCellChangedFn);
// Return the function pointer that can be used when calling removeListener.

View File

@ -40,5 +40,5 @@ class LoadingState with _$LoadingState {
) = _Finish;
const LoadingState._();
isLoading() => this is _Loading;
bool isLoading() => this is _Loading;
}

View File

@ -166,7 +166,7 @@ class FieldController {
/// Listen for filter changes in the backend.
void _listenOnFilterChanges() {
deleteFilterFromChangeset(
void deleteFilterFromChangeset(
List<FilterInfo> filters,
FilterChangesetNotificationPB changeset,
) {
@ -178,7 +178,7 @@ class FieldController {
}
}
insertFilterFromChangeset(
void insertFilterFromChangeset(
List<FilterInfo> filters,
FilterChangesetNotificationPB changeset,
) {
@ -198,7 +198,7 @@ class FieldController {
}
}
updateFilterFromChangeset(
void updateFilterFromChangeset(
List<FilterInfo> filters,
FilterChangesetNotificationPB changeset,
) {
@ -264,7 +264,7 @@ class FieldController {
/// Listen for sort changes in the backend.
void _listenOnSortChanged() {
deleteSortFromChangeset(
void deleteSortFromChangeset(
List<SortInfo> newSortInfos,
SortChangesetNotificationPB changeset,
) {
@ -276,7 +276,7 @@ class FieldController {
}
}
insertSortFromChangeset(
void insertSortFromChangeset(
List<SortInfo> newSortInfos,
SortChangesetNotificationPB changeset,
) {
@ -297,7 +297,7 @@ class FieldController {
}
}
updateSortFromChangeset(
void updateSortFromChangeset(
List<SortInfo> newSortInfos,
SortChangesetNotificationPB changeset,
) {
@ -677,7 +677,7 @@ class FieldController {
bool Function()? listenWhen,
}) {
if (onFieldsChanged != null) {
callback(List<FieldInfo> updateFields) {
void callback(List<FieldInfo> updateFields) {
if (listenWhen != null && listenWhen() == false) {
return;
}
@ -688,7 +688,7 @@ class FieldController {
}
if (onReceiveFields != null) {
callback() {
void callback() {
if (listenWhen != null && listenWhen() == false) {
return;
}
@ -700,7 +700,7 @@ class FieldController {
}
if (onFilters != null) {
callback() {
void callback() {
if (listenWhen != null && listenWhen() == false) {
return;
}
@ -712,7 +712,7 @@ class FieldController {
}
if (onSorts != null) {
callback() {
void callback() {
if (listenWhen != null && listenWhen() == false) {
return;
}

View File

@ -99,7 +99,7 @@ class TypeOptionController {
}
void Function() addFieldListener(void Function(FieldPB) callback) {
listener() {
void listener() {
callback(field);
}

View File

@ -1,4 +1,5 @@
import 'dart:collection';
import 'package:appflowy/plugins/database_view/application/field/field_info.dart';
import 'package:appflowy_backend/dispatch/dispatch.dart';
import 'package:appflowy_backend/log.dart';
@ -9,6 +10,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
import '../cell/cell_service.dart';
import 'row_list.dart';
import 'row_service.dart';
part 'row_cache.freezed.dart';
typedef RowUpdateCallback = void Function();
@ -188,7 +190,7 @@ class RowCache {
required RowId rowId,
void Function(CellContextByFieldId, ChangedReason)? onRowChanged,
}) {
listenerHandler() async {
void listenerHandler() async {
if (onRowChanged != null) {
final rowInfo = _rowList.get(rowId);
if (rowInfo != null) {

View File

@ -12,9 +12,9 @@ class RowController {
final List<VoidCallback> _onRowChangedListeners = [];
final RowCache _rowCache;
get cellCache => _rowCache.cellCache;
CellMemCache get cellCache => _rowCache.cellCache;
get rowId => rowMeta.id;
String get rowId => rowMeta.id;
RowController({
required this.rowMeta,

View File

@ -6,8 +6,8 @@ class BoardSettingBar extends StatelessWidget {
final DatabaseController databaseController;
const BoardSettingBar({
required this.databaseController,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {

View File

@ -148,7 +148,7 @@ class CalendarDayCard extends StatelessWidget {
);
}
notifyEnter(BuildContext context, bool isEnter) =>
bool notifyEnter(BuildContext context, bool isEnter) =>
Provider.of<_CardEnterNotifier>(context, listen: false).onEnter = isEnter;
Border _borderFromPosition(BuildContext context, CellPosition position) {

View File

@ -181,8 +181,8 @@ class PropertyCell extends StatefulWidget {
const PropertyCell({
required this.cellContext,
required this.cellBuilder,
Key? key,
}) : super(key: key);
super.key,
});
@override
State<StatefulWidget> createState() => _PropertyCellState();

View File

@ -17,7 +17,6 @@ import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:calendar_view/calendar_view.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/size.dart';
import 'package:flowy_infra/theme_extension.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
@ -229,7 +228,6 @@ class _CalendarPageState extends State<CalendarPage> {
firstDate: CalendarConstants.epochDate.withoutTime,
lastDate: CalendarConstants.maxDate.withoutTime,
selectedDate: currentMonth,
initialDate: currentMonth,
currentDate: DateTime.now(),
onChanged: (newDate) {
_calendarState?.currentState?.jumpToMonth(newDate);

View File

@ -32,7 +32,7 @@ import 'widgets/shortcuts.dart';
class ToggleExtensionNotifier extends ChangeNotifier {
bool _isToggled = false;
get isToggled => _isToggled;
bool get isToggled => _isToggled;
void toggle() {
_isToggled = !_isToggled;
@ -90,8 +90,8 @@ class GridPage extends StatefulWidget {
required this.view,
required this.databaseController,
this.onDeleted,
Key? key,
}) : super(key: key);
super.key,
});
final ViewPB view;
final VoidCallback? onDeleted;

View File

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
class TypeOptionSeparator extends StatelessWidget {
final double spacing;
const TypeOptionSeparator({this.spacing = 6.0, Key? key}) : super(key: key);
const TypeOptionSeparator({this.spacing = 6.0, super.key});
@override
Widget build(BuildContext context) {

View File

@ -17,8 +17,7 @@ import 'choicechip.dart';
class CheckboxFilterChoicechip extends StatefulWidget {
final FilterInfo filterInfo;
const CheckboxFilterChoicechip({required this.filterInfo, Key? key})
: super(key: key);
const CheckboxFilterChoicechip({required this.filterInfo, super.key});
@override
State<CheckboxFilterChoicechip> createState() =>
@ -72,7 +71,7 @@ class _CheckboxFilterChoicechipState extends State<CheckboxFilterChoicechip> {
class CheckboxFilterEditor extends StatefulWidget {
final CheckboxFilterEditorBloc bloc;
const CheckboxFilterEditor({required this.bloc, Key? key}) : super(key: key);
const CheckboxFilterEditor({required this.bloc, super.key});
@override
State<CheckboxFilterEditor> createState() => _CheckboxFilterEditorState();
@ -150,8 +149,8 @@ class CheckboxFilterConditionList extends StatelessWidget {
required this.filterInfo,
required this.popoverMutex,
required this.onCondition,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {

View File

@ -14,8 +14,7 @@ import '../choicechip.dart';
class ChecklistFilterChoicechip extends StatefulWidget {
final FilterInfo filterInfo;
const ChecklistFilterChoicechip({required this.filterInfo, Key? key})
: super(key: key);
const ChecklistFilterChoicechip({required this.filterInfo, super.key});
@override
State<ChecklistFilterChoicechip> createState() =>
@ -73,8 +72,8 @@ class ChecklistFilterEditor extends StatefulWidget {
const ChecklistFilterEditor({
required this.bloc,
required this.popoverMutex,
Key? key,
}) : super(key: key);
super.key,
});
@override
ChecklistState createState() => ChecklistState();
@ -126,8 +125,8 @@ class ChecklistFilterConditionList extends StatelessWidget {
final FilterInfo filterInfo;
const ChecklistFilterConditionList({
required this.filterInfo,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {

View File

@ -15,11 +15,11 @@ class ChoiceChipButton extends StatelessWidget {
final String filterDesc;
const ChoiceChipButton({
Key? key,
super.key,
required this.filterInfo,
this.filterDesc = '',
this.onTap,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {
@ -59,8 +59,7 @@ class ChoiceChipButton extends StatelessWidget {
class _ChoicechipFilterDesc extends StatelessWidget {
final String filterDesc;
const _ChoicechipFilterDesc({this.filterDesc = '', Key? key})
: super(key: key);
const _ChoicechipFilterDesc({this.filterDesc = ''});
@override
Widget build(BuildContext context) {

View File

@ -5,8 +5,7 @@ import 'choicechip.dart';
class DateFilterChoicechip extends StatelessWidget {
final FilterInfo filterInfo;
const DateFilterChoicechip({required this.filterInfo, Key? key})
: super(key: key);
const DateFilterChoicechip({required this.filterInfo, super.key});
@override
Widget build(BuildContext context) {

View File

@ -5,8 +5,7 @@ import 'choicechip.dart';
class NumberFilterChoicechip extends StatelessWidget {
final FilterInfo filterInfo;
const NumberFilterChoicechip({required this.filterInfo, Key? key})
: super(key: key);
const NumberFilterChoicechip({required this.filterInfo, super.key});
@override
Widget build(BuildContext context) {

View File

@ -19,8 +19,8 @@ class SelectOptionFilterConditionList extends StatelessWidget {
required this.filterInfo,
required this.popoverMutex,
required this.onCondition,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {

View File

@ -20,8 +20,8 @@ class SelectOptionFilterList extends StatelessWidget {
required this.filterInfo,
required this.selectedOptionIds,
required this.onSelectedOptions,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {

View File

@ -15,8 +15,7 @@ import 'select_option_loader.dart';
class SelectOptionFilterChoicechip extends StatefulWidget {
final FilterInfo filterInfo;
const SelectOptionFilterChoicechip({required this.filterInfo, Key? key})
: super(key: key);
const SelectOptionFilterChoicechip({required this.filterInfo, super.key});
@override
State<SelectOptionFilterChoicechip> createState() =>
@ -77,8 +76,7 @@ class _SelectOptionFilterChoicechipState
class SelectOptionFilterEditor extends StatefulWidget {
final SelectOptionFilterEditorBloc bloc;
const SelectOptionFilterEditor({required this.bloc, Key? key})
: super(key: key);
const SelectOptionFilterEditor({required this.bloc, super.key});
@override
State<SelectOptionFilterEditor> createState() =>

View File

@ -16,8 +16,7 @@ import 'choicechip.dart';
class TextFilterChoicechip extends StatefulWidget {
final FilterInfo filterInfo;
const TextFilterChoicechip({required this.filterInfo, Key? key})
: super(key: key);
const TextFilterChoicechip({required this.filterInfo, super.key});
@override
State<TextFilterChoicechip> createState() => _TextFilterChoicechipState();
@ -79,7 +78,7 @@ class _TextFilterChoicechipState extends State<TextFilterChoicechip> {
class TextFilterEditor extends StatefulWidget {
final TextFilterEditorBloc bloc;
const TextFilterEditor({required this.bloc, Key? key}) : super(key: key);
const TextFilterEditor({required this.bloc, super.key});
@override
State<TextFilterEditor> createState() => _TextFilterEditorState();
@ -180,8 +179,8 @@ class TextFilterConditionPBList extends StatelessWidget {
required this.filterInfo,
required this.popoverMutex,
required this.onCondition,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {

View File

@ -4,8 +4,7 @@ import 'choicechip.dart';
class URLFilterChoicechip extends StatelessWidget {
final FilterInfo filterInfo;
const URLFilterChoicechip({required this.filterInfo, Key? key})
: super(key: key);
const URLFilterChoicechip({required this.filterInfo, super.key});
@override
Widget build(BuildContext context) {

View File

@ -12,8 +12,8 @@ class ConditionButton extends StatelessWidget {
const ConditionButton({
required this.conditionName,
required this.onTap,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {

View File

@ -27,8 +27,8 @@ class GridCreateFilterList extends StatefulWidget {
required this.fieldController,
required this.onClosed,
this.onCreateFilter,
Key? key,
}) : super(key: key);
super.key,
});
@override
State<StatefulWidget> createState() => _GridCreateFilterListState();
@ -155,8 +155,8 @@ class GridFilterPropertyCell extends StatelessWidget {
const GridFilterPropertyCell({
required this.fieldInfo,
required this.onTap,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {

View File

@ -14,8 +14,8 @@ class DisclosureButton extends StatefulWidget {
const DisclosureButton({
required this.popoverMutex,
required this.onAction,
Key? key,
}) : super(key: key);
super.key,
});
@override
State<DisclosureButton> createState() => _DisclosureButtonState();

View File

@ -17,8 +17,8 @@ class FilterMenu extends StatelessWidget {
final FieldController fieldController;
const FilterMenu({
required this.fieldController,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {
@ -63,7 +63,7 @@ class FilterMenu extends StatelessWidget {
class AddFilterButton extends StatefulWidget {
final String viewId;
const AddFilterButton({required this.viewId, Key? key}) : super(key: key);
const AddFilterButton({required this.viewId, super.key});
@override
State<AddFilterButton> createState() => _AddFilterButtonState();

View File

@ -12,7 +12,7 @@ import 'filter_info.dart';
class FilterMenuItem extends StatelessWidget {
final FilterInfo filterInfo;
const FilterMenuItem({required this.filterInfo, Key? key}) : super(key: key);
const FilterMenuItem({required this.filterInfo, super.key});
@override
Widget build(BuildContext context) {

View File

@ -2,12 +2,11 @@ import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/plugins/database_view/application/field/field_cell_bloc.dart';
import 'package:appflowy/plugins/database_view/application/field/field_controller.dart';
import 'package:appflowy/plugins/database_view/application/field/field_info.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:flowy_infra/theme_extension.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@ -58,7 +57,7 @@ class _GridFieldCellState extends State<GridFieldCell> {
}
@override
didUpdateWidget(covariant oldWidget) {
void didUpdateWidget(covariant oldWidget) {
if (widget.fieldInfo != oldWidget.fieldInfo && !_bloc.isClosed) {
_bloc.add(FieldCellEvent.onFieldChanged(widget.fieldInfo));
}
@ -132,8 +131,7 @@ class _GridHeaderCellContainer extends StatelessWidget {
const _GridHeaderCellContainer({
required this.child,
required this.width,
Key? key,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {
@ -157,9 +155,7 @@ class _GridHeaderCellContainer extends StatelessWidget {
}
class _DragToExpandLine extends StatelessWidget {
const _DragToExpandLine({
Key? key,
}) : super(key: key);
const _DragToExpandLine();
@override
Widget build(BuildContext context) {
@ -208,8 +204,8 @@ class FieldCellButton extends StatelessWidget {
this.maxLines = 1,
this.radius = BorderRadius.zero,
this.margin,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {

View File

@ -11,8 +11,7 @@ typedef SelectFieldCallback = void Function(FieldType);
class FieldTypeList extends StatelessWidget with FlowyOverlayDelegate {
final SelectFieldCallback onSelectField;
const FieldTypeList({required this.onSelectField, Key? key})
: super(key: key);
const FieldTypeList({required this.onSelectField, super.key});
@override
Widget build(BuildContext context) {
@ -50,8 +49,8 @@ class FieldTypeCell extends StatelessWidget {
const FieldTypeCell({
required this.fieldType,
required this.onSelectField,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {

View File

@ -74,7 +74,7 @@ class _GridHeaderState extends State<_GridHeader> {
/// [ReorderableRow] warps the child's key with a [GlobalKey].
/// It will trigger the child's widget's to recreate.
/// The state will lose.
_getKeyById(String id) {
ValueKey<String>? _getKeyById(String id) {
if (_gridMap.containsKey(id)) {
return _gridMap[id];
}

View File

@ -37,8 +37,8 @@ class DateTypeOptionWidget extends TypeOptionWidget {
const DateTypeOptionWidget({
required this.typeOptionContext,
required this.popoverMutex,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {
@ -136,8 +136,8 @@ class DateFormatButton extends StatelessWidget {
const DateFormatButton({
this.onTap,
this.onHover,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {
@ -161,8 +161,8 @@ class TimeFormatButton extends StatelessWidget {
required this.timeFormat,
this.onTap,
this.onHover,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {
@ -184,8 +184,8 @@ class DateFormatList extends StatelessWidget {
const DateFormatList({
required this.selectedFormat,
required this.onSelected,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {
@ -222,8 +222,8 @@ class DateFormatCell extends StatelessWidget {
required this.dateFormat,
required this.onSelected,
required this.isSelected,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {
@ -268,8 +268,8 @@ class TimeFormatList extends StatelessWidget {
const TimeFormatList({
required this.selectedFormat,
required this.onSelected,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {
@ -306,8 +306,8 @@ class TimeFormatCell extends StatelessWidget {
required this.timeFormat,
required this.onSelected,
required this.isSelected,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {

View File

@ -122,8 +122,8 @@ class NumberFormatList extends StatelessWidget {
const NumberFormatList({
required this.selectedFormat,
required this.onSelected,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {
@ -178,8 +178,8 @@ class NumberFormatCell extends StatelessWidget {
required this.isSelected,
required this.format,
required this.onSelected,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {
@ -200,7 +200,7 @@ class NumberFormatCell extends StatelessWidget {
}
class _FilterTextField extends StatelessWidget {
const _FilterTextField({Key? key}) : super(key: key);
const _FilterTextField();
@override
Widget build(BuildContext context) {
return Padding(

View File

@ -86,7 +86,7 @@ class _OptionTitle extends StatelessWidget {
class _OptionList extends StatelessWidget {
final PopoverMutex? popoverMutex;
const _OptionList({Key? key, this.popoverMutex}) : super(key: key);
const _OptionList({this.popoverMutex});
@override
Widget build(BuildContext context) {
@ -120,8 +120,7 @@ class _OptionList extends StatelessWidget {
class _OptionCell extends StatefulWidget {
final SelectOptionPB option;
final PopoverMutex? popoverMutex;
const _OptionCell({required this.option, Key? key, this.popoverMutex})
: super(key: key);
const _OptionCell({required this.option, this.popoverMutex});
@override
State<_OptionCell> createState() => _OptionCellState();
@ -190,7 +189,7 @@ class _OptionCellState extends State<_OptionCell> {
}
class _AddOptionButton extends StatelessWidget {
const _AddOptionButton({Key? key}) : super(key: key);
const _AddOptionButton();
@override
Widget build(BuildContext context) {

View File

@ -29,8 +29,8 @@ class SelectOptionTypeOptionEditor extends StatelessWidget {
required this.onUpdated,
this.showOptions = true,
this.autoFocus = true,
Key? key,
}) : super(key: key);
super.key,
});
static String get identifier => (SelectOptionTypeOptionEditor).toString();
@ -98,7 +98,7 @@ class SelectOptionTypeOptionEditor extends StatelessWidget {
}
class _DeleteTag extends StatelessWidget {
const _DeleteTag({Key? key}) : super(key: key);
const _DeleteTag();
@override
Widget build(BuildContext context) {
@ -125,8 +125,7 @@ class _OptionNameTextField extends StatelessWidget {
const _OptionNameTextField({
required this.name,
required this.autoFocus,
Key? key,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {
@ -201,8 +200,7 @@ class _SelectOptionColorCell extends StatelessWidget {
required this.color,
required this.isSelected,
required this.onSelectedColor,
Key? key,
}) : super(key: key);
});
final SelectOptionColorPB color;
final bool isSelected;

View File

@ -40,8 +40,8 @@ class TimestampTypeOptionWidget extends TypeOptionWidget {
const TimestampTypeOptionWidget({
required this.typeOptionContext,
required this.popoverMutex,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {

View File

@ -78,7 +78,7 @@ class MobileGridFab extends StatelessWidget {
@override
Widget build(BuildContext context) {
final radius = BorderRadius.circular(20);
return Container(
return DecoratedBox(
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: radius,

View File

@ -20,8 +20,8 @@ class RowActions extends StatelessWidget {
required this.viewId,
required this.rowId,
this.groupId,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {

View File

@ -172,7 +172,7 @@ class _RowLeadingState extends State<_RowLeading> {
}
class InsertRowButton extends StatelessWidget {
const InsertRowButton({Key? key}) : super(key: key);
const InsertRowButton({super.key});
@override
Widget build(BuildContext context) {
@ -238,8 +238,8 @@ class RowContent extends StatelessWidget {
const RowContent({
required this.builder,
required this.onExpand,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {
@ -329,7 +329,7 @@ class RegionStateNotifier extends ChangeNotifier {
class _RowEnterRegion extends StatefulWidget {
final Widget child;
const _RowEnterRegion({required this.child, Key? key}) : super(key: key);
const _RowEnterRegion({required this.child, super.key});
@override
State<_RowEnterRegion> createState() => _RowEnterRegionState();

View File

@ -3,7 +3,7 @@ import 'package:flutter/services.dart';
class GridShortcuts extends StatelessWidget {
final Widget child;
const GridShortcuts({required this.child, Key? key}) : super(key: key);
const GridShortcuts({required this.child, super.key});
@override
Widget build(BuildContext context) {

View File

@ -27,8 +27,8 @@ class GridCreateSortList extends StatefulWidget {
required this.fieldController,
required this.onClosed,
this.onCreateSort,
Key? key,
}) : super(key: key);
super.key,
});
@override
State<StatefulWidget> createState() => _GridCreateSortListState();
@ -155,8 +155,8 @@ class GridSortPropertyCell extends StatelessWidget {
const GridSortPropertyCell({
required this.fieldInfo,
required this.onTap,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {

View File

@ -7,7 +7,7 @@ import 'package:flutter/material.dart';
class OrderPanel extends StatelessWidget {
final Function(SortConditionPB) onCondition;
const OrderPanel({required this.onCondition, Key? key}) : super(key: key);
const OrderPanel({required this.onCondition, super.key});
@override
Widget build(BuildContext context) {

View File

@ -18,8 +18,8 @@ class SortChoiceButton extends StatelessWidget {
this.leftIcon,
this.rightIcon,
this.editable = true,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {

View File

@ -12,7 +12,7 @@ import '../../layout/sizes.dart';
import '../filter/create_filter_list.dart';
class FilterButton extends StatefulWidget {
const FilterButton({Key? key}) : super(key: key);
const FilterButton({super.key});
@override
State<FilterButton> createState() => _FilterButtonState();

View File

@ -12,7 +12,7 @@ import 'package:appflowy/plugins/database_view/grid/presentation/layout/sizes.da
import '../sort/create_sort_list.dart';
class SortButton extends StatefulWidget {
const SortButton({Key? key}) : super(key: key);
const SortButton({super.key});
@override
State<SortButton> createState() => _SortButtonState();

View File

@ -48,8 +48,7 @@ class _DatabaseViewSettingContent extends StatelessWidget {
final FieldController fieldController;
const _DatabaseViewSettingContent({
required this.fieldController,
Key? key,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {

View File

@ -312,8 +312,7 @@ class _CardEditOption extends StatelessWidget with CardAccessory {
final EditableRowNotifier rowNotifier;
const _CardEditOption({
required this.rowNotifier,
Key? key,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {

View File

@ -64,7 +64,7 @@ class RowCardRenderHook<CustomCardData> {
CellRenderHook<dynamic, CustomCardData> _typeSafeHook<C>(
CellRenderHook<C, CustomCardData?> hook,
) {
hookFn(cellData, cardData, buildContext) {
Widget? hookFn(cellData, cardData, buildContext) {
if (cellData == null) {
return null;
}

View File

@ -13,8 +13,8 @@ class CheckboxCardCell extends CardCell {
const CheckboxCardCell({
required this.cellControllerBuilder,
Key? key,
}) : super(key: key);
super.key,
});
@override
State<CheckboxCardCell> createState() => _CheckboxCellState();

View File

@ -9,8 +9,7 @@ import 'card_cell.dart';
class ChecklistCardCell extends CardCell {
final CellControllerBuilder cellControllerBuilder;
const ChecklistCardCell({required this.cellControllerBuilder, Key? key})
: super(key: key);
const ChecklistCardCell({required this.cellControllerBuilder, super.key});
@override
State<ChecklistCardCell> createState() => _ChecklistCellState();

View File

@ -14,8 +14,8 @@ class DateCardCell<CustomCardData> extends CardCell {
const DateCardCell({
required this.cellControllerBuilder,
this.renderHook,
Key? key,
}) : super(key: key);
super.key,
});
@override
State<DateCardCell> createState() => _DateCellState();

View File

@ -20,11 +20,11 @@ class NumberCardCell<CustomCardData>
const NumberCardCell({
required this.cellControllerBuilder,
CustomCardData? cardData,
NumberCardCellStyle? style,
super.cardData,
super.style,
this.renderHook,
Key? key,
}) : super(key: key, style: style, cardData: cardData);
super.key,
});
@override
State<NumberCardCell> createState() => _NumberCellState();

View File

@ -21,11 +21,11 @@ class SelectOptionCardCell<CustomCardData>
SelectOptionCardCell({
required this.cellControllerBuilder,
required CustomCardData? cardData,
required super.cardData,
this.renderHook,
this.editableNotifier,
Key? key,
}) : super(key: key, cardData: cardData);
super.key,
});
@override
State<SelectOptionCardCell> createState() => _SelectOptionCellState();

View File

@ -14,8 +14,8 @@ class TimestampCardCell<CustomCardData> extends CardCell {
const TimestampCardCell({
required this.cellControllerBuilder,
this.renderHook,
Key? key,
}) : super(key: key);
super.key,
});
@override
State<TimestampCardCell> createState() => _TimestampCellState();

View File

@ -18,9 +18,9 @@ class URLCardCell<CustomCardData>
const URLCardCell({
required this.cellControllerBuilder,
URLCardCellStyle? style,
Key? key,
}) : super(key: key, style: style);
super.style,
super.key,
});
@override
State<URLCardCell> createState() => _URLCellState();

View File

@ -21,8 +21,8 @@ class CardAccessoryContainer extends StatelessWidget {
const CardAccessoryContainer({
required this.accessories,
required this.onTapAccessory,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {

View File

@ -15,8 +15,8 @@ class RowCardContainer extends StatelessWidget {
required this.openAccessory,
required this.accessories,
this.buildAccessoryWhen,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {
@ -60,8 +60,7 @@ class _CardEnterRegion extends StatelessWidget {
required this.child,
required this.accessories,
required this.onTapAccessory,
Key? key,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {

View File

@ -129,8 +129,8 @@ class _GridGroupCell extends StatelessWidget {
const _GridGroupCell({
required this.fieldInfo,
required this.onSelected,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {

View File

@ -57,8 +57,8 @@ class PrimaryCellAccessory extends StatefulWidget {
const PrimaryCellAccessory({
required this.onTapCallback,
required this.isCellEditing,
Key? key,
}) : super(key: key);
super.key,
});
@override
State<StatefulWidget> createState() => _PrimaryCellAccessoryState();
@ -153,8 +153,7 @@ class _AccessoryHoverState extends State<AccessoryHover> {
class CellAccessoryContainer extends StatelessWidget {
final List<GridCellAccessoryBuilder> accessories;
const CellAccessoryContainer({required this.accessories, Key? key})
: super(key: key);
const CellAccessoryContainer({required this.accessories, super.key});
@override
Widget build(BuildContext context) {

View File

@ -12,14 +12,14 @@ enum CellKeyboardKey {
}
abstract class CellShortcuts extends Widget {
const CellShortcuts({Key? key}) : super(key: key);
const CellShortcuts({super.key});
Map<CellKeyboardKey, CellKeyboardAction> get shortcutHandlers;
}
class GridCellShortcuts extends StatelessWidget {
final CellShortcuts child;
const GridCellShortcuts({required this.child, Key? key}) : super(key: key);
const GridCellShortcuts({required this.child, super.key});
@override
Widget build(BuildContext context) {

View File

@ -273,7 +273,7 @@ class MobileRowDetailPageCellBuilder {
}
class BlankCell extends StatelessWidget {
const BlankCell({Key? key}) : super(key: key);
const BlankCell({super.key});
@override
Widget build(BuildContext context) {
@ -294,7 +294,7 @@ typedef AccessoryBuilder = List<GridCellAccessoryBuilder> Function(
);
abstract class CellAccessory extends Widget {
const CellAccessory({Key? key}) : super(key: key);
const CellAccessory({super.key});
// The hover will show if the isHover's value is true
ValueNotifier<bool>? get onAccessoryHover;

View File

@ -15,12 +15,12 @@ class CellContainer extends StatelessWidget {
final bool isPrimary;
const CellContainer({
Key? key,
super.key,
required this.child,
required this.width,
required this.isPrimary,
this.accessoryBuilder,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {
@ -87,8 +87,7 @@ class _GridCellEnterRegion extends StatelessWidget {
required this.child,
required this.accessories,
required this.isPrimary,
Key? key,
}) : super(key: key);
});
final Widget child;
final List<GridCellAccessoryBuilder> accessories;

View File

@ -23,8 +23,8 @@ class GridCheckboxCell extends GridCellWidget {
GridCheckboxCell({
required this.cellControllerBuilder,
GridCellStyle? style,
Key? key,
}) : super(key: key) {
super.key,
}) {
if (style != null) {
cellStyle = (style as GridCheckboxCellStyle);
} else {

View File

@ -28,10 +28,10 @@ class DateCellEditor extends StatefulWidget {
final DateCellController cellController;
const DateCellEditor({
Key? key,
super.key,
required this.onDismissed,
required this.cellController,
}) : super(key: key);
});
@override
State<StatefulWidget> createState() => _DateCellEditor();
@ -303,7 +303,7 @@ class _DatePickerState extends State<DatePicker> {
}
class _IncludeTimeButton extends StatelessWidget {
const _IncludeTimeButton({Key? key}) : super(key: key);
const _IncludeTimeButton();
@override
Widget build(BuildContext context) {
@ -476,8 +476,8 @@ class DateTypeOptionButton extends StatelessWidget {
final PopoverMutex popoverMutex;
const DateTypeOptionButton({
required this.popoverMutex,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {
@ -524,8 +524,7 @@ class _CalDateTimeSetting extends StatefulWidget {
const _CalDateTimeSetting({
required this.dateTypeOptionPB,
required this.onEvent,
Key? key,
}) : super(key: key);
});
@override
State<_CalDateTimeSetting> createState() => _CalDateTimeSettingState();
@ -594,7 +593,7 @@ class _CalDateTimeSettingState extends State<_CalDateTimeSetting> {
@visibleForTesting
class ClearDateButton extends StatelessWidget {
const ClearDateButton({Key? key}) : super(key: key);
const ClearDateButton({super.key});
@override
Widget build(BuildContext context) {

View File

@ -99,8 +99,7 @@ class _GridCellEnterRegion extends StatelessWidget {
required this.child,
required this.accessories,
required this.isPrimary,
Key? key,
}) : super(key: key);
});
final Widget child;
final List<GridCellAccessoryBuilder> accessories;

View File

@ -37,8 +37,8 @@ class GridTextCell extends GridCellWidget {
GridTextCell({
required this.cellControllerBuilder,
GridCellStyle? style,
Key? key,
}) : super(key: key) {
super.key,
}) {
if (style != null) {
cellStyle = (style as GridTextCellStyle);
} else {

View File

@ -11,8 +11,8 @@ class URLCellEditor extends StatefulWidget {
const URLCellEditor({
required this.cellController,
required this.onExit,
Key? key,
}) : super(key: key);
super.key,
});
@override
State<URLCellEditor> createState() => _URLCellEditorState();
@ -85,8 +85,8 @@ class URLEditorPopover extends StatelessWidget {
const URLEditorPopover({
required this.cellController,
required this.onExit,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {

View File

@ -137,8 +137,7 @@ class _BannerTitle extends StatefulWidget {
required this.cellBuilder,
required this.popoverController,
required this.rowController,
Key? key,
}) : super(key: key);
});
@override
State<_BannerTitle> createState() => _BannerTitleState();

View File

@ -77,7 +77,7 @@ class _RowEditorState extends State<RowEditor> {
}
@override
dispose() {
void dispose() {
documentBloc.close();
super.dispose();
}

View File

@ -12,8 +12,8 @@ class DocumentBanner extends StatelessWidget {
const DocumentBanner({
required this.onRestore,
required this.onDelete,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {

View File

@ -34,7 +34,7 @@ final List<CommandShortcutEvent> commandShortcutEvents = [
];
final List<CommandShortcutEvent> defaultCommandShortcutEvents = [
...commandShortcutEvents.map((e) => e.copyWith()).toList(),
...commandShortcutEvents.map((e) => e.copyWith()),
];
/// Wrapper for the appflowy editor.
@ -299,6 +299,9 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
onPaste: () => pasteCommand.execute(editorState),
onSelectAll: () => selectAllCommand.execute(editorState),
onLiveTextInput: null,
onLookUp: null,
onSearchWeb: null,
onShare: null,
anchors: TextSelectionToolbarAnchors(
primaryAnchor: anchor,
),

View File

@ -11,12 +11,12 @@ import 'package:flutter/services.dart';
class BlockAddButton extends StatelessWidget {
const BlockAddButton({
Key? key,
super.key,
required this.blockComponentContext,
required this.blockComponentState,
required this.editorState,
required this.showSlashMenu,
}) : super(key: key);
});
final BlockComponentContext blockComponentContext;
final BlockComponentActionState blockComponentState;

View File

@ -12,12 +12,12 @@ import 'package:flutter_bloc/flutter_bloc.dart';
class BlockOptionButton extends StatelessWidget {
const BlockOptionButton({
Key? key,
super.key,
required this.blockComponentContext,
required this.blockComponentState,
required this.actions,
required this.editorState,
}) : super(key: key);
});
final BlockComponentContext blockComponentContext;
final BlockComponentActionState blockComponentState;

View File

@ -8,12 +8,12 @@ import 'package:flutter/material.dart';
class OptionActionList extends StatelessWidget {
const OptionActionList({
Key? key,
super.key,
required this.blockComponentContext,
required this.blockComponentState,
required this.actions,
required this.editorState,
}) : super(key: key);
});
final BlockComponentContext blockComponentContext;
final BlockComponentActionState blockComponentState;

View File

@ -21,11 +21,11 @@ import 'package:flowy_infra_ui/style_widget/icon_button.dart';
class BuiltInPageWidget extends StatefulWidget {
const BuiltInPageWidget({
Key? key,
super.key,
required this.node,
required this.editorState,
required this.builder,
}) : super(key: key);
});
final Node node;
final EditorState editorState;

View File

@ -400,9 +400,9 @@ class _CoverColorPickerState extends State<CoverColorPicker> {
class DeleteImageAlertDialog extends StatelessWidget {
const DeleteImageAlertDialog({
Key? key,
super.key,
required this.onSubmit,
}) : super(key: key);
});
final Function() onSubmit;
@ -452,11 +452,11 @@ class DeleteImageAlertDialog extends StatelessWidget {
class ImageGridItem extends StatefulWidget {
const ImageGridItem({
Key? key,
super.key,
required this.onImageSelect,
required this.onImageDelete,
required this.imagePath,
}) : super(key: key);
});
final Function() onImageSelect;
final Function() onImageDelete;

View File

@ -200,7 +200,7 @@ class CoverImagePreviewWidget extends StatefulWidget {
}
class _CoverImagePreviewWidgetState extends State<CoverImagePreviewWidget> {
_buildFilePickerWidget(BuildContext ctx) {
DecoratedBox _buildFilePickerWidget(BuildContext ctx) {
return DecoratedBox(
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
@ -255,7 +255,7 @@ class _CoverImagePreviewWidgetState extends State<CoverImagePreviewWidget> {
);
}
_buildImageDeleteButton(BuildContext ctx) {
Positioned _buildImageDeleteButton(BuildContext ctx) {
return Positioned(
right: 10,
top: 10,

View File

@ -81,7 +81,7 @@ class CoverImagePickerBloc
);
}
_saveToGallery(CoverImagePickerState state) async {
Future<List<String>?>? _saveToGallery(CoverImagePickerState state) async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
final List<String> imagePaths = prefs.getStringList(kLocalImagesKey) ?? [];
final directory = await _coverPath();

View File

@ -3,14 +3,14 @@ import 'package:flutter_svg/flutter_svg.dart';
class Svg extends StatelessWidget {
const Svg({
Key? key,
super.key,
this.name,
this.width,
this.height,
this.color,
this.number,
this.padding,
}) : super(key: key);
});
final String? name;
final double? width;

View File

@ -10,8 +10,8 @@ import 'package:flutter_bloc/flutter_bloc.dart';
class DocumentMoreButton extends StatelessWidget {
const DocumentMoreButton({
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {

View File

@ -14,7 +14,7 @@ import 'package:flutter/material.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
class MenuTrash extends StatelessWidget {
const MenuTrash({Key? key}) : super(key: key);
const MenuTrash({super.key});
@override
Widget build(BuildContext context) {

View File

@ -17,8 +17,8 @@ class TrashCell extends StatelessWidget {
required this.object,
required this.onRestore,
required this.onDelete,
Key? key,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context) {

Some files were not shown because too many files have changed in this diff Show More