refactor: use same bloc in grid and cards (#3511)

This commit is contained in:
Richard Shiue 2023-09-24 20:24:38 +08:00 committed by GitHub
parent 847290d9a4
commit 375ff5ed6d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 91 additions and 721 deletions

View File

@ -1,12 +1,12 @@
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/plugins/database_view/application/row/row_cache.dart';
import 'package:appflowy/plugins/database_view/widgets/card/bloc/text_card_cell_bloc.dart';
import 'package:appflowy/plugins/database_view/widgets/card/card.dart';
import 'package:appflowy/plugins/database_view/widgets/card/card_cell_builder.dart';
import 'package:appflowy/plugins/database_view/widgets/card/cells/card_cell.dart';
import 'package:appflowy/plugins/database_view/widgets/card/cells/number_card_cell.dart';
import 'package:appflowy/plugins/database_view/widgets/card/cells/url_card_cell.dart';
import 'package:appflowy/plugins/database_view/widgets/row/cells/select_option_cell/extension.dart';
import 'package:appflowy/plugins/database_view/widgets/row/cells/text_cell/text_cell_bloc.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
@ -179,13 +179,10 @@ class _EventCardState extends State<EventCard> {
) {
final renderHook = RowCardRenderHook<CalendarDayEvent>();
renderHook.addTextCellHook((cellData, eventData, _) {
return BlocBuilder<TextCardCellBloc, TextCardCellState>(
return BlocBuilder<TextCellBloc, TextCellState>(
builder: (context, state) {
final isTitle = context
.read<TextCardCellBloc>()
.cellController
.fieldInfo
.isPrimary;
final isTitle =
context.read<TextCellBloc>().cellController.fieldInfo.isPrimary;
final text = isTitle && cellData.isEmpty
? LocaleKeys.grid_row_titlePlaceholder.tr()
: cellData;

View File

@ -1,77 +0,0 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async';
import '../../../application/cell/cell_controller_builder.dart';
part 'checkbox_card_cell_bloc.freezed.dart';
class CheckboxCardCellBloc
extends Bloc<CheckboxCardCellEvent, CheckboxCardCellState> {
final CheckboxCellController cellController;
void Function()? _onCellChangedFn;
CheckboxCardCellBloc({
required this.cellController,
}) : super(CheckboxCardCellState.initial(cellController)) {
on<CheckboxCardCellEvent>(
(event, emit) async {
await event.when(
initial: () async {
_startListening();
},
didReceiveCellUpdate: (cellData) {
emit(state.copyWith(isSelected: _isSelected(cellData)));
},
select: () async {
cellController.saveCellData(!state.isSelected ? "Yes" : "No");
},
);
},
);
}
@override
Future<void> close() async {
if (_onCellChangedFn != null) {
cellController.removeListener(_onCellChangedFn!);
_onCellChangedFn = null;
}
await cellController.dispose();
return super.close();
}
void _startListening() {
_onCellChangedFn = cellController.startListening(
onCellChanged: ((cellContent) {
if (!isClosed) {
add(CheckboxCardCellEvent.didReceiveCellUpdate(cellContent ?? ""));
}
}),
);
}
}
@freezed
class CheckboxCardCellEvent with _$CheckboxCardCellEvent {
const factory CheckboxCardCellEvent.initial() = _InitialCell;
const factory CheckboxCardCellEvent.select() = _Selected;
const factory CheckboxCardCellEvent.didReceiveCellUpdate(String cellContent) =
_DidReceiveCellUpdate;
}
@freezed
class CheckboxCardCellState with _$CheckboxCardCellState {
const factory CheckboxCardCellState({
required bool isSelected,
}) = _CheckboxCellState;
factory CheckboxCardCellState.initial(TextCellController context) {
return CheckboxCardCellState(
isSelected: _isSelected(context.getCellData()),
);
}
}
bool _isSelected(String? cellData) {
// The backend use "Yes" and "No" to represent the checkbox cell data.
return cellData == "Yes";
}

View File

@ -1,99 +0,0 @@
import 'package:appflowy/plugins/database_view/application/field/field_info.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/date_entities.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async';
import '../../../application/cell/cell_controller_builder.dart';
part 'date_card_cell_bloc.freezed.dart';
class DateCardCellBloc extends Bloc<DateCardCellEvent, DateCardCellState> {
final DateCellController cellController;
void Function()? _onCellChangedFn;
DateCardCellBloc({required this.cellController})
: super(DateCardCellState.initial(cellController)) {
on<DateCardCellEvent>(
(event, emit) async {
event.when(
initial: () => _startListening(),
didReceiveCellUpdate: (DateCellDataPB? cellData) {
emit(
state.copyWith(
data: cellData,
dateStr: _dateStrFromCellData(cellData),
),
);
},
);
},
);
}
@override
Future<void> close() async {
if (_onCellChangedFn != null) {
cellController.removeListener(_onCellChangedFn!);
_onCellChangedFn = null;
}
await cellController.dispose();
return super.close();
}
void _startListening() {
_onCellChangedFn = cellController.startListening(
onCellChanged: ((data) {
if (!isClosed) {
add(DateCardCellEvent.didReceiveCellUpdate(data));
}
}),
);
}
}
@freezed
class DateCardCellEvent with _$DateCardCellEvent {
const factory DateCardCellEvent.initial() = _InitialCell;
const factory DateCardCellEvent.didReceiveCellUpdate(DateCellDataPB? data) =
_DidReceiveCellUpdate;
}
@freezed
class DateCardCellState with _$DateCardCellState {
const factory DateCardCellState({
required DateCellDataPB? data,
required String dateStr,
required FieldInfo fieldInfo,
}) = _DateCardCellState;
factory DateCardCellState.initial(DateCellController context) {
final cellData = context.getCellData();
return DateCardCellState(
fieldInfo: context.fieldInfo,
data: cellData,
dateStr: _dateStrFromCellData(cellData),
);
}
}
String _dateStrFromCellData(DateCellDataPB? cellData) {
String dateStr = "";
if (cellData != null) {
if (cellData.isRange) {
if (cellData.includeTime) {
dateStr =
"${cellData.date} ${cellData.time}${cellData.endDate} ${cellData.endTime}";
} else {
dateStr = "${cellData.date}${cellData.endDate}";
}
} else {
if (cellData.includeTime) {
dateStr = "${cellData.date} ${cellData.time}";
} else {
dateStr = cellData.date;
}
}
}
return dateStr;
}

View File

@ -1,68 +0,0 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async';
import '../../../application/cell/cell_controller_builder.dart';
part 'number_card_cell_bloc.freezed.dart';
class NumberCardCellBloc
extends Bloc<NumberCardCellEvent, NumberCardCellState> {
final NumberCellController cellController;
void Function()? _onCellChangedFn;
NumberCardCellBloc({
required this.cellController,
}) : super(NumberCardCellState.initial(cellController)) {
on<NumberCardCellEvent>(
(event, emit) async {
await event.when(
initial: () async {
_startListening();
},
didReceiveCellUpdate: (content) {
emit(state.copyWith(content: content));
},
);
},
);
}
@override
Future<void> close() async {
if (_onCellChangedFn != null) {
cellController.removeListener(_onCellChangedFn!);
_onCellChangedFn = null;
}
await cellController.dispose();
return super.close();
}
void _startListening() {
_onCellChangedFn = cellController.startListening(
onCellChanged: ((cellContent) {
if (!isClosed) {
add(NumberCardCellEvent.didReceiveCellUpdate(cellContent ?? ""));
}
}),
);
}
}
@freezed
class NumberCardCellEvent with _$NumberCardCellEvent {
const factory NumberCardCellEvent.initial() = _InitialCell;
const factory NumberCardCellEvent.didReceiveCellUpdate(String cellContent) =
_DidReceiveCellUpdate;
}
@freezed
class NumberCardCellState with _$NumberCardCellState {
const factory NumberCardCellState({
required String content,
}) = _NumberCardCellState;
factory NumberCardCellState.initial(TextCellController context) =>
NumberCardCellState(
content: context.getCellData() ?? "",
);
}

View File

@ -1,78 +0,0 @@
import 'dart:async';
import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/select_option.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'select_option_card_cell_bloc.freezed.dart';
class SelectOptionCardCellBloc
extends Bloc<SelectOptionCardCellEvent, SelectOptionCardCellState> {
final SelectOptionCellController cellController;
void Function()? _onCellChangedFn;
SelectOptionCardCellBloc({
required this.cellController,
}) : super(SelectOptionCardCellState.initial(cellController)) {
on<SelectOptionCardCellEvent>(
(event, emit) async {
await event.when(
initial: () async {
_startListening();
},
didReceiveOptions: (List<SelectOptionPB> selectedOptions) {
emit(state.copyWith(selectedOptions: selectedOptions));
},
);
},
);
}
@override
Future<void> close() async {
if (_onCellChangedFn != null) {
cellController.removeListener(_onCellChangedFn!);
_onCellChangedFn = null;
}
await cellController.dispose();
return super.close();
}
void _startListening() {
_onCellChangedFn = cellController.startListening(
onCellChanged: ((selectOptionContext) {
if (!isClosed) {
add(
SelectOptionCardCellEvent.didReceiveOptions(
selectOptionContext?.selectOptions ?? [],
),
);
}
}),
);
}
}
@freezed
class SelectOptionCardCellEvent with _$SelectOptionCardCellEvent {
const factory SelectOptionCardCellEvent.initial() = _InitialCell;
const factory SelectOptionCardCellEvent.didReceiveOptions(
List<SelectOptionPB> selectedOptions,
) = _DidReceiveOptions;
}
@freezed
class SelectOptionCardCellState with _$SelectOptionCardCellState {
const factory SelectOptionCardCellState({
required List<SelectOptionPB> selectedOptions,
}) = _SelectOptionCardCellState;
factory SelectOptionCardCellState.initial(
SelectOptionCellController context,
) {
final data = context.getCellData();
return SelectOptionCardCellState(
selectedOptions: data?.selectOptions ?? [],
);
}
}

View File

@ -1,79 +0,0 @@
import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async';
part 'text_card_cell_bloc.freezed.dart';
class TextCardCellBloc extends Bloc<TextCardCellEvent, TextCardCellState> {
final TextCellController cellController;
void Function()? _onCellChangedFn;
TextCardCellBloc({
required this.cellController,
}) : super(TextCardCellState.initial(cellController)) {
on<TextCardCellEvent>(
(event, emit) async {
await event.when(
initial: () async {
_startListening();
},
didReceiveCellUpdate: (content) {
emit(state.copyWith(content: content));
},
updateText: (text) {
if (text != state.content) {
cellController.saveCellData(text);
emit(state.copyWith(content: text));
}
},
enableEdit: (bool enabled) {
emit(state.copyWith(enableEdit: enabled));
},
);
},
);
}
@override
Future<void> close() async {
if (_onCellChangedFn != null) {
cellController.removeListener(_onCellChangedFn!);
_onCellChangedFn = null;
}
await cellController.dispose();
return super.close();
}
void _startListening() {
_onCellChangedFn = cellController.startListening(
onCellChanged: ((cellContent) {
if (!isClosed) {
add(TextCardCellEvent.didReceiveCellUpdate(cellContent ?? ""));
}
}),
);
}
}
@freezed
class TextCardCellEvent with _$TextCardCellEvent {
const factory TextCardCellEvent.initial() = _InitialCell;
const factory TextCardCellEvent.updateText(String text) = _UpdateContent;
const factory TextCardCellEvent.enableEdit(bool enabled) = _EnableEdit;
const factory TextCardCellEvent.didReceiveCellUpdate(String cellContent) =
_DidReceiveCellUpdate;
}
@freezed
class TextCardCellState with _$TextCardCellState {
const factory TextCardCellState({
required String content,
required bool enableEdit,
}) = _TextCardCellState;
factory TextCardCellState.initial(TextCellController context) =>
TextCardCellState(
content: context.getCellData() ?? "",
enableEdit: false,
);
}

View File

@ -1,80 +0,0 @@
import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart';
import 'package:appflowy/plugins/database_view/application/field/field_info.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/timestamp_entities.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async';
part 'timestamp_card_cell_bloc.freezed.dart';
class TimestampCardCellBloc
extends Bloc<TimestampCardCellEvent, TimestampCardCellState> {
final TimestampCellController cellController;
void Function()? _onCellChangedFn;
TimestampCardCellBloc({required this.cellController})
: super(TimestampCardCellState.initial(cellController)) {
on<TimestampCardCellEvent>(
(event, emit) async {
event.when(
initial: () => _startListening(),
didReceiveCellUpdate: (TimestampCellDataPB? cellData) {
emit(
state.copyWith(
data: cellData,
dateStr: cellData?.dateTime ?? "",
),
);
},
);
},
);
}
@override
Future<void> close() async {
if (_onCellChangedFn != null) {
cellController.removeListener(_onCellChangedFn!);
_onCellChangedFn = null;
}
await cellController.dispose();
return super.close();
}
void _startListening() {
_onCellChangedFn = cellController.startListening(
onCellChanged: ((data) {
if (!isClosed) {
add(TimestampCardCellEvent.didReceiveCellUpdate(data));
}
}),
);
}
}
@freezed
class TimestampCardCellEvent with _$TimestampCardCellEvent {
const factory TimestampCardCellEvent.initial() = _InitialCell;
const factory TimestampCardCellEvent.didReceiveCellUpdate(
TimestampCellDataPB? data,
) = _DidReceiveCellUpdate;
}
@freezed
class TimestampCardCellState with _$TimestampCardCellState {
const factory TimestampCardCellState({
required TimestampCellDataPB? data,
required String dateStr,
required FieldInfo fieldInfo,
}) = _TimestampCardCellState;
factory TimestampCardCellState.initial(TimestampCellController context) {
final cellData = context.getCellData();
return TimestampCardCellState(
fieldInfo: context.fieldInfo,
data: cellData,
dateStr: cellData?.dateTime ?? "",
);
}
}

View File

@ -1,80 +0,0 @@
import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/url_entities.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async';
part 'url_card_cell_bloc.freezed.dart';
class URLCardCellBloc extends Bloc<URLCardCellEvent, URLCardCellState> {
final URLCellController cellController;
void Function()? _onCellChangedFn;
URLCardCellBloc({
required this.cellController,
}) : super(URLCardCellState.initial(cellController)) {
on<URLCardCellEvent>(
(event, emit) async {
event.when(
initial: () {
_startListening();
},
didReceiveCellUpdate: (cellData) {
emit(
state.copyWith(
content: cellData?.content ?? "",
url: cellData?.url ?? "",
),
);
},
updateURL: (String url) {
cellController.saveCellData(url, deduplicate: true);
},
);
},
);
}
@override
Future<void> close() async {
if (_onCellChangedFn != null) {
cellController.removeListener(_onCellChangedFn!);
_onCellChangedFn = null;
}
await cellController.dispose();
return super.close();
}
void _startListening() {
_onCellChangedFn = cellController.startListening(
onCellChanged: ((cellData) {
if (!isClosed) {
add(URLCardCellEvent.didReceiveCellUpdate(cellData));
}
}),
);
}
}
@freezed
class URLCardCellEvent with _$URLCardCellEvent {
const factory URLCardCellEvent.initial() = _InitialCell;
const factory URLCardCellEvent.updateURL(String url) = _UpdateURL;
const factory URLCardCellEvent.didReceiveCellUpdate(URLCellDataPB? cell) =
_DidReceiveCellUpdate;
}
@freezed
class URLCardCellState with _$URLCardCellState {
const factory URLCardCellState({
required String content,
required String url,
}) = _URLCardCellState;
factory URLCardCellState.initial(URLCellController context) {
final cellData = context.getCellData();
return URLCardCellState(
content: cellData?.content ?? "",
url: cellData?.url ?? "",
);
}
}

View File

@ -1,68 +0,0 @@
import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'bloc/number_card_cell_bloc.dart';
import 'define.dart';
class BoardNumberCell extends StatefulWidget {
final String groupId;
final CellControllerBuilder cellControllerBuilder;
const BoardNumberCell({
required this.groupId,
required this.cellControllerBuilder,
Key? key,
}) : super(key: key);
@override
State<BoardNumberCell> createState() => _NumberCardCellState();
}
class _NumberCardCellState extends State<BoardNumberCell> {
late NumberCardCellBloc _cellBloc;
@override
void initState() {
final cellController =
widget.cellControllerBuilder.build() as NumberCellController;
_cellBloc = NumberCardCellBloc(cellController: cellController)
..add(const NumberCardCellEvent.initial());
super.initState();
}
@override
Widget build(BuildContext context) {
return BlocProvider.value(
value: _cellBloc,
child: BlocBuilder<NumberCardCellBloc, NumberCardCellState>(
buildWhen: (previous, current) => previous.content != current.content,
builder: (context, state) {
if (state.content.isEmpty) {
return const SizedBox();
} else {
return Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: EdgeInsets.symmetric(
vertical: CardSizes.cardCellVPadding,
),
child: FlowyText.medium(
state.content,
fontSize: 14,
),
),
);
}
},
),
);
}
@override
Future<void> dispose() async {
_cellBloc.close();
super.dispose();
}
}

View File

@ -1,11 +1,10 @@
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart';
import 'package:appflowy/plugins/database_view/widgets/row/cells/checkbox_cell/checkbox_cell_bloc.dart';
import 'package:flowy_infra_ui/style_widget/icon_button.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../bloc/checkbox_card_cell_bloc.dart';
import 'card_cell.dart';
class CheckboxCardCell extends CardCell {
@ -17,18 +16,18 @@ class CheckboxCardCell extends CardCell {
}) : super(key: key);
@override
State<CheckboxCardCell> createState() => _CheckboxCardCellState();
State<CheckboxCardCell> createState() => _CheckboxCellState();
}
class _CheckboxCardCellState extends State<CheckboxCardCell> {
late CheckboxCardCellBloc _cellBloc;
class _CheckboxCellState extends State<CheckboxCardCell> {
late CheckboxCellBloc _cellBloc;
@override
void initState() {
final cellController =
widget.cellControllerBuilder.build() as CheckboxCellController;
_cellBloc = CheckboxCardCellBloc(cellController: cellController);
_cellBloc.add(const CheckboxCardCellEvent.initial());
_cellBloc = CheckboxCellBloc(cellController: cellController);
_cellBloc.add(const CheckboxCellEvent.initial());
super.initState();
}
@ -36,7 +35,7 @@ class _CheckboxCardCellState extends State<CheckboxCardCell> {
Widget build(BuildContext context) {
return BlocProvider.value(
value: _cellBloc,
child: BlocBuilder<CheckboxCardCellBloc, CheckboxCardCellState>(
child: BlocBuilder<CheckboxCellBloc, CheckboxCellState>(
buildWhen: (previous, current) =>
previous.isSelected != current.isSelected,
builder: (context, state) {
@ -55,8 +54,8 @@ class _CheckboxCardCellState extends State<CheckboxCardCell> {
icon: icon,
width: 20,
onPressed: () => context
.read<CheckboxCardCellBloc>()
.add(const CheckboxCardCellEvent.select()),
.read<CheckboxCellBloc>()
.add(const CheckboxCellEvent.select()),
),
),
);

View File

@ -12,17 +12,17 @@ class ChecklistCardCell extends CardCell {
: super(key: key);
@override
State<ChecklistCardCell> createState() => _ChecklistCardCellState();
State<ChecklistCardCell> createState() => _ChecklistCellState();
}
class _ChecklistCardCellState extends State<ChecklistCardCell> {
late ChecklistCardCellBloc _cellBloc;
class _ChecklistCellState extends State<ChecklistCardCell> {
late ChecklistCellBloc _cellBloc;
@override
void initState() {
final cellController =
widget.cellControllerBuilder.build() as ChecklistCellController;
_cellBloc = ChecklistCardCellBloc(cellController: cellController);
_cellBloc = ChecklistCellBloc(cellController: cellController);
_cellBloc.add(const ChecklistCellEvent.initial());
super.initState();
}
@ -31,7 +31,7 @@ class _ChecklistCardCellState extends State<ChecklistCardCell> {
Widget build(BuildContext context) {
return BlocProvider.value(
value: _cellBloc,
child: BlocBuilder<ChecklistCardCellBloc, ChecklistCellState>(
child: BlocBuilder<ChecklistCellBloc, ChecklistCellState>(
builder: (context, state) {
if (state.allOptions.isEmpty) {
return const SizedBox.shrink();

View File

@ -1,9 +1,9 @@
import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart';
import 'package:appflowy/plugins/database_view/widgets/row/cells/date_cell/date_cell_bloc.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../bloc/date_card_cell_bloc.dart';
import '../define.dart';
import 'card_cell.dart';
@ -18,19 +18,19 @@ class DateCardCell<CustomCardData> extends CardCell {
}) : super(key: key);
@override
State<DateCardCell> createState() => _DateCardCellState();
State<DateCardCell> createState() => _DateCellState();
}
class _DateCardCellState extends State<DateCardCell> {
late DateCardCellBloc _cellBloc;
class _DateCellState extends State<DateCardCell> {
late DateCellBloc _cellBloc;
@override
void initState() {
final cellController =
widget.cellControllerBuilder.build() as DateCellController;
_cellBloc = DateCardCellBloc(cellController: cellController)
..add(const DateCardCellEvent.initial());
_cellBloc = DateCellBloc(cellController: cellController)
..add(const DateCellEvent.initial());
super.initState();
}
@ -38,7 +38,7 @@ class _DateCardCellState extends State<DateCardCell> {
Widget build(BuildContext context) {
return BlocProvider.value(
value: _cellBloc,
child: BlocBuilder<DateCardCellBloc, DateCardCellState>(
child: BlocBuilder<DateCellBloc, DateCellState>(
buildWhen: (previous, current) => previous.dateStr != current.dateStr,
builder: (context, state) {
if (state.dateStr.isEmpty) {

View File

@ -1,9 +1,9 @@
import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart';
import 'package:appflowy/plugins/database_view/widgets/row/cells/number_cell/number_cell_bloc.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../bloc/number_card_cell_bloc.dart';
import '../define.dart';
import 'card_cell.dart';
@ -27,19 +27,19 @@ class NumberCardCell<CustomCardData>
}) : super(key: key, style: style, cardData: cardData);
@override
State<NumberCardCell> createState() => _NumberCardCellState();
State<NumberCardCell> createState() => _NumberCellState();
}
class _NumberCardCellState extends State<NumberCardCell> {
late NumberCardCellBloc _cellBloc;
class _NumberCellState extends State<NumberCardCell> {
late NumberCellBloc _cellBloc;
@override
void initState() {
final cellController =
widget.cellControllerBuilder.build() as NumberCellController;
_cellBloc = NumberCardCellBloc(cellController: cellController)
..add(const NumberCardCellEvent.initial());
_cellBloc = NumberCellBloc(cellController: cellController)
..add(const NumberCellEvent.initial());
super.initState();
}
@ -47,14 +47,15 @@ class _NumberCardCellState extends State<NumberCardCell> {
Widget build(BuildContext context) {
return BlocProvider.value(
value: _cellBloc,
child: BlocBuilder<NumberCardCellBloc, NumberCardCellState>(
buildWhen: (previous, current) => previous.content != current.content,
child: BlocBuilder<NumberCellBloc, NumberCellState>(
buildWhen: (previous, current) =>
previous.cellContent != current.cellContent,
builder: (context, state) {
if (state.content.isEmpty) {
if (state.cellContent.isEmpty) {
return const SizedBox();
} else {
final Widget? custom = widget.renderHook?.call(
state.content,
state.cellContent,
widget.cardData,
context,
);
@ -69,7 +70,7 @@ class _NumberCardCellState extends State<NumberCardCell> {
vertical: CardSizes.cardCellVPadding,
),
child: FlowyText.medium(
state.content,
state.cellContent,
fontSize: widget.style?.fontSize ?? 14,
),
),

View File

@ -1,12 +1,13 @@
import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart';
import 'package:appflowy/plugins/database_view/widgets/row/cells/select_option_cell/extension.dart';
import 'package:appflowy/plugins/database_view/widgets/row/cells/select_option_cell/select_option_cell_bloc.dart';
import 'package:appflowy/plugins/database_view/widgets/row/cells/select_option_cell/select_option_editor.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/select_option.pb.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../bloc/select_option_card_cell_bloc.dart';
import 'card_cell.dart';
class SelectOptionCardCellStyle extends CardCellStyle {}
@ -29,11 +30,11 @@ class SelectOptionCardCell<CustomCardData>
}) : super(key: key, cardData: cardData);
@override
State<SelectOptionCardCell> createState() => _SelectOptionCardCellState();
State<SelectOptionCardCell> createState() => _SelectOptionCellState();
}
class _SelectOptionCardCellState extends State<SelectOptionCardCell> {
late SelectOptionCardCellBloc _cellBloc;
class _SelectOptionCellState extends State<SelectOptionCardCell> {
late SelectOptionCellBloc _cellBloc;
late PopoverController _popover;
@override
@ -41,8 +42,8 @@ class _SelectOptionCardCellState extends State<SelectOptionCardCell> {
_popover = PopoverController();
final cellController =
widget.cellControllerBuilder.build() as SelectOptionCellController;
_cellBloc = SelectOptionCardCellBloc(cellController: cellController)
..add(const SelectOptionCardCellEvent.initial());
_cellBloc = SelectOptionCellBloc(cellController: cellController)
..add(const SelectOptionCellEvent.initial());
super.initState();
}
@ -50,7 +51,7 @@ class _SelectOptionCardCellState extends State<SelectOptionCardCell> {
Widget build(BuildContext context) {
return BlocProvider.value(
value: _cellBloc,
child: BlocBuilder<SelectOptionCardCellBloc, SelectOptionCardCellState>(
child: BlocBuilder<SelectOptionCellBloc, SelectOptionCellState>(
buildWhen: (previous, current) {
return previous.selectedOptions != current.selectedOptions;
},

View File

@ -1,9 +1,9 @@
import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart';
import 'package:appflowy/plugins/database_view/widgets/row/cells/text_cell/text_cell_bloc.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../row/cell_builder.dart';
import '../bloc/text_card_cell_bloc.dart';
import '../define.dart';
import 'card_cell.dart';
@ -30,11 +30,11 @@ class TextCardCell<CustomCardData>
}) : super(key: key, style: style, cardData: cardData);
@override
State<TextCardCell> createState() => _TextCardCellState();
State<TextCardCell> createState() => _TextCellState();
}
class _TextCardCellState extends State<TextCardCell> {
late TextCardCellBloc _cellBloc;
class _TextCellState extends State<TextCardCell> {
late TextCellBloc _cellBloc;
late TextEditingController _controller;
bool focusWhenInit = false;
final focusNode = SingleListenerFocusNode();
@ -43,8 +43,8 @@ class _TextCardCellState extends State<TextCardCell> {
void initState() {
final cellController =
widget.cellControllerBuilder.build() as TextCellController;
_cellBloc = TextCardCellBloc(cellController: cellController)
..add(const TextCardCellEvent.initial());
_cellBloc = TextCellBloc(cellController: cellController)
..add(const TextCellEvent.initial());
_controller = TextEditingController(text: _cellBloc.state.content);
focusWhenInit = widget.editableNotifier?.isCellEditing.value ?? false;
if (focusWhenInit) {
@ -58,7 +58,7 @@ class _TextCardCellState extends State<TextCardCell> {
if (!focusNode.hasFocus) {
focusWhenInit = false;
widget.editableNotifier?.isCellEditing.value = false;
_cellBloc.add(const TextCardCellEvent.enableEdit(false));
_cellBloc.add(const TextCellEvent.enableEdit(false));
}
});
_bindEditableNotifier();
@ -75,7 +75,7 @@ class _TextCardCellState extends State<TextCardCell> {
focusNode.requestFocus();
});
}
_cellBloc.add(TextCardCellEvent.enableEdit(isEditing));
_cellBloc.add(TextCellEvent.enableEdit(isEditing));
});
}
@ -89,13 +89,13 @@ class _TextCardCellState extends State<TextCardCell> {
Widget build(BuildContext context) {
return BlocProvider.value(
value: _cellBloc,
child: BlocListener<TextCardCellBloc, TextCardCellState>(
child: BlocListener<TextCellBloc, TextCellState>(
listener: (context, state) {
if (_controller.text != state.content) {
_controller.text = state.content;
}
},
child: BlocBuilder<TextCardCellBloc, TextCardCellState>(
child: BlocBuilder<TextCellBloc, TextCellState>(
buildWhen: (previous, current) {
if (previous.content != current.content &&
_controller.text == current.content &&
@ -137,7 +137,7 @@ class _TextCardCellState extends State<TextCardCell> {
}
Future<void> focusChanged() async {
_cellBloc.add(TextCardCellEvent.updateText(_controller.text));
_cellBloc.add(TextCellEvent.updateText(_controller.text));
}
@override
@ -156,7 +156,7 @@ class _TextCardCellState extends State<TextCardCell> {
}
}
Widget _buildText(TextCardCellState state) {
Widget _buildText(TextCellState state) {
return Padding(
padding: EdgeInsets.symmetric(
vertical: CardSizes.cardCellVPadding,

View File

@ -1,5 +1,5 @@
import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart';
import 'package:appflowy/plugins/database_view/widgets/card/bloc/timestamp_card_cell_bloc.dart';
import 'package:appflowy/plugins/database_view/widgets/row/cells/timestamp_cell/timestamp_cell_bloc.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@ -18,19 +18,19 @@ class TimestampCardCell<CustomCardData> extends CardCell {
}) : super(key: key);
@override
State<TimestampCardCell> createState() => _TimestampCardCellState();
State<TimestampCardCell> createState() => _TimestampCellState();
}
class _TimestampCardCellState extends State<TimestampCardCell> {
late TimestampCardCellBloc _cellBloc;
class _TimestampCellState extends State<TimestampCardCell> {
late TimestampCellBloc _cellBloc;
@override
void initState() {
final cellController =
widget.cellControllerBuilder.build() as TimestampCellController;
_cellBloc = TimestampCardCellBloc(cellController: cellController)
..add(const TimestampCardCellEvent.initial());
_cellBloc = TimestampCellBloc(cellController: cellController)
..add(const TimestampCellEvent.initial());
super.initState();
}
@ -38,7 +38,7 @@ class _TimestampCardCellState extends State<TimestampCardCell> {
Widget build(BuildContext context) {
return BlocProvider.value(
value: _cellBloc,
child: BlocBuilder<TimestampCardCellBloc, TimestampCardCellState>(
child: BlocBuilder<TimestampCellBloc, TimestampCellState>(
buildWhen: (previous, current) => previous.dateStr != current.dateStr,
builder: (context, state) {
if (state.dateStr.isEmpty) {

View File

@ -1,9 +1,9 @@
import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart';
import 'package:appflowy/plugins/database_view/widgets/row/cells/url_cell/url_cell_bloc.dart';
import 'package:flowy_infra/size.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../bloc/url_card_cell_bloc.dart';
import '../define.dart';
import 'card_cell.dart';
@ -24,18 +24,18 @@ class URLCardCell<CustomCardData>
}) : super(key: key, style: style);
@override
State<URLCardCell> createState() => _URLCardCellState();
State<URLCardCell> createState() => _URLCellState();
}
class _URLCardCellState extends State<URLCardCell> {
late URLCardCellBloc _cellBloc;
class _URLCellState extends State<URLCardCell> {
late URLCellBloc _cellBloc;
@override
void initState() {
final cellController =
widget.cellControllerBuilder.build() as URLCellController;
_cellBloc = URLCardCellBloc(cellController: cellController);
_cellBloc.add(const URLCardCellEvent.initial());
_cellBloc = URLCellBloc(cellController: cellController);
_cellBloc.add(const URLCellEvent.initial());
super.initState();
}
@ -43,7 +43,7 @@ class _URLCardCellState extends State<URLCardCell> {
Widget build(BuildContext context) {
return BlocProvider.value(
value: _cellBloc,
child: BlocBuilder<URLCardCellBloc, URLCardCellState>(
child: BlocBuilder<URLCellBloc, URLCellState>(
buildWhen: (previous, current) => previous.content != current.content,
builder: (context, state) {
if (state.content.isEmpty) {

View File

@ -1,13 +1,12 @@
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart';
import 'package:appflowy/plugins/database_view/application/cell/cell_service.dart';
import 'package:appflowy/plugins/database_view/grid/presentation/layout/sizes.dart';
import 'package:appflowy/plugins/database_view/widgets/row/cell_builder.dart';
import 'package:flowy_infra_ui/style_widget/icon_button.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'checkbox_cell_bloc.dart';
import '../../../../grid/presentation/layout/sizes.dart';
import '../../cell_builder.dart';
class GridCheckboxCellStyle extends GridCellStyle {
EdgeInsets? cellPadding;
@ -44,10 +43,8 @@ class _CheckboxCellState extends GridCellState<GridCheckboxCell> {
void initState() {
final cellController =
widget.cellControllerBuilder.build() as CheckboxCellController;
_cellBloc = CheckboxCellBloc(
service: CellBackendService(),
cellController: cellController,
)..add(const CheckboxCellEvent.initial());
_cellBloc = CheckboxCellBloc(cellController: cellController)
..add(const CheckboxCellEvent.initial());
super.initState();
}

View File

@ -1,5 +1,4 @@
import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart';
import 'package:appflowy/plugins/database_view/application/cell/cell_service.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async';
@ -11,7 +10,6 @@ class CheckboxCellBloc extends Bloc<CheckboxCellEvent, CheckboxCellState> {
void Function()? _onCellChangedFn;
CheckboxCellBloc({
required CellBackendService service,
required this.cellController,
}) : super(CheckboxCellState.initial(cellController)) {
on<CheckboxCellEvent>(
@ -20,12 +18,12 @@ class CheckboxCellBloc extends Bloc<CheckboxCellEvent, CheckboxCellState> {
initial: () {
_startListening();
},
select: () async {
cellController.saveCellData(!state.isSelected ? "Yes" : "No");
},
didReceiveCellUpdate: (cellData) {
emit(state.copyWith(isSelected: _isSelected(cellData)));
},
select: () async {
cellController.saveCellData(!state.isSelected ? "Yes" : "No");
},
);
},
);
@ -73,5 +71,6 @@ class CheckboxCellState with _$CheckboxCellState {
}
bool _isSelected(String? cellData) {
// The backend use "Yes" and "No" to represent the checkbox cell data.
return cellData == "Yes";
}

View File

@ -36,7 +36,7 @@ class GridChecklistCell extends GridCellWidget {
}
class GridChecklistCellState extends GridCellState<GridChecklistCell> {
late ChecklistCardCellBloc _cellBloc;
late ChecklistCellBloc _cellBloc;
late final PopoverController _popover;
@override
@ -44,7 +44,7 @@ class GridChecklistCellState extends GridCellState<GridChecklistCell> {
_popover = PopoverController();
final cellController =
widget.cellControllerBuilder.build() as ChecklistCellController;
_cellBloc = ChecklistCardCellBloc(cellController: cellController);
_cellBloc = ChecklistCellBloc(cellController: cellController);
_cellBloc.add(const ChecklistCellEvent.initial());
super.initState();
}
@ -74,7 +74,7 @@ class GridChecklistCellState extends GridCellState<GridChecklistCell> {
child: Padding(
padding:
widget.cellStyle?.cellPadding ?? GridSize.cellContentInsets,
child: BlocBuilder<ChecklistCardCellBloc, ChecklistCellState>(
child: BlocBuilder<ChecklistCellBloc, ChecklistCellState>(
builder: (context, state) {
if (state.allOptions.isEmpty) {
return FlowyText.medium(

View File

@ -8,12 +8,11 @@ import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async';
part 'checklist_cell_bloc.freezed.dart';
class ChecklistCardCellBloc
extends Bloc<ChecklistCellEvent, ChecklistCellState> {
class ChecklistCellBloc extends Bloc<ChecklistCellEvent, ChecklistCellState> {
final ChecklistCellController cellController;
final ChecklistCellBackendService _checklistCellSvc;
void Function()? _onCellChangedFn;
ChecklistCardCellBloc({
ChecklistCellBloc({
required this.cellController,
}) : _checklistCellSvc = ChecklistCellBackendService(
viewId: cellController.viewId,

View File

@ -29,6 +29,9 @@ class TextCellBloc extends Bloc<TextCellEvent, TextCellState> {
didUpdateEmoji: (String emoji) {
emit(state.copyWith(emoji: emoji));
},
enableEdit: (bool enabled) {
emit(state.copyWith(enableEdit: enabled));
},
);
},
);
@ -66,6 +69,7 @@ class TextCellEvent with _$TextCellEvent {
const factory TextCellEvent.didReceiveCellUpdate(String cellContent) =
_DidReceiveCellUpdate;
const factory TextCellEvent.updateText(String text) = _UpdateText;
const factory TextCellEvent.enableEdit(bool enabled) = _EnableEdit;
const factory TextCellEvent.didUpdateEmoji(String emoji) = _UpdateEmoji;
}
@ -74,10 +78,12 @@ class TextCellState with _$TextCellState {
const factory TextCellState({
required String content,
required String emoji,
required bool enableEdit,
}) = _TextCellState;
factory TextCellState.initial(TextCellController context) => TextCellState(
content: context.getCellData() ?? "",
emoji: context.emoji ?? "",
enableEdit: false,
);
}