mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
Merge branch 'main' into feat/insert_cell_test
This commit is contained in:
commit
cca577f967
6
.gitignore
vendored
6
.gitignore
vendored
@ -27,4 +27,8 @@ frontend/.vscode/*
|
|||||||
!frontend/.vscode/tasks.json
|
!frontend/.vscode/tasks.json
|
||||||
!frontend/.vscode/launch.json
|
!frontend/.vscode/launch.json
|
||||||
!frontend/.vscode/extensions.json
|
!frontend/.vscode/extensions.json
|
||||||
!frontend/.vscode/*.code-snippets
|
!frontend/.vscode/*.code-snippets
|
||||||
|
|
||||||
|
# Commit the highest level pubspec.lock, but ignore the others
|
||||||
|
pubspec.lock
|
||||||
|
!frontend/app_flowy/pubspec.lock
|
||||||
|
@ -153,31 +153,31 @@ void _resolveGridDeps(GetIt getIt) {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
getIt.registerFactoryParam<TextCellBloc, GridCellContext, void>(
|
getIt.registerFactoryParam<TextCellBloc, GridCellController, void>(
|
||||||
(context, _) => TextCellBloc(
|
(context, _) => TextCellBloc(
|
||||||
cellContext: context,
|
cellContext: context,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
getIt.registerFactoryParam<SelectOptionCellBloc, GridSelectOptionCellContext, void>(
|
getIt.registerFactoryParam<SelectOptionCellBloc, GridSelectOptionCellController, void>(
|
||||||
(context, _) => SelectOptionCellBloc(
|
(context, _) => SelectOptionCellBloc(
|
||||||
cellContext: context,
|
cellContext: context,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
getIt.registerFactoryParam<NumberCellBloc, GridCellContext, void>(
|
getIt.registerFactoryParam<NumberCellBloc, GridCellController, void>(
|
||||||
(context, _) => NumberCellBloc(
|
(context, _) => NumberCellBloc(
|
||||||
cellContext: context,
|
cellContext: context,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
getIt.registerFactoryParam<DateCellBloc, GridDateCellContext, void>(
|
getIt.registerFactoryParam<DateCellBloc, GridDateCellController, void>(
|
||||||
(context, _) => DateCellBloc(
|
(context, _) => DateCellBloc(
|
||||||
cellContext: context,
|
cellContext: context,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
getIt.registerFactoryParam<CheckboxCellBloc, GridCellContext, void>(
|
getIt.registerFactoryParam<CheckboxCellBloc, GridCellController, void>(
|
||||||
(cellData, _) => CheckboxCellBloc(
|
(cellData, _) => CheckboxCellBloc(
|
||||||
service: CellService(),
|
service: CellService(),
|
||||||
cellContext: cellData,
|
cellContext: cellData,
|
||||||
|
@ -6,24 +6,25 @@ import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
|
|||||||
|
|
||||||
import 'block_listener.dart';
|
import 'block_listener.dart';
|
||||||
|
|
||||||
class GridBlockCacheService {
|
/// Read https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/architecture/frontend/grid for more information
|
||||||
|
class GridBlockCache {
|
||||||
final String gridId;
|
final String gridId;
|
||||||
final GridBlock block;
|
final GridBlock block;
|
||||||
late GridRowCacheService _rowCache;
|
late GridRowCache _rowCache;
|
||||||
late GridBlockListener _listener;
|
late GridBlockListener _listener;
|
||||||
|
|
||||||
List<GridRow> get rows => _rowCache.rows;
|
List<GridRow> get rows => _rowCache.rows;
|
||||||
GridRowCacheService get rowCache => _rowCache;
|
GridRowCache get rowCache => _rowCache;
|
||||||
|
|
||||||
GridBlockCacheService({
|
GridBlockCache({
|
||||||
required this.gridId,
|
required this.gridId,
|
||||||
required this.block,
|
required this.block,
|
||||||
required GridFieldCache fieldCache,
|
required GridFieldCache fieldCache,
|
||||||
}) {
|
}) {
|
||||||
_rowCache = GridRowCacheService(
|
_rowCache = GridRowCache(
|
||||||
gridId: gridId,
|
gridId: gridId,
|
||||||
block: block,
|
block: block,
|
||||||
delegate: GridRowCacheDelegateImpl(fieldCache),
|
notifier: GridRowCacheFieldNotifierImpl(fieldCache),
|
||||||
);
|
);
|
||||||
|
|
||||||
_listener = GridBlockListener(blockId: block.id);
|
_listener = GridBlockListener(blockId: block.id);
|
@ -1,109 +0,0 @@
|
|||||||
part of 'cell_service.dart';
|
|
||||||
|
|
||||||
typedef GridCellMap = LinkedHashMap<String, GridCell>;
|
|
||||||
|
|
||||||
class _GridCellCacheObject {
|
|
||||||
_GridCellCacheKey key;
|
|
||||||
dynamic object;
|
|
||||||
_GridCellCacheObject({
|
|
||||||
required this.key,
|
|
||||||
required this.object,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
class _GridCellCacheKey {
|
|
||||||
final String fieldId;
|
|
||||||
final String rowId;
|
|
||||||
_GridCellCacheKey({
|
|
||||||
required this.fieldId,
|
|
||||||
required this.rowId,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class GridCellCacheDelegate {
|
|
||||||
void onFieldUpdated(void Function(Field) callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
class GridCellCacheService {
|
|
||||||
final String gridId;
|
|
||||||
final GridCellCacheDelegate delegate;
|
|
||||||
|
|
||||||
/// fieldId: {objectId: callback}
|
|
||||||
final Map<String, Map<String, List<VoidCallback>>> _fieldListenerByFieldId = {};
|
|
||||||
|
|
||||||
/// fieldId: {cacheKey: cacheData}
|
|
||||||
final Map<String, Map<String, dynamic>> _cellDataByFieldId = {};
|
|
||||||
GridCellCacheService({
|
|
||||||
required this.gridId,
|
|
||||||
required this.delegate,
|
|
||||||
}) {
|
|
||||||
delegate.onFieldUpdated((field) {
|
|
||||||
_cellDataByFieldId.remove(field.id);
|
|
||||||
final map = _fieldListenerByFieldId[field.id];
|
|
||||||
if (map != null) {
|
|
||||||
for (final callbacks in map.values) {
|
|
||||||
for (final callback in callbacks) {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void addFieldListener(_GridCellCacheKey cacheKey, VoidCallback onFieldChanged) {
|
|
||||||
var map = _fieldListenerByFieldId[cacheKey.fieldId];
|
|
||||||
if (map == null) {
|
|
||||||
_fieldListenerByFieldId[cacheKey.fieldId] = {};
|
|
||||||
map = _fieldListenerByFieldId[cacheKey.fieldId];
|
|
||||||
map![cacheKey.rowId] = [onFieldChanged];
|
|
||||||
} else {
|
|
||||||
var objects = map[cacheKey.rowId];
|
|
||||||
if (objects == null) {
|
|
||||||
map[cacheKey.rowId] = [onFieldChanged];
|
|
||||||
} else {
|
|
||||||
objects.add(onFieldChanged);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeFieldListener(_GridCellCacheKey cacheKey, VoidCallback fn) {
|
|
||||||
var callbacks = _fieldListenerByFieldId[cacheKey.fieldId]?[cacheKey.rowId];
|
|
||||||
final index = callbacks?.indexWhere((callback) => callback == fn);
|
|
||||||
if (index != null && index != -1) {
|
|
||||||
callbacks?.removeAt(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void insert<T extends _GridCellCacheObject>(T item) {
|
|
||||||
var map = _cellDataByFieldId[item.key.fieldId];
|
|
||||||
if (map == null) {
|
|
||||||
_cellDataByFieldId[item.key.fieldId] = {};
|
|
||||||
map = _cellDataByFieldId[item.key.fieldId];
|
|
||||||
}
|
|
||||||
|
|
||||||
map![item.key.rowId] = item.object;
|
|
||||||
}
|
|
||||||
|
|
||||||
T? get<T>(_GridCellCacheKey key) {
|
|
||||||
final map = _cellDataByFieldId[key.fieldId];
|
|
||||||
if (map == null) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
final object = map[key.rowId];
|
|
||||||
if (object is T) {
|
|
||||||
return object;
|
|
||||||
} else {
|
|
||||||
if (object != null) {
|
|
||||||
Log.error("Cache data type does not match the cache data type");
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> dispose() async {
|
|
||||||
_fieldListenerByFieldId.clear();
|
|
||||||
_cellDataByFieldId.clear();
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,70 @@
|
|||||||
|
part of 'cell_service.dart';
|
||||||
|
|
||||||
|
typedef GridCellMap = LinkedHashMap<String, GridCellIdentifier>;
|
||||||
|
|
||||||
|
class GridCell {
|
||||||
|
dynamic object;
|
||||||
|
GridCell({
|
||||||
|
required this.object,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Use to index the cell in the grid.
|
||||||
|
/// We use [fieldId + rowId] to identify the cell.
|
||||||
|
class GridCellCacheKey {
|
||||||
|
final String fieldId;
|
||||||
|
final String rowId;
|
||||||
|
GridCellCacheKey({
|
||||||
|
required this.fieldId,
|
||||||
|
required this.rowId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// GridCellCache is used to cache cell data of each block.
|
||||||
|
/// We use GridCellCacheKey to index the cell in the cache.
|
||||||
|
/// Read https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/architecture/frontend/grid
|
||||||
|
/// for more information
|
||||||
|
class GridCellCache {
|
||||||
|
final String gridId;
|
||||||
|
|
||||||
|
/// fieldId: {cacheKey: GridCell}
|
||||||
|
final Map<String, Map<String, dynamic>> _cellDataByFieldId = {};
|
||||||
|
GridCellCache({
|
||||||
|
required this.gridId,
|
||||||
|
});
|
||||||
|
|
||||||
|
void remove(String fieldId) {
|
||||||
|
_cellDataByFieldId.remove(fieldId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert<T extends GridCell>(GridCellCacheKey key, T value) {
|
||||||
|
var map = _cellDataByFieldId[key.fieldId];
|
||||||
|
if (map == null) {
|
||||||
|
_cellDataByFieldId[key.fieldId] = {};
|
||||||
|
map = _cellDataByFieldId[key.fieldId];
|
||||||
|
}
|
||||||
|
|
||||||
|
map![key.rowId] = value.object;
|
||||||
|
}
|
||||||
|
|
||||||
|
T? get<T>(GridCellCacheKey key) {
|
||||||
|
final map = _cellDataByFieldId[key.fieldId];
|
||||||
|
if (map == null) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
final value = map[key.rowId];
|
||||||
|
if (value is T) {
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
if (value != null) {
|
||||||
|
Log.error("Expected value type: $T, but receive $value");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> dispose() async {
|
||||||
|
_cellDataByFieldId.clear();
|
||||||
|
}
|
||||||
|
}
|
@ -3,58 +3,26 @@ part of 'cell_service.dart';
|
|||||||
abstract class IGridCellDataConfig {
|
abstract class IGridCellDataConfig {
|
||||||
// The cell data will reload if it receives the field's change notification.
|
// The cell data will reload if it receives the field's change notification.
|
||||||
bool get reloadOnFieldChanged;
|
bool get reloadOnFieldChanged;
|
||||||
|
|
||||||
// When the reloadOnCellChanged is true, it will load the cell data after user input.
|
|
||||||
// For example: The number cell reload the cell data that carries the format
|
|
||||||
// user input: 12
|
|
||||||
// cell display: $12
|
|
||||||
bool get reloadOnCellChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
class GridCellDataConfig implements IGridCellDataConfig {
|
|
||||||
@override
|
|
||||||
final bool reloadOnCellChanged;
|
|
||||||
|
|
||||||
@override
|
|
||||||
final bool reloadOnFieldChanged;
|
|
||||||
|
|
||||||
const GridCellDataConfig({
|
|
||||||
this.reloadOnCellChanged = false,
|
|
||||||
this.reloadOnFieldChanged = false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class IGridCellDataLoader<T> {
|
|
||||||
Future<T?> loadData();
|
|
||||||
|
|
||||||
IGridCellDataConfig get config;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class ICellDataParser<T> {
|
abstract class ICellDataParser<T> {
|
||||||
T? parserData(List<int> data);
|
T? parserData(List<int> data);
|
||||||
}
|
}
|
||||||
|
|
||||||
class GridCellDataLoader<T> extends IGridCellDataLoader<T> {
|
class GridCellDataLoader<T> {
|
||||||
final CellService service = CellService();
|
final CellService service = CellService();
|
||||||
final GridCell gridCell;
|
final GridCellIdentifier cellId;
|
||||||
final ICellDataParser<T> parser;
|
final ICellDataParser<T> parser;
|
||||||
|
final bool reloadOnFieldChanged;
|
||||||
@override
|
|
||||||
final IGridCellDataConfig config;
|
|
||||||
|
|
||||||
GridCellDataLoader({
|
GridCellDataLoader({
|
||||||
required this.gridCell,
|
required this.cellId,
|
||||||
required this.parser,
|
required this.parser,
|
||||||
this.config = const GridCellDataConfig(),
|
this.reloadOnFieldChanged = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
|
||||||
Future<T?> loadData() {
|
Future<T?> loadData() {
|
||||||
final fut = service.getCell(
|
final fut = service.getCell(cellId: cellId);
|
||||||
gridId: gridCell.gridId,
|
|
||||||
fieldId: gridCell.field.id,
|
|
||||||
rowId: gridCell.rowId,
|
|
||||||
);
|
|
||||||
return fut.then(
|
return fut.then(
|
||||||
(result) => result.fold((Cell cell) {
|
(result) => result.fold((Cell cell) {
|
||||||
try {
|
try {
|
||||||
@ -72,29 +40,6 @@ class GridCellDataLoader<T> extends IGridCellDataLoader<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SelectOptionCellDataLoader extends IGridCellDataLoader<SelectOptionCellData> {
|
|
||||||
final SelectOptionService service;
|
|
||||||
final GridCell gridCell;
|
|
||||||
SelectOptionCellDataLoader({
|
|
||||||
required this.gridCell,
|
|
||||||
}) : service = SelectOptionService(gridCell: gridCell);
|
|
||||||
@override
|
|
||||||
Future<SelectOptionCellData?> loadData() async {
|
|
||||||
return service.getOpitonContext().then((result) {
|
|
||||||
return result.fold(
|
|
||||||
(data) => data,
|
|
||||||
(err) {
|
|
||||||
Log.error(err);
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
IGridCellDataConfig get config => const GridCellDataConfig(reloadOnFieldChanged: true);
|
|
||||||
}
|
|
||||||
|
|
||||||
class StringCellDataParser implements ICellDataParser<String> {
|
class StringCellDataParser implements ICellDataParser<String> {
|
||||||
@override
|
@override
|
||||||
String? parserData(List<int> data) {
|
String? parserData(List<int> data) {
|
||||||
|
@ -1,25 +1,22 @@
|
|||||||
part of 'cell_service.dart';
|
part of 'cell_service.dart';
|
||||||
|
|
||||||
abstract class _GridCellDataPersistence<D> {
|
/// Save the cell data to disk
|
||||||
|
/// You can extend this class to do custom operations. For example, the DateCellDataPersistence.
|
||||||
|
abstract class IGridCellDataPersistence<D> {
|
||||||
Future<Option<FlowyError>> save(D data);
|
Future<Option<FlowyError>> save(D data);
|
||||||
}
|
}
|
||||||
|
|
||||||
class CellDataPersistence implements _GridCellDataPersistence<String> {
|
class CellDataPersistence implements IGridCellDataPersistence<String> {
|
||||||
final GridCell gridCell;
|
final GridCellIdentifier cellId;
|
||||||
|
|
||||||
CellDataPersistence({
|
CellDataPersistence({
|
||||||
required this.gridCell,
|
required this.cellId,
|
||||||
});
|
});
|
||||||
final CellService _cellService = CellService();
|
final CellService _cellService = CellService();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Option<FlowyError>> save(String data) async {
|
Future<Option<FlowyError>> save(String data) async {
|
||||||
final fut = _cellService.updateCell(
|
final fut = _cellService.updateCell(cellId: cellId, data: data);
|
||||||
gridId: gridCell.gridId,
|
|
||||||
fieldId: gridCell.field.id,
|
|
||||||
rowId: gridCell.rowId,
|
|
||||||
data: data,
|
|
||||||
);
|
|
||||||
|
|
||||||
return fut.then((result) {
|
return fut.then((result) {
|
||||||
return result.fold(
|
return result.fold(
|
||||||
@ -35,15 +32,15 @@ class CalendarData with _$CalendarData {
|
|||||||
const factory CalendarData({required DateTime date, String? time}) = _CalendarData;
|
const factory CalendarData({required DateTime date, String? time}) = _CalendarData;
|
||||||
}
|
}
|
||||||
|
|
||||||
class DateCellDataPersistence implements _GridCellDataPersistence<CalendarData> {
|
class DateCellDataPersistence implements IGridCellDataPersistence<CalendarData> {
|
||||||
final GridCell gridCell;
|
final GridCellIdentifier cellId;
|
||||||
DateCellDataPersistence({
|
DateCellDataPersistence({
|
||||||
required this.gridCell,
|
required this.cellId,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Option<FlowyError>> save(CalendarData data) {
|
Future<Option<FlowyError>> save(CalendarData data) {
|
||||||
var payload = DateChangesetPayload.create()..cellIdentifier = _cellIdentifier(gridCell);
|
var payload = DateChangesetPayload.create()..cellIdentifier = _makeCellIdPayload(cellId);
|
||||||
|
|
||||||
final date = (data.date.millisecondsSinceEpoch ~/ 1000).toString();
|
final date = (data.date.millisecondsSinceEpoch ~/ 1000).toString();
|
||||||
payload.date = date;
|
payload.date = date;
|
||||||
@ -61,9 +58,9 @@ class DateCellDataPersistence implements _GridCellDataPersistence<CalendarData>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CellIdentifierPayload _cellIdentifier(GridCell gridCell) {
|
CellIdentifierPayload _makeCellIdPayload(GridCellIdentifier cellId) {
|
||||||
return CellIdentifierPayload.create()
|
return CellIdentifierPayload.create()
|
||||||
..gridId = gridCell.gridId
|
..gridId = cellId.gridId
|
||||||
..fieldId = gridCell.field.id
|
..fieldId = cellId.fieldId
|
||||||
..rowId = gridCell.rowId;
|
..rowId = cellId.rowId;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,60 @@
|
|||||||
|
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
|
import 'cell_service.dart';
|
||||||
|
|
||||||
|
abstract class GridFieldChangedNotifier {
|
||||||
|
void onFieldChanged(void Function(Field) callback);
|
||||||
|
void dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Grid's cell helper wrapper that enables each cell will get notified when the corresponding field was changed.
|
||||||
|
/// You Register an onFieldChanged callback to listen to the cell changes, and unregister if you don't want to listen.
|
||||||
|
class GridCellFieldNotifier {
|
||||||
|
/// fieldId: {objectId: callback}
|
||||||
|
final Map<String, Map<String, List<VoidCallback>>> _fieldListenerByFieldId = {};
|
||||||
|
|
||||||
|
GridCellFieldNotifier({required GridFieldChangedNotifier notifier}) {
|
||||||
|
notifier.onFieldChanged(
|
||||||
|
(field) {
|
||||||
|
final map = _fieldListenerByFieldId[field.id];
|
||||||
|
if (map != null) {
|
||||||
|
for (final callbacks in map.values) {
|
||||||
|
for (final callback in callbacks) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
void register(GridCellCacheKey cacheKey, VoidCallback onFieldChanged) {
|
||||||
|
var map = _fieldListenerByFieldId[cacheKey.fieldId];
|
||||||
|
if (map == null) {
|
||||||
|
_fieldListenerByFieldId[cacheKey.fieldId] = {};
|
||||||
|
map = _fieldListenerByFieldId[cacheKey.fieldId];
|
||||||
|
map![cacheKey.rowId] = [onFieldChanged];
|
||||||
|
} else {
|
||||||
|
var objects = map[cacheKey.rowId];
|
||||||
|
if (objects == null) {
|
||||||
|
map[cacheKey.rowId] = [onFieldChanged];
|
||||||
|
} else {
|
||||||
|
objects.add(onFieldChanged);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void unregister(GridCellCacheKey cacheKey, VoidCallback fn) {
|
||||||
|
var callbacks = _fieldListenerByFieldId[cacheKey.fieldId]?[cacheKey.rowId];
|
||||||
|
final index = callbacks?.indexWhere((callback) => callback == fn);
|
||||||
|
if (index != null && index != -1) {
|
||||||
|
callbacks?.removeAt(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> dispose() async {
|
||||||
|
_fieldListenerByFieldId.clear();
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
|
|
||||||
|
import 'package:app_flowy/workspace/application/grid/grid_service.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||||
@ -14,13 +15,15 @@ import 'package:flowy_sdk/protobuf/flowy-grid/url_type_option_entities.pb.dart';
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/cell/cell_listener.dart';
|
import 'package:app_flowy/workspace/application/grid/cell/cell_listener.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/cell/select_option_service.dart';
|
|
||||||
import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
|
import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
|
||||||
import 'dart:convert' show utf8;
|
import 'dart:convert' show utf8;
|
||||||
|
|
||||||
|
import '../../field/type_option/type_option_service.dart';
|
||||||
|
import 'cell_field_notifier.dart';
|
||||||
part 'cell_service.freezed.dart';
|
part 'cell_service.freezed.dart';
|
||||||
part 'cell_data_loader.dart';
|
part 'cell_data_loader.dart';
|
||||||
part 'context_builder.dart';
|
part 'context_builder.dart';
|
||||||
part 'cache.dart';
|
part 'cell_cache.dart';
|
||||||
part 'cell_data_persistence.dart';
|
part 'cell_data_persistence.dart';
|
||||||
|
|
||||||
// key: rowId
|
// key: rowId
|
||||||
@ -29,44 +32,46 @@ class CellService {
|
|||||||
CellService();
|
CellService();
|
||||||
|
|
||||||
Future<Either<void, FlowyError>> updateCell({
|
Future<Either<void, FlowyError>> updateCell({
|
||||||
required String gridId,
|
required GridCellIdentifier cellId,
|
||||||
required String fieldId,
|
|
||||||
required String rowId,
|
|
||||||
required String data,
|
required String data,
|
||||||
}) {
|
}) {
|
||||||
final payload = CellChangeset.create()
|
final payload = CellChangeset.create()
|
||||||
..gridId = gridId
|
..gridId = cellId.gridId
|
||||||
..fieldId = fieldId
|
..fieldId = cellId.fieldId
|
||||||
..rowId = rowId
|
..rowId = cellId.rowId
|
||||||
..content = data;
|
..content = data;
|
||||||
return GridEventUpdateCell(payload).send();
|
return GridEventUpdateCell(payload).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<Cell, FlowyError>> getCell({
|
Future<Either<Cell, FlowyError>> getCell({
|
||||||
required String gridId,
|
required GridCellIdentifier cellId,
|
||||||
required String fieldId,
|
|
||||||
required String rowId,
|
|
||||||
}) {
|
}) {
|
||||||
final payload = CellIdentifierPayload.create()
|
final payload = CellIdentifierPayload.create()
|
||||||
..gridId = gridId
|
..gridId = cellId.gridId
|
||||||
..fieldId = fieldId
|
..fieldId = cellId.fieldId
|
||||||
..rowId = rowId;
|
..rowId = cellId.rowId;
|
||||||
return GridEventGetCell(payload).send();
|
return GridEventGetCell(payload).send();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Id of the cell
|
||||||
|
/// We can locate the cell by using gridId + rowId + field.id.
|
||||||
@freezed
|
@freezed
|
||||||
class GridCell with _$GridCell {
|
class GridCellIdentifier with _$GridCellIdentifier {
|
||||||
const factory GridCell({
|
const factory GridCellIdentifier({
|
||||||
required String gridId,
|
required String gridId,
|
||||||
required String rowId,
|
required String rowId,
|
||||||
required Field field,
|
required Field field,
|
||||||
}) = _GridCell;
|
}) = _GridCellIdentifier;
|
||||||
|
|
||||||
// ignore: unused_element
|
// ignore: unused_element
|
||||||
const GridCell._();
|
const GridCellIdentifier._();
|
||||||
|
|
||||||
String cellId() {
|
String get fieldId => field.id;
|
||||||
return rowId + field.id + "${field.fieldType}";
|
|
||||||
|
FieldType get fieldType => field.fieldType;
|
||||||
|
|
||||||
|
ValueKey key() {
|
||||||
|
return ValueKey(rowId + fieldId + "${field.fieldType}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,154 +1,185 @@
|
|||||||
part of 'cell_service.dart';
|
part of 'cell_service.dart';
|
||||||
|
|
||||||
typedef GridCellContext = _GridCellContext<String, String>;
|
typedef GridCellController = IGridCellController<String, String>;
|
||||||
typedef GridSelectOptionCellContext = _GridCellContext<SelectOptionCellData, String>;
|
typedef GridSelectOptionCellController = IGridCellController<SelectOptionCellData, String>;
|
||||||
typedef GridDateCellContext = _GridCellContext<DateCellData, CalendarData>;
|
typedef GridDateCellController = IGridCellController<DateCellData, CalendarData>;
|
||||||
typedef GridURLCellContext = _GridCellContext<URLCellData, String>;
|
typedef GridURLCellController = IGridCellController<URLCellData, String>;
|
||||||
|
|
||||||
class GridCellContextBuilder {
|
class GridCellControllerBuilder {
|
||||||
final GridCellCacheService _cellCache;
|
final GridCellIdentifier _cellId;
|
||||||
final GridCell _gridCell;
|
final GridCellCache _cellCache;
|
||||||
GridCellContextBuilder({
|
final GridFieldCache _fieldCache;
|
||||||
required GridCellCacheService cellCache,
|
|
||||||
required GridCell gridCell,
|
GridCellControllerBuilder({
|
||||||
|
required GridCellIdentifier cellId,
|
||||||
|
required GridCellCache cellCache,
|
||||||
|
required GridFieldCache fieldCache,
|
||||||
}) : _cellCache = cellCache,
|
}) : _cellCache = cellCache,
|
||||||
_gridCell = gridCell;
|
_fieldCache = fieldCache,
|
||||||
|
_cellId = cellId;
|
||||||
|
|
||||||
_GridCellContext build() {
|
IGridCellController build() {
|
||||||
switch (_gridCell.field.fieldType) {
|
final cellFieldNotifier = GridCellFieldNotifier(notifier: _GridFieldChangedNotifierImpl(_fieldCache));
|
||||||
|
|
||||||
|
switch (_cellId.fieldType) {
|
||||||
case FieldType.Checkbox:
|
case FieldType.Checkbox:
|
||||||
final cellDataLoader = GridCellDataLoader(
|
final cellDataLoader = GridCellDataLoader(
|
||||||
gridCell: _gridCell,
|
cellId: _cellId,
|
||||||
parser: StringCellDataParser(),
|
parser: StringCellDataParser(),
|
||||||
);
|
);
|
||||||
return GridCellContext(
|
return GridCellController(
|
||||||
gridCell: _gridCell,
|
cellId: _cellId,
|
||||||
cellCache: _cellCache,
|
cellCache: _cellCache,
|
||||||
cellDataLoader: cellDataLoader,
|
cellDataLoader: cellDataLoader,
|
||||||
cellDataPersistence: CellDataPersistence(gridCell: _gridCell),
|
fieldNotifier: cellFieldNotifier,
|
||||||
|
cellDataPersistence: CellDataPersistence(cellId: _cellId),
|
||||||
);
|
);
|
||||||
case FieldType.DateTime:
|
case FieldType.DateTime:
|
||||||
final cellDataLoader = GridCellDataLoader(
|
final cellDataLoader = GridCellDataLoader(
|
||||||
gridCell: _gridCell,
|
cellId: _cellId,
|
||||||
parser: DateCellDataParser(),
|
parser: DateCellDataParser(),
|
||||||
config: const GridCellDataConfig(reloadOnFieldChanged: true),
|
reloadOnFieldChanged: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
return GridDateCellContext(
|
return GridDateCellController(
|
||||||
gridCell: _gridCell,
|
cellId: _cellId,
|
||||||
cellCache: _cellCache,
|
cellCache: _cellCache,
|
||||||
cellDataLoader: cellDataLoader,
|
cellDataLoader: cellDataLoader,
|
||||||
cellDataPersistence: DateCellDataPersistence(gridCell: _gridCell),
|
fieldNotifier: cellFieldNotifier,
|
||||||
|
cellDataPersistence: DateCellDataPersistence(cellId: _cellId),
|
||||||
);
|
);
|
||||||
case FieldType.Number:
|
case FieldType.Number:
|
||||||
final cellDataLoader = GridCellDataLoader(
|
final cellDataLoader = GridCellDataLoader(
|
||||||
gridCell: _gridCell,
|
cellId: _cellId,
|
||||||
parser: StringCellDataParser(),
|
parser: StringCellDataParser(),
|
||||||
config: const GridCellDataConfig(reloadOnCellChanged: true, reloadOnFieldChanged: true),
|
|
||||||
);
|
);
|
||||||
return GridCellContext(
|
return GridCellController(
|
||||||
gridCell: _gridCell,
|
cellId: _cellId,
|
||||||
cellCache: _cellCache,
|
cellCache: _cellCache,
|
||||||
cellDataLoader: cellDataLoader,
|
cellDataLoader: cellDataLoader,
|
||||||
cellDataPersistence: CellDataPersistence(gridCell: _gridCell),
|
fieldNotifier: cellFieldNotifier,
|
||||||
|
cellDataPersistence: CellDataPersistence(cellId: _cellId),
|
||||||
);
|
);
|
||||||
case FieldType.RichText:
|
case FieldType.RichText:
|
||||||
final cellDataLoader = GridCellDataLoader(
|
final cellDataLoader = GridCellDataLoader(
|
||||||
gridCell: _gridCell,
|
cellId: _cellId,
|
||||||
parser: StringCellDataParser(),
|
parser: StringCellDataParser(),
|
||||||
);
|
);
|
||||||
return GridCellContext(
|
return GridCellController(
|
||||||
gridCell: _gridCell,
|
cellId: _cellId,
|
||||||
cellCache: _cellCache,
|
cellCache: _cellCache,
|
||||||
cellDataLoader: cellDataLoader,
|
cellDataLoader: cellDataLoader,
|
||||||
cellDataPersistence: CellDataPersistence(gridCell: _gridCell),
|
fieldNotifier: cellFieldNotifier,
|
||||||
|
cellDataPersistence: CellDataPersistence(cellId: _cellId),
|
||||||
);
|
);
|
||||||
case FieldType.MultiSelect:
|
case FieldType.MultiSelect:
|
||||||
case FieldType.SingleSelect:
|
case FieldType.SingleSelect:
|
||||||
final cellDataLoader = GridCellDataLoader(
|
final cellDataLoader = GridCellDataLoader(
|
||||||
gridCell: _gridCell,
|
cellId: _cellId,
|
||||||
parser: SelectOptionCellDataParser(),
|
parser: SelectOptionCellDataParser(),
|
||||||
config: const GridCellDataConfig(reloadOnFieldChanged: true),
|
reloadOnFieldChanged: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
return GridSelectOptionCellContext(
|
return GridSelectOptionCellController(
|
||||||
gridCell: _gridCell,
|
cellId: _cellId,
|
||||||
cellCache: _cellCache,
|
cellCache: _cellCache,
|
||||||
cellDataLoader: cellDataLoader,
|
cellDataLoader: cellDataLoader,
|
||||||
cellDataPersistence: CellDataPersistence(gridCell: _gridCell),
|
fieldNotifier: cellFieldNotifier,
|
||||||
|
cellDataPersistence: CellDataPersistence(cellId: _cellId),
|
||||||
);
|
);
|
||||||
|
|
||||||
case FieldType.URL:
|
case FieldType.URL:
|
||||||
final cellDataLoader = GridCellDataLoader(
|
final cellDataLoader = GridCellDataLoader(
|
||||||
gridCell: _gridCell,
|
cellId: _cellId,
|
||||||
parser: URLCellDataParser(),
|
parser: URLCellDataParser(),
|
||||||
);
|
);
|
||||||
return GridURLCellContext(
|
return GridURLCellController(
|
||||||
gridCell: _gridCell,
|
cellId: _cellId,
|
||||||
cellCache: _cellCache,
|
cellCache: _cellCache,
|
||||||
cellDataLoader: cellDataLoader,
|
cellDataLoader: cellDataLoader,
|
||||||
cellDataPersistence: CellDataPersistence(gridCell: _gridCell),
|
fieldNotifier: cellFieldNotifier,
|
||||||
|
cellDataPersistence: CellDataPersistence(cellId: _cellId),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
throw UnimplementedError;
|
throw UnimplementedError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// T: the type of the CellData
|
/// IGridCellController is used to manipulate the cell and receive notifications.
|
||||||
// D: the type of the data that will be save to disk
|
/// * Read/Write cell data
|
||||||
|
/// * Listen on field/cell notifications.
|
||||||
|
///
|
||||||
|
/// Generic T represents the type of the cell data.
|
||||||
|
/// Generic D represents the type of data that will be saved to the disk
|
||||||
|
///
|
||||||
// ignore: must_be_immutable
|
// ignore: must_be_immutable
|
||||||
class _GridCellContext<T, D> extends Equatable {
|
class IGridCellController<T, D> extends Equatable {
|
||||||
final GridCell gridCell;
|
final GridCellIdentifier cellId;
|
||||||
final GridCellCacheService cellCache;
|
final GridCellCache _cellsCache;
|
||||||
final _GridCellCacheKey _cacheKey;
|
final GridCellCacheKey _cacheKey;
|
||||||
final IGridCellDataLoader<T> cellDataLoader;
|
|
||||||
final _GridCellDataPersistence<D> cellDataPersistence;
|
|
||||||
final FieldService _fieldService;
|
final FieldService _fieldService;
|
||||||
|
final GridCellFieldNotifier _fieldNotifier;
|
||||||
|
final GridCellDataLoader<T> _cellDataLoader;
|
||||||
|
final IGridCellDataPersistence<D> _cellDataPersistence;
|
||||||
|
|
||||||
late final CellListener _cellListener;
|
late final CellListener _cellListener;
|
||||||
late final ValueNotifier<T?>? _cellDataNotifier;
|
ValueNotifier<T?>? _cellDataNotifier;
|
||||||
|
|
||||||
bool isListening = false;
|
bool isListening = false;
|
||||||
VoidCallback? _onFieldChangedFn;
|
VoidCallback? _onFieldChangedFn;
|
||||||
Timer? _loadDataOperation;
|
Timer? _loadDataOperation;
|
||||||
Timer? _saveDataOperation;
|
Timer? _saveDataOperation;
|
||||||
|
bool _isDispose = false;
|
||||||
|
|
||||||
_GridCellContext({
|
IGridCellController({
|
||||||
required this.gridCell,
|
required this.cellId,
|
||||||
required this.cellCache,
|
required GridCellCache cellCache,
|
||||||
required this.cellDataLoader,
|
required GridCellFieldNotifier fieldNotifier,
|
||||||
required this.cellDataPersistence,
|
required GridCellDataLoader<T> cellDataLoader,
|
||||||
}) : _fieldService = FieldService(gridId: gridCell.gridId, fieldId: gridCell.field.id),
|
required IGridCellDataPersistence<D> cellDataPersistence,
|
||||||
_cacheKey = _GridCellCacheKey(rowId: gridCell.rowId, fieldId: gridCell.field.id);
|
}) : _cellsCache = cellCache,
|
||||||
|
_cellDataLoader = cellDataLoader,
|
||||||
|
_cellDataPersistence = cellDataPersistence,
|
||||||
|
_fieldNotifier = fieldNotifier,
|
||||||
|
_fieldService = FieldService(gridId: cellId.gridId, fieldId: cellId.field.id),
|
||||||
|
_cacheKey = GridCellCacheKey(rowId: cellId.rowId, fieldId: cellId.field.id);
|
||||||
|
|
||||||
_GridCellContext<T, D> clone() {
|
IGridCellController<T, D> clone() {
|
||||||
return _GridCellContext(
|
return IGridCellController(
|
||||||
gridCell: gridCell,
|
cellId: cellId,
|
||||||
cellDataLoader: cellDataLoader,
|
cellDataLoader: _cellDataLoader,
|
||||||
cellCache: cellCache,
|
cellCache: _cellsCache,
|
||||||
cellDataPersistence: cellDataPersistence);
|
fieldNotifier: _fieldNotifier,
|
||||||
|
cellDataPersistence: _cellDataPersistence);
|
||||||
}
|
}
|
||||||
|
|
||||||
String get gridId => gridCell.gridId;
|
String get gridId => cellId.gridId;
|
||||||
|
|
||||||
String get rowId => gridCell.rowId;
|
String get rowId => cellId.rowId;
|
||||||
|
|
||||||
String get cellId => gridCell.rowId + gridCell.field.id;
|
String get fieldId => cellId.field.id;
|
||||||
|
|
||||||
String get fieldId => gridCell.field.id;
|
Field get field => cellId.field;
|
||||||
|
|
||||||
Field get field => gridCell.field;
|
FieldType get fieldType => cellId.field.fieldType;
|
||||||
|
|
||||||
FieldType get fieldType => gridCell.field.fieldType;
|
VoidCallback? startListening({required void Function(T?) onCellChanged, VoidCallback? onCellFieldChanged}) {
|
||||||
|
|
||||||
VoidCallback? startListening({required void Function(T?) onCellChanged}) {
|
|
||||||
if (isListening) {
|
if (isListening) {
|
||||||
Log.error("Already started. It seems like you should call clone first");
|
Log.error("Already started. It seems like you should call clone first");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
isListening = true;
|
isListening = true;
|
||||||
_cellDataNotifier = ValueNotifier(cellCache.get(_cacheKey));
|
|
||||||
_cellListener = CellListener(rowId: gridCell.rowId, fieldId: gridCell.field.id);
|
/// The cell data will be changed by two reasons:
|
||||||
|
/// 1. User edit the cell
|
||||||
|
/// 2. User edit the field
|
||||||
|
/// For example: The number cell reload the cell data that carries the format
|
||||||
|
/// user input: 12
|
||||||
|
/// cell display: $12
|
||||||
|
_cellDataNotifier = ValueNotifier(_cellsCache.get(_cacheKey));
|
||||||
|
_cellListener = CellListener(rowId: cellId.rowId, fieldId: cellId.field.id);
|
||||||
|
|
||||||
|
/// 1.Listen on user edit event and load the new cell data if needed.
|
||||||
_cellListener.start(onCellChanged: (result) {
|
_cellListener.start(onCellChanged: (result) {
|
||||||
result.fold(
|
result.fold(
|
||||||
(_) => _loadData(),
|
(_) => _loadData(),
|
||||||
@ -156,22 +187,24 @@ class _GridCellContext<T, D> extends Equatable {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (cellDataLoader.config.reloadOnFieldChanged) {
|
/// 2.Listen on the field event and load the cell data if needed.
|
||||||
_onFieldChangedFn = () {
|
_onFieldChangedFn = () {
|
||||||
_loadData();
|
if (onCellFieldChanged != null) {
|
||||||
};
|
onCellFieldChanged();
|
||||||
cellCache.addFieldListener(_cacheKey, _onFieldChangedFn!);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
onCellChangedFn() {
|
if (_cellDataLoader.reloadOnFieldChanged) {
|
||||||
onCellChanged(_cellDataNotifier?.value);
|
|
||||||
|
|
||||||
if (cellDataLoader.config.reloadOnCellChanged) {
|
|
||||||
_loadData();
|
_loadData();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
_fieldNotifier.register(_cacheKey, _onFieldChangedFn!);
|
||||||
|
|
||||||
|
/// Notify the listener, the cell data was changed.
|
||||||
|
onCellChangedFn() => onCellChanged(_cellDataNotifier?.value);
|
||||||
_cellDataNotifier?.addListener(onCellChangedFn);
|
_cellDataNotifier?.addListener(onCellChangedFn);
|
||||||
|
|
||||||
|
// Return the function pointer that can be used when calling removeListener.
|
||||||
return onCellChangedFn;
|
return onCellChangedFn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,29 +212,45 @@ class _GridCellContext<T, D> extends Equatable {
|
|||||||
_cellDataNotifier?.removeListener(fn);
|
_cellDataNotifier?.removeListener(fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
T? getCellData({bool loadIfNoCache = true}) {
|
/// Return the cell data.
|
||||||
final data = cellCache.get(_cacheKey);
|
/// The cell data will be read from the Cache first, and load from disk if it does not exist.
|
||||||
if (data == null && loadIfNoCache) {
|
/// You can set [loadIfNotExist] to false (default is true) to disable loading the cell data.
|
||||||
|
T? getCellData({bool loadIfNotExist = true}) {
|
||||||
|
final data = _cellsCache.get(_cacheKey);
|
||||||
|
if (data == null && loadIfNotExist) {
|
||||||
_loadData();
|
_loadData();
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<FieldTypeOptionData, FlowyError>> getTypeOptionData() {
|
/// Return the FieldTypeOptionData that can be parsed into corresponding class using the [parser].
|
||||||
return _fieldService.getFieldTypeOptionData(fieldType: fieldType);
|
/// [PD] is the type that the parser return.
|
||||||
|
Future<Either<PD, FlowyError>> getFieldTypeOption<PD, P extends TypeOptionDataParser>(P parser) {
|
||||||
|
return _fieldService.getFieldTypeOptionData(fieldType: fieldType).then((result) {
|
||||||
|
return result.fold(
|
||||||
|
(data) => parser.fromBuffer(data.typeOptionData),
|
||||||
|
(err) => right(err),
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Save the cell data to disk
|
||||||
|
/// You can set [dedeplicate] to true (default is false) to reduce the save operation.
|
||||||
|
/// It's useful when you call this method when user editing the [TextField].
|
||||||
|
/// The default debounce interval is 300 milliseconds.
|
||||||
void saveCellData(D data, {bool deduplicate = false, void Function(Option<FlowyError>)? resultCallback}) async {
|
void saveCellData(D data, {bool deduplicate = false, void Function(Option<FlowyError>)? resultCallback}) async {
|
||||||
if (deduplicate) {
|
if (deduplicate) {
|
||||||
_loadDataOperation?.cancel();
|
_loadDataOperation?.cancel();
|
||||||
_loadDataOperation = Timer(const Duration(milliseconds: 300), () async {
|
|
||||||
final result = await cellDataPersistence.save(data);
|
_saveDataOperation?.cancel();
|
||||||
|
_saveDataOperation = Timer(const Duration(milliseconds: 300), () async {
|
||||||
|
final result = await _cellDataPersistence.save(data);
|
||||||
if (resultCallback != null) {
|
if (resultCallback != null) {
|
||||||
resultCallback(result);
|
resultCallback(result);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
final result = await cellDataPersistence.save(data);
|
final result = await _cellDataPersistence.save(data);
|
||||||
if (resultCallback != null) {
|
if (resultCallback != null) {
|
||||||
resultCallback(result);
|
resultCallback(result);
|
||||||
}
|
}
|
||||||
@ -209,26 +258,59 @@ class _GridCellContext<T, D> extends Equatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _loadData() {
|
void _loadData() {
|
||||||
|
_saveDataOperation?.cancel();
|
||||||
|
|
||||||
_loadDataOperation?.cancel();
|
_loadDataOperation?.cancel();
|
||||||
_loadDataOperation = Timer(const Duration(milliseconds: 10), () {
|
_loadDataOperation = Timer(const Duration(milliseconds: 10), () {
|
||||||
cellDataLoader.loadData().then((data) {
|
_cellDataLoader.loadData().then((data) {
|
||||||
_cellDataNotifier?.value = data;
|
_cellDataNotifier?.value = data;
|
||||||
cellCache.insert(_GridCellCacheObject(key: _cacheKey, object: data));
|
_cellsCache.insert(_cacheKey, GridCell(object: data));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
if (_isDispose) {
|
||||||
|
Log.error("$this should only dispose once");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_isDispose = true;
|
||||||
_cellListener.stop();
|
_cellListener.stop();
|
||||||
_loadDataOperation?.cancel();
|
_loadDataOperation?.cancel();
|
||||||
_saveDataOperation?.cancel();
|
_saveDataOperation?.cancel();
|
||||||
|
_cellDataNotifier = null;
|
||||||
|
|
||||||
if (_onFieldChangedFn != null) {
|
if (_onFieldChangedFn != null) {
|
||||||
cellCache.removeFieldListener(_cacheKey, _onFieldChangedFn!);
|
_fieldNotifier.unregister(_cacheKey, _onFieldChangedFn!);
|
||||||
_onFieldChangedFn = null;
|
_onFieldChangedFn = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [cellCache.get(_cacheKey) ?? "", cellId];
|
List<Object> get props => [_cellsCache.get(_cacheKey) ?? "", cellId.rowId + cellId.field.id];
|
||||||
|
}
|
||||||
|
|
||||||
|
class _GridFieldChangedNotifierImpl extends GridFieldChangedNotifier {
|
||||||
|
final GridFieldCache _cache;
|
||||||
|
FieldChangesetCallback? _onChangesetFn;
|
||||||
|
|
||||||
|
_GridFieldChangedNotifierImpl(GridFieldCache cache) : _cache = cache;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
if (_onChangesetFn != null) {
|
||||||
|
_cache.removeListener(onChangsetListener: _onChangesetFn!);
|
||||||
|
_onChangesetFn = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onFieldChanged(void Function(Field p1) callback) {
|
||||||
|
_onChangesetFn = (GridFieldChangeset changeset) {
|
||||||
|
for (final updatedField in changeset.updatedFields) {
|
||||||
|
callback(updatedField);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
_cache.addListener(onChangeset: _onChangesetFn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import 'cell_service/cell_service.dart';
|
|||||||
part 'checkbox_cell_bloc.freezed.dart';
|
part 'checkbox_cell_bloc.freezed.dart';
|
||||||
|
|
||||||
class CheckboxCellBloc extends Bloc<CheckboxCellEvent, CheckboxCellState> {
|
class CheckboxCellBloc extends Bloc<CheckboxCellEvent, CheckboxCellState> {
|
||||||
final GridCellContext cellContext;
|
final GridCellController cellContext;
|
||||||
void Function()? _onCellChangedFn;
|
void Function()? _onCellChangedFn;
|
||||||
|
|
||||||
CheckboxCellBloc({
|
CheckboxCellBloc({
|
||||||
@ -67,7 +67,7 @@ class CheckboxCellState with _$CheckboxCellState {
|
|||||||
required bool isSelected,
|
required bool isSelected,
|
||||||
}) = _CheckboxCellState;
|
}) = _CheckboxCellState;
|
||||||
|
|
||||||
factory CheckboxCellState.initial(GridCellContext context) {
|
factory CheckboxCellState.initial(GridCellController context) {
|
||||||
return CheckboxCellState(isSelected: _isSelected(context.getCellData()));
|
return CheckboxCellState(isSelected: _isSelected(context.getCellData()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ import 'package:fixnum/fixnum.dart' as $fixnum;
|
|||||||
part 'date_cal_bloc.freezed.dart';
|
part 'date_cal_bloc.freezed.dart';
|
||||||
|
|
||||||
class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
|
class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
|
||||||
final GridDateCellContext cellContext;
|
final GridDateCellController cellContext;
|
||||||
void Function()? _onCellChangedFn;
|
void Function()? _onCellChangedFn;
|
||||||
|
|
||||||
DateCalBloc({
|
DateCalBloc({
|
||||||
|
@ -7,7 +7,7 @@ import 'cell_service/cell_service.dart';
|
|||||||
part 'date_cell_bloc.freezed.dart';
|
part 'date_cell_bloc.freezed.dart';
|
||||||
|
|
||||||
class DateCellBloc extends Bloc<DateCellEvent, DateCellState> {
|
class DateCellBloc extends Bloc<DateCellEvent, DateCellState> {
|
||||||
final GridDateCellContext cellContext;
|
final GridDateCellController cellContext;
|
||||||
void Function()? _onCellChangedFn;
|
void Function()? _onCellChangedFn;
|
||||||
|
|
||||||
DateCellBloc({required this.cellContext}) : super(DateCellState.initial(cellContext)) {
|
DateCellBloc({required this.cellContext}) : super(DateCellState.initial(cellContext)) {
|
||||||
@ -60,7 +60,7 @@ class DateCellState with _$DateCellState {
|
|||||||
required Field field,
|
required Field field,
|
||||||
}) = _DateCellState;
|
}) = _DateCellState;
|
||||||
|
|
||||||
factory DateCellState.initial(GridDateCellContext context) {
|
factory DateCellState.initial(GridDateCellController context) {
|
||||||
final cellData = context.getCellData();
|
final cellData = context.getCellData();
|
||||||
|
|
||||||
return DateCellState(
|
return DateCellState(
|
||||||
|
@ -8,7 +8,7 @@ import 'cell_service/cell_service.dart';
|
|||||||
part 'number_cell_bloc.freezed.dart';
|
part 'number_cell_bloc.freezed.dart';
|
||||||
|
|
||||||
class NumberCellBloc extends Bloc<NumberCellEvent, NumberCellState> {
|
class NumberCellBloc extends Bloc<NumberCellEvent, NumberCellState> {
|
||||||
final GridCellContext cellContext;
|
final GridCellController cellContext;
|
||||||
void Function()? _onCellChangedFn;
|
void Function()? _onCellChangedFn;
|
||||||
|
|
||||||
NumberCellBloc({
|
NumberCellBloc({
|
||||||
@ -72,7 +72,7 @@ class NumberCellState with _$NumberCellState {
|
|||||||
required Either<String, FlowyError> content,
|
required Either<String, FlowyError> content,
|
||||||
}) = _NumberCellState;
|
}) = _NumberCellState;
|
||||||
|
|
||||||
factory NumberCellState.initial(GridCellContext context) {
|
factory NumberCellState.initial(GridCellController context) {
|
||||||
final cellContent = context.getCellData() ?? "";
|
final cellContent = context.getCellData() ?? "";
|
||||||
return NumberCellState(
|
return NumberCellState(
|
||||||
content: left(cellContent),
|
content: left(cellContent),
|
||||||
|
@ -7,7 +7,7 @@ import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_serv
|
|||||||
part 'select_option_cell_bloc.freezed.dart';
|
part 'select_option_cell_bloc.freezed.dart';
|
||||||
|
|
||||||
class SelectOptionCellBloc extends Bloc<SelectOptionCellEvent, SelectOptionCellState> {
|
class SelectOptionCellBloc extends Bloc<SelectOptionCellEvent, SelectOptionCellState> {
|
||||||
final GridSelectOptionCellContext cellContext;
|
final GridSelectOptionCellController cellContext;
|
||||||
void Function()? _onCellChangedFn;
|
void Function()? _onCellChangedFn;
|
||||||
|
|
||||||
SelectOptionCellBloc({
|
SelectOptionCellBloc({
|
||||||
@ -66,7 +66,7 @@ class SelectOptionCellState with _$SelectOptionCellState {
|
|||||||
required List<SelectOption> selectedOptions,
|
required List<SelectOption> selectedOptions,
|
||||||
}) = _SelectOptionCellState;
|
}) = _SelectOptionCellState;
|
||||||
|
|
||||||
factory SelectOptionCellState.initial(GridSelectOptionCellContext context) {
|
factory SelectOptionCellState.initial(GridSelectOptionCellController context) {
|
||||||
final data = context.getCellData();
|
final data = context.getCellData();
|
||||||
|
|
||||||
return SelectOptionCellState(
|
return SelectOptionCellState(
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:app_flowy/workspace/application/grid/field/grid_listenr.dart';
|
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:flowy_sdk/log.dart';
|
import 'package:flowy_sdk/log.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
||||||
@ -13,16 +12,13 @@ part 'select_option_editor_bloc.freezed.dart';
|
|||||||
|
|
||||||
class SelectOptionCellEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOptionEditorState> {
|
class SelectOptionCellEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOptionEditorState> {
|
||||||
final SelectOptionService _selectOptionService;
|
final SelectOptionService _selectOptionService;
|
||||||
final GridSelectOptionCellContext cellContext;
|
final GridSelectOptionCellController cellController;
|
||||||
late final GridFieldsListener _fieldListener;
|
|
||||||
void Function()? _onCellChangedFn;
|
|
||||||
Timer? _delayOperation;
|
Timer? _delayOperation;
|
||||||
|
|
||||||
SelectOptionCellEditorBloc({
|
SelectOptionCellEditorBloc({
|
||||||
required this.cellContext,
|
required this.cellController,
|
||||||
}) : _selectOptionService = SelectOptionService(gridCell: cellContext.gridCell),
|
}) : _selectOptionService = SelectOptionService(cellId: cellController.cellId),
|
||||||
_fieldListener = GridFieldsListener(gridId: cellContext.gridId),
|
super(SelectOptionEditorState.initial(cellController)) {
|
||||||
super(SelectOptionEditorState.initial(cellContext)) {
|
|
||||||
on<SelectOptionEditorEvent>(
|
on<SelectOptionEditorEvent>(
|
||||||
(event, emit) async {
|
(event, emit) async {
|
||||||
await event.map(
|
await event.map(
|
||||||
@ -64,13 +60,8 @@ class SelectOptionCellEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOpt
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> close() async {
|
Future<void> close() async {
|
||||||
if (_onCellChangedFn != null) {
|
|
||||||
cellContext.removeListener(_onCellChangedFn!);
|
|
||||||
_onCellChangedFn = null;
|
|
||||||
}
|
|
||||||
_delayOperation?.cancel();
|
_delayOperation?.cancel();
|
||||||
await _fieldListener.stop();
|
cellController.dispose();
|
||||||
cellContext.dispose();
|
|
||||||
return super.close();
|
return super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,24 +148,16 @@ class SelectOptionCellEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOpt
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _startListening() {
|
void _startListening() {
|
||||||
_onCellChangedFn = cellContext.startListening(
|
cellController.startListening(
|
||||||
onCellChanged: ((selectOptionContext) {
|
onCellChanged: ((selectOptionContext) {
|
||||||
if (!isClosed) {
|
if (!isClosed) {
|
||||||
_loadOptions();
|
_loadOptions();
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
onCellFieldChanged: () {
|
||||||
|
_loadOptions();
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
_fieldListener.start(onFieldsChanged: (result) {
|
|
||||||
result.fold(
|
|
||||||
(changeset) {
|
|
||||||
if (changeset.updatedFields.isNotEmpty) {
|
|
||||||
_loadOptions();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(err) => Log.error(err),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,8 +183,8 @@ class SelectOptionEditorState with _$SelectOptionEditorState {
|
|||||||
required Option<String> filter,
|
required Option<String> filter,
|
||||||
}) = _SelectOptionEditorState;
|
}) = _SelectOptionEditorState;
|
||||||
|
|
||||||
factory SelectOptionEditorState.initial(GridSelectOptionCellContext context) {
|
factory SelectOptionEditorState.initial(GridSelectOptionCellController context) {
|
||||||
final data = context.getCellData(loadIfNoCache: false);
|
final data = context.getCellData(loadIfNotExist: false);
|
||||||
return SelectOptionEditorState(
|
return SelectOptionEditorState(
|
||||||
options: data?.options ?? [],
|
options: data?.options ?? [],
|
||||||
allOptions: data?.options ?? [],
|
allOptions: data?.options ?? [],
|
||||||
|
@ -7,12 +7,12 @@ import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
|||||||
import 'cell_service/cell_service.dart';
|
import 'cell_service/cell_service.dart';
|
||||||
|
|
||||||
class SelectOptionService {
|
class SelectOptionService {
|
||||||
final GridCell gridCell;
|
final GridCellIdentifier cellId;
|
||||||
SelectOptionService({required this.gridCell});
|
SelectOptionService({required this.cellId});
|
||||||
|
|
||||||
String get gridId => gridCell.gridId;
|
String get gridId => cellId.gridId;
|
||||||
String get fieldId => gridCell.field.id;
|
String get fieldId => cellId.field.id;
|
||||||
String get rowId => gridCell.rowId;
|
String get rowId => cellId.rowId;
|
||||||
|
|
||||||
Future<Either<Unit, FlowyError>> create({required String name}) {
|
Future<Either<Unit, FlowyError>> create({required String name}) {
|
||||||
return TypeOptionService(gridId: gridId, fieldId: fieldId).newOption(name: name).then(
|
return TypeOptionService(gridId: gridId, fieldId: fieldId).newOption(name: name).then(
|
||||||
|
@ -6,7 +6,7 @@ import 'cell_service/cell_service.dart';
|
|||||||
part 'text_cell_bloc.freezed.dart';
|
part 'text_cell_bloc.freezed.dart';
|
||||||
|
|
||||||
class TextCellBloc extends Bloc<TextCellEvent, TextCellState> {
|
class TextCellBloc extends Bloc<TextCellEvent, TextCellState> {
|
||||||
final GridCellContext cellContext;
|
final GridCellController cellContext;
|
||||||
void Function()? _onCellChangedFn;
|
void Function()? _onCellChangedFn;
|
||||||
TextCellBloc({
|
TextCellBloc({
|
||||||
required this.cellContext,
|
required this.cellContext,
|
||||||
@ -63,7 +63,7 @@ class TextCellState with _$TextCellState {
|
|||||||
required String content,
|
required String content,
|
||||||
}) = _TextCellState;
|
}) = _TextCellState;
|
||||||
|
|
||||||
factory TextCellState.initial(GridCellContext context) => TextCellState(
|
factory TextCellState.initial(GridCellController context) => TextCellState(
|
||||||
content: context.getCellData() ?? "",
|
content: context.getCellData() ?? "",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import 'cell_service/cell_service.dart';
|
|||||||
part 'url_cell_bloc.freezed.dart';
|
part 'url_cell_bloc.freezed.dart';
|
||||||
|
|
||||||
class URLCellBloc extends Bloc<URLCellEvent, URLCellState> {
|
class URLCellBloc extends Bloc<URLCellEvent, URLCellState> {
|
||||||
final GridURLCellContext cellContext;
|
final GridURLCellController cellContext;
|
||||||
void Function()? _onCellChangedFn;
|
void Function()? _onCellChangedFn;
|
||||||
URLCellBloc({
|
URLCellBloc({
|
||||||
required this.cellContext,
|
required this.cellContext,
|
||||||
@ -67,7 +67,7 @@ class URLCellState with _$URLCellState {
|
|||||||
required String url,
|
required String url,
|
||||||
}) = _URLCellState;
|
}) = _URLCellState;
|
||||||
|
|
||||||
factory URLCellState.initial(GridURLCellContext context) {
|
factory URLCellState.initial(GridURLCellController context) {
|
||||||
final cellData = context.getCellData();
|
final cellData = context.getCellData();
|
||||||
return URLCellState(
|
return URLCellState(
|
||||||
content: cellData?.content ?? "",
|
content: cellData?.content ?? "",
|
||||||
|
@ -7,7 +7,7 @@ import 'cell_service/cell_service.dart';
|
|||||||
part 'url_cell_editor_bloc.freezed.dart';
|
part 'url_cell_editor_bloc.freezed.dart';
|
||||||
|
|
||||||
class URLCellEditorBloc extends Bloc<URLCellEditorEvent, URLCellEditorState> {
|
class URLCellEditorBloc extends Bloc<URLCellEditorEvent, URLCellEditorState> {
|
||||||
final GridURLCellContext cellContext;
|
final GridURLCellController cellContext;
|
||||||
void Function()? _onCellChangedFn;
|
void Function()? _onCellChangedFn;
|
||||||
URLCellEditorBloc({
|
URLCellEditorBloc({
|
||||||
required this.cellContext,
|
required this.cellContext,
|
||||||
@ -64,7 +64,7 @@ class URLCellEditorState with _$URLCellEditorState {
|
|||||||
required String content,
|
required String content,
|
||||||
}) = _URLCellEditorState;
|
}) = _URLCellEditorState;
|
||||||
|
|
||||||
factory URLCellEditorState.initial(GridURLCellContext context) {
|
factory URLCellEditorState.initial(GridURLCellController context) {
|
||||||
final cellData = context.getCellData();
|
final cellData = context.getCellData();
|
||||||
return URLCellEditorState(
|
return URLCellEditorState(
|
||||||
content: cellData?.content ?? "",
|
content: cellData?.content ?? "",
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
@ -6,27 +7,32 @@ import 'package:dartz/dartz.dart';
|
|||||||
part 'field_editor_bloc.freezed.dart';
|
part 'field_editor_bloc.freezed.dart';
|
||||||
|
|
||||||
class FieldEditorBloc extends Bloc<FieldEditorEvent, FieldEditorState> {
|
class FieldEditorBloc extends Bloc<FieldEditorEvent, FieldEditorState> {
|
||||||
|
final TypeOptionDataController dataController;
|
||||||
|
|
||||||
FieldEditorBloc({
|
FieldEditorBloc({
|
||||||
required String gridId,
|
required String gridId,
|
||||||
required String fieldName,
|
required String fieldName,
|
||||||
required IFieldContextLoader fieldContextLoader,
|
required IFieldTypeOptionLoader loader,
|
||||||
}) : super(FieldEditorState.initial(gridId, fieldName, fieldContextLoader)) {
|
}) : dataController = TypeOptionDataController(gridId: gridId, loader: loader),
|
||||||
|
super(FieldEditorState.initial(gridId, fieldName)) {
|
||||||
on<FieldEditorEvent>(
|
on<FieldEditorEvent>(
|
||||||
(event, emit) async {
|
(event, emit) async {
|
||||||
await event.when(
|
await event.when(
|
||||||
initial: () async {
|
initial: () async {
|
||||||
final fieldContext = GridFieldContext(gridId: gridId, loader: fieldContextLoader);
|
dataController.addFieldListener((field) {
|
||||||
await fieldContext.loadData().then((result) {
|
if (!isClosed) {
|
||||||
result.fold(
|
add(FieldEditorEvent.didReceiveFieldChanged(field));
|
||||||
(l) => emit(state.copyWith(fieldContext: Some(fieldContext), name: fieldContext.field.name)),
|
}
|
||||||
(r) => null,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
await dataController.loadData();
|
||||||
},
|
},
|
||||||
updateName: (name) {
|
updateName: (name) {
|
||||||
state.fieldContext.fold(() => null, (fieldContext) => fieldContext.fieldName = name);
|
dataController.fieldName = name;
|
||||||
emit(state.copyWith(name: name));
|
emit(state.copyWith(name: name));
|
||||||
},
|
},
|
||||||
|
didReceiveFieldChanged: (Field field) {
|
||||||
|
emit(state.copyWith(field: Some(field)));
|
||||||
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -42,6 +48,7 @@ class FieldEditorBloc extends Bloc<FieldEditorEvent, FieldEditorState> {
|
|||||||
class FieldEditorEvent with _$FieldEditorEvent {
|
class FieldEditorEvent with _$FieldEditorEvent {
|
||||||
const factory FieldEditorEvent.initial() = _InitialField;
|
const factory FieldEditorEvent.initial() = _InitialField;
|
||||||
const factory FieldEditorEvent.updateName(String name) = _UpdateName;
|
const factory FieldEditorEvent.updateName(String name) = _UpdateName;
|
||||||
|
const factory FieldEditorEvent.didReceiveFieldChanged(Field field) = _DidReceiveFieldChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
@ -50,13 +57,17 @@ class FieldEditorState with _$FieldEditorState {
|
|||||||
required String gridId,
|
required String gridId,
|
||||||
required String errorText,
|
required String errorText,
|
||||||
required String name,
|
required String name,
|
||||||
required Option<GridFieldContext> fieldContext,
|
required Option<Field> field,
|
||||||
}) = _FieldEditorState;
|
}) = _FieldEditorState;
|
||||||
|
|
||||||
factory FieldEditorState.initial(String gridId, String fieldName, IFieldContextLoader loader) => FieldEditorState(
|
factory FieldEditorState.initial(
|
||||||
|
String gridId,
|
||||||
|
String fieldName,
|
||||||
|
) =>
|
||||||
|
FieldEditorState(
|
||||||
gridId: gridId,
|
gridId: gridId,
|
||||||
fieldContext: none(),
|
|
||||||
errorText: '',
|
errorText: '',
|
||||||
|
field: none(),
|
||||||
name: fieldName,
|
name: fieldName,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,57 +0,0 @@
|
|||||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'field_service.dart';
|
|
||||||
|
|
||||||
part 'field_editor_pannel_bloc.freezed.dart';
|
|
||||||
|
|
||||||
class FieldEditorPannelBloc extends Bloc<FieldEditorPannelEvent, FieldEditorPannelState> {
|
|
||||||
final GridFieldContext _fieldContext;
|
|
||||||
void Function()? _fieldListenFn;
|
|
||||||
|
|
||||||
FieldEditorPannelBloc(GridFieldContext fieldContext)
|
|
||||||
: _fieldContext = fieldContext,
|
|
||||||
super(FieldEditorPannelState.initial(fieldContext)) {
|
|
||||||
on<FieldEditorPannelEvent>(
|
|
||||||
(event, emit) async {
|
|
||||||
event.when(
|
|
||||||
initial: () {
|
|
||||||
_fieldListenFn = fieldContext.addFieldListener((field) {
|
|
||||||
add(FieldEditorPannelEvent.didReceiveFieldUpdated(field));
|
|
||||||
});
|
|
||||||
},
|
|
||||||
didReceiveFieldUpdated: (field) {
|
|
||||||
emit(state.copyWith(field: field));
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> close() async {
|
|
||||||
if (_fieldListenFn != null) {
|
|
||||||
_fieldContext.removeFieldListener(_fieldListenFn!);
|
|
||||||
}
|
|
||||||
return super.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class FieldEditorPannelEvent with _$FieldEditorPannelEvent {
|
|
||||||
const factory FieldEditorPannelEvent.initial() = _Initial;
|
|
||||||
const factory FieldEditorPannelEvent.didReceiveFieldUpdated(Field field) = _DidReceiveFieldUpdated;
|
|
||||||
}
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class FieldEditorPannelState with _$FieldEditorPannelState {
|
|
||||||
const factory FieldEditorPannelState({
|
|
||||||
required Field field,
|
|
||||||
}) = _FieldEditorPannelState;
|
|
||||||
|
|
||||||
factory FieldEditorPannelState.initial(GridFieldContext fieldContext) => FieldEditorPannelState(
|
|
||||||
field: fieldContext.field,
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:flowy_infra/notifier.dart';
|
||||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||||
import 'package:flowy_sdk/log.dart';
|
import 'package:flowy_sdk/log.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||||
@ -9,6 +10,10 @@ import 'package:freezed_annotation/freezed_annotation.dart';
|
|||||||
import 'package:protobuf/protobuf.dart';
|
import 'package:protobuf/protobuf.dart';
|
||||||
part 'field_service.freezed.dart';
|
part 'field_service.freezed.dart';
|
||||||
|
|
||||||
|
/// FieldService consists of lots of event functions. We define the events in the backend(Rust),
|
||||||
|
/// you can find the corresponding event implementation in event_map.rs of the corresponding crate.
|
||||||
|
///
|
||||||
|
/// You could check out the rust-lib/flowy-grid/event_map.rs for more information.
|
||||||
class FieldService {
|
class FieldService {
|
||||||
final String gridId;
|
final String gridId;
|
||||||
final String fieldId;
|
final String fieldId;
|
||||||
@ -137,7 +142,7 @@ class GridFieldCellContext with _$GridFieldCellContext {
|
|||||||
}) = _GridFieldCellContext;
|
}) = _GridFieldCellContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class IFieldContextLoader {
|
abstract class IFieldTypeOptionLoader {
|
||||||
String get gridId;
|
String get gridId;
|
||||||
Future<Either<FieldTypeOptionData, FlowyError>> load();
|
Future<Either<FieldTypeOptionData, FlowyError>> load();
|
||||||
|
|
||||||
@ -151,10 +156,10 @@ abstract class IFieldContextLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NewFieldContextLoader extends IFieldContextLoader {
|
class NewFieldTypeOptionLoader extends IFieldTypeOptionLoader {
|
||||||
@override
|
@override
|
||||||
final String gridId;
|
final String gridId;
|
||||||
NewFieldContextLoader({
|
NewFieldTypeOptionLoader({
|
||||||
required this.gridId,
|
required this.gridId,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -168,12 +173,12 @@ class NewFieldContextLoader extends IFieldContextLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class FieldContextLoader extends IFieldContextLoader {
|
class FieldTypeOptionLoader extends IFieldTypeOptionLoader {
|
||||||
@override
|
@override
|
||||||
final String gridId;
|
final String gridId;
|
||||||
final Field field;
|
final Field field;
|
||||||
|
|
||||||
FieldContextLoader({
|
FieldTypeOptionLoader({
|
||||||
required this.gridId,
|
required this.gridId,
|
||||||
required this.field,
|
required this.field,
|
||||||
});
|
});
|
||||||
@ -189,16 +194,16 @@ class FieldContextLoader extends IFieldContextLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class GridFieldContext {
|
class TypeOptionDataController {
|
||||||
final String gridId;
|
final String gridId;
|
||||||
final IFieldContextLoader _loader;
|
final IFieldTypeOptionLoader _loader;
|
||||||
|
|
||||||
late FieldTypeOptionData _data;
|
late FieldTypeOptionData _data;
|
||||||
ValueNotifier<Field>? _fieldNotifier;
|
final PublishNotifier<Field> _fieldNotifier = PublishNotifier();
|
||||||
|
|
||||||
GridFieldContext({
|
TypeOptionDataController({
|
||||||
required this.gridId,
|
required this.gridId,
|
||||||
required IFieldContextLoader loader,
|
required IFieldTypeOptionLoader loader,
|
||||||
}) : _loader = loader;
|
}) : _loader = loader;
|
||||||
|
|
||||||
Future<Either<Unit, FlowyError>> loadData() async {
|
Future<Either<Unit, FlowyError>> loadData() async {
|
||||||
@ -207,13 +212,7 @@ class GridFieldContext {
|
|||||||
(data) {
|
(data) {
|
||||||
data.freeze();
|
data.freeze();
|
||||||
_data = data;
|
_data = data;
|
||||||
|
_fieldNotifier.value = data.field_2;
|
||||||
if (_fieldNotifier == null) {
|
|
||||||
_fieldNotifier = ValueNotifier(data.field_2);
|
|
||||||
} else {
|
|
||||||
_fieldNotifier?.value = data.field_2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return left(unit);
|
return left(unit);
|
||||||
},
|
},
|
||||||
(err) {
|
(err) {
|
||||||
@ -256,9 +255,7 @@ class GridFieldContext {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (_data.field_2 != _fieldNotifier?.value) {
|
_fieldNotifier.value = _data.field_2;
|
||||||
_fieldNotifier?.value = _data.field_2;
|
|
||||||
}
|
|
||||||
|
|
||||||
FieldService.insertField(
|
FieldService.insertField(
|
||||||
gridId: gridId,
|
gridId: gridId,
|
||||||
@ -288,11 +285,11 @@ class GridFieldContext {
|
|||||||
callback(field);
|
callback(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
_fieldNotifier?.addListener(listener);
|
_fieldNotifier.addListener(listener);
|
||||||
return listener;
|
return listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeFieldListener(void Function() listener) {
|
void removeFieldListener(void Function() listener) {
|
||||||
_fieldNotifier?.removeListener(listener);
|
_fieldNotifier.removeListener(listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'field_service.dart';
|
||||||
|
|
||||||
|
part 'field_type_option_edit_bloc.freezed.dart';
|
||||||
|
|
||||||
|
class FieldTypeOptionEditBloc extends Bloc<FieldTypeOptionEditEvent, FieldTypeOptionEditState> {
|
||||||
|
final TypeOptionDataController _dataController;
|
||||||
|
void Function()? _fieldListenFn;
|
||||||
|
|
||||||
|
FieldTypeOptionEditBloc(TypeOptionDataController dataController)
|
||||||
|
: _dataController = dataController,
|
||||||
|
super(FieldTypeOptionEditState.initial(dataController)) {
|
||||||
|
on<FieldTypeOptionEditEvent>(
|
||||||
|
(event, emit) async {
|
||||||
|
event.when(
|
||||||
|
initial: () {
|
||||||
|
_fieldListenFn = dataController.addFieldListener((field) {
|
||||||
|
add(FieldTypeOptionEditEvent.didReceiveFieldUpdated(field));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
didReceiveFieldUpdated: (field) {
|
||||||
|
emit(state.copyWith(field: field));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> close() async {
|
||||||
|
if (_fieldListenFn != null) {
|
||||||
|
_dataController.removeFieldListener(_fieldListenFn!);
|
||||||
|
}
|
||||||
|
return super.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class FieldTypeOptionEditEvent with _$FieldTypeOptionEditEvent {
|
||||||
|
const factory FieldTypeOptionEditEvent.initial() = _Initial;
|
||||||
|
const factory FieldTypeOptionEditEvent.didReceiveFieldUpdated(Field field) = _DidReceiveFieldUpdated;
|
||||||
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class FieldTypeOptionEditState with _$FieldTypeOptionEditState {
|
||||||
|
const factory FieldTypeOptionEditState({
|
||||||
|
required Field field,
|
||||||
|
}) = _FieldTypeOptionEditState;
|
||||||
|
|
||||||
|
factory FieldTypeOptionEditState.initial(TypeOptionDataController fieldContext) => FieldTypeOptionEditState(
|
||||||
|
field: fieldContext.field,
|
||||||
|
);
|
||||||
|
}
|
@ -7,9 +7,9 @@ import 'dart:async';
|
|||||||
import 'package:protobuf/protobuf.dart';
|
import 'package:protobuf/protobuf.dart';
|
||||||
part 'date_bloc.freezed.dart';
|
part 'date_bloc.freezed.dart';
|
||||||
|
|
||||||
typedef DateTypeOptionContext = TypeOptionContext<DateTypeOption>;
|
typedef DateTypeOptionContext = TypeOptionWidgetContext<DateTypeOption>;
|
||||||
|
|
||||||
class DateTypeOptionDataBuilder extends TypeOptionDataBuilder<DateTypeOption> {
|
class DateTypeOptionDataParser extends TypeOptionDataParser<DateTypeOption> {
|
||||||
@override
|
@override
|
||||||
DateTypeOption fromBuffer(List<int> buffer) {
|
DateTypeOption fromBuffer(List<int> buffer) {
|
||||||
return DateTypeOption.fromBuffer(buffer);
|
return DateTypeOption.fromBuffer(buffer);
|
||||||
|
@ -7,17 +7,18 @@ import 'package:protobuf/protobuf.dart';
|
|||||||
import 'select_option_type_option_bloc.dart';
|
import 'select_option_type_option_bloc.dart';
|
||||||
import 'type_option_service.dart';
|
import 'type_option_service.dart';
|
||||||
|
|
||||||
class MultiSelectTypeOptionContext extends TypeOptionContext<MultiSelectTypeOption> with SelectOptionTypeOptionAction {
|
class MultiSelectTypeOptionContext extends TypeOptionWidgetContext<MultiSelectTypeOption>
|
||||||
|
with SelectOptionTypeOptionAction {
|
||||||
final TypeOptionService service;
|
final TypeOptionService service;
|
||||||
|
|
||||||
MultiSelectTypeOptionContext({
|
MultiSelectTypeOptionContext({
|
||||||
required MultiSelectTypeOptionDataBuilder dataBuilder,
|
required MultiSelectTypeOptionWidgetDataParser dataBuilder,
|
||||||
required GridFieldContext fieldContext,
|
required TypeOptionDataController dataController,
|
||||||
}) : service = TypeOptionService(
|
}) : service = TypeOptionService(
|
||||||
gridId: fieldContext.gridId,
|
gridId: dataController.gridId,
|
||||||
fieldId: fieldContext.field.id,
|
fieldId: dataController.field.id,
|
||||||
),
|
),
|
||||||
super(dataBuilder: dataBuilder, fieldContext: fieldContext);
|
super(dataParser: dataBuilder, dataController: dataController);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<SelectOption> Function(SelectOption) get deleteOption {
|
List<SelectOption> Function(SelectOption) get deleteOption {
|
||||||
@ -70,7 +71,7 @@ class MultiSelectTypeOptionContext extends TypeOptionContext<MultiSelectTypeOpti
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MultiSelectTypeOptionDataBuilder extends TypeOptionDataBuilder<MultiSelectTypeOption> {
|
class MultiSelectTypeOptionWidgetDataParser extends TypeOptionDataParser<MultiSelectTypeOption> {
|
||||||
@override
|
@override
|
||||||
MultiSelectTypeOption fromBuffer(List<int> buffer) {
|
MultiSelectTypeOption fromBuffer(List<int> buffer) {
|
||||||
return MultiSelectTypeOption.fromBuffer(buffer);
|
return MultiSelectTypeOption.fromBuffer(buffer);
|
||||||
|
@ -8,9 +8,9 @@ import 'package:protobuf/protobuf.dart';
|
|||||||
|
|
||||||
part 'number_bloc.freezed.dart';
|
part 'number_bloc.freezed.dart';
|
||||||
|
|
||||||
typedef NumberTypeOptionContext = TypeOptionContext<NumberTypeOption>;
|
typedef NumberTypeOptionContext = TypeOptionWidgetContext<NumberTypeOption>;
|
||||||
|
|
||||||
class NumberTypeOptionDataBuilder extends TypeOptionDataBuilder<NumberTypeOption> {
|
class NumberTypeOptionWidgetDataParser extends TypeOptionDataParser<NumberTypeOption> {
|
||||||
@override
|
@override
|
||||||
NumberTypeOption fromBuffer(List<int> buffer) {
|
NumberTypeOption fromBuffer(List<int> buffer) {
|
||||||
return NumberTypeOption.fromBuffer(buffer);
|
return NumberTypeOption.fromBuffer(buffer);
|
||||||
|
@ -7,18 +7,18 @@ import 'package:protobuf/protobuf.dart';
|
|||||||
import 'select_option_type_option_bloc.dart';
|
import 'select_option_type_option_bloc.dart';
|
||||||
import 'type_option_service.dart';
|
import 'type_option_service.dart';
|
||||||
|
|
||||||
class SingleSelectTypeOptionContext extends TypeOptionContext<SingleSelectTypeOption>
|
class SingleSelectTypeOptionContext extends TypeOptionWidgetContext<SingleSelectTypeOption>
|
||||||
with SelectOptionTypeOptionAction {
|
with SelectOptionTypeOptionAction {
|
||||||
final TypeOptionService service;
|
final TypeOptionService service;
|
||||||
|
|
||||||
SingleSelectTypeOptionContext({
|
SingleSelectTypeOptionContext({
|
||||||
required SingleSelectTypeOptionDataBuilder dataBuilder,
|
required SingleSelectTypeOptionWidgetDataParser dataBuilder,
|
||||||
required GridFieldContext fieldContext,
|
required TypeOptionDataController fieldContext,
|
||||||
}) : service = TypeOptionService(
|
}) : service = TypeOptionService(
|
||||||
gridId: fieldContext.gridId,
|
gridId: fieldContext.gridId,
|
||||||
fieldId: fieldContext.field.id,
|
fieldId: fieldContext.field.id,
|
||||||
),
|
),
|
||||||
super(dataBuilder: dataBuilder, fieldContext: fieldContext);
|
super(dataParser: dataBuilder, dataController: fieldContext);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<SelectOption> Function(SelectOption) get deleteOption {
|
List<SelectOption> Function(SelectOption) get deleteOption {
|
||||||
@ -71,7 +71,7 @@ class SingleSelectTypeOptionContext extends TypeOptionContext<SingleSelectTypeOp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SingleSelectTypeOptionDataBuilder extends TypeOptionDataBuilder<SingleSelectTypeOption> {
|
class SingleSelectTypeOptionWidgetDataParser extends TypeOptionDataParser<SingleSelectTypeOption> {
|
||||||
@override
|
@override
|
||||||
SingleSelectTypeOption fromBuffer(List<int> buffer) {
|
SingleSelectTypeOption fromBuffer(List<int> buffer) {
|
||||||
return SingleSelectTypeOption.fromBuffer(buffer);
|
return SingleSelectTypeOption.fromBuffer(buffer);
|
||||||
|
@ -33,36 +33,36 @@ class TypeOptionService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class TypeOptionDataBuilder<T> {
|
abstract class TypeOptionDataParser<T> {
|
||||||
T fromBuffer(List<int> buffer);
|
T fromBuffer(List<int> buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
class TypeOptionContext<T extends GeneratedMessage> {
|
class TypeOptionWidgetContext<T extends GeneratedMessage> {
|
||||||
T? _typeOptionObject;
|
T? _typeOptionObject;
|
||||||
final GridFieldContext _fieldContext;
|
final TypeOptionDataController _dataController;
|
||||||
final TypeOptionDataBuilder<T> dataBuilder;
|
final TypeOptionDataParser<T> dataParser;
|
||||||
|
|
||||||
TypeOptionContext({
|
TypeOptionWidgetContext({
|
||||||
required this.dataBuilder,
|
required this.dataParser,
|
||||||
required GridFieldContext fieldContext,
|
required TypeOptionDataController dataController,
|
||||||
}) : _fieldContext = fieldContext;
|
}) : _dataController = dataController;
|
||||||
|
|
||||||
String get gridId => _fieldContext.gridId;
|
String get gridId => _dataController.gridId;
|
||||||
|
|
||||||
Field get field => _fieldContext.field;
|
Field get field => _dataController.field;
|
||||||
|
|
||||||
T get typeOption {
|
T get typeOption {
|
||||||
if (_typeOptionObject != null) {
|
if (_typeOptionObject != null) {
|
||||||
return _typeOptionObject!;
|
return _typeOptionObject!;
|
||||||
}
|
}
|
||||||
|
|
||||||
final T object = dataBuilder.fromBuffer(_fieldContext.typeOptionData);
|
final T object = dataParser.fromBuffer(_dataController.typeOptionData);
|
||||||
_typeOptionObject = object;
|
_typeOptionObject = object;
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
set typeOption(T typeOption) {
|
set typeOption(T typeOption) {
|
||||||
_fieldContext.typeOptionData = typeOption.writeToBuffer();
|
_dataController.typeOptionData = typeOption.writeToBuffer();
|
||||||
_typeOptionObject = typeOption;
|
_typeOptionObject = typeOption;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,7 +77,7 @@ class TypeOptionContext2<T> {
|
|||||||
final Field field;
|
final Field field;
|
||||||
final FieldService _fieldService;
|
final FieldService _fieldService;
|
||||||
T? _data;
|
T? _data;
|
||||||
final TypeOptionDataBuilder dataBuilder;
|
final TypeOptionDataParser dataBuilder;
|
||||||
|
|
||||||
TypeOptionContext2({
|
TypeOptionContext2({
|
||||||
required this.gridId,
|
required this.gridId,
|
||||||
|
@ -7,7 +7,7 @@ import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
|||||||
import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'block/block_service.dart';
|
import 'block/block_cache.dart';
|
||||||
import 'grid_service.dart';
|
import 'grid_service.dart';
|
||||||
import 'row/row_service.dart';
|
import 'row/row_service.dart';
|
||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
@ -20,7 +20,7 @@ class GridBloc extends Bloc<GridEvent, GridState> {
|
|||||||
final GridFieldCache fieldCache;
|
final GridFieldCache fieldCache;
|
||||||
|
|
||||||
// key: the block id
|
// key: the block id
|
||||||
final LinkedHashMap<String, GridBlockCacheService> _blocks;
|
final LinkedHashMap<String, GridBlockCache> _blocks;
|
||||||
|
|
||||||
List<GridRow> get rows {
|
List<GridRow> get rows {
|
||||||
final List<GridRow> rows = [];
|
final List<GridRow> rows = [];
|
||||||
@ -68,8 +68,8 @@ class GridBloc extends Bloc<GridEvent, GridState> {
|
|||||||
return super.close();
|
return super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
GridRowCacheService? getRowCache(String blockId, String rowId) {
|
GridRowCache? getRowCache(String blockId, String rowId) {
|
||||||
final GridBlockCacheService? blockCache = _blocks[blockId];
|
final GridBlockCache? blockCache = _blocks[blockId];
|
||||||
return blockCache?.rowCache;
|
return blockCache?.rowCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +119,7 @@ class GridBloc extends Bloc<GridEvent, GridState> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final cache = GridBlockCacheService(
|
final cache = GridBlockCache(
|
||||||
gridId: gridId,
|
gridId: gridId,
|
||||||
block: block,
|
block: block,
|
||||||
fieldCache: fieldCache,
|
fieldCache: fieldCache,
|
||||||
|
@ -61,13 +61,12 @@ typedef FieldsCallback = void Function(List<Field>);
|
|||||||
|
|
||||||
class GridFieldCache {
|
class GridFieldCache {
|
||||||
final String gridId;
|
final String gridId;
|
||||||
late final GridFieldsListener _fieldListener;
|
final GridFieldsListener _fieldListener;
|
||||||
FieldsNotifier? _fieldNotifier = FieldsNotifier();
|
FieldsNotifier? _fieldNotifier = FieldsNotifier();
|
||||||
final Map<FieldsCallback, VoidCallback> _fieldsCallbackMap = {};
|
final Map<FieldsCallback, VoidCallback> _fieldsCallbackMap = {};
|
||||||
final Map<FieldChangesetCallback, FieldChangesetCallback> _changesetCallbackMap = {};
|
final Map<FieldChangesetCallback, FieldChangesetCallback> _changesetCallbackMap = {};
|
||||||
|
|
||||||
GridFieldCache({required this.gridId}) {
|
GridFieldCache({required this.gridId}) : _fieldListener = GridFieldsListener(gridId: gridId) {
|
||||||
_fieldListener = GridFieldsListener(gridId: gridId);
|
|
||||||
_fieldListener.start(onFieldsChanged: (result) {
|
_fieldListener.start(onFieldsChanged: (result) {
|
||||||
result.fold(
|
result.fold(
|
||||||
(changeset) {
|
(changeset) {
|
||||||
@ -186,11 +185,11 @@ class GridFieldCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class GridRowCacheDelegateImpl extends GridRowCacheDelegate {
|
class GridRowCacheFieldNotifierImpl extends GridRowCacheFieldNotifier {
|
||||||
final GridFieldCache _cache;
|
final GridFieldCache _cache;
|
||||||
FieldChangesetCallback? _onChangesetFn;
|
FieldChangesetCallback? _onChangesetFn;
|
||||||
FieldsCallback? _onFieldFn;
|
FieldsCallback? _onFieldFn;
|
||||||
GridRowCacheDelegateImpl(GridFieldCache cache) : _cache = cache;
|
GridRowCacheFieldNotifierImpl(GridFieldCache cache) : _cache = cache;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
UnmodifiableListView<Field> get fields => _cache.unmodifiableFields;
|
UnmodifiableListView<Field> get fields => _cache.unmodifiableFields;
|
||||||
@ -202,7 +201,7 @@ class GridRowCacheDelegateImpl extends GridRowCacheDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onFieldUpdated(void Function(Field) callback) {
|
void onFieldChanged(void Function(Field) callback) {
|
||||||
_onChangesetFn = (GridFieldChangeset changeset) {
|
_onChangesetFn = (GridFieldChangeset changeset) {
|
||||||
for (final updatedField in changeset.updatedFields) {
|
for (final updatedField in changeset.updatedFields) {
|
||||||
callback(updatedField);
|
callback(updatedField);
|
||||||
|
@ -8,7 +8,7 @@ export 'grid_header_bloc.dart';
|
|||||||
export 'field/field_service.dart';
|
export 'field/field_service.dart';
|
||||||
export 'field/field_action_sheet_bloc.dart';
|
export 'field/field_action_sheet_bloc.dart';
|
||||||
export 'field/field_editor_bloc.dart';
|
export 'field/field_editor_bloc.dart';
|
||||||
export 'field/field_editor_pannel_bloc.dart';
|
export 'field/field_type_option_edit_bloc.dart';
|
||||||
|
|
||||||
// Field Type Option
|
// Field Type Option
|
||||||
export 'field/type_option/date_bloc.dart';
|
export 'field/type_option/date_bloc.dart';
|
||||||
|
@ -15,7 +15,7 @@ class RowActionSheetBloc extends Bloc<RowActionSheetEvent, RowActionSheetState>
|
|||||||
: _rowService = RowService(
|
: _rowService = RowService(
|
||||||
gridId: rowData.gridId,
|
gridId: rowData.gridId,
|
||||||
blockId: rowData.blockId,
|
blockId: rowData.blockId,
|
||||||
rowId: rowData.rowId,
|
rowId: rowData.id,
|
||||||
),
|
),
|
||||||
super(RowActionSheetState.initial(rowData)) {
|
super(RowActionSheetState.initial(rowData)) {
|
||||||
on<RowActionSheetEvent>(
|
on<RowActionSheetEvent>(
|
||||||
|
@ -11,19 +11,19 @@ part 'row_bloc.freezed.dart';
|
|||||||
|
|
||||||
class RowBloc extends Bloc<RowEvent, RowState> {
|
class RowBloc extends Bloc<RowEvent, RowState> {
|
||||||
final RowService _rowService;
|
final RowService _rowService;
|
||||||
final GridRowCacheService _rowCache;
|
final GridRowCache _rowCache;
|
||||||
void Function()? _rowListenFn;
|
void Function()? _rowListenFn;
|
||||||
|
|
||||||
RowBloc({
|
RowBloc({
|
||||||
required GridRow rowData,
|
required GridRow rowData,
|
||||||
required GridRowCacheService rowCache,
|
required GridRowCache rowCache,
|
||||||
}) : _rowService = RowService(
|
}) : _rowService = RowService(
|
||||||
gridId: rowData.gridId,
|
gridId: rowData.gridId,
|
||||||
blockId: rowData.blockId,
|
blockId: rowData.blockId,
|
||||||
rowId: rowData.rowId,
|
rowId: rowData.id,
|
||||||
),
|
),
|
||||||
_rowCache = rowCache,
|
_rowCache = rowCache,
|
||||||
super(RowState.initial(rowData, rowCache.loadGridCells(rowData.rowId))) {
|
super(RowState.initial(rowData, rowCache.loadGridCells(rowData.id))) {
|
||||||
on<RowEvent>(
|
on<RowEvent>(
|
||||||
(event, emit) async {
|
(event, emit) async {
|
||||||
await event.map(
|
await event.map(
|
||||||
@ -58,7 +58,7 @@ class RowBloc extends Bloc<RowEvent, RowState> {
|
|||||||
|
|
||||||
Future<void> _startListening() async {
|
Future<void> _startListening() async {
|
||||||
_rowListenFn = _rowCache.addListener(
|
_rowListenFn = _rowCache.addListener(
|
||||||
rowId: state.rowData.rowId,
|
rowId: state.rowData.id,
|
||||||
onCellUpdated: (cellDatas, reason) => add(RowEvent.didReceiveCellDatas(cellDatas, reason)),
|
onCellUpdated: (cellDatas, reason) => add(RowEvent.didReceiveCellDatas(cellDatas, reason)),
|
||||||
listenWhen: () => !isClosed,
|
listenWhen: () => !isClosed,
|
||||||
);
|
);
|
||||||
|
@ -8,12 +8,12 @@ part 'row_detail_bloc.freezed.dart';
|
|||||||
|
|
||||||
class RowDetailBloc extends Bloc<RowDetailEvent, RowDetailState> {
|
class RowDetailBloc extends Bloc<RowDetailEvent, RowDetailState> {
|
||||||
final GridRow rowData;
|
final GridRow rowData;
|
||||||
final GridRowCacheService _rowCache;
|
final GridRowCache _rowCache;
|
||||||
void Function()? _rowListenFn;
|
void Function()? _rowListenFn;
|
||||||
|
|
||||||
RowDetailBloc({
|
RowDetailBloc({
|
||||||
required this.rowData,
|
required this.rowData,
|
||||||
required GridRowCacheService rowCache,
|
required GridRowCache rowCache,
|
||||||
}) : _rowCache = rowCache,
|
}) : _rowCache = rowCache,
|
||||||
super(RowDetailState.initial()) {
|
super(RowDetailState.initial()) {
|
||||||
on<RowDetailEvent>(
|
on<RowDetailEvent>(
|
||||||
@ -41,14 +41,14 @@ class RowDetailBloc extends Bloc<RowDetailEvent, RowDetailState> {
|
|||||||
|
|
||||||
Future<void> _startListening() async {
|
Future<void> _startListening() async {
|
||||||
_rowListenFn = _rowCache.addListener(
|
_rowListenFn = _rowCache.addListener(
|
||||||
rowId: rowData.rowId,
|
rowId: rowData.id,
|
||||||
onCellUpdated: (cellDatas, reason) => add(RowDetailEvent.didReceiveCellDatas(cellDatas.values.toList())),
|
onCellUpdated: (cellDatas, reason) => add(RowDetailEvent.didReceiveCellDatas(cellDatas.values.toList())),
|
||||||
listenWhen: () => !isClosed,
|
listenWhen: () => !isClosed,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _loadCellData() async {
|
Future<void> _loadCellData() async {
|
||||||
final cellDataMap = _rowCache.loadGridCells(rowData.rowId);
|
final cellDataMap = _rowCache.loadGridCells(rowData.id);
|
||||||
if (!isClosed) {
|
if (!isClosed) {
|
||||||
add(RowDetailEvent.didReceiveCellDatas(cellDataMap.values.toList()));
|
add(RowDetailEvent.didReceiveCellDatas(cellDataMap.values.toList()));
|
||||||
}
|
}
|
||||||
@ -58,13 +58,13 @@ class RowDetailBloc extends Bloc<RowDetailEvent, RowDetailState> {
|
|||||||
@freezed
|
@freezed
|
||||||
class RowDetailEvent with _$RowDetailEvent {
|
class RowDetailEvent with _$RowDetailEvent {
|
||||||
const factory RowDetailEvent.initial() = _Initial;
|
const factory RowDetailEvent.initial() = _Initial;
|
||||||
const factory RowDetailEvent.didReceiveCellDatas(List<GridCell> gridCells) = _DidReceiveCellDatas;
|
const factory RowDetailEvent.didReceiveCellDatas(List<GridCellIdentifier> gridCells) = _DidReceiveCellDatas;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class RowDetailState with _$RowDetailState {
|
class RowDetailState with _$RowDetailState {
|
||||||
const factory RowDetailState({
|
const factory RowDetailState({
|
||||||
required List<GridCell> gridCells,
|
required List<GridCellIdentifier> gridCells,
|
||||||
}) = _RowDetailState;
|
}) = _RowDetailState;
|
||||||
|
|
||||||
factory RowDetailState.initial() => RowDetailState(
|
factory RowDetailState.initial() => RowDetailState(
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
|
|
||||||
import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart';
|
import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||||
@ -15,40 +14,53 @@ part 'row_service.freezed.dart';
|
|||||||
|
|
||||||
typedef RowUpdateCallback = void Function();
|
typedef RowUpdateCallback = void Function();
|
||||||
|
|
||||||
abstract class GridRowCacheDelegate with GridCellCacheDelegate {
|
abstract class GridRowCacheFieldNotifier {
|
||||||
UnmodifiableListView<Field> get fields;
|
UnmodifiableListView<Field> get fields;
|
||||||
void onFieldsChanged(void Function() callback);
|
void onFieldsChanged(VoidCallback callback);
|
||||||
|
void onFieldChanged(void Function(Field) callback);
|
||||||
void dispose();
|
void dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
class GridRowCacheService {
|
/// Cache the rows in memory
|
||||||
|
/// Insert / delete / update row
|
||||||
|
///
|
||||||
|
/// Read https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/architecture/frontend/grid for more information.
|
||||||
|
|
||||||
|
class GridRowCache {
|
||||||
final String gridId;
|
final String gridId;
|
||||||
final GridBlock block;
|
final GridBlock block;
|
||||||
final _Notifier _notifier;
|
|
||||||
|
/// _rows containers the current block's rows
|
||||||
|
/// Use List to reverse the order of the GridRow.
|
||||||
List<GridRow> _rows = [];
|
List<GridRow> _rows = [];
|
||||||
|
|
||||||
|
/// Use Map for faster access the raw row data.
|
||||||
final HashMap<String, Row> _rowByRowId;
|
final HashMap<String, Row> _rowByRowId;
|
||||||
final GridRowCacheDelegate _delegate;
|
|
||||||
final GridCellCacheService _cellCache;
|
|
||||||
|
|
||||||
List<GridRow> get rows => _rows;
|
final GridCellCache _cellCache;
|
||||||
GridCellCacheService get cellCache => _cellCache;
|
final GridRowCacheFieldNotifier _fieldNotifier;
|
||||||
|
final _GridRowChangesetNotifier _rowChangeReasonNotifier;
|
||||||
|
|
||||||
GridRowCacheService({
|
UnmodifiableListView<GridRow> get rows => UnmodifiableListView(_rows);
|
||||||
|
GridCellCache get cellCache => _cellCache;
|
||||||
|
|
||||||
|
GridRowCache({
|
||||||
required this.gridId,
|
required this.gridId,
|
||||||
required this.block,
|
required this.block,
|
||||||
required GridRowCacheDelegate delegate,
|
required GridRowCacheFieldNotifier notifier,
|
||||||
}) : _cellCache = GridCellCacheService(gridId: gridId, delegate: delegate),
|
}) : _cellCache = GridCellCache(gridId: gridId),
|
||||||
_rowByRowId = HashMap(),
|
_rowByRowId = HashMap(),
|
||||||
_notifier = _Notifier(),
|
_rowChangeReasonNotifier = _GridRowChangesetNotifier(),
|
||||||
_delegate = delegate {
|
_fieldNotifier = notifier {
|
||||||
//
|
//
|
||||||
delegate.onFieldsChanged(() => _notifier.receive(const GridRowChangeReason.fieldDidChange()));
|
notifier.onFieldsChanged(() => _rowChangeReasonNotifier.receive(const GridRowChangeReason.fieldDidChange()));
|
||||||
|
notifier.onFieldChanged((field) => _cellCache.remove(field.id));
|
||||||
_rows = block.rowInfos.map((rowInfo) => buildGridRow(rowInfo.rowId, rowInfo.height.toDouble())).toList();
|
_rows = block.rowInfos.map((rowInfo) => buildGridRow(rowInfo.rowId, rowInfo.height.toDouble())).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> dispose() async {
|
Future<void> dispose() async {
|
||||||
_delegate.dispose();
|
_fieldNotifier.dispose();
|
||||||
_notifier.dispose();
|
_rowChangeReasonNotifier.dispose();
|
||||||
await _cellCache.dispose();
|
await _cellCache.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,14 +84,15 @@ class GridRowCacheService {
|
|||||||
final Map<String, String> deletedRowByRowId = {for (var rowId in deletedRows) rowId: rowId};
|
final Map<String, String> deletedRowByRowId = {for (var rowId in deletedRows) rowId: rowId};
|
||||||
|
|
||||||
_rows.asMap().forEach((index, row) {
|
_rows.asMap().forEach((index, row) {
|
||||||
if (deletedRowByRowId[row.rowId] == null) {
|
if (deletedRowByRowId[row.id] == null) {
|
||||||
newRows.add(row);
|
newRows.add(row);
|
||||||
} else {
|
} else {
|
||||||
|
_rowByRowId.remove(row.id);
|
||||||
deletedIndex.add(DeletedIndex(index: index, row: row));
|
deletedIndex.add(DeletedIndex(index: index, row: row));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
_rows = newRows;
|
_rows = newRows;
|
||||||
_notifier.receive(GridRowChangeReason.delete(deletedIndex));
|
_rowChangeReasonNotifier.receive(GridRowChangeReason.delete(deletedIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _insertRows(List<InsertedRow> insertRows) {
|
void _insertRows(List<InsertedRow> insertRows) {
|
||||||
@ -88,17 +101,16 @@ class GridRowCacheService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
InsertedIndexs insertIndexs = [];
|
InsertedIndexs insertIndexs = [];
|
||||||
final List<GridRow> newRows = _rows;
|
|
||||||
for (final insertRow in insertRows) {
|
for (final insertRow in insertRows) {
|
||||||
final insertIndex = InsertedIndex(
|
final insertIndex = InsertedIndex(
|
||||||
index: insertRow.index,
|
index: insertRow.index,
|
||||||
rowId: insertRow.rowId,
|
rowId: insertRow.rowId,
|
||||||
);
|
);
|
||||||
insertIndexs.add(insertIndex);
|
insertIndexs.add(insertIndex);
|
||||||
newRows.insert(insertRow.index, (buildGridRow(insertRow.rowId, insertRow.height.toDouble())));
|
_rows.insert(insertRow.index, (buildGridRow(insertRow.rowId, insertRow.height.toDouble())));
|
||||||
}
|
}
|
||||||
|
|
||||||
_notifier.receive(GridRowChangeReason.insert(insertIndexs));
|
_rowChangeReasonNotifier.receive(GridRowChangeReason.insert(insertIndexs));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _updateRows(List<UpdatedRow> updatedRows) {
|
void _updateRows(List<UpdatedRow> updatedRows) {
|
||||||
@ -107,20 +119,19 @@ class GridRowCacheService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final UpdatedIndexs updatedIndexs = UpdatedIndexs();
|
final UpdatedIndexs updatedIndexs = UpdatedIndexs();
|
||||||
final List<GridRow> newRows = _rows;
|
|
||||||
for (final updatedRow in updatedRows) {
|
for (final updatedRow in updatedRows) {
|
||||||
final rowId = updatedRow.rowId;
|
final rowId = updatedRow.rowId;
|
||||||
final index = newRows.indexWhere((row) => row.rowId == rowId);
|
final index = _rows.indexWhere((row) => row.id == rowId);
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
_rowByRowId[rowId] = updatedRow.row;
|
_rowByRowId[rowId] = updatedRow.row;
|
||||||
|
|
||||||
newRows.removeAt(index);
|
_rows.removeAt(index);
|
||||||
newRows.insert(index, buildGridRow(rowId, updatedRow.row.height.toDouble()));
|
_rows.insert(index, buildGridRow(rowId, updatedRow.row.height.toDouble()));
|
||||||
updatedIndexs[rowId] = UpdatedIndex(index: index, rowId: rowId);
|
updatedIndexs[rowId] = UpdatedIndex(index: index, rowId: rowId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_notifier.receive(GridRowChangeReason.update(updatedIndexs));
|
_rowChangeReasonNotifier.receive(GridRowChangeReason.update(updatedIndexs));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _hideRows(List<String> hideRows) {}
|
void _hideRows(List<String> hideRows) {}
|
||||||
@ -130,8 +141,8 @@ class GridRowCacheService {
|
|||||||
void onRowsChanged(
|
void onRowsChanged(
|
||||||
void Function(GridRowChangeReason) onRowChanged,
|
void Function(GridRowChangeReason) onRowChanged,
|
||||||
) {
|
) {
|
||||||
_notifier.addListener(() {
|
_rowChangeReasonNotifier.addListener(() {
|
||||||
onRowChanged(_notifier._reason);
|
onRowChanged(_rowChangeReasonNotifier.reason);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,12 +161,12 @@ class GridRowCacheService {
|
|||||||
final row = _rowByRowId[rowId];
|
final row = _rowByRowId[rowId];
|
||||||
if (row != null) {
|
if (row != null) {
|
||||||
final GridCellMap cellDataMap = _makeGridCells(rowId, row);
|
final GridCellMap cellDataMap = _makeGridCells(rowId, row);
|
||||||
onCellUpdated(cellDataMap, _notifier._reason);
|
onCellUpdated(cellDataMap, _rowChangeReasonNotifier.reason);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_notifier._reason.whenOrNull(
|
_rowChangeReasonNotifier.reason.whenOrNull(
|
||||||
update: (indexs) {
|
update: (indexs) {
|
||||||
if (indexs[rowId] != null) notifyUpdate();
|
if (indexs[rowId] != null) notifyUpdate();
|
||||||
},
|
},
|
||||||
@ -163,12 +174,12 @@ class GridRowCacheService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_notifier.addListener(listenrHandler);
|
_rowChangeReasonNotifier.addListener(listenrHandler);
|
||||||
return listenrHandler;
|
return listenrHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeRowListener(VoidCallback callback) {
|
void removeRowListener(VoidCallback callback) {
|
||||||
_notifier.removeListener(callback);
|
_rowChangeReasonNotifier.removeListener(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
GridCellMap loadGridCells(String rowId) {
|
GridCellMap loadGridCells(String rowId) {
|
||||||
@ -194,9 +205,9 @@ class GridRowCacheService {
|
|||||||
|
|
||||||
GridCellMap _makeGridCells(String rowId, Row? row) {
|
GridCellMap _makeGridCells(String rowId, Row? row) {
|
||||||
var cellDataMap = GridCellMap.new();
|
var cellDataMap = GridCellMap.new();
|
||||||
for (final field in _delegate.fields) {
|
for (final field in _fieldNotifier.fields) {
|
||||||
if (field.visibility) {
|
if (field.visibility) {
|
||||||
cellDataMap[field.id] = GridCell(
|
cellDataMap[field.id] = GridCellIdentifier(
|
||||||
rowId: rowId,
|
rowId: rowId,
|
||||||
gridId: gridId,
|
gridId: gridId,
|
||||||
field: field,
|
field: field,
|
||||||
@ -214,19 +225,19 @@ class GridRowCacheService {
|
|||||||
updatedRow.freeze();
|
updatedRow.freeze();
|
||||||
|
|
||||||
_rowByRowId[updatedRow.id] = updatedRow;
|
_rowByRowId[updatedRow.id] = updatedRow;
|
||||||
final index = _rows.indexWhere((gridRow) => gridRow.rowId == updatedRow.id);
|
final index = _rows.indexWhere((gridRow) => gridRow.id == updatedRow.id);
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
// update the corresponding row in _rows if they are not the same
|
// update the corresponding row in _rows if they are not the same
|
||||||
if (_rows[index].data != updatedRow) {
|
if (_rows[index].rawRow != updatedRow) {
|
||||||
final row = _rows.removeAt(index).copyWith(data: updatedRow);
|
final row = _rows.removeAt(index).copyWith(rawRow: updatedRow);
|
||||||
_rows.insert(index, row);
|
_rows.insert(index, row);
|
||||||
|
|
||||||
// Calculate the update index
|
// Calculate the update index
|
||||||
final UpdatedIndexs updatedIndexs = UpdatedIndexs();
|
final UpdatedIndexs updatedIndexs = UpdatedIndexs();
|
||||||
updatedIndexs[row.rowId] = UpdatedIndex(index: index, rowId: row.rowId);
|
updatedIndexs[row.id] = UpdatedIndex(index: index, rowId: row.id);
|
||||||
|
|
||||||
//
|
//
|
||||||
_notifier.receive(GridRowChangeReason.update(updatedIndexs));
|
_rowChangeReasonNotifier.receive(GridRowChangeReason.update(updatedIndexs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -235,20 +246,20 @@ class GridRowCacheService {
|
|||||||
return GridRow(
|
return GridRow(
|
||||||
gridId: gridId,
|
gridId: gridId,
|
||||||
blockId: block.id,
|
blockId: block.id,
|
||||||
fields: _delegate.fields,
|
fields: _fieldNotifier.fields,
|
||||||
rowId: rowId,
|
id: rowId,
|
||||||
height: rowHeight,
|
height: rowHeight,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _Notifier extends ChangeNotifier {
|
class _GridRowChangesetNotifier extends ChangeNotifier {
|
||||||
GridRowChangeReason _reason = const InitialListState();
|
GridRowChangeReason reason = const InitialListState();
|
||||||
|
|
||||||
_Notifier();
|
_GridRowChangesetNotifier();
|
||||||
|
|
||||||
void receive(GridRowChangeReason reason) {
|
void receive(GridRowChangeReason newReason) {
|
||||||
_reason = reason;
|
reason = newReason;
|
||||||
reason.map(
|
reason.map(
|
||||||
insert: (_) => notifyListeners(),
|
insert: (_) => notifyListeners(),
|
||||||
delete: (_) => notifyListeners(),
|
delete: (_) => notifyListeners(),
|
||||||
@ -318,10 +329,10 @@ class GridRow with _$GridRow {
|
|||||||
const factory GridRow({
|
const factory GridRow({
|
||||||
required String gridId,
|
required String gridId,
|
||||||
required String blockId,
|
required String blockId,
|
||||||
required String rowId,
|
required String id,
|
||||||
required UnmodifiableListView<Field> fields,
|
required UnmodifiableListView<Field> fields,
|
||||||
required double height,
|
required double height,
|
||||||
Row? data,
|
Row? rawRow,
|
||||||
}) = _GridRow;
|
}) = _GridRow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,14 +227,16 @@ class _GridRowsState extends State<_GridRows> {
|
|||||||
GridRow rowData,
|
GridRow rowData,
|
||||||
Animation<double> animation,
|
Animation<double> animation,
|
||||||
) {
|
) {
|
||||||
final rowCache = context.read<GridBloc>().getRowCache(rowData.blockId, rowData.rowId);
|
final rowCache = context.read<GridBloc>().getRowCache(rowData.blockId, rowData.id);
|
||||||
|
final fieldCache = context.read<GridBloc>().fieldCache;
|
||||||
if (rowCache != null) {
|
if (rowCache != null) {
|
||||||
return SizeTransition(
|
return SizeTransition(
|
||||||
sizeFactor: animation,
|
sizeFactor: animation,
|
||||||
child: GridRowWidget(
|
child: GridRowWidget(
|
||||||
rowData: rowData,
|
rowData: rowData,
|
||||||
rowCache: rowCache,
|
rowCache: rowCache,
|
||||||
key: ValueKey(rowData.rowId),
|
fieldCache: fieldCache,
|
||||||
|
key: ValueKey(rowData.id),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart';
|
import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart';
|
||||||
|
import 'package:app_flowy/workspace/application/grid/grid_service.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
@ -12,28 +13,39 @@ import 'select_option_cell/select_option_cell.dart';
|
|||||||
import 'text_cell.dart';
|
import 'text_cell.dart';
|
||||||
import 'url_cell/url_cell.dart';
|
import 'url_cell/url_cell.dart';
|
||||||
|
|
||||||
GridCellWidget buildGridCellWidget(GridCell gridCell, GridCellCacheService cellCache, {GridCellStyle? style}) {
|
class GridCellBuilder {
|
||||||
final key = ValueKey(gridCell.cellId());
|
final GridCellCache cellCache;
|
||||||
|
final GridFieldCache fieldCache;
|
||||||
|
GridCellBuilder({
|
||||||
|
required this.cellCache,
|
||||||
|
required this.fieldCache,
|
||||||
|
});
|
||||||
|
|
||||||
final cellContextBuilder = GridCellContextBuilder(gridCell: gridCell, cellCache: cellCache);
|
GridCellWidget build(GridCellIdentifier cell, {GridCellStyle? style}) {
|
||||||
|
final cellControllerBuilder = GridCellControllerBuilder(
|
||||||
switch (gridCell.field.fieldType) {
|
cellId: cell,
|
||||||
case FieldType.Checkbox:
|
cellCache: cellCache,
|
||||||
return CheckboxCell(cellContextBuilder: cellContextBuilder, key: key);
|
fieldCache: fieldCache,
|
||||||
case FieldType.DateTime:
|
);
|
||||||
return DateCell(cellContextBuilder: cellContextBuilder, key: key, style: style);
|
final key = cell.key();
|
||||||
case FieldType.SingleSelect:
|
switch (cell.fieldType) {
|
||||||
return SingleSelectCell(cellContextBuilder: cellContextBuilder, style: style, key: key);
|
case FieldType.Checkbox:
|
||||||
case FieldType.MultiSelect:
|
return CheckboxCell(cellControllerBuilder: cellControllerBuilder, key: key);
|
||||||
return MultiSelectCell(cellContextBuilder: cellContextBuilder, style: style, key: key);
|
case FieldType.DateTime:
|
||||||
case FieldType.Number:
|
return DateCell(cellControllerBuilder: cellControllerBuilder, key: key, style: style);
|
||||||
return NumberCell(cellContextBuilder: cellContextBuilder, key: key);
|
case FieldType.SingleSelect:
|
||||||
case FieldType.RichText:
|
return SingleSelectCell(cellContorllerBuilder: cellControllerBuilder, style: style, key: key);
|
||||||
return GridTextCell(cellContextBuilder: cellContextBuilder, style: style, key: key);
|
case FieldType.MultiSelect:
|
||||||
case FieldType.URL:
|
return MultiSelectCell(cellContorllerBuilder: cellControllerBuilder, style: style, key: key);
|
||||||
return GridURLCell(cellContextBuilder: cellContextBuilder, style: style, key: key);
|
case FieldType.Number:
|
||||||
|
return NumberCell(cellContorllerBuilder: cellControllerBuilder, key: key);
|
||||||
|
case FieldType.RichText:
|
||||||
|
return GridTextCell(cellContorllerBuilder: cellControllerBuilder, style: style, key: key);
|
||||||
|
case FieldType.URL:
|
||||||
|
return GridURLCell(cellContorllerBuilder: cellControllerBuilder, style: style, key: key);
|
||||||
|
}
|
||||||
|
throw UnimplementedError;
|
||||||
}
|
}
|
||||||
throw UnimplementedError;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class BlankCell extends StatelessWidget {
|
class BlankCell extends StatelessWidget {
|
||||||
|
@ -7,9 +7,9 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'cell_builder.dart';
|
import 'cell_builder.dart';
|
||||||
|
|
||||||
class CheckboxCell extends GridCellWidget {
|
class CheckboxCell extends GridCellWidget {
|
||||||
final GridCellContextBuilder cellContextBuilder;
|
final GridCellControllerBuilder cellControllerBuilder;
|
||||||
CheckboxCell({
|
CheckboxCell({
|
||||||
required this.cellContextBuilder,
|
required this.cellControllerBuilder,
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ class _CheckboxCellState extends GridCellState<CheckboxCell> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
final cellContext = widget.cellContextBuilder.build();
|
final cellContext = widget.cellControllerBuilder.build();
|
||||||
_cellBloc = getIt<CheckboxCellBloc>(param1: cellContext)..add(const CheckboxCellEvent.initial());
|
_cellBloc = getIt<CheckboxCellBloc>(param1: cellContext)..add(const CheckboxCellEvent.initial());
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
@ -19,12 +19,12 @@ abstract class GridCellDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class DateCell extends GridCellWidget {
|
class DateCell extends GridCellWidget {
|
||||||
final GridCellContextBuilder cellContextBuilder;
|
final GridCellControllerBuilder cellControllerBuilder;
|
||||||
late final DateCellStyle? cellStyle;
|
late final DateCellStyle? cellStyle;
|
||||||
|
|
||||||
DateCell({
|
DateCell({
|
||||||
GridCellStyle? style,
|
GridCellStyle? style,
|
||||||
required this.cellContextBuilder,
|
required this.cellControllerBuilder,
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key) {
|
}) : super(key: key) {
|
||||||
if (style != null) {
|
if (style != null) {
|
||||||
@ -43,7 +43,7 @@ class _DateCellState extends GridCellState<DateCell> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
final cellContext = widget.cellContextBuilder.build();
|
final cellContext = widget.cellControllerBuilder.build();
|
||||||
_cellBloc = getIt<DateCellBloc>(param1: cellContext)..add(const DateCellEvent.initial());
|
_cellBloc = getIt<DateCellBloc>(param1: cellContext)..add(const DateCellEvent.initial());
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
@ -80,7 +80,7 @@ class _DateCellState extends GridCellState<DateCell> {
|
|||||||
final calendar = DateCellEditor(onDismissed: () => widget.onCellEditing.value = false);
|
final calendar = DateCellEditor(onDismissed: () => widget.onCellEditing.value = false);
|
||||||
calendar.show(
|
calendar.show(
|
||||||
context,
|
context,
|
||||||
cellContext: bloc.cellContext.clone(),
|
cellController: bloc.cellContext.clone(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,16 +31,16 @@ class DateCellEditor with FlowyOverlayDelegate {
|
|||||||
|
|
||||||
Future<void> show(
|
Future<void> show(
|
||||||
BuildContext context, {
|
BuildContext context, {
|
||||||
required GridDateCellContext cellContext,
|
required GridDateCellController cellController,
|
||||||
}) async {
|
}) async {
|
||||||
DateCellEditor.remove(context);
|
DateCellEditor.remove(context);
|
||||||
|
|
||||||
final result = await cellContext.getTypeOptionData();
|
final result = await cellController.getFieldTypeOption(DateTypeOptionDataParser());
|
||||||
result.fold(
|
result.fold(
|
||||||
(data) {
|
(dateTypeOption) {
|
||||||
final calendar = _CellCalendarWidget(
|
final calendar = _CellCalendarWidget(
|
||||||
cellContext: cellContext,
|
cellContext: cellController,
|
||||||
dateTypeOption: DateTypeOption.fromBuffer(data.typeOptionData),
|
dateTypeOption: dateTypeOption,
|
||||||
);
|
);
|
||||||
|
|
||||||
FlowyOverlay.of(context).insertWithAnchor(
|
FlowyOverlay.of(context).insertWithAnchor(
|
||||||
@ -75,7 +75,7 @@ class DateCellEditor with FlowyOverlayDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _CellCalendarWidget extends StatelessWidget {
|
class _CellCalendarWidget extends StatelessWidget {
|
||||||
final GridDateCellContext cellContext;
|
final GridDateCellController cellContext;
|
||||||
final DateTypeOption dateTypeOption;
|
final DateTypeOption dateTypeOption;
|
||||||
|
|
||||||
const _CellCalendarWidget({
|
const _CellCalendarWidget({
|
||||||
|
@ -7,10 +7,10 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'cell_builder.dart';
|
import 'cell_builder.dart';
|
||||||
|
|
||||||
class NumberCell extends GridCellWidget {
|
class NumberCell extends GridCellWidget {
|
||||||
final GridCellContextBuilder cellContextBuilder;
|
final GridCellControllerBuilder cellContorllerBuilder;
|
||||||
|
|
||||||
NumberCell({
|
NumberCell({
|
||||||
required this.cellContextBuilder,
|
required this.cellContorllerBuilder,
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ class _NumberCellState extends GridFocusNodeCellState<NumberCell> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
final cellContext = widget.cellContextBuilder.build();
|
final cellContext = widget.cellContorllerBuilder.build();
|
||||||
_cellBloc = getIt<NumberCellBloc>(param1: cellContext)..add(const NumberCellEvent.initial());
|
_cellBloc = getIt<NumberCellBloc>(param1: cellContext)..add(const NumberCellEvent.initial());
|
||||||
_controller = TextEditingController(text: contentFromState(_cellBloc.state));
|
_controller = TextEditingController(text: contentFromState(_cellBloc.state));
|
||||||
super.initState();
|
super.initState();
|
||||||
|
@ -21,11 +21,11 @@ class SelectOptionCellStyle extends GridCellStyle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class SingleSelectCell extends GridCellWidget {
|
class SingleSelectCell extends GridCellWidget {
|
||||||
final GridCellContextBuilder cellContextBuilder;
|
final GridCellControllerBuilder cellContorllerBuilder;
|
||||||
late final SelectOptionCellStyle? cellStyle;
|
late final SelectOptionCellStyle? cellStyle;
|
||||||
|
|
||||||
SingleSelectCell({
|
SingleSelectCell({
|
||||||
required this.cellContextBuilder,
|
required this.cellContorllerBuilder,
|
||||||
GridCellStyle? style,
|
GridCellStyle? style,
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key) {
|
}) : super(key: key) {
|
||||||
@ -45,7 +45,7 @@ class _SingleSelectCellState extends State<SingleSelectCell> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
final cellContext = widget.cellContextBuilder.build() as GridSelectOptionCellContext;
|
final cellContext = widget.cellContorllerBuilder.build() as GridSelectOptionCellController;
|
||||||
_cellBloc = getIt<SelectOptionCellBloc>(param1: cellContext)..add(const SelectOptionCellEvent.initial());
|
_cellBloc = getIt<SelectOptionCellBloc>(param1: cellContext)..add(const SelectOptionCellEvent.initial());
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
@ -60,7 +60,7 @@ class _SingleSelectCellState extends State<SingleSelectCell> {
|
|||||||
selectOptions: state.selectedOptions,
|
selectOptions: state.selectedOptions,
|
||||||
cellStyle: widget.cellStyle,
|
cellStyle: widget.cellStyle,
|
||||||
onFocus: (value) => widget.onCellEditing.value = value,
|
onFocus: (value) => widget.onCellEditing.value = value,
|
||||||
cellContextBuilder: widget.cellContextBuilder);
|
cellContorllerBuilder: widget.cellContorllerBuilder);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -75,11 +75,11 @@ class _SingleSelectCellState extends State<SingleSelectCell> {
|
|||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
class MultiSelectCell extends GridCellWidget {
|
class MultiSelectCell extends GridCellWidget {
|
||||||
final GridCellContextBuilder cellContextBuilder;
|
final GridCellControllerBuilder cellContorllerBuilder;
|
||||||
late final SelectOptionCellStyle? cellStyle;
|
late final SelectOptionCellStyle? cellStyle;
|
||||||
|
|
||||||
MultiSelectCell({
|
MultiSelectCell({
|
||||||
required this.cellContextBuilder,
|
required this.cellContorllerBuilder,
|
||||||
GridCellStyle? style,
|
GridCellStyle? style,
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key) {
|
}) : super(key: key) {
|
||||||
@ -99,7 +99,7 @@ class _MultiSelectCellState extends State<MultiSelectCell> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
final cellContext = widget.cellContextBuilder.build() as GridSelectOptionCellContext;
|
final cellContext = widget.cellContorllerBuilder.build() as GridSelectOptionCellController;
|
||||||
_cellBloc = getIt<SelectOptionCellBloc>(param1: cellContext)..add(const SelectOptionCellEvent.initial());
|
_cellBloc = getIt<SelectOptionCellBloc>(param1: cellContext)..add(const SelectOptionCellEvent.initial());
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
@ -114,7 +114,7 @@ class _MultiSelectCellState extends State<MultiSelectCell> {
|
|||||||
selectOptions: state.selectedOptions,
|
selectOptions: state.selectedOptions,
|
||||||
cellStyle: widget.cellStyle,
|
cellStyle: widget.cellStyle,
|
||||||
onFocus: (value) => widget.onCellEditing.value = value,
|
onFocus: (value) => widget.onCellEditing.value = value,
|
||||||
cellContextBuilder: widget.cellContextBuilder);
|
cellContorllerBuilder: widget.cellContorllerBuilder);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -131,12 +131,12 @@ class _SelectOptionCell extends StatelessWidget {
|
|||||||
final List<SelectOption> selectOptions;
|
final List<SelectOption> selectOptions;
|
||||||
final void Function(bool) onFocus;
|
final void Function(bool) onFocus;
|
||||||
final SelectOptionCellStyle? cellStyle;
|
final SelectOptionCellStyle? cellStyle;
|
||||||
final GridCellContextBuilder cellContextBuilder;
|
final GridCellControllerBuilder cellContorllerBuilder;
|
||||||
const _SelectOptionCell({
|
const _SelectOptionCell({
|
||||||
required this.selectOptions,
|
required this.selectOptions,
|
||||||
required this.onFocus,
|
required this.onFocus,
|
||||||
required this.cellStyle,
|
required this.cellStyle,
|
||||||
required this.cellContextBuilder,
|
required this.cellContorllerBuilder,
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@ -172,7 +172,7 @@ class _SelectOptionCell extends StatelessWidget {
|
|||||||
InkWell(
|
InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
onFocus(true);
|
onFocus(true);
|
||||||
final cellContext = cellContextBuilder.build() as GridSelectOptionCellContext;
|
final cellContext = cellContorllerBuilder.build() as GridSelectOptionCellController;
|
||||||
SelectOptionCellEditor.show(context, cellContext, () => onFocus(false));
|
SelectOptionCellEditor.show(context, cellContext, () => onFocus(false));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -24,11 +24,11 @@ import 'text_field.dart';
|
|||||||
const double _editorPannelWidth = 300;
|
const double _editorPannelWidth = 300;
|
||||||
|
|
||||||
class SelectOptionCellEditor extends StatelessWidget with FlowyOverlayDelegate {
|
class SelectOptionCellEditor extends StatelessWidget with FlowyOverlayDelegate {
|
||||||
final GridSelectOptionCellContext cellContext;
|
final GridSelectOptionCellController cellController;
|
||||||
final VoidCallback onDismissed;
|
final VoidCallback onDismissed;
|
||||||
|
|
||||||
const SelectOptionCellEditor({
|
const SelectOptionCellEditor({
|
||||||
required this.cellContext,
|
required this.cellController,
|
||||||
required this.onDismissed,
|
required this.onDismissed,
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
@ -37,7 +37,7 @@ class SelectOptionCellEditor extends StatelessWidget with FlowyOverlayDelegate {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) => SelectOptionCellEditorBloc(
|
create: (context) => SelectOptionCellEditorBloc(
|
||||||
cellContext: cellContext,
|
cellController: cellController,
|
||||||
)..add(const SelectOptionEditorEvent.initial()),
|
)..add(const SelectOptionEditorEvent.initial()),
|
||||||
child: BlocBuilder<SelectOptionCellEditorBloc, SelectOptionEditorState>(
|
child: BlocBuilder<SelectOptionCellEditorBloc, SelectOptionEditorState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
@ -59,12 +59,12 @@ class SelectOptionCellEditor extends StatelessWidget with FlowyOverlayDelegate {
|
|||||||
|
|
||||||
static void show(
|
static void show(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
GridSelectOptionCellContext cellContext,
|
GridSelectOptionCellController cellContext,
|
||||||
VoidCallback onDismissed,
|
VoidCallback onDismissed,
|
||||||
) {
|
) {
|
||||||
SelectOptionCellEditor.remove(context);
|
SelectOptionCellEditor.remove(context);
|
||||||
final editor = SelectOptionCellEditor(
|
final editor = SelectOptionCellEditor(
|
||||||
cellContext: cellContext,
|
cellController: cellContext,
|
||||||
onDismissed: onDismissed,
|
onDismissed: onDismissed,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -14,10 +14,10 @@ class GridTextCellStyle extends GridCellStyle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class GridTextCell extends GridCellWidget {
|
class GridTextCell extends GridCellWidget {
|
||||||
final GridCellContextBuilder cellContextBuilder;
|
final GridCellControllerBuilder cellContorllerBuilder;
|
||||||
late final GridTextCellStyle? cellStyle;
|
late final GridTextCellStyle? cellStyle;
|
||||||
GridTextCell({
|
GridTextCell({
|
||||||
required this.cellContextBuilder,
|
required this.cellContorllerBuilder,
|
||||||
GridCellStyle? style,
|
GridCellStyle? style,
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key) {
|
}) : super(key: key) {
|
||||||
@ -39,7 +39,7 @@ class _GridTextCellState extends GridFocusNodeCellState<GridTextCell> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
final cellContext = widget.cellContextBuilder.build();
|
final cellContext = widget.cellContorllerBuilder.build();
|
||||||
_cellBloc = getIt<TextCellBloc>(param1: cellContext);
|
_cellBloc = getIt<TextCellBloc>(param1: cellContext);
|
||||||
_cellBloc.add(const TextCellEvent.initial());
|
_cellBloc.add(const TextCellEvent.initial());
|
||||||
_controller = TextEditingController(text: _cellBloc.state.content);
|
_controller = TextEditingController(text: _cellBloc.state.content);
|
||||||
|
@ -7,21 +7,21 @@ import 'dart:async';
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
class URLCellEditor extends StatefulWidget with FlowyOverlayDelegate {
|
class URLCellEditor extends StatefulWidget with FlowyOverlayDelegate {
|
||||||
final GridURLCellContext cellContext;
|
final GridURLCellController cellController;
|
||||||
final VoidCallback completed;
|
final VoidCallback completed;
|
||||||
const URLCellEditor({required this.cellContext, required this.completed, Key? key}) : super(key: key);
|
const URLCellEditor({required this.cellController, required this.completed, Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<URLCellEditor> createState() => _URLCellEditorState();
|
State<URLCellEditor> createState() => _URLCellEditorState();
|
||||||
|
|
||||||
static void show(
|
static void show(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
GridURLCellContext cellContext,
|
GridURLCellController cellContext,
|
||||||
VoidCallback completed,
|
VoidCallback completed,
|
||||||
) {
|
) {
|
||||||
FlowyOverlay.of(context).remove(identifier());
|
FlowyOverlay.of(context).remove(identifier());
|
||||||
final editor = URLCellEditor(
|
final editor = URLCellEditor(
|
||||||
cellContext: cellContext,
|
cellController: cellContext,
|
||||||
completed: completed,
|
completed: completed,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ class _URLCellEditorState extends State<URLCellEditor> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
_cellBloc = URLCellEditorBloc(cellContext: widget.cellContext);
|
_cellBloc = URLCellEditorBloc(cellContext: widget.cellController);
|
||||||
_cellBloc.add(const URLCellEditorEvent.initial());
|
_cellBloc.add(const URLCellEditorEvent.initial());
|
||||||
_controller = TextEditingController(text: _cellBloc.state.content);
|
_controller = TextEditingController(text: _cellBloc.state.content);
|
||||||
|
|
||||||
|
@ -31,10 +31,10 @@ enum GridURLCellAccessoryType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class GridURLCell extends GridCellWidget {
|
class GridURLCell extends GridCellWidget {
|
||||||
final GridCellContextBuilder cellContextBuilder;
|
final GridCellControllerBuilder cellContorllerBuilder;
|
||||||
late final GridURLCellStyle? cellStyle;
|
late final GridURLCellStyle? cellStyle;
|
||||||
GridURLCell({
|
GridURLCell({
|
||||||
required this.cellContextBuilder,
|
required this.cellContorllerBuilder,
|
||||||
GridCellStyle? style,
|
GridCellStyle? style,
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key) {
|
}) : super(key: key) {
|
||||||
@ -51,11 +51,11 @@ class GridURLCell extends GridCellWidget {
|
|||||||
GridCellAccessory accessoryFromType(GridURLCellAccessoryType ty, GridCellAccessoryBuildContext buildContext) {
|
GridCellAccessory accessoryFromType(GridURLCellAccessoryType ty, GridCellAccessoryBuildContext buildContext) {
|
||||||
switch (ty) {
|
switch (ty) {
|
||||||
case GridURLCellAccessoryType.edit:
|
case GridURLCellAccessoryType.edit:
|
||||||
final cellContext = cellContextBuilder.build() as GridURLCellContext;
|
final cellContext = cellContorllerBuilder.build() as GridURLCellController;
|
||||||
return _EditURLAccessory(cellContext: cellContext, anchorContext: buildContext.anchorContext);
|
return _EditURLAccessory(cellContext: cellContext, anchorContext: buildContext.anchorContext);
|
||||||
|
|
||||||
case GridURLCellAccessoryType.copyURL:
|
case GridURLCellAccessoryType.copyURL:
|
||||||
final cellContext = cellContextBuilder.build() as GridURLCellContext;
|
final cellContext = cellContorllerBuilder.build() as GridURLCellController;
|
||||||
return _CopyURLAccessory(cellContext: cellContext);
|
return _CopyURLAccessory(cellContext: cellContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,7 +83,7 @@ class _GridURLCellState extends GridCellState<GridURLCell> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
final cellContext = widget.cellContextBuilder.build() as GridURLCellContext;
|
final cellContext = widget.cellContorllerBuilder.build() as GridURLCellController;
|
||||||
_cellBloc = URLCellBloc(cellContext: cellContext);
|
_cellBloc = URLCellBloc(cellContext: cellContext);
|
||||||
_cellBloc.add(const URLCellEvent.initial());
|
_cellBloc.add(const URLCellEvent.initial());
|
||||||
super.initState();
|
super.initState();
|
||||||
@ -132,7 +132,7 @@ class _GridURLCellState extends GridCellState<GridURLCell> {
|
|||||||
if (url.isNotEmpty && await canLaunchUrl(uri)) {
|
if (url.isNotEmpty && await canLaunchUrl(uri)) {
|
||||||
await launchUrl(uri);
|
await launchUrl(uri);
|
||||||
} else {
|
} else {
|
||||||
final cellContext = widget.cellContextBuilder.build() as GridURLCellContext;
|
final cellContext = widget.cellContorllerBuilder.build() as GridURLCellController;
|
||||||
widget.onCellEditing.value = true;
|
widget.onCellEditing.value = true;
|
||||||
URLCellEditor.show(context, cellContext, () {
|
URLCellEditor.show(context, cellContext, () {
|
||||||
widget.onCellEditing.value = false;
|
widget.onCellEditing.value = false;
|
||||||
@ -155,7 +155,7 @@ class _GridURLCellState extends GridCellState<GridURLCell> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _EditURLAccessory extends StatelessWidget with GridCellAccessory {
|
class _EditURLAccessory extends StatelessWidget with GridCellAccessory {
|
||||||
final GridURLCellContext cellContext;
|
final GridURLCellController cellContext;
|
||||||
final BuildContext anchorContext;
|
final BuildContext anchorContext;
|
||||||
const _EditURLAccessory({
|
const _EditURLAccessory({
|
||||||
required this.cellContext,
|
required this.cellContext,
|
||||||
@ -176,7 +176,7 @@ class _EditURLAccessory extends StatelessWidget with GridCellAccessory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _CopyURLAccessory extends StatelessWidget with GridCellAccessory {
|
class _CopyURLAccessory extends StatelessWidget with GridCellAccessory {
|
||||||
final GridURLCellContext cellContext;
|
final GridURLCellController cellContext;
|
||||||
const _CopyURLAccessory({required this.cellContext, Key? key}) : super(key: key);
|
const _CopyURLAccessory({required this.cellContext, Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -187,7 +187,7 @@ class _CopyURLAccessory extends StatelessWidget with GridCellAccessory {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void onTap() {
|
void onTap() {
|
||||||
final content = cellContext.getCellData(loadIfNoCache: false)?.content ?? "";
|
final content = cellContext.getCellData(loadIfNotExist: false)?.content ?? "";
|
||||||
Clipboard.setData(ClipboardData(text: content));
|
Clipboard.setData(ClipboardData(text: content));
|
||||||
showMessageToast(LocaleKeys.grid_row_copyProperty.tr());
|
showMessageToast(LocaleKeys.grid_row_copyProperty.tr());
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ class GridFieldCell extends StatelessWidget {
|
|||||||
FieldEditor(
|
FieldEditor(
|
||||||
gridId: state.gridId,
|
gridId: state.gridId,
|
||||||
fieldName: field.name,
|
fieldName: field.name,
|
||||||
contextLoader: FieldContextLoader(
|
typeOptionLoader: FieldTypeOptionLoader(
|
||||||
gridId: state.gridId,
|
gridId: state.gridId,
|
||||||
field: field,
|
field: field,
|
||||||
),
|
),
|
||||||
|
@ -8,17 +8,17 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||||
import 'field_name_input.dart';
|
import 'field_name_input.dart';
|
||||||
import 'field_editor_pannel.dart';
|
import 'field_type_option_editor.dart';
|
||||||
|
|
||||||
class FieldEditor extends StatelessWidget with FlowyOverlayDelegate {
|
class FieldEditor extends StatelessWidget with FlowyOverlayDelegate {
|
||||||
final String gridId;
|
final String gridId;
|
||||||
final String fieldName;
|
final String fieldName;
|
||||||
|
|
||||||
final IFieldContextLoader contextLoader;
|
final IFieldTypeOptionLoader typeOptionLoader;
|
||||||
const FieldEditor({
|
const FieldEditor({
|
||||||
required this.gridId,
|
required this.gridId,
|
||||||
required this.fieldName,
|
required this.fieldName,
|
||||||
required this.contextLoader,
|
required this.typeOptionLoader,
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ class FieldEditor extends StatelessWidget with FlowyOverlayDelegate {
|
|||||||
create: (context) => FieldEditorBloc(
|
create: (context) => FieldEditorBloc(
|
||||||
gridId: gridId,
|
gridId: gridId,
|
||||||
fieldName: fieldName,
|
fieldName: fieldName,
|
||||||
fieldContextLoader: contextLoader,
|
loader: typeOptionLoader,
|
||||||
)..add(const FieldEditorEvent.initial()),
|
)..add(const FieldEditorEvent.initial()),
|
||||||
child: BlocBuilder<FieldEditorBloc, FieldEditorState>(
|
child: BlocBuilder<FieldEditorBloc, FieldEditorState>(
|
||||||
buildWhen: (p, c) => false,
|
buildWhen: (p, c) => false,
|
||||||
@ -38,9 +38,9 @@ class FieldEditor extends StatelessWidget with FlowyOverlayDelegate {
|
|||||||
children: [
|
children: [
|
||||||
FlowyText.medium(LocaleKeys.grid_field_editProperty.tr(), fontSize: 12),
|
FlowyText.medium(LocaleKeys.grid_field_editProperty.tr(), fontSize: 12),
|
||||||
const VSpace(10),
|
const VSpace(10),
|
||||||
const _FieldNameTextField(),
|
const _FieldNameCell(),
|
||||||
const VSpace(10),
|
const VSpace(10),
|
||||||
const _FieldPannel(),
|
const _FieldTypeOptionCell(),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -74,25 +74,28 @@ class FieldEditor extends StatelessWidget with FlowyOverlayDelegate {
|
|||||||
bool asBarrier() => true;
|
bool asBarrier() => true;
|
||||||
}
|
}
|
||||||
|
|
||||||
class _FieldPannel extends StatelessWidget {
|
class _FieldTypeOptionCell extends StatelessWidget {
|
||||||
const _FieldPannel({Key? key}) : super(key: key);
|
const _FieldTypeOptionCell({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<FieldEditorBloc, FieldEditorState>(
|
return BlocBuilder<FieldEditorBloc, FieldEditorState>(
|
||||||
buildWhen: (p, c) => p.fieldContext != c.fieldContext,
|
buildWhen: (p, c) => p.field != c.field,
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return state.fieldContext.fold(
|
return state.field.fold(
|
||||||
() => const SizedBox(),
|
() => const SizedBox(),
|
||||||
(fieldContext) => FieldEditorPannel(fieldContext: fieldContext),
|
(fieldContext) {
|
||||||
|
final dataController = context.read<FieldEditorBloc>().dataController;
|
||||||
|
return FieldTypeOptionEditor(dataController: dataController);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _FieldNameTextField extends StatelessWidget {
|
class _FieldNameCell extends StatelessWidget {
|
||||||
const _FieldNameTextField({Key? key}) : super(key: key);
|
const _FieldNameCell({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -1,243 +0,0 @@
|
|||||||
import 'dart:typed_data';
|
|
||||||
|
|
||||||
import 'package:app_flowy/workspace/application/grid/field/type_option/multi_select_type_option.dart';
|
|
||||||
import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart';
|
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/checkbox.dart';
|
|
||||||
import 'package:dartz/dartz.dart' show Either;
|
|
||||||
import 'package:flowy_infra/image.dart';
|
|
||||||
import 'package:flowy_infra/theme.dart';
|
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
|
||||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
|
||||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:app_flowy/workspace/application/grid/prelude.dart';
|
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
|
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart';
|
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart';
|
|
||||||
import 'field_type_extension.dart';
|
|
||||||
import 'type_option/multi_select.dart';
|
|
||||||
import 'type_option/number.dart';
|
|
||||||
import 'type_option/rich_text.dart';
|
|
||||||
import 'type_option/single_select.dart';
|
|
||||||
import 'type_option/url.dart';
|
|
||||||
|
|
||||||
typedef UpdateFieldCallback = void Function(Field, Uint8List);
|
|
||||||
typedef SwitchToFieldCallback = Future<Either<FieldTypeOptionData, FlowyError>> Function(
|
|
||||||
String fieldId,
|
|
||||||
FieldType fieldType,
|
|
||||||
);
|
|
||||||
|
|
||||||
class FieldEditorPannel extends StatefulWidget {
|
|
||||||
final GridFieldContext fieldContext;
|
|
||||||
|
|
||||||
const FieldEditorPannel({
|
|
||||||
required this.fieldContext,
|
|
||||||
Key? key,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<FieldEditorPannel> createState() => _FieldEditorPannelState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _FieldEditorPannelState extends State<FieldEditorPannel> {
|
|
||||||
String? currentOverlayIdentifier;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return BlocProvider(
|
|
||||||
create: (context) => FieldEditorPannelBloc(widget.fieldContext)..add(const FieldEditorPannelEvent.initial()),
|
|
||||||
child: BlocBuilder<FieldEditorPannelBloc, FieldEditorPannelState>(
|
|
||||||
builder: (context, state) {
|
|
||||||
List<Widget> children = [_switchFieldTypeButton(context, widget.fieldContext.field)];
|
|
||||||
final typeOptionWidget = _typeOptionWidget(context: context, state: state);
|
|
||||||
|
|
||||||
if (typeOptionWidget != null) {
|
|
||||||
children.add(typeOptionWidget);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ListView(
|
|
||||||
shrinkWrap: true,
|
|
||||||
children: children,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _switchFieldTypeButton(BuildContext context, Field field) {
|
|
||||||
final theme = context.watch<AppTheme>();
|
|
||||||
return SizedBox(
|
|
||||||
height: GridSize.typeOptionItemHeight,
|
|
||||||
child: FlowyButton(
|
|
||||||
text: FlowyText.medium(field.fieldType.title(), fontSize: 12),
|
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
|
||||||
hoverColor: theme.hover,
|
|
||||||
onTap: () {
|
|
||||||
final list = FieldTypeList(onSelectField: (newFieldType) {
|
|
||||||
widget.fieldContext.switchToField(newFieldType);
|
|
||||||
});
|
|
||||||
_showOverlay(context, list);
|
|
||||||
},
|
|
||||||
leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor),
|
|
||||||
rightIcon: svgWidget("grid/more", color: theme.iconColor),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget? _typeOptionWidget({
|
|
||||||
required BuildContext context,
|
|
||||||
required FieldEditorPannelState state,
|
|
||||||
}) {
|
|
||||||
final overlayDelegate = TypeOptionOverlayDelegate(
|
|
||||||
showOverlay: _showOverlay,
|
|
||||||
hideOverlay: _hideOverlay,
|
|
||||||
);
|
|
||||||
|
|
||||||
final builder = _makeTypeOptionBuild(
|
|
||||||
typeOptionContext: _makeTypeOptionContext(widget.fieldContext),
|
|
||||||
overlayDelegate: overlayDelegate,
|
|
||||||
);
|
|
||||||
|
|
||||||
return builder.customWidget;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _showOverlay(BuildContext context, Widget child, {VoidCallback? onRemoved}) {
|
|
||||||
final identifier = child.toString();
|
|
||||||
if (currentOverlayIdentifier != null) {
|
|
||||||
FlowyOverlay.of(context).remove(currentOverlayIdentifier!);
|
|
||||||
}
|
|
||||||
|
|
||||||
currentOverlayIdentifier = identifier;
|
|
||||||
FlowyOverlay.of(context).insertWithAnchor(
|
|
||||||
widget: OverlayContainer(
|
|
||||||
child: child,
|
|
||||||
constraints: BoxConstraints.loose(const Size(460, 440)),
|
|
||||||
),
|
|
||||||
identifier: identifier,
|
|
||||||
anchorContext: context,
|
|
||||||
anchorDirection: AnchorDirection.leftWithCenterAligned,
|
|
||||||
style: FlowyOverlayStyle(blur: false),
|
|
||||||
anchorOffset: const Offset(-20, 0),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _hideOverlay(BuildContext context) {
|
|
||||||
if (currentOverlayIdentifier != null) {
|
|
||||||
FlowyOverlay.of(context).remove(currentOverlayIdentifier!);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class TypeOptionBuilder {
|
|
||||||
Widget? get customWidget;
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeOptionBuilder _makeTypeOptionBuild({
|
|
||||||
required TypeOptionContext typeOptionContext,
|
|
||||||
required TypeOptionOverlayDelegate overlayDelegate,
|
|
||||||
}) {
|
|
||||||
switch (typeOptionContext.field.fieldType) {
|
|
||||||
case FieldType.Checkbox:
|
|
||||||
return CheckboxTypeOptionBuilder(
|
|
||||||
typeOptionContext as CheckboxTypeOptionContext,
|
|
||||||
);
|
|
||||||
case FieldType.DateTime:
|
|
||||||
return DateTypeOptionBuilder(
|
|
||||||
typeOptionContext as DateTypeOptionContext,
|
|
||||||
overlayDelegate,
|
|
||||||
);
|
|
||||||
case FieldType.SingleSelect:
|
|
||||||
return SingleSelectTypeOptionBuilder(
|
|
||||||
typeOptionContext as SingleSelectTypeOptionContext,
|
|
||||||
overlayDelegate,
|
|
||||||
);
|
|
||||||
case FieldType.MultiSelect:
|
|
||||||
return MultiSelectTypeOptionBuilder(
|
|
||||||
typeOptionContext as MultiSelectTypeOptionContext,
|
|
||||||
overlayDelegate,
|
|
||||||
);
|
|
||||||
case FieldType.Number:
|
|
||||||
return NumberTypeOptionBuilder(
|
|
||||||
typeOptionContext as NumberTypeOptionContext,
|
|
||||||
overlayDelegate,
|
|
||||||
);
|
|
||||||
case FieldType.RichText:
|
|
||||||
return RichTextTypeOptionBuilder(
|
|
||||||
typeOptionContext as RichTextTypeOptionContext,
|
|
||||||
);
|
|
||||||
|
|
||||||
case FieldType.URL:
|
|
||||||
return URLTypeOptionBuilder(
|
|
||||||
typeOptionContext as URLTypeOptionContext,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
throw UnimplementedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeOptionContext _makeTypeOptionContext(GridFieldContext fieldContext) {
|
|
||||||
switch (fieldContext.field.fieldType) {
|
|
||||||
case FieldType.Checkbox:
|
|
||||||
return CheckboxTypeOptionContext(
|
|
||||||
fieldContext: fieldContext,
|
|
||||||
dataBuilder: CheckboxTypeOptionDataBuilder(),
|
|
||||||
);
|
|
||||||
case FieldType.DateTime:
|
|
||||||
return DateTypeOptionContext(
|
|
||||||
fieldContext: fieldContext,
|
|
||||||
dataBuilder: DateTypeOptionDataBuilder(),
|
|
||||||
);
|
|
||||||
case FieldType.MultiSelect:
|
|
||||||
return MultiSelectTypeOptionContext(
|
|
||||||
fieldContext: fieldContext,
|
|
||||||
dataBuilder: MultiSelectTypeOptionDataBuilder(),
|
|
||||||
);
|
|
||||||
case FieldType.Number:
|
|
||||||
return NumberTypeOptionContext(
|
|
||||||
fieldContext: fieldContext,
|
|
||||||
dataBuilder: NumberTypeOptionDataBuilder(),
|
|
||||||
);
|
|
||||||
case FieldType.RichText:
|
|
||||||
return RichTextTypeOptionContext(
|
|
||||||
fieldContext: fieldContext,
|
|
||||||
dataBuilder: RichTextTypeOptionDataBuilder(),
|
|
||||||
);
|
|
||||||
case FieldType.SingleSelect:
|
|
||||||
return SingleSelectTypeOptionContext(
|
|
||||||
fieldContext: fieldContext,
|
|
||||||
dataBuilder: SingleSelectTypeOptionDataBuilder(),
|
|
||||||
);
|
|
||||||
|
|
||||||
case FieldType.URL:
|
|
||||||
return URLTypeOptionContext(
|
|
||||||
fieldContext: fieldContext,
|
|
||||||
dataBuilder: URLTypeOptionDataBuilder(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw UnimplementedError();
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class TypeOptionWidget extends StatelessWidget {
|
|
||||||
const TypeOptionWidget({Key? key}) : super(key: key);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef TypeOptionData = Uint8List;
|
|
||||||
typedef TypeOptionDataCallback = void Function(TypeOptionData typeOptionData);
|
|
||||||
typedef ShowOverlayCallback = void Function(
|
|
||||||
BuildContext anchorContext,
|
|
||||||
Widget child, {
|
|
||||||
VoidCallback? onRemoved,
|
|
||||||
});
|
|
||||||
typedef HideOverlayCallback = void Function(BuildContext anchorContext);
|
|
||||||
|
|
||||||
class TypeOptionOverlayDelegate {
|
|
||||||
ShowOverlayCallback showOverlay;
|
|
||||||
HideOverlayCallback hideOverlay;
|
|
||||||
TypeOptionOverlayDelegate({
|
|
||||||
required this.showOverlay,
|
|
||||||
required this.hideOverlay,
|
|
||||||
});
|
|
||||||
}
|
|
@ -0,0 +1,127 @@
|
|||||||
|
import 'dart:typed_data';
|
||||||
|
import 'package:dartz/dartz.dart' show Either;
|
||||||
|
import 'package:flowy_infra/image.dart';
|
||||||
|
import 'package:flowy_infra/theme.dart';
|
||||||
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
|
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||||
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:app_flowy/workspace/application/grid/prelude.dart';
|
||||||
|
import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
|
||||||
|
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart';
|
||||||
|
import 'field_type_extension.dart';
|
||||||
|
import 'type_option/builder.dart';
|
||||||
|
|
||||||
|
typedef UpdateFieldCallback = void Function(Field, Uint8List);
|
||||||
|
typedef SwitchToFieldCallback = Future<Either<FieldTypeOptionData, FlowyError>> Function(
|
||||||
|
String fieldId,
|
||||||
|
FieldType fieldType,
|
||||||
|
);
|
||||||
|
|
||||||
|
class FieldTypeOptionEditor extends StatefulWidget {
|
||||||
|
final TypeOptionDataController dataController;
|
||||||
|
|
||||||
|
const FieldTypeOptionEditor({
|
||||||
|
required this.dataController,
|
||||||
|
Key? key,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<FieldTypeOptionEditor> createState() => _FieldTypeOptionEditorState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _FieldTypeOptionEditorState extends State<FieldTypeOptionEditor> {
|
||||||
|
String? currentOverlayIdentifier;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocProvider(
|
||||||
|
create: (context) =>
|
||||||
|
FieldTypeOptionEditBloc(widget.dataController)..add(const FieldTypeOptionEditEvent.initial()),
|
||||||
|
child: BlocBuilder<FieldTypeOptionEditBloc, FieldTypeOptionEditState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
List<Widget> children = [_switchFieldTypeButton(context, widget.dataController.field)];
|
||||||
|
final typeOptionWidget = _typeOptionWidget(context: context, state: state);
|
||||||
|
|
||||||
|
if (typeOptionWidget != null) {
|
||||||
|
children.add(typeOptionWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ListView(
|
||||||
|
shrinkWrap: true,
|
||||||
|
children: children,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _switchFieldTypeButton(BuildContext context, Field field) {
|
||||||
|
final theme = context.watch<AppTheme>();
|
||||||
|
return SizedBox(
|
||||||
|
height: GridSize.typeOptionItemHeight,
|
||||||
|
child: FlowyButton(
|
||||||
|
text: FlowyText.medium(field.fieldType.title(), fontSize: 12),
|
||||||
|
margin: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||||
|
hoverColor: theme.hover,
|
||||||
|
onTap: () {
|
||||||
|
final list = FieldTypeList(onSelectField: (newFieldType) {
|
||||||
|
widget.dataController.switchToField(newFieldType);
|
||||||
|
});
|
||||||
|
_showOverlay(context, list);
|
||||||
|
},
|
||||||
|
leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor),
|
||||||
|
rightIcon: svgWidget("grid/more", color: theme.iconColor),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget? _typeOptionWidget({
|
||||||
|
required BuildContext context,
|
||||||
|
required FieldTypeOptionEditState state,
|
||||||
|
}) {
|
||||||
|
final overlayDelegate = TypeOptionOverlayDelegate(
|
||||||
|
showOverlay: _showOverlay,
|
||||||
|
hideOverlay: _hideOverlay,
|
||||||
|
);
|
||||||
|
|
||||||
|
return makeTypeOptionWidget(
|
||||||
|
context: context,
|
||||||
|
dataController: widget.dataController,
|
||||||
|
overlayDelegate: overlayDelegate,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showOverlay(BuildContext context, Widget child, {VoidCallback? onRemoved}) {
|
||||||
|
final identifier = child.toString();
|
||||||
|
if (currentOverlayIdentifier != null) {
|
||||||
|
FlowyOverlay.of(context).remove(currentOverlayIdentifier!);
|
||||||
|
}
|
||||||
|
|
||||||
|
currentOverlayIdentifier = identifier;
|
||||||
|
FlowyOverlay.of(context).insertWithAnchor(
|
||||||
|
widget: OverlayContainer(
|
||||||
|
child: child,
|
||||||
|
constraints: BoxConstraints.loose(const Size(460, 440)),
|
||||||
|
),
|
||||||
|
identifier: identifier,
|
||||||
|
anchorContext: context,
|
||||||
|
anchorDirection: AnchorDirection.leftWithCenterAligned,
|
||||||
|
style: FlowyOverlayStyle(blur: false),
|
||||||
|
anchorOffset: const Offset(-20, 0),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _hideOverlay(BuildContext context) {
|
||||||
|
if (currentOverlayIdentifier != null) {
|
||||||
|
FlowyOverlay.of(context).remove(currentOverlayIdentifier!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class TypeOptionWidget extends StatelessWidget {
|
||||||
|
const TypeOptionWidget({Key? key}) : super(key: key);
|
||||||
|
}
|
@ -151,7 +151,7 @@ class CreateFieldButton extends StatelessWidget {
|
|||||||
onTap: () => FieldEditor(
|
onTap: () => FieldEditor(
|
||||||
gridId: gridId,
|
gridId: gridId,
|
||||||
fieldName: "",
|
fieldName: "",
|
||||||
contextLoader: NewFieldContextLoader(gridId: gridId),
|
typeOptionLoader: NewFieldTypeOptionLoader(gridId: gridId),
|
||||||
).show(context),
|
).show(context),
|
||||||
leftIcon: svgWidget("home/add"),
|
leftIcon: svgWidget("home/add"),
|
||||||
);
|
);
|
||||||
|
@ -0,0 +1,108 @@
|
|||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:app_flowy/workspace/application/grid/field/type_option/multi_select_type_option.dart';
|
||||||
|
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/checkbox.dart';
|
||||||
|
import 'package:app_flowy/workspace/application/grid/prelude.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'date.dart';
|
||||||
|
import 'multi_select.dart';
|
||||||
|
import 'number.dart';
|
||||||
|
import 'rich_text.dart';
|
||||||
|
import 'single_select.dart';
|
||||||
|
import 'url.dart';
|
||||||
|
|
||||||
|
typedef TypeOptionData = Uint8List;
|
||||||
|
typedef TypeOptionDataCallback = void Function(TypeOptionData typeOptionData);
|
||||||
|
typedef ShowOverlayCallback = void Function(
|
||||||
|
BuildContext anchorContext,
|
||||||
|
Widget child, {
|
||||||
|
VoidCallback? onRemoved,
|
||||||
|
});
|
||||||
|
typedef HideOverlayCallback = void Function(BuildContext anchorContext);
|
||||||
|
|
||||||
|
class TypeOptionOverlayDelegate {
|
||||||
|
ShowOverlayCallback showOverlay;
|
||||||
|
HideOverlayCallback hideOverlay;
|
||||||
|
TypeOptionOverlayDelegate({
|
||||||
|
required this.showOverlay,
|
||||||
|
required this.hideOverlay,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class TypeOptionWidgetBuilder {
|
||||||
|
Widget? build(BuildContext context);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget? makeTypeOptionWidget({
|
||||||
|
required BuildContext context,
|
||||||
|
required TypeOptionDataController dataController,
|
||||||
|
required TypeOptionOverlayDelegate overlayDelegate,
|
||||||
|
}) {
|
||||||
|
final builder = makeTypeOptionWidgetBuilder(dataController, overlayDelegate);
|
||||||
|
return builder.build(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeOptionWidgetBuilder makeTypeOptionWidgetBuilder(
|
||||||
|
TypeOptionDataController dataController,
|
||||||
|
TypeOptionOverlayDelegate overlayDelegate,
|
||||||
|
) {
|
||||||
|
switch (dataController.field.fieldType) {
|
||||||
|
case FieldType.Checkbox:
|
||||||
|
final context = CheckboxTypeOptionContext(
|
||||||
|
dataController: dataController,
|
||||||
|
dataParser: CheckboxTypeOptionWidgetDataParser(),
|
||||||
|
);
|
||||||
|
return CheckboxTypeOptionWidgetBuilder(context);
|
||||||
|
case FieldType.DateTime:
|
||||||
|
final context = DateTypeOptionContext(
|
||||||
|
dataController: dataController,
|
||||||
|
dataParser: DateTypeOptionDataParser(),
|
||||||
|
);
|
||||||
|
return DateTypeOptionWidgetBuilder(
|
||||||
|
context,
|
||||||
|
overlayDelegate,
|
||||||
|
);
|
||||||
|
case FieldType.SingleSelect:
|
||||||
|
final context = SingleSelectTypeOptionContext(
|
||||||
|
fieldContext: dataController,
|
||||||
|
dataBuilder: SingleSelectTypeOptionWidgetDataParser(),
|
||||||
|
);
|
||||||
|
return SingleSelectTypeOptionWidgetBuilder(
|
||||||
|
context,
|
||||||
|
overlayDelegate,
|
||||||
|
);
|
||||||
|
case FieldType.MultiSelect:
|
||||||
|
final context = MultiSelectTypeOptionContext(
|
||||||
|
dataController: dataController,
|
||||||
|
dataBuilder: MultiSelectTypeOptionWidgetDataParser(),
|
||||||
|
);
|
||||||
|
return MultiSelectTypeOptionWidgetBuilder(
|
||||||
|
context,
|
||||||
|
overlayDelegate,
|
||||||
|
);
|
||||||
|
case FieldType.Number:
|
||||||
|
final context = NumberTypeOptionContext(
|
||||||
|
dataController: dataController,
|
||||||
|
dataParser: NumberTypeOptionWidgetDataParser(),
|
||||||
|
);
|
||||||
|
return NumberTypeOptionWidgetBuilder(
|
||||||
|
context,
|
||||||
|
overlayDelegate,
|
||||||
|
);
|
||||||
|
case FieldType.RichText:
|
||||||
|
final context = RichTextTypeOptionContext(
|
||||||
|
dataController: dataController,
|
||||||
|
dataParser: RichTextTypeOptionWidgetDataParser(),
|
||||||
|
);
|
||||||
|
return RichTextTypeOptionWidgetBuilder(context);
|
||||||
|
|
||||||
|
case FieldType.URL:
|
||||||
|
final context = URLTypeOptionContext(
|
||||||
|
dataController: dataController,
|
||||||
|
dataParser: URLTypeOptionWidgetDataParser(),
|
||||||
|
);
|
||||||
|
return URLTypeOptionWidgetBuilder(context);
|
||||||
|
}
|
||||||
|
throw UnimplementedError;
|
||||||
|
}
|
@ -1,20 +1,20 @@
|
|||||||
import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart';
|
import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_editor_pannel.dart';
|
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_type_option.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_type_option.pb.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'builder.dart';
|
||||||
|
|
||||||
typedef CheckboxTypeOptionContext = TypeOptionContext<CheckboxTypeOption>;
|
typedef CheckboxTypeOptionContext = TypeOptionWidgetContext<CheckboxTypeOption>;
|
||||||
|
|
||||||
class CheckboxTypeOptionDataBuilder extends TypeOptionDataBuilder<CheckboxTypeOption> {
|
class CheckboxTypeOptionWidgetDataParser extends TypeOptionDataParser<CheckboxTypeOption> {
|
||||||
@override
|
@override
|
||||||
CheckboxTypeOption fromBuffer(List<int> buffer) {
|
CheckboxTypeOption fromBuffer(List<int> buffer) {
|
||||||
return CheckboxTypeOption.fromBuffer(buffer);
|
return CheckboxTypeOption.fromBuffer(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CheckboxTypeOptionBuilder extends TypeOptionBuilder {
|
class CheckboxTypeOptionWidgetBuilder extends TypeOptionWidgetBuilder {
|
||||||
CheckboxTypeOptionBuilder(CheckboxTypeOptionContext typeOptionContext);
|
CheckboxTypeOptionWidgetBuilder(CheckboxTypeOptionContext typeOptionContext);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget? get customWidget => null;
|
Widget? build(BuildContext context) => null;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:app_flowy/workspace/application/grid/field/type_option/date_bloc.dart';
|
import 'package:app_flowy/workspace/application/grid/field/type_option/date_bloc.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
|
import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_editor_pannel.dart';
|
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_type_option_editor.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart' hide DateFormat;
|
import 'package:easy_localization/easy_localization.dart' hide DateFormat;
|
||||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
@ -12,11 +12,12 @@ import 'package:flowy_infra_ui/widget/spacing.dart';
|
|||||||
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option_entities.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option_entities.pb.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'builder.dart';
|
||||||
|
|
||||||
class DateTypeOptionBuilder extends TypeOptionBuilder {
|
class DateTypeOptionWidgetBuilder extends TypeOptionWidgetBuilder {
|
||||||
final DateTypeOptionWidget _widget;
|
final DateTypeOptionWidget _widget;
|
||||||
|
|
||||||
DateTypeOptionBuilder(
|
DateTypeOptionWidgetBuilder(
|
||||||
DateTypeOptionContext typeOptionContext,
|
DateTypeOptionContext typeOptionContext,
|
||||||
TypeOptionOverlayDelegate overlayDelegate,
|
TypeOptionOverlayDelegate overlayDelegate,
|
||||||
) : _widget = DateTypeOptionWidget(
|
) : _widget = DateTypeOptionWidget(
|
||||||
@ -25,7 +26,9 @@ class DateTypeOptionBuilder extends TypeOptionBuilder {
|
|||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget? get customWidget => _widget;
|
Widget? build(BuildContext context) {
|
||||||
|
return _widget;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DateTypeOptionWidget extends TypeOptionWidget {
|
class DateTypeOptionWidget extends TypeOptionWidget {
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
import 'package:app_flowy/workspace/application/grid/field/type_option/multi_select_type_option.dart';
|
import 'package:app_flowy/workspace/application/grid/field/type_option/multi_select_type_option.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_editor_pannel.dart';
|
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_type_option_editor.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import 'builder.dart';
|
||||||
import 'select_option.dart';
|
import 'select_option.dart';
|
||||||
|
|
||||||
class MultiSelectTypeOptionBuilder extends TypeOptionBuilder {
|
class MultiSelectTypeOptionWidgetBuilder extends TypeOptionWidgetBuilder {
|
||||||
final MultiSelectTypeOptionWidget _widget;
|
final MultiSelectTypeOptionWidget _widget;
|
||||||
|
|
||||||
MultiSelectTypeOptionBuilder(
|
MultiSelectTypeOptionWidgetBuilder(
|
||||||
MultiSelectTypeOptionContext typeOptionContext,
|
MultiSelectTypeOptionContext typeOptionContext,
|
||||||
TypeOptionOverlayDelegate overlayDelegate,
|
TypeOptionOverlayDelegate overlayDelegate,
|
||||||
) : _widget = MultiSelectTypeOptionWidget(
|
) : _widget = MultiSelectTypeOptionWidget(
|
||||||
@ -16,7 +17,7 @@ class MultiSelectTypeOptionBuilder extends TypeOptionBuilder {
|
|||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget? get customWidget => _widget;
|
Widget? build(BuildContext context) => _widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
class MultiSelectTypeOptionWidget extends TypeOptionWidget {
|
class MultiSelectTypeOptionWidget extends TypeOptionWidget {
|
||||||
|
@ -2,7 +2,7 @@ import 'package:app_flowy/workspace/application/grid/field/type_option/number_bl
|
|||||||
import 'package:app_flowy/workspace/application/grid/field/type_option/number_format_bloc.dart';
|
import 'package:app_flowy/workspace/application/grid/field/type_option/number_format_bloc.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
|
import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/common/text_field.dart';
|
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/common/text_field.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_editor_pannel.dart';
|
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_type_option_editor.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
@ -15,10 +15,12 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:easy_localization/easy_localization.dart' hide NumberFormat;
|
import 'package:easy_localization/easy_localization.dart' hide NumberFormat;
|
||||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||||
|
|
||||||
class NumberTypeOptionBuilder extends TypeOptionBuilder {
|
import 'builder.dart';
|
||||||
|
|
||||||
|
class NumberTypeOptionWidgetBuilder extends TypeOptionWidgetBuilder {
|
||||||
final NumberTypeOptionWidget _widget;
|
final NumberTypeOptionWidget _widget;
|
||||||
|
|
||||||
NumberTypeOptionBuilder(
|
NumberTypeOptionWidgetBuilder(
|
||||||
NumberTypeOptionContext typeOptionContext,
|
NumberTypeOptionContext typeOptionContext,
|
||||||
TypeOptionOverlayDelegate overlayDelegate,
|
TypeOptionOverlayDelegate overlayDelegate,
|
||||||
) : _widget = NumberTypeOptionWidget(
|
) : _widget = NumberTypeOptionWidget(
|
||||||
@ -27,7 +29,7 @@ class NumberTypeOptionBuilder extends TypeOptionBuilder {
|
|||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget? get customWidget => _widget;
|
Widget? build(BuildContext context) => _widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
class NumberTypeOptionWidget extends TypeOptionWidget {
|
class NumberTypeOptionWidget extends TypeOptionWidget {
|
||||||
|
@ -1,21 +1,20 @@
|
|||||||
import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart';
|
import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_editor_pannel.dart';
|
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/text_type_option.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/text_type_option.pb.dart';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'builder.dart';
|
||||||
|
|
||||||
typedef RichTextTypeOptionContext = TypeOptionContext<RichTextTypeOption>;
|
typedef RichTextTypeOptionContext = TypeOptionWidgetContext<RichTextTypeOption>;
|
||||||
|
|
||||||
class RichTextTypeOptionDataBuilder extends TypeOptionDataBuilder<RichTextTypeOption> {
|
class RichTextTypeOptionWidgetDataParser extends TypeOptionDataParser<RichTextTypeOption> {
|
||||||
@override
|
@override
|
||||||
RichTextTypeOption fromBuffer(List<int> buffer) {
|
RichTextTypeOption fromBuffer(List<int> buffer) {
|
||||||
return RichTextTypeOption.fromBuffer(buffer);
|
return RichTextTypeOption.fromBuffer(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RichTextTypeOptionBuilder extends TypeOptionBuilder {
|
class RichTextTypeOptionWidgetBuilder extends TypeOptionWidgetBuilder {
|
||||||
RichTextTypeOptionBuilder(RichTextTypeOptionContext typeOptionContext);
|
RichTextTypeOptionWidgetBuilder(RichTextTypeOptionContext typeOptionContext);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget? get customWidget => null;
|
Widget? build(BuildContext context) => null;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ import 'package:app_flowy/workspace/application/grid/field/type_option/select_op
|
|||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
|
import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/select_option_cell/extension.dart';
|
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/select_option_cell/extension.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/common/text_field.dart';
|
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/common/text_field.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_editor_pannel.dart';
|
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||||
@ -14,6 +13,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||||
|
|
||||||
|
import 'builder.dart';
|
||||||
import 'select_option_editor.dart';
|
import 'select_option_editor.dart';
|
||||||
|
|
||||||
class SelectOptionTypeOptionWidget extends StatelessWidget {
|
class SelectOptionTypeOptionWidget extends StatelessWidget {
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import 'package:app_flowy/workspace/application/grid/field/type_option/single_select_type_option.dart';
|
import 'package:app_flowy/workspace/application/grid/field/type_option/single_select_type_option.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_editor_pannel.dart';
|
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_type_option_editor.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'builder.dart';
|
||||||
import 'select_option.dart';
|
import 'select_option.dart';
|
||||||
|
|
||||||
class SingleSelectTypeOptionBuilder extends TypeOptionBuilder {
|
class SingleSelectTypeOptionWidgetBuilder extends TypeOptionWidgetBuilder {
|
||||||
final SingleSelectTypeOptionWidget _widget;
|
final SingleSelectTypeOptionWidget _widget;
|
||||||
|
|
||||||
SingleSelectTypeOptionBuilder(
|
SingleSelectTypeOptionWidgetBuilder(
|
||||||
SingleSelectTypeOptionContext typeOptionContext,
|
SingleSelectTypeOptionContext typeOptionContext,
|
||||||
TypeOptionOverlayDelegate overlayDelegate,
|
TypeOptionOverlayDelegate overlayDelegate,
|
||||||
) : _widget = SingleSelectTypeOptionWidget(
|
) : _widget = SingleSelectTypeOptionWidget(
|
||||||
@ -15,7 +16,7 @@ class SingleSelectTypeOptionBuilder extends TypeOptionBuilder {
|
|||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget? get customWidget => _widget;
|
Widget? build(BuildContext context) => _widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
class SingleSelectTypeOptionWidget extends TypeOptionWidget {
|
class SingleSelectTypeOptionWidget extends TypeOptionWidget {
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart';
|
import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_editor_pannel.dart';
|
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/url_type_option.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/url_type_option.pb.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'builder.dart';
|
||||||
|
|
||||||
typedef URLTypeOptionContext = TypeOptionContext<URLTypeOption>;
|
typedef URLTypeOptionContext = TypeOptionWidgetContext<URLTypeOption>;
|
||||||
|
|
||||||
class URLTypeOptionDataBuilder extends TypeOptionDataBuilder<URLTypeOption> {
|
class URLTypeOptionWidgetDataParser extends TypeOptionDataParser<URLTypeOption> {
|
||||||
@override
|
@override
|
||||||
URLTypeOption fromBuffer(List<int> buffer) {
|
URLTypeOption fromBuffer(List<int> buffer) {
|
||||||
return URLTypeOption.fromBuffer(buffer);
|
return URLTypeOption.fromBuffer(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class URLTypeOptionBuilder extends TypeOptionBuilder {
|
class URLTypeOptionWidgetBuilder extends TypeOptionWidgetBuilder {
|
||||||
URLTypeOptionBuilder(URLTypeOptionContext typeOptionContext);
|
URLTypeOptionWidgetBuilder(URLTypeOptionContext typeOptionContext);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget? get customWidget => null;
|
Widget? build(BuildContext context) => null;
|
||||||
}
|
}
|
||||||
|
@ -10,19 +10,25 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'row_action_sheet.dart';
|
|
||||||
|
|
||||||
|
import 'row_action_sheet.dart';
|
||||||
import 'row_detail.dart';
|
import 'row_detail.dart';
|
||||||
|
|
||||||
class GridRowWidget extends StatefulWidget {
|
class GridRowWidget extends StatefulWidget {
|
||||||
final GridRow rowData;
|
final GridRow rowData;
|
||||||
final GridRowCacheService rowCache;
|
final GridRowCache rowCache;
|
||||||
|
final GridCellBuilder cellBuilder;
|
||||||
|
|
||||||
const GridRowWidget({
|
GridRowWidget({
|
||||||
required this.rowData,
|
required this.rowData,
|
||||||
required this.rowCache,
|
required this.rowCache,
|
||||||
|
required GridFieldCache fieldCache,
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key);
|
}) : cellBuilder = GridCellBuilder(
|
||||||
|
cellCache: rowCache.cellCache,
|
||||||
|
fieldCache: fieldCache,
|
||||||
|
),
|
||||||
|
super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<GridRowWidget> createState() => _GridRowWidgetState();
|
State<GridRowWidget> createState() => _GridRowWidgetState();
|
||||||
@ -52,7 +58,11 @@ class _GridRowWidgetState extends State<GridRowWidget> {
|
|||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
const _RowLeading(),
|
const _RowLeading(),
|
||||||
Expanded(child: _RowCells(cellCache: widget.rowCache.cellCache, onExpand: () => _expandRow(context))),
|
Expanded(
|
||||||
|
child: _RowCells(
|
||||||
|
builder: widget.cellBuilder,
|
||||||
|
onExpand: () => _expandRow(context),
|
||||||
|
)),
|
||||||
const _RowTrailing(),
|
const _RowTrailing(),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@ -72,6 +82,7 @@ class _GridRowWidgetState extends State<GridRowWidget> {
|
|||||||
final page = RowDetailPage(
|
final page = RowDetailPage(
|
||||||
rowData: widget.rowData,
|
rowData: widget.rowData,
|
||||||
rowCache: widget.rowCache,
|
rowCache: widget.rowCache,
|
||||||
|
cellBuilder: widget.cellBuilder,
|
||||||
);
|
);
|
||||||
page.show(context);
|
page.show(context);
|
||||||
}
|
}
|
||||||
@ -146,9 +157,13 @@ class _DeleteRowButton extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _RowCells extends StatelessWidget {
|
class _RowCells extends StatelessWidget {
|
||||||
final GridCellCacheService cellCache;
|
|
||||||
final VoidCallback onExpand;
|
final VoidCallback onExpand;
|
||||||
const _RowCells({required this.cellCache, required this.onExpand, Key? key}) : super(key: key);
|
final GridCellBuilder builder;
|
||||||
|
const _RowCells({
|
||||||
|
required this.builder,
|
||||||
|
required this.onExpand,
|
||||||
|
Key? key,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -168,13 +183,12 @@ class _RowCells extends StatelessWidget {
|
|||||||
|
|
||||||
List<Widget> _makeCells(BuildContext context, GridCellMap gridCellMap) {
|
List<Widget> _makeCells(BuildContext context, GridCellMap gridCellMap) {
|
||||||
return gridCellMap.values.map(
|
return gridCellMap.values.map(
|
||||||
(gridCell) {
|
(cellId) {
|
||||||
final GridCellWidget child = buildGridCellWidget(gridCell, cellCache);
|
final GridCellWidget child = builder.build(cellId);
|
||||||
|
|
||||||
accessoryBuilder(GridCellAccessoryBuildContext buildContext) {
|
accessoryBuilder(GridCellAccessoryBuildContext buildContext) {
|
||||||
final builder = child.accessoryBuilder;
|
final builder = child.accessoryBuilder;
|
||||||
List<GridCellAccessory> accessories = [];
|
List<GridCellAccessory> accessories = [];
|
||||||
if (gridCell.field.isPrimary) {
|
if (cellId.field.isPrimary) {
|
||||||
accessories.add(PrimaryCellAccessory(
|
accessories.add(PrimaryCellAccessory(
|
||||||
onTapCallback: onExpand,
|
onTapCallback: onExpand,
|
||||||
isCellEditing: buildContext.isCellEditing,
|
isCellEditing: buildContext.isCellEditing,
|
||||||
@ -188,7 +202,7 @@ class _RowCells extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return CellContainer(
|
return CellContainer(
|
||||||
width: gridCell.field.width.toDouble(),
|
width: cellId.field.width.toDouble(),
|
||||||
child: child,
|
child: child,
|
||||||
rowStateNotifier: Provider.of<RegionStateNotifier>(context, listen: false),
|
rowStateNotifier: Provider.of<RegionStateNotifier>(context, listen: false),
|
||||||
accessoryBuilder: accessoryBuilder,
|
accessoryBuilder: accessoryBuilder,
|
||||||
|
@ -22,11 +22,13 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
|
|
||||||
class RowDetailPage extends StatefulWidget with FlowyOverlayDelegate {
|
class RowDetailPage extends StatefulWidget with FlowyOverlayDelegate {
|
||||||
final GridRow rowData;
|
final GridRow rowData;
|
||||||
final GridRowCacheService rowCache;
|
final GridRowCache rowCache;
|
||||||
|
final GridCellBuilder cellBuilder;
|
||||||
|
|
||||||
const RowDetailPage({
|
const RowDetailPage({
|
||||||
required this.rowData,
|
required this.rowData,
|
||||||
required this.rowCache,
|
required this.rowCache,
|
||||||
|
required this.cellBuilder,
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@ -74,7 +76,7 @@ class _RowDetailPageState extends State<RowDetailPage> {
|
|||||||
children: const [Spacer(), _CloseButton()],
|
children: const [Spacer(), _CloseButton()],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(child: _PropertyList(cellCache: widget.rowCache.cellCache)),
|
Expanded(child: _PropertyList(cellBuilder: widget.cellBuilder)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -98,10 +100,10 @@ class _CloseButton extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _PropertyList extends StatelessWidget {
|
class _PropertyList extends StatelessWidget {
|
||||||
final GridCellCacheService cellCache;
|
final GridCellBuilder cellBuilder;
|
||||||
final ScrollController _scrollController;
|
final ScrollController _scrollController;
|
||||||
_PropertyList({
|
_PropertyList({
|
||||||
required this.cellCache,
|
required this.cellBuilder,
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : _scrollController = ScrollController(),
|
}) : _scrollController = ScrollController(),
|
||||||
super(key: key);
|
super(key: key);
|
||||||
@ -120,8 +122,8 @@ class _PropertyList extends StatelessWidget {
|
|||||||
itemCount: state.gridCells.length,
|
itemCount: state.gridCells.length,
|
||||||
itemBuilder: (BuildContext context, int index) {
|
itemBuilder: (BuildContext context, int index) {
|
||||||
return _RowDetailCell(
|
return _RowDetailCell(
|
||||||
gridCell: state.gridCells[index],
|
cellId: state.gridCells[index],
|
||||||
cellCache: cellCache,
|
cellBuilder: cellBuilder,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
separatorBuilder: (BuildContext context, int index) {
|
separatorBuilder: (BuildContext context, int index) {
|
||||||
@ -135,19 +137,19 @@ class _PropertyList extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _RowDetailCell extends StatelessWidget {
|
class _RowDetailCell extends StatelessWidget {
|
||||||
final GridCell gridCell;
|
final GridCellIdentifier cellId;
|
||||||
final GridCellCacheService cellCache;
|
final GridCellBuilder cellBuilder;
|
||||||
const _RowDetailCell({
|
const _RowDetailCell({
|
||||||
required this.gridCell,
|
required this.cellId,
|
||||||
required this.cellCache,
|
required this.cellBuilder,
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final theme = context.watch<AppTheme>();
|
final theme = context.watch<AppTheme>();
|
||||||
final style = _customCellStyle(theme, gridCell.field.fieldType);
|
final style = _customCellStyle(theme, cellId.fieldType);
|
||||||
final cell = buildGridCellWidget(gridCell, cellCache, style: style);
|
final cell = cellBuilder.build(cellId, style: style);
|
||||||
|
|
||||||
final gesture = GestureDetector(
|
final gesture = GestureDetector(
|
||||||
behavior: HitTestBehavior.translucent,
|
behavior: HitTestBehavior.translucent,
|
||||||
@ -167,7 +169,7 @@ class _RowDetailCell extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 150,
|
width: 150,
|
||||||
child: FieldCellButton(field: gridCell.field, onTap: () => _showFieldEditor(context)),
|
child: FieldCellButton(field: cellId.field, onTap: () => _showFieldEditor(context)),
|
||||||
),
|
),
|
||||||
const HSpace(10),
|
const HSpace(10),
|
||||||
Expanded(child: gesture),
|
Expanded(child: gesture),
|
||||||
@ -179,11 +181,11 @@ class _RowDetailCell extends StatelessWidget {
|
|||||||
|
|
||||||
void _showFieldEditor(BuildContext context) {
|
void _showFieldEditor(BuildContext context) {
|
||||||
FieldEditor(
|
FieldEditor(
|
||||||
gridId: gridCell.gridId,
|
gridId: cellId.gridId,
|
||||||
fieldName: gridCell.field.name,
|
fieldName: cellId.field.name,
|
||||||
contextLoader: FieldContextLoader(
|
typeOptionLoader: FieldTypeOptionLoader(
|
||||||
gridId: gridCell.gridId,
|
gridId: cellId.gridId,
|
||||||
field: gridCell.field,
|
field: cellId.field,
|
||||||
),
|
),
|
||||||
).show(context);
|
).show(context);
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@ class _GridPropertyCell extends StatelessWidget {
|
|||||||
FieldEditor(
|
FieldEditor(
|
||||||
gridId: gridId,
|
gridId: gridId,
|
||||||
fieldName: field.name,
|
fieldName: field.name,
|
||||||
contextLoader: FieldContextLoader(gridId: gridId, field: field),
|
typeOptionLoader: FieldTypeOptionLoader(gridId: gridId, field: field),
|
||||||
).show(context, anchorDirection: AnchorDirection.bottomRight);
|
).show(context, anchorDirection: AnchorDirection.bottomRight);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -1,231 +0,0 @@
|
|||||||
# Generated by pub
|
|
||||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
|
||||||
packages:
|
|
||||||
async:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: async
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.8.2"
|
|
||||||
boolean_selector:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: boolean_selector
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.0"
|
|
||||||
characters:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: characters
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
charcode:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: charcode
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.3.1"
|
|
||||||
clock:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: clock
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.0"
|
|
||||||
collection:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: collection
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.15.0"
|
|
||||||
crypto:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: crypto
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.1"
|
|
||||||
fake_async:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: fake_async
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
flutter:
|
|
||||||
dependency: "direct main"
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
flutter_lints:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description:
|
|
||||||
name: flutter_lints
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.4"
|
|
||||||
flutter_svg:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: flutter_svg
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.22.0"
|
|
||||||
flutter_test:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
lints:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: lints
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.1"
|
|
||||||
matcher:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: matcher
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.12.11"
|
|
||||||
material_color_utilities:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: material_color_utilities
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.1.3"
|
|
||||||
meta:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: meta
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.7.0"
|
|
||||||
path:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: path
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.8.0"
|
|
||||||
path_drawing:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: path_drawing
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.5.1"
|
|
||||||
path_parsing:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: path_parsing
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.2.1"
|
|
||||||
petitparser:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: petitparser
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "4.2.0"
|
|
||||||
sky_engine:
|
|
||||||
dependency: transitive
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.99"
|
|
||||||
source_span:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: source_span
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.8.1"
|
|
||||||
stack_trace:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: stack_trace
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.10.0"
|
|
||||||
stream_channel:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: stream_channel
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.0"
|
|
||||||
string_scanner:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: string_scanner
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.0"
|
|
||||||
term_glyph:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: term_glyph
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
test_api:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: test_api
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.4.8"
|
|
||||||
textstyle_extensions:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: textstyle_extensions
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.0-nullsafety"
|
|
||||||
time:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: time
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.0"
|
|
||||||
typed_data:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: typed_data
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.3.0"
|
|
||||||
uuid:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: uuid
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.4"
|
|
||||||
vector_math:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: vector_math
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.1"
|
|
||||||
xml:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: xml
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "5.2.0"
|
|
||||||
sdks:
|
|
||||||
dart: ">=2.14.0 <3.0.0"
|
|
||||||
flutter: ">=1.24.0-7.0"
|
|
@ -1,334 +0,0 @@
|
|||||||
# Generated by pub
|
|
||||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
|
||||||
packages:
|
|
||||||
animations:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: animations
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.1"
|
|
||||||
async:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: async
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.8.2"
|
|
||||||
boolean_selector:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: boolean_selector
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.0"
|
|
||||||
characters:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: characters
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
charcode:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: charcode
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.3.1"
|
|
||||||
clock:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: clock
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.0"
|
|
||||||
collection:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: collection
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.15.0"
|
|
||||||
crypto:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: crypto
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.1"
|
|
||||||
cupertino_icons:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: cupertino_icons
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.3"
|
|
||||||
dartz:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: dartz
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.10.0-nullsafety.2"
|
|
||||||
equatable:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: equatable
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.3"
|
|
||||||
fake_async:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: fake_async
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
flowy_infra:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
path: "../../flowy_infra"
|
|
||||||
relative: true
|
|
||||||
source: path
|
|
||||||
version: "0.0.1"
|
|
||||||
flowy_infra_ui:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
path: ".."
|
|
||||||
relative: true
|
|
||||||
source: path
|
|
||||||
version: "0.0.1"
|
|
||||||
flowy_infra_ui_platform_interface:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
path: "../flowy_infra_ui_platform_interface"
|
|
||||||
relative: true
|
|
||||||
source: path
|
|
||||||
version: "0.0.1"
|
|
||||||
flowy_infra_ui_web:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
path: "../flowy_infra_ui_web"
|
|
||||||
relative: true
|
|
||||||
source: path
|
|
||||||
version: "0.0.1"
|
|
||||||
flutter:
|
|
||||||
dependency: "direct main"
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
flutter_lints:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description:
|
|
||||||
name: flutter_lints
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.4"
|
|
||||||
flutter_svg:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: flutter_svg
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.22.0"
|
|
||||||
flutter_test:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
flutter_web_plugins:
|
|
||||||
dependency: transitive
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
js:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: js
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.6.3"
|
|
||||||
lint:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: lint
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.5.3"
|
|
||||||
lints:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: lints
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.1"
|
|
||||||
loading_indicator:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: loading_indicator
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.1"
|
|
||||||
matcher:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: matcher
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.12.11"
|
|
||||||
meta:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: meta
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.7.0"
|
|
||||||
nested:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: nested
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.0"
|
|
||||||
path:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: path
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.8.0"
|
|
||||||
path_drawing:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: path_drawing
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.5.1+1"
|
|
||||||
path_parsing:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: path_parsing
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.2.1"
|
|
||||||
petitparser:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: petitparser
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "4.4.0"
|
|
||||||
plugin_platform_interface:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: plugin_platform_interface
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.1"
|
|
||||||
provider:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: provider
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "6.0.1"
|
|
||||||
sky_engine:
|
|
||||||
dependency: transitive
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.99"
|
|
||||||
source_span:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: source_span
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.8.1"
|
|
||||||
stack_trace:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: stack_trace
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.10.0"
|
|
||||||
stream_channel:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: stream_channel
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.0"
|
|
||||||
string_scanner:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: string_scanner
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.0"
|
|
||||||
styled_widget:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: styled_widget
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.3.1+2"
|
|
||||||
term_glyph:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: term_glyph
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
test_api:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: test_api
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.4.3"
|
|
||||||
textstyle_extensions:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: textstyle_extensions
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.0-nullsafety"
|
|
||||||
time:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: time
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.0"
|
|
||||||
typed_data:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: typed_data
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.3.0"
|
|
||||||
uuid:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: uuid
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.4"
|
|
||||||
vector_math:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: vector_math
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.0"
|
|
||||||
xml:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: xml
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "5.3.1"
|
|
||||||
sdks:
|
|
||||||
dart: ">=2.14.0 <3.0.0"
|
|
||||||
flutter: ">=2.0.0"
|
|
@ -1,168 +0,0 @@
|
|||||||
# Generated by pub
|
|
||||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
|
||||||
packages:
|
|
||||||
async:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: async
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.6.1"
|
|
||||||
boolean_selector:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: boolean_selector
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.0"
|
|
||||||
characters:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: characters
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.0"
|
|
||||||
charcode:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: charcode
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
clock:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: clock
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.0"
|
|
||||||
collection:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: collection
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.15.0"
|
|
||||||
fake_async:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: fake_async
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
flutter:
|
|
||||||
dependency: "direct main"
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
flutter_lints:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description:
|
|
||||||
name: flutter_lints
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.4"
|
|
||||||
flutter_test:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
lints:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: lints
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.1"
|
|
||||||
matcher:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: matcher
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.12.10"
|
|
||||||
meta:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: meta
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.3.0"
|
|
||||||
path:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: path
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.8.0"
|
|
||||||
plugin_platform_interface:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: plugin_platform_interface
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.1"
|
|
||||||
sky_engine:
|
|
||||||
dependency: transitive
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.99"
|
|
||||||
source_span:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: source_span
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.8.1"
|
|
||||||
stack_trace:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: stack_trace
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.10.0"
|
|
||||||
stream_channel:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: stream_channel
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.0"
|
|
||||||
string_scanner:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: string_scanner
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.0"
|
|
||||||
term_glyph:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: term_glyph
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
test_api:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: test_api
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.3.0"
|
|
||||||
typed_data:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: typed_data
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.3.0"
|
|
||||||
vector_math:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: vector_math
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.0"
|
|
||||||
sdks:
|
|
||||||
dart: ">=2.12.0 <3.0.0"
|
|
||||||
flutter: ">=1.17.0"
|
|
@ -1,187 +0,0 @@
|
|||||||
# Generated by pub
|
|
||||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
|
||||||
packages:
|
|
||||||
async:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: async
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.6.1"
|
|
||||||
boolean_selector:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: boolean_selector
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.0"
|
|
||||||
characters:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: characters
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.0"
|
|
||||||
charcode:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: charcode
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
clock:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: clock
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.0"
|
|
||||||
collection:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: collection
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.15.0"
|
|
||||||
fake_async:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: fake_async
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
flowy_infra_ui_platform_interface:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
path: "../flowy_infra_ui_platform_interface"
|
|
||||||
relative: true
|
|
||||||
source: path
|
|
||||||
version: "0.0.1"
|
|
||||||
flutter:
|
|
||||||
dependency: transitive
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
flutter_lints:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description:
|
|
||||||
name: flutter_lints
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.4"
|
|
||||||
flutter_test:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
flutter_web_plugins:
|
|
||||||
dependency: "direct main"
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
js:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: js
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.6.3"
|
|
||||||
lints:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: lints
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.1"
|
|
||||||
matcher:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: matcher
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.12.10"
|
|
||||||
meta:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: meta
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.3.0"
|
|
||||||
path:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: path
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.8.0"
|
|
||||||
plugin_platform_interface:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: plugin_platform_interface
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.1"
|
|
||||||
sky_engine:
|
|
||||||
dependency: transitive
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.99"
|
|
||||||
source_span:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: source_span
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.8.1"
|
|
||||||
stack_trace:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: stack_trace
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.10.0"
|
|
||||||
stream_channel:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: stream_channel
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.0"
|
|
||||||
string_scanner:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: string_scanner
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.0"
|
|
||||||
term_glyph:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: term_glyph
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
test_api:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: test_api
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.3.0"
|
|
||||||
typed_data:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: typed_data
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.3.0"
|
|
||||||
vector_math:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: vector_math
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.0"
|
|
||||||
sdks:
|
|
||||||
dart: ">=2.12.0 <3.0.0"
|
|
||||||
flutter: ">=1.17.0"
|
|
@ -1,320 +0,0 @@
|
|||||||
# Generated by pub
|
|
||||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
|
||||||
packages:
|
|
||||||
animations:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: animations
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.1"
|
|
||||||
async:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: async
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.8.2"
|
|
||||||
boolean_selector:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: boolean_selector
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.0"
|
|
||||||
characters:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: characters
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
charcode:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: charcode
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.3.1"
|
|
||||||
clock:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: clock
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.0"
|
|
||||||
collection:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: collection
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.15.0"
|
|
||||||
crypto:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: crypto
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.1"
|
|
||||||
dartz:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: dartz
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.10.0-nullsafety.2"
|
|
||||||
equatable:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: equatable
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.3"
|
|
||||||
fake_async:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: fake_async
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
flowy_infra:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
path: "../flowy_infra"
|
|
||||||
relative: true
|
|
||||||
source: path
|
|
||||||
version: "0.0.1"
|
|
||||||
flowy_infra_ui_platform_interface:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
path: flowy_infra_ui_platform_interface
|
|
||||||
relative: true
|
|
||||||
source: path
|
|
||||||
version: "0.0.1"
|
|
||||||
flowy_infra_ui_web:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
path: flowy_infra_ui_web
|
|
||||||
relative: true
|
|
||||||
source: path
|
|
||||||
version: "0.0.1"
|
|
||||||
flutter:
|
|
||||||
dependency: "direct main"
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
flutter_lints:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description:
|
|
||||||
name: flutter_lints
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.4"
|
|
||||||
flutter_svg:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: flutter_svg
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.22.0"
|
|
||||||
flutter_test:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
flutter_web_plugins:
|
|
||||||
dependency: transitive
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
js:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: js
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.6.3"
|
|
||||||
lint:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: lint
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.5.3"
|
|
||||||
lints:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: lints
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.1"
|
|
||||||
loading_indicator:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: loading_indicator
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.1"
|
|
||||||
matcher:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: matcher
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.12.11"
|
|
||||||
meta:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: meta
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.7.0"
|
|
||||||
nested:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: nested
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.0"
|
|
||||||
path:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: path
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.8.0"
|
|
||||||
path_drawing:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: path_drawing
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.5.1+1"
|
|
||||||
path_parsing:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: path_parsing
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.2.1"
|
|
||||||
petitparser:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: petitparser
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "4.4.0"
|
|
||||||
plugin_platform_interface:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: plugin_platform_interface
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.1"
|
|
||||||
provider:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: provider
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "6.0.1"
|
|
||||||
sky_engine:
|
|
||||||
dependency: transitive
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.99"
|
|
||||||
source_span:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: source_span
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.8.1"
|
|
||||||
stack_trace:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: stack_trace
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.10.0"
|
|
||||||
stream_channel:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: stream_channel
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.0"
|
|
||||||
string_scanner:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: string_scanner
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.0"
|
|
||||||
styled_widget:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: styled_widget
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.3.1+2"
|
|
||||||
term_glyph:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: term_glyph
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
test_api:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: test_api
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.4.3"
|
|
||||||
textstyle_extensions:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: textstyle_extensions
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.0-nullsafety"
|
|
||||||
time:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: time
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.0"
|
|
||||||
typed_data:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: typed_data
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.3.0"
|
|
||||||
uuid:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: uuid
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.4"
|
|
||||||
vector_math:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: vector_math
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.0"
|
|
||||||
xml:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: xml
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "5.3.1"
|
|
||||||
sdks:
|
|
||||||
dart: ">=2.14.0 <3.0.0"
|
|
||||||
flutter: ">=2.0.0"
|
|
@ -1,309 +0,0 @@
|
|||||||
# Generated by pub
|
|
||||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
|
||||||
packages:
|
|
||||||
archive:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: archive
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "3.1.6"
|
|
||||||
async:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: async
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.8.2"
|
|
||||||
boolean_selector:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: boolean_selector
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.0"
|
|
||||||
characters:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: characters
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
charcode:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: charcode
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.3.1"
|
|
||||||
clock:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: clock
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.0"
|
|
||||||
collection:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: collection
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.15.0"
|
|
||||||
crypto:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: crypto
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.1"
|
|
||||||
cupertino_icons:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: cupertino_icons
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.2"
|
|
||||||
dartz:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: dartz
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.10.0-nullsafety.2"
|
|
||||||
fake_async:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: fake_async
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
ffi:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: ffi
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.0"
|
|
||||||
file:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: file
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "6.1.2"
|
|
||||||
fixnum:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: fixnum
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.0"
|
|
||||||
flowy_sdk:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
path: ".."
|
|
||||||
relative: true
|
|
||||||
source: path
|
|
||||||
version: "0.0.1"
|
|
||||||
flutter:
|
|
||||||
dependency: "direct main"
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
flutter_driver:
|
|
||||||
dependency: transitive
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
flutter_lints:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description:
|
|
||||||
name: flutter_lints
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.3"
|
|
||||||
flutter_test:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
freezed_annotation:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: freezed_annotation
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.14.1"
|
|
||||||
fuchsia_remote_debug_protocol:
|
|
||||||
dependency: transitive
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
integration_test:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
isolates:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: isolates
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.3+8"
|
|
||||||
json_annotation:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: json_annotation
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "4.0.1"
|
|
||||||
lints:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: lints
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.1"
|
|
||||||
logger:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: logger
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.0"
|
|
||||||
matcher:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: matcher
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.12.11"
|
|
||||||
material_color_utilities:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: material_color_utilities
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.1.3"
|
|
||||||
meta:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: meta
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.7.0"
|
|
||||||
path:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: path
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.8.0"
|
|
||||||
platform:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: platform
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "3.1.0"
|
|
||||||
process:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: process
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "4.2.4"
|
|
||||||
protobuf:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: protobuf
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.0"
|
|
||||||
sky_engine:
|
|
||||||
dependency: transitive
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.99"
|
|
||||||
source_span:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: source_span
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.8.1"
|
|
||||||
stack_trace:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: stack_trace
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.10.0"
|
|
||||||
stream_channel:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: stream_channel
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.0"
|
|
||||||
string_scanner:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: string_scanner
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.0"
|
|
||||||
sync_http:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: sync_http
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.3.0"
|
|
||||||
term_glyph:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: term_glyph
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
test_api:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: test_api
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.4.8"
|
|
||||||
typed_data:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: typed_data
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.3.0"
|
|
||||||
vector_math:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: vector_math
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.1"
|
|
||||||
vm_service:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: vm_service
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "7.5.0"
|
|
||||||
webdriver:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: webdriver
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.0"
|
|
||||||
sdks:
|
|
||||||
dart: ">=2.14.0 <3.0.0"
|
|
||||||
flutter: ">=1.17.0"
|
|
@ -1,504 +0,0 @@
|
|||||||
# Generated by pub
|
|
||||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
|
||||||
packages:
|
|
||||||
_fe_analyzer_shared:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: _fe_analyzer_shared
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "20.0.0"
|
|
||||||
analyzer:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: analyzer
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.4.0"
|
|
||||||
args:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: args
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.6.0"
|
|
||||||
async:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: async
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.8.2"
|
|
||||||
boolean_selector:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: boolean_selector
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.0"
|
|
||||||
build:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: build
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.0"
|
|
||||||
build_config:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: build_config
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.4.7"
|
|
||||||
build_daemon:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: build_daemon
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.10"
|
|
||||||
build_resolvers:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: build_resolvers
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.0"
|
|
||||||
build_runner:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description:
|
|
||||||
name: build_runner
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.12.2"
|
|
||||||
build_runner_core:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: build_runner_core
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "6.1.12"
|
|
||||||
built_collection:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: built_collection
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "5.1.0"
|
|
||||||
built_value:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: built_value
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "8.1.0"
|
|
||||||
characters:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: characters
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
charcode:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: charcode
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.3.1"
|
|
||||||
checked_yaml:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: checked_yaml
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.1"
|
|
||||||
cli_util:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: cli_util
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.3.0"
|
|
||||||
clock:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: clock
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.0"
|
|
||||||
code_builder:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: code_builder
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "3.6.0"
|
|
||||||
collection:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: collection
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.15.0"
|
|
||||||
convert:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: convert
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.0"
|
|
||||||
crypto:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: crypto
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.1"
|
|
||||||
dart_style:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: dart_style
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.0"
|
|
||||||
dartz:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: dartz
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.10.0-nullsafety.2"
|
|
||||||
fake_async:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: fake_async
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
ffi:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: ffi
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.0"
|
|
||||||
file:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: file
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "6.1.0"
|
|
||||||
fixnum:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: fixnum
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.0"
|
|
||||||
flutter:
|
|
||||||
dependency: "direct main"
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
flutter_lints:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description:
|
|
||||||
name: flutter_lints
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.3"
|
|
||||||
flutter_test:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
freezed:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description:
|
|
||||||
name: freezed
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.14.1+2"
|
|
||||||
freezed_annotation:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: freezed_annotation
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.14.1"
|
|
||||||
glob:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: glob
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.1"
|
|
||||||
graphs:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: graphs
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.0"
|
|
||||||
http_multi_server:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: http_multi_server
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.2.0"
|
|
||||||
http_parser:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: http_parser
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "3.1.4"
|
|
||||||
io:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: io
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.3.4"
|
|
||||||
isolates:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: isolates
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.3+8"
|
|
||||||
js:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: js
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.6.3"
|
|
||||||
json_annotation:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: json_annotation
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "4.0.1"
|
|
||||||
lints:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: lints
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.1"
|
|
||||||
logger:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: logger
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.0"
|
|
||||||
logging:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: logging
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.1"
|
|
||||||
matcher:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: matcher
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.12.11"
|
|
||||||
material_color_utilities:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: material_color_utilities
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.1.3"
|
|
||||||
meta:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: meta
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.7.0"
|
|
||||||
mime:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: mime
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.9.7"
|
|
||||||
package_config:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: package_config
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.0"
|
|
||||||
path:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: path
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.8.0"
|
|
||||||
pedantic:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: pedantic
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.11.0"
|
|
||||||
pool:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: pool
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.5.0"
|
|
||||||
protobuf:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: protobuf
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.0"
|
|
||||||
pub_semver:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: pub_semver
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.0"
|
|
||||||
pubspec_parse:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: pubspec_parse
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.0"
|
|
||||||
shelf:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: shelf
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.7.9"
|
|
||||||
shelf_web_socket:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: shelf_web_socket
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.2.3"
|
|
||||||
sky_engine:
|
|
||||||
dependency: transitive
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.99"
|
|
||||||
source_gen:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: source_gen
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.0"
|
|
||||||
source_span:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: source_span
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.8.1"
|
|
||||||
stack_trace:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: stack_trace
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.10.0"
|
|
||||||
stream_channel:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: stream_channel
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.0"
|
|
||||||
stream_transform:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: stream_transform
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.0"
|
|
||||||
string_scanner:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: string_scanner
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.0"
|
|
||||||
term_glyph:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: term_glyph
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
test_api:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: test_api
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.4.8"
|
|
||||||
timing:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: timing
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.1.1+3"
|
|
||||||
typed_data:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: typed_data
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.3.0"
|
|
||||||
vector_math:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: vector_math
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.1"
|
|
||||||
watcher:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: watcher
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.0"
|
|
||||||
web_socket_channel:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: web_socket_channel
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
yaml:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: yaml
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "3.1.0"
|
|
||||||
sdks:
|
|
||||||
dart: ">=2.14.0 <3.0.0"
|
|
||||||
flutter: ">=1.17.0"
|
|
Loading…
Reference in New Issue
Block a user