draft freshen up albums page
This commit is contained in:
parent
a750a52e2e
commit
cb2aadc658
5 changed files with 261 additions and 58 deletions
|
@ -1,12 +1,16 @@
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||||
import 'package:get_it/get_it.dart';
|
import 'package:get_it/get_it.dart';
|
||||||
|
import 'package:mobx/mobx.dart';
|
||||||
|
import 'package:mobx/mobx.dart' as mobx;
|
||||||
|
import 'package:mucke/presentation/widgets/album_art_grid.dart';
|
||||||
|
import 'package:mucke/presentation/widgets/album_art_list.dart';
|
||||||
|
|
||||||
import '../../domain/entities/album.dart';
|
import '../../domain/entities/album.dart';
|
||||||
import '../state/music_data_store.dart';
|
import '../state/music_data_store.dart';
|
||||||
import '../state/navigation_store.dart';
|
import '../state/navigation_store.dart';
|
||||||
import '../widgets/album_art_list_tile.dart';
|
|
||||||
import 'album_details_page.dart';
|
|
||||||
|
|
||||||
class AlbumsPage extends StatefulWidget {
|
class AlbumsPage extends StatefulWidget {
|
||||||
const AlbumsPage({Key? key}) : super(key: key);
|
const AlbumsPage({Key? key}) : super(key: key);
|
||||||
|
@ -15,8 +19,11 @@ class AlbumsPage extends StatefulWidget {
|
||||||
_AlbumsPageState createState() => _AlbumsPageState();
|
_AlbumsPageState createState() => _AlbumsPageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AlbumsPageState extends State<AlbumsPage> with AutomaticKeepAliveClientMixin {
|
class _AlbumsPageState extends State<AlbumsPage>
|
||||||
final ScrollController _scrollController = ScrollController();
|
with AutomaticKeepAliveClientMixin {
|
||||||
|
final ScrollController scrollController = ScrollController();
|
||||||
|
final Observable<bool> showAlbumGrid = Observable(false);
|
||||||
|
final Observable<String> sortingMode = Observable('name');
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -28,33 +35,54 @@ class _AlbumsPageState extends State<AlbumsPage> with AutomaticKeepAliveClientMi
|
||||||
return Observer(builder: (_) {
|
return Observer(builder: (_) {
|
||||||
print('AlbumsPage.build -> Observer.builder');
|
print('AlbumsPage.build -> Observer.builder');
|
||||||
final List<Album> albums = store.albumStream.value ?? [];
|
final List<Album> albums = store.albumStream.value ?? [];
|
||||||
return Scrollbar(
|
switch (sortingMode.value) {
|
||||||
controller: _scrollController,
|
case 'name':
|
||||||
child: ListView.separated(
|
break;
|
||||||
controller: _scrollController,
|
case 'artistName':
|
||||||
itemCount: albums.length,
|
albums.sort((a,b) => a.artist.compareTo(b.artist));
|
||||||
itemBuilder: (_, int index) {
|
break;
|
||||||
final Album album = albums[index];
|
case 'random':
|
||||||
return AlbumArtListTile(
|
albums.shuffle(Random());
|
||||||
title: album.title,
|
break;
|
||||||
subtitle: album.artist,
|
}
|
||||||
albumArtPath: album.albumArtPath,
|
return CustomScrollView(
|
||||||
onTap: () {
|
slivers: [
|
||||||
navStore.push(
|
SliverAppBar(
|
||||||
context,
|
floating: true,
|
||||||
MaterialPageRoute<Widget>(
|
leading: IconButton(
|
||||||
builder: (BuildContext context) => AlbumDetailsPage(
|
onPressed: () {
|
||||||
album: album,
|
showAlbumGrid.toggle();
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
);
|
icon: Icon(showAlbumGrid.value ? Icons.list : Icons.grid_view),
|
||||||
},
|
),
|
||||||
separatorBuilder: (BuildContext context, int index) => const SizedBox(
|
actions: [
|
||||||
height: 4.0,
|
DropdownButton(
|
||||||
|
value: sortingMode.value,
|
||||||
|
items: const [
|
||||||
|
DropdownMenuItem(value: 'name', child: Text('name')),
|
||||||
|
DropdownMenuItem(value: 'artistName', child: Text('artistName')),
|
||||||
|
DropdownMenuItem(value: 'random', child: Text('random')),
|
||||||
|
],
|
||||||
|
onChanged: (selectedValue) {
|
||||||
|
if (selectedValue != null)
|
||||||
|
mobx.Action(() {
|
||||||
|
sortingMode.value = selectedValue;
|
||||||
|
})();
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
if (showAlbumGrid.value)
|
||||||
|
AlbumArtGrid(
|
||||||
|
albums: albums,
|
||||||
|
scrollController: scrollController,
|
||||||
|
navStore: navStore)
|
||||||
|
else
|
||||||
|
AlbumArtList(
|
||||||
|
albums: albums,
|
||||||
|
scrollController: scrollController,
|
||||||
|
navStore: navStore),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
45
src/lib/presentation/widgets/album_art_grid.dart
Normal file
45
src/lib/presentation/widgets/album_art_grid.dart
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mucke/presentation/pages/album_details_page.dart';
|
||||||
|
import 'package:mucke/presentation/state/navigation_store.dart';
|
||||||
|
import 'package:mucke/presentation/widgets/album_art_grid_tile.dart';
|
||||||
|
|
||||||
|
import '../../domain/entities/album.dart';
|
||||||
|
|
||||||
|
class AlbumArtGrid extends StatelessWidget {
|
||||||
|
const AlbumArtGrid({
|
||||||
|
Key? key,
|
||||||
|
required this.albums,
|
||||||
|
required this.scrollController,
|
||||||
|
required this.navStore,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final List<Album> albums;
|
||||||
|
final ScrollController scrollController;
|
||||||
|
final NavigationStore navStore;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SliverGrid.builder(
|
||||||
|
itemCount: albums.length,
|
||||||
|
gridDelegate:
|
||||||
|
const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
|
||||||
|
itemBuilder: (_, int index) {
|
||||||
|
final Album album = albums[index];
|
||||||
|
return AlbumArtGridTile(
|
||||||
|
title: album.title,
|
||||||
|
subtitle: album.artist,
|
||||||
|
albumArtPath: album.albumArtPath,
|
||||||
|
onTap: () {
|
||||||
|
navStore.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute<Widget>(
|
||||||
|
builder: (BuildContext context) => AlbumDetailsPage(
|
||||||
|
album: album,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
69
src/lib/presentation/widgets/album_art_grid_tile.dart
Normal file
69
src/lib/presentation/widgets/album_art_grid_tile.dart
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../theming.dart';
|
||||||
|
import '../utils.dart' as utils;
|
||||||
|
|
||||||
|
class AlbumArtGridTile extends StatelessWidget {
|
||||||
|
const AlbumArtGridTile({
|
||||||
|
Key? key,
|
||||||
|
required this.title,
|
||||||
|
required this.subtitle,
|
||||||
|
required this.onTap,
|
||||||
|
this.albumArtPath,
|
||||||
|
this.highlight = false,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final String title;
|
||||||
|
final String subtitle;
|
||||||
|
final String? albumArtPath;
|
||||||
|
final Function onTap;
|
||||||
|
final bool highlight;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () => onTap(),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 20),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: 128,
|
||||||
|
height: 128,
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(4.0),
|
||||||
|
boxShadow: const [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.black54,
|
||||||
|
blurRadius: 8,
|
||||||
|
offset: Offset(0, 2),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
clipBehavior: Clip.antiAlias,
|
||||||
|
child: Image(
|
||||||
|
image: utils.getAlbumImage(albumArtPath),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Padding(padding: EdgeInsets.symmetric(vertical: 3, horizontal: 0)),
|
||||||
|
Text(
|
||||||
|
title,
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
subtitle,
|
||||||
|
style: TEXT_SMALL_SUBTITLE.copyWith(color: Colors.white),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
37
src/lib/presentation/widgets/album_art_list.dart
Normal file
37
src/lib/presentation/widgets/album_art_list.dart
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mucke/presentation/state/navigation_store.dart';
|
||||||
|
|
||||||
|
import '../../domain/entities/album.dart';
|
||||||
|
import 'album_art_list_tile.dart';
|
||||||
|
|
||||||
|
class AlbumArtList extends StatelessWidget {
|
||||||
|
const AlbumArtList({
|
||||||
|
Key? key,
|
||||||
|
required this.albums,
|
||||||
|
required this.scrollController,
|
||||||
|
required this.navStore,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final List<Album> albums;
|
||||||
|
final ScrollController scrollController;
|
||||||
|
final NavigationStore navStore;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SliverList.separated(
|
||||||
|
itemCount: albums.length,
|
||||||
|
itemBuilder: (_, int index) {
|
||||||
|
final Album album = albums[index];
|
||||||
|
return AlbumArtListTile(
|
||||||
|
title: album.title,
|
||||||
|
subtitle: album.artist,
|
||||||
|
albumArtPath: album.albumArtPath,
|
||||||
|
onTap: () {},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
separatorBuilder: (BuildContext context, int index) => const SizedBox(
|
||||||
|
height: 4.0,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -229,10 +229,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: collection
|
name: collection
|
||||||
sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
|
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.17.1"
|
version: "1.18.0"
|
||||||
convert:
|
convert:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -245,10 +245,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: coverage
|
name: coverage
|
||||||
sha256: "2fb815080e44a09b85e0f2ca8a820b15053982b2e714b59267719e8a9ff17097"
|
sha256: "3945034e86ea203af7a056d98e98e42a5518fff200d6e8e6647e1886b07e936e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.6.3"
|
version: "1.8.0"
|
||||||
cross_file:
|
cross_file:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -505,10 +505,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: intl
|
name: intl
|
||||||
sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6
|
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.18.0"
|
version: "0.18.1"
|
||||||
io:
|
io:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -557,6 +557,30 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.8"
|
version: "0.4.8"
|
||||||
|
leak_tracker:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker
|
||||||
|
sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "10.0.0"
|
||||||
|
leak_tracker_flutter_testing:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker_flutter_testing
|
||||||
|
sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.1"
|
||||||
|
leak_tracker_testing:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker_testing
|
||||||
|
sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.1"
|
||||||
logging:
|
logging:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -569,26 +593,26 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: matcher
|
name: matcher
|
||||||
sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
|
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.15"
|
version: "0.12.16+1"
|
||||||
material_color_utilities:
|
material_color_utilities:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
|
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.0"
|
version: "0.8.0"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
|
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.1"
|
version: "1.11.0"
|
||||||
metadata_god:
|
metadata_god:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -690,10 +714,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: path
|
name: path
|
||||||
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
|
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.3"
|
version: "1.9.0"
|
||||||
path_provider:
|
path_provider:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -959,10 +983,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: source_span
|
name: source_span
|
||||||
sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
|
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.1"
|
version: "1.10.0"
|
||||||
sqflite:
|
sqflite:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -1007,18 +1031,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stack_trace
|
name: stack_trace
|
||||||
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
|
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.11.0"
|
version: "1.11.1"
|
||||||
stream_channel:
|
stream_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stream_channel
|
name: stream_channel
|
||||||
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
|
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.1.2"
|
||||||
stream_transform:
|
stream_transform:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -1063,26 +1087,26 @@ packages:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: test
|
name: test
|
||||||
sha256: "3dac9aecf2c3991d09b9cdde4f98ded7b30804a88a0d7e4e7e1678e78d6b97f4"
|
sha256: a1f7595805820fcc05e5c52e3a231aedd0b72972cb333e8c738a8b1239448b6f
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.24.1"
|
version: "1.24.9"
|
||||||
test_api:
|
test_api:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
|
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.1"
|
version: "0.6.1"
|
||||||
test_core:
|
test_core:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_core
|
name: test_core
|
||||||
sha256: "5138dbffb77b2289ecb12b81c11ba46036590b72a64a7a90d6ffb880f1a29e93"
|
sha256: a757b14fc47507060a162cc2530d9a4a2f92f5100a952c7443b5cad5ef5b106a
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.1"
|
version: "0.5.9"
|
||||||
text_scroll:
|
text_scroll:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -1167,10 +1191,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vm_service
|
name: vm_service
|
||||||
sha256: c538be99af830f478718b51630ec1b6bee5e74e52c8a802d328d9e71d35d2583
|
sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "11.10.0"
|
version: "13.0.0"
|
||||||
watcher:
|
watcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -1236,5 +1260,5 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.2"
|
version: "3.1.2"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.0.0 <4.0.0"
|
dart: ">=3.2.0-0 <4.0.0"
|
||||||
flutter: ">=3.7.0"
|
flutter: ">=3.7.0"
|
||||||
|
|
Loading…
Add table
Reference in a new issue