Skip to content

Commit cd33499

Browse files
authored
♻️ Make delegate respect generic types as much as possible (#639)
We have `Asset` and `Path` generic abstractions, but we didn't consider the delegate's generic abstractions. They are necessary when building delegates that rely on custom data source providers.
2 parents 562c55d + 19d2236 commit cd33499

17 files changed

+664
-497
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ that can be found in the LICENSE file. -->
99
1010
## Unreleased
1111

12-
*None.*
12+
- Make delegate respect generic types as much as possible.
13+
This is a breaking change for users who use custom delegates and providers.
1314

1415
## 9.6.0
1516

example/lib/constants/picker_method.dart

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,9 @@ class PickMethod {
207207
return;
208208
}
209209
final picker = context.findAncestorWidgetOfExactType<
210-
AssetPicker<AssetEntity, AssetPathEntity>>()!;
211-
final builder =
212-
picker.builder as DefaultAssetPickerBuilderDelegate;
213-
final p = builder.provider;
210+
AssetPicker<AssetEntity, AssetPathEntity,
211+
DefaultAssetPickerBuilderDelegate>>()!;
212+
final p = picker.builder.provider;
214213
await p.switchPath(
215214
PathWrapper<AssetPathEntity>(
216215
path:

example/lib/customs/pickers/directory_file_asset_picker.dart

Lines changed: 32 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -163,18 +163,19 @@ class _DirectoryFileAssetPickerState extends State<DirectoryFileAssetPicker> {
163163
return GestureDetector(
164164
onTap: isDisplayingDetail
165165
? () async {
166-
final Widget viewer = AssetPickerViewer<File, Directory>(
167-
builder: FileAssetPickerViewerBuilderDelegate(
166+
final result = await AssetPickerViewer.pushToViewerWithDelegate<
167+
File,
168+
Directory,
169+
FileAssetPickerViewerProvider,
170+
FileAssetPickerViewerBuilderDelegate>(
171+
context,
172+
delegate: FileAssetPickerViewerBuilderDelegate(
168173
currentIndex: index,
169174
previewAssets: fileList,
170175
provider: FileAssetPickerViewerProvider(fileList),
171176
themeData: AssetPicker.themeData(themeColor),
172177
),
173178
);
174-
final List<File>? result =
175-
await Navigator.maybeOf(context)?.push<List<File>>(
176-
AssetPickerViewerPageRoute(builder: (context) => viewer),
177-
);
178179
if (result != null && result != fileList) {
179180
fileList
180181
..clear()
@@ -261,7 +262,8 @@ class _DirectoryFileAssetPickerState extends State<DirectoryFileAssetPicker> {
261262
}
262263
}
263264

264-
class FileAssetPickerProvider extends AssetPickerProvider<File, Directory> {
265+
final class FileAssetPickerProvider
266+
extends AssetPickerProvider<File, Directory> {
265267
FileAssetPickerProvider({
266268
required List<File> selectedAssets,
267269
}) : super(selectedAssets: selectedAssets) {
@@ -346,7 +348,7 @@ class FileAssetPickerProvider extends AssetPickerProvider<File, Directory> {
346348
}
347349
}
348350

349-
class FileAssetPickerBuilder
351+
final class FileAssetPickerBuilder
350352
extends AssetPickerBuilderDelegate<File, Directory> {
351353
FileAssetPickerBuilder({
352354
required this.provider,
@@ -368,8 +370,13 @@ class FileAssetPickerBuilder
368370
int? index,
369371
File currentAsset,
370372
) async {
371-
final Widget viewer = AssetPickerViewer<File, Directory>(
372-
builder: FileAssetPickerViewerBuilderDelegate(
373+
final result = await AssetPickerViewer.pushToViewerWithDelegate<
374+
File,
375+
Directory,
376+
FileAssetPickerViewerProvider,
377+
FileAssetPickerViewerBuilderDelegate>(
378+
context,
379+
delegate: FileAssetPickerViewerBuilderDelegate(
373380
currentIndex: index ?? provider.selectedAssets.indexOf(currentAsset),
374381
previewAssets: provider.selectedAssets,
375382
provider: FileAssetPickerViewerProvider(provider.selectedAssets),
@@ -378,39 +385,11 @@ class FileAssetPickerBuilder
378385
selectorProvider: provider,
379386
),
380387
);
381-
final List<File>? result =
382-
await Navigator.maybeOf(context)?.push<List<File>?>(
383-
AssetPickerViewerPageRoute(builder: (context) => viewer),
384-
);
385388
if (result != null) {
386389
Navigator.maybeOf(context)?.maybePop(result);
387390
}
388391
}
389392

390-
Future<List<File>?> pushToPicker(
391-
BuildContext context, {
392-
required int index,
393-
required List<File> previewAssets,
394-
List<File>? selectedAssets,
395-
FileAssetPickerProvider? selectorProvider,
396-
}) async {
397-
final Widget viewer = AssetPickerViewer<File, Directory>(
398-
builder: FileAssetPickerViewerBuilderDelegate(
399-
currentIndex: index,
400-
previewAssets: previewAssets,
401-
provider: selectedAssets != null
402-
? FileAssetPickerViewerProvider(selectedAssets)
403-
: null,
404-
themeData: AssetPicker.themeData(themeColor),
405-
selectedAssets: selectedAssets,
406-
selectorProvider: selectorProvider,
407-
),
408-
);
409-
return await Navigator.maybeOf(context)?.push<List<File>?>(
410-
AssetPickerViewerPageRoute(builder: (context) => viewer),
411-
);
412-
}
413-
414393
@override
415394
void selectAsset(BuildContext context, File asset, int index, bool selected) {
416395
if (selected) {
@@ -975,23 +954,12 @@ class FileAssetPickerBuilder
975954

976955
@override
977956
Widget previewButton(BuildContext context) {
978-
return Selector<FileAssetPickerProvider, bool>(
979-
selector: (_, FileAssetPickerProvider p) => p.isSelectedNotEmpty,
980-
builder: (_, bool isSelectedNotEmpty, __) {
957+
return Consumer<FileAssetPickerProvider>(
958+
builder: (_, p, __) {
959+
final isSelectedNotEmpty = p.isSelectedNotEmpty;
981960
return GestureDetector(
982961
onTap: isSelectedNotEmpty
983-
? () async {
984-
final List<File>? result = await pushToPicker(
985-
context,
986-
index: 0,
987-
previewAssets: provider.selectedAssets,
988-
selectedAssets: provider.selectedAssets,
989-
selectorProvider: provider,
990-
);
991-
if (result != null) {
992-
Navigator.maybeOf(context)?.pop(result);
993-
}
994-
}
962+
? () => viewAsset(context, null, p.selectedAssets.first)
995963
: null,
996964
child: Padding(
997965
padding: const EdgeInsets.symmetric(vertical: 12.0),
@@ -1099,15 +1067,8 @@ class FileAssetPickerBuilder
10991067
selectedAssets.where((File f) => f.path == asset.path).isNotEmpty;
11001068
return Positioned.fill(
11011069
child: GestureDetector(
1102-
onTap: () async {
1103-
final List<File>? result = await pushToPicker(
1104-
context,
1105-
index: index,
1106-
previewAssets: provider.currentAssets,
1107-
);
1108-
if (result != null) {
1109-
Navigator.maybeOf(context)?.pop(result);
1110-
}
1070+
onTap: () {
1071+
viewAsset(context, index, asset);
11111072
},
11121073
child: AnimatedContainer(
11131074
duration: switchingPathDuration,
@@ -1159,7 +1120,8 @@ class FileAssetPickerBuilder
11591120
}
11601121
}
11611122

1162-
class FileAssetPickerViewerProvider extends AssetPickerViewerProvider<File> {
1123+
final class FileAssetPickerViewerProvider
1124+
extends AssetPickerViewerProvider<File> {
11631125
FileAssetPickerViewerProvider(List<File> super.assets);
11641126

11651127
@override
@@ -1170,18 +1132,19 @@ class FileAssetPickerViewerProvider extends AssetPickerViewerProvider<File> {
11701132
}
11711133
}
11721134

1173-
class FileAssetPickerViewerBuilderDelegate
1174-
extends AssetPickerViewerBuilderDelegate<File, Directory> {
1135+
final class FileAssetPickerViewerBuilderDelegate
1136+
extends AssetPickerViewerBuilderDelegate<File, Directory,
1137+
FileAssetPickerViewerProvider> {
11751138
FileAssetPickerViewerBuilderDelegate({
11761139
required super.previewAssets,
11771140
required super.themeData,
11781141
required super.currentIndex,
11791142
super.selectedAssets,
1180-
super.selectorProvider,
1143+
this.selectorProvider,
11811144
super.provider,
1182-
}) : super(
1183-
maxAssets: selectorProvider?.maxAssets,
1184-
);
1145+
}) : super(maxAssets: selectorProvider?.maxAssets);
1146+
1147+
final FileAssetPickerProvider? selectorProvider;
11851148

11861149
late final PageController _pageController = PageController(
11871150
initialPage: currentIndex,

example/lib/customs/pickers/insta_asset_picker.dart

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ class _InstaAssetPickerState extends State<InstaAssetPicker> {
286286
}
287287
}
288288

289-
class InstaAssetPickerBuilder extends DefaultAssetPickerBuilderDelegate {
289+
final class InstaAssetPickerBuilder extends DefaultAssetPickerBuilderDelegate {
290290
InstaAssetPickerBuilder({
291291
required super.provider,
292292
required super.initialPermission,
@@ -488,8 +488,8 @@ class InstaAssetPickerBuilder extends DefaultAssetPickerBuilderDelegate {
488488
width: MediaQuery.sizeOf(context).width,
489489
height: previewHeight(context),
490490
child: Selector<DefaultAssetPickerProvider, List<AssetEntity>>(
491-
selector: (_, DefaultAssetPickerProvider p) => p.selectedAssets,
492-
builder: (_, List<AssetEntity> selected, __) {
491+
selector: (_, p) => p.selectedAssets,
492+
builder: (_, selected, __) {
493493
if (previewAsset == null && selected.isEmpty) {
494494
return loadingIndicator(context);
495495
}
@@ -499,10 +499,13 @@ class InstaAssetPickerBuilder extends DefaultAssetPickerBuilderDelegate {
499499
if (previewAsset != null) {
500500
effectiveIndex = selected.indexOf(previewAsset);
501501
}
502-
final List<AssetEntity> assets =
503-
selected.isEmpty ? <AssetEntity>[previewAsset!] : selected;
502+
final assets = selected.isEmpty ? [previewAsset!] : selected;
504503

505-
return AssetPickerViewer<AssetEntity, AssetPathEntity>(
504+
return AssetPickerViewer<
505+
AssetEntity,
506+
AssetPathEntity,
507+
AssetPickerViewerProvider<AssetEntity>,
508+
InstaAssetPickerViewerBuilder>(
506509
builder: InstaAssetPickerViewerBuilder(
507510
currentIndex: effectiveIndex == -1 ? 0 : effectiveIndex,
508511
previewAssets: assets,
@@ -645,7 +648,7 @@ class InstaAssetPickerBuilder extends DefaultAssetPickerBuilderDelegate {
645648
Widget _buildListAlbums(BuildContext context) {
646649
appBarPreferredSize ??= appBar(context).preferredSize;
647650
return Consumer<DefaultAssetPickerProvider>(
648-
builder: (BuildContext context, DefaultAssetPickerProvider provider, __) {
651+
builder: (context, provider, __) {
649652
if (isAppleOS(context)) {
650653
return pathEntityListWidget(context);
651654
}
@@ -673,7 +676,7 @@ class InstaAssetPickerBuilder extends DefaultAssetPickerBuilderDelegate {
673676
Widget _buildGrid(BuildContext context) {
674677
appBarPreferredSize ??= appBar(context).preferredSize;
675678
return Consumer<DefaultAssetPickerProvider>(
676-
builder: (BuildContext context, DefaultAssetPickerProvider p, __) {
679+
builder: (context, p, __) {
677680
final bool shouldDisplayAssets =
678681
p.hasAssetsToDisplay || shouldBuildSpecialItem;
679682
_initializePreviewAsset(p, shouldDisplayAssets);
@@ -767,7 +770,7 @@ class InstaAssetPickerBuilder extends DefaultAssetPickerBuilderDelegate {
767770
const SizedBox.shrink();
768771
}
769772

770-
class InstaAssetPickerViewerBuilder
773+
final class InstaAssetPickerViewerBuilder
771774
extends DefaultAssetPickerViewerBuilderDelegate {
772775
InstaAssetPickerViewerBuilder({
773776
required super.currentIndex,

example/lib/customs/pickers/multi_tabs_assets_picker.dart

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,8 @@ class _MultiTabAssetPickerState extends State<MultiTabAssetPicker> {
260260
}
261261
}
262262

263-
class MultiTabAssetPickerBuilder extends DefaultAssetPickerBuilderDelegate {
263+
final class MultiTabAssetPickerBuilder
264+
extends DefaultAssetPickerBuilderDelegate {
264265
MultiTabAssetPickerBuilder({
265266
required super.provider,
266267
required this.videosProvider,
@@ -279,7 +280,10 @@ class MultiTabAssetPickerBuilder extends DefaultAssetPickerBuilderDelegate {
279280
late final TabController _tabController;
280281

281282
@override
282-
void initState(AssetPickerState<AssetEntity, AssetPathEntity> state) {
283+
void initState(
284+
AssetPickerState<AssetEntity, AssetPathEntity, MultiTabAssetPickerBuilder>
285+
state,
286+
) {
283287
super.initState(state);
284288
_tabController = TabController(length: 3, vsync: state);
285289
}

0 commit comments

Comments
 (0)