1
0
mirror of https://github.com/flutter/samples.git synced 2025-11-08 13:58:47 +00:00

Dart 3.9 / Flutter 3.35 [first LLM release] (#2714)

I got carried away with Gemini and basically rewrote CI and the release
process for the new LLM reality. This work was largely completed by
Gemini.

- Bump all SDK versions to the current beta (3.9.0-0)
- Run `flutter channel beta`
- Wrote `ci_script.dart` to replace the bash scripts
- Converted repository to pub workspace #2499 
- Added llm.md and release.md
- Added redirect for deprecated Samples Index

## Pre-launch Checklist

- [x] I read the [Flutter Style Guide] _recently_, and have followed its
advice.
- [x] I signed the [CLA].
- [x] I read the [Contributors Guide].
- [x] I have added sample code updates to the [changelog].
- [x] I updated/added relevant documentation (doc comments with `///`).
This commit is contained in:
Eric Windmill
2025-08-14 12:26:24 -07:00
committed by GitHub
parent 0aa5415d5e
commit 2999d738b8
410 changed files with 28166 additions and 27661 deletions

View File

@@ -24,7 +24,9 @@ void main() {
Logger.root.level = Level.ALL;
Logger.root.onRecord.listen((rec) {
// ignore: avoid_print
print('${rec.loggerName} ${rec.level.name}: ${rec.time}: ${rec.message}');
print(
'${rec.loggerName} ${rec.level.name}: ${rec.time}: ${rec.message}',
);
});
if (unsplashAccessKey.isEmpty) {
@@ -39,8 +41,8 @@ void main() {
runApp(
ChangeNotifierProvider<PhotoSearchModel>(
create:
(context) => PhotoSearchModel(Unsplash(accessKey: unsplashAccessKey)),
create: (context) =>
PhotoSearchModel(Unsplash(accessKey: unsplashAccessKey)),
child: const UnsplashSearchApp(),
),
);
@@ -50,7 +52,8 @@ const double windowWidth = 1024;
const double windowHeight = 800;
void setupWindow() {
if (!kIsWeb && (Platform.isWindows || Platform.isLinux || Platform.isMacOS)) {
if (!kIsWeb &&
(Platform.isWindows || Platform.isLinux || Platform.isMacOS)) {
WidgetsFlutterBinding.ensureInitialized();
setWindowMinSize(const Size(windowWidth, windowHeight));
}
@@ -85,9 +88,9 @@ class UnsplashHomePage extends StatelessWidget {
onSelected: () {
showDialog<void>(
context: context,
builder:
(context) =>
PhotoSearchDialog(callback: photoSearchModel.addSearch),
builder: (context) => PhotoSearchDialog(
callback: photoSearchModel.addSearch,
),
);
},
),
@@ -119,20 +122,17 @@ class UnsplashHomePage extends StatelessWidget {
return UnsplashNotice(
child: Scaffold(
appBar: AppBar(title: Text(title)),
body:
photoSearchModel.entries.isNotEmpty
? const UnsplashSearchContent()
: const Center(
child: Text('Search for Photos using the Fab button'),
),
floatingActionButton: FloatingActionButton(
onPressed:
() => showDialog<void>(
context: context,
builder:
(context) =>
PhotoSearchDialog(callback: photoSearchModel.addSearch),
body: photoSearchModel.entries.isNotEmpty
? const UnsplashSearchContent()
: const Center(
child: Text('Search for Photos using the Fab button'),
),
floatingActionButton: FloatingActionButton(
onPressed: () => showDialog<void>(
context: context,
builder: (context) =>
PhotoSearchDialog(callback: photoSearchModel.addSearch),
),
tooltip: 'Search for a photo',
child: const Icon(Icons.search),
),

View File

@@ -45,5 +45,6 @@ class PhotoSearchModel extends ChangeNotifier {
notifyListeners();
}
Future<Uint8List> download({required Photo photo}) => _client.download(photo);
Future<Uint8List> download({required Photo photo}) =>
_client.download(photo);
}

View File

@@ -33,7 +33,9 @@ class _$SearchSerializer implements StructuredSerializer<Search> {
'results',
serializers.serialize(
object.results,
specifiedType: const FullType(BuiltList, const [const FullType(Photo)]),
specifiedType: const FullType(BuiltList, const [
const FullType(Photo),
]),
),
];

View File

@@ -21,7 +21,9 @@ abstract class ApiError implements Built<ApiError, ApiErrorBuilder> {
BuiltList<String>? get errors;
String toJson() {
return json.encode(serializers.serializeWith(ApiError.serializer, this));
return json.encode(
serializers.serializeWith(ApiError.serializer, this),
);
}
static ApiError? fromJson(String jsonString) {

View File

@@ -106,8 +106,9 @@ class _$ApiError extends ApiError {
@override
String toString() {
return (newBuiltValueToStringHelper(r'ApiError')
..add('errors', errors)).toString();
return (newBuiltValueToStringHelper(
r'ApiError',
)..add('errors', errors)).toString();
}
}

View File

@@ -39,7 +39,10 @@ class _$CurrentUserCollectionsSerializer
result
..add('title')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
value = object.publishedAt;
@@ -47,7 +50,10 @@ class _$CurrentUserCollectionsSerializer
result
..add('published_at')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
value = object.updatedAt;
@@ -55,7 +61,10 @@ class _$CurrentUserCollectionsSerializer
result
..add('updated_at')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
return result;
@@ -134,7 +143,11 @@ class _$CurrentUserCollections extends CurrentUserCollections {
this.publishedAt,
this.updatedAt,
}) : super._() {
BuiltValueNullFieldError.checkNotNull(id, r'CurrentUserCollections', 'id');
BuiltValueNullFieldError.checkNotNull(
id,
r'CurrentUserCollections',
'id',
);
}
@override

View File

@@ -31,7 +31,10 @@ class _$ExifSerializer implements StructuredSerializer<Exif> {
result
..add('make')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
value = object.model;
@@ -39,7 +42,10 @@ class _$ExifSerializer implements StructuredSerializer<Exif> {
result
..add('model')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
value = object.exposureTime;
@@ -47,7 +53,10 @@ class _$ExifSerializer implements StructuredSerializer<Exif> {
result
..add('exposure_time')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
value = object.aperture;
@@ -55,7 +64,10 @@ class _$ExifSerializer implements StructuredSerializer<Exif> {
result
..add('aperture')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
value = object.focalLength;
@@ -63,14 +75,19 @@ class _$ExifSerializer implements StructuredSerializer<Exif> {
result
..add('focal_length')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
value = object.iso;
if (value != null) {
result
..add('iso')
..add(serializers.serialize(value, specifiedType: const FullType(int)));
..add(
serializers.serialize(value, specifiedType: const FullType(int)),
);
}
return result;
}
@@ -131,7 +148,10 @@ class _$ExifSerializer implements StructuredSerializer<Exif> {
break;
case 'iso':
result.iso =
serializers.deserialize(value, specifiedType: const FullType(int))
serializers.deserialize(
value,
specifiedType: const FullType(int),
)
as int?;
break;
}
@@ -225,7 +245,8 @@ class ExifBuilder implements Builder<Exif, ExifBuilder> {
String? _exposureTime;
String? get exposureTime => _$this._exposureTime;
set exposureTime(String? exposureTime) => _$this._exposureTime = exposureTime;
set exposureTime(String? exposureTime) =>
_$this._exposureTime = exposureTime;
String? _aperture;
String? get aperture => _$this._aperture;

View File

@@ -31,7 +31,10 @@ class _$LinksSerializer implements StructuredSerializer<Links> {
result
..add('self')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
value = object.html;
@@ -39,7 +42,10 @@ class _$LinksSerializer implements StructuredSerializer<Links> {
result
..add('html')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
value = object.download;
@@ -47,7 +53,10 @@ class _$LinksSerializer implements StructuredSerializer<Links> {
result
..add('download')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
value = object.downloadLocation;
@@ -55,7 +64,10 @@ class _$LinksSerializer implements StructuredSerializer<Links> {
result
..add('download_location')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
return result;

View File

@@ -27,7 +27,9 @@ abstract class Location implements Built<Location, LocationBuilder> {
Position? get position;
String toJson() {
return json.encode(serializers.serializeWith(Location.serializer, this));
return json.encode(
serializers.serializeWith(Location.serializer, this),
);
}
static Location? fromJson(String jsonString) {

View File

@@ -31,7 +31,10 @@ class _$LocationSerializer implements StructuredSerializer<Location> {
result
..add('city')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
value = object.country;
@@ -39,7 +42,10 @@ class _$LocationSerializer implements StructuredSerializer<Location> {
result
..add('country')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
value = object.position;
@@ -47,7 +53,10 @@ class _$LocationSerializer implements StructuredSerializer<Location> {
result
..add('position')
..add(
serializers.serialize(value, specifiedType: const FullType(Position)),
serializers.serialize(
value,
specifiedType: const FullType(Position),
),
);
}
return result;

View File

@@ -26,7 +26,10 @@ class _$PhotoSerializer implements StructuredSerializer<Photo> {
}) {
final result = <Object?>[
'id',
serializers.serialize(object.id, specifiedType: const FullType(String)),
serializers.serialize(
object.id,
specifiedType: const FullType(String),
),
];
Object? value;
value = object.createdAt;
@@ -34,7 +37,10 @@ class _$PhotoSerializer implements StructuredSerializer<Photo> {
result
..add('created_at')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
value = object.updatedAt;
@@ -42,47 +48,64 @@ class _$PhotoSerializer implements StructuredSerializer<Photo> {
result
..add('updated_at')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
value = object.width;
if (value != null) {
result
..add('width')
..add(serializers.serialize(value, specifiedType: const FullType(int)));
..add(
serializers.serialize(value, specifiedType: const FullType(int)),
);
}
value = object.height;
if (value != null) {
result
..add('height')
..add(serializers.serialize(value, specifiedType: const FullType(int)));
..add(
serializers.serialize(value, specifiedType: const FullType(int)),
);
}
value = object.color;
if (value != null) {
result
..add('color')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
value = object.downloads;
if (value != null) {
result
..add('downloads')
..add(serializers.serialize(value, specifiedType: const FullType(int)));
..add(
serializers.serialize(value, specifiedType: const FullType(int)),
);
}
value = object.likes;
if (value != null) {
result
..add('likes')
..add(serializers.serialize(value, specifiedType: const FullType(int)));
..add(
serializers.serialize(value, specifiedType: const FullType(int)),
);
}
value = object.likedByUser;
if (value != null) {
result
..add('liked_by_user')
..add(
serializers.serialize(value, specifiedType: const FullType(bool)),
serializers.serialize(
value,
specifiedType: const FullType(bool),
),
);
}
value = object.description;
@@ -90,7 +113,10 @@ class _$PhotoSerializer implements StructuredSerializer<Photo> {
result
..add('description')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
value = object.exif;
@@ -98,7 +124,10 @@ class _$PhotoSerializer implements StructuredSerializer<Photo> {
result
..add('exif')
..add(
serializers.serialize(value, specifiedType: const FullType(Exif)),
serializers.serialize(
value,
specifiedType: const FullType(Exif),
),
);
}
value = object.location;
@@ -106,7 +135,10 @@ class _$PhotoSerializer implements StructuredSerializer<Photo> {
result
..add('location')
..add(
serializers.serialize(value, specifiedType: const FullType(Location)),
serializers.serialize(
value,
specifiedType: const FullType(Location),
),
);
}
value = object.tags;
@@ -140,7 +172,10 @@ class _$PhotoSerializer implements StructuredSerializer<Photo> {
result
..add('urls')
..add(
serializers.serialize(value, specifiedType: const FullType(Urls)),
serializers.serialize(
value,
specifiedType: const FullType(Urls),
),
);
}
value = object.links;
@@ -148,7 +183,10 @@ class _$PhotoSerializer implements StructuredSerializer<Photo> {
result
..add('links')
..add(
serializers.serialize(value, specifiedType: const FullType(Links)),
serializers.serialize(
value,
specifiedType: const FullType(Links),
),
);
}
value = object.user;
@@ -156,7 +194,10 @@ class _$PhotoSerializer implements StructuredSerializer<Photo> {
result
..add('user')
..add(
serializers.serialize(value, specifiedType: const FullType(User)),
serializers.serialize(
value,
specifiedType: const FullType(User),
),
);
}
return result;
@@ -202,12 +243,18 @@ class _$PhotoSerializer implements StructuredSerializer<Photo> {
break;
case 'width':
result.width =
serializers.deserialize(value, specifiedType: const FullType(int))
serializers.deserialize(
value,
specifiedType: const FullType(int),
)
as int?;
break;
case 'height':
result.height =
serializers.deserialize(value, specifiedType: const FullType(int))
serializers.deserialize(
value,
specifiedType: const FullType(int),
)
as int?;
break;
case 'color':
@@ -220,12 +267,18 @@ class _$PhotoSerializer implements StructuredSerializer<Photo> {
break;
case 'downloads':
result.downloads =
serializers.deserialize(value, specifiedType: const FullType(int))
serializers.deserialize(
value,
specifiedType: const FullType(int),
)
as int?;
break;
case 'likes':
result.likes =
serializers.deserialize(value, specifiedType: const FullType(int))
serializers.deserialize(
value,
specifiedType: const FullType(int),
)
as int?;
break;
case 'liked_by_user':
@@ -246,7 +299,10 @@ class _$PhotoSerializer implements StructuredSerializer<Photo> {
break;
case 'exif':
result.exif.replace(
serializers.deserialize(value, specifiedType: const FullType(Exif))!
serializers.deserialize(
value,
specifiedType: const FullType(Exif),
)!
as Exif,
);
break;
@@ -283,7 +339,10 @@ class _$PhotoSerializer implements StructuredSerializer<Photo> {
break;
case 'urls':
result.urls.replace(
serializers.deserialize(value, specifiedType: const FullType(Urls))!
serializers.deserialize(
value,
specifiedType: const FullType(Urls),
)!
as Urls,
);
break;
@@ -298,7 +357,10 @@ class _$PhotoSerializer implements StructuredSerializer<Photo> {
break;
case 'user':
result.user.replace(
serializers.deserialize(value, specifiedType: const FullType(User))!
serializers.deserialize(
value,
specifiedType: const FullType(User),
)!
as User,
);
break;

View File

@@ -23,7 +23,9 @@ abstract class Position implements Built<Position, PositionBuilder> {
double get longitude;
String toJson() {
return json.encode(serializers.serializeWith(Position.serializer, this));
return json.encode(
serializers.serializeWith(Position.serializer, this),
);
}
static Position? fromJson(String jsonString) {

View File

@@ -87,8 +87,16 @@ class _$Position extends Position {
(new PositionBuilder()..update(updates))._build();
_$Position._({required this.latitude, required this.longitude}) : super._() {
BuiltValueNullFieldError.checkNotNull(latitude, r'Position', 'latitude');
BuiltValueNullFieldError.checkNotNull(longitude, r'Position', 'longitude');
BuiltValueNullFieldError.checkNotNull(
latitude,
r'Position',
'latitude',
);
BuiltValueNullFieldError.checkNotNull(
longitude,
r'Position',
'longitude',
);
}
@override

View File

@@ -33,7 +33,9 @@ class _$SearchPhotosResponseSerializer
'results',
serializers.serialize(
object.results,
specifiedType: const FullType(BuiltList, const [const FullType(Photo)]),
specifiedType: const FullType(BuiltList, const [
const FullType(Photo),
]),
),
];
Object? value;
@@ -41,13 +43,17 @@ class _$SearchPhotosResponseSerializer
if (value != null) {
result
..add('total')
..add(serializers.serialize(value, specifiedType: const FullType(int)));
..add(
serializers.serialize(value, specifiedType: const FullType(int)),
);
}
value = object.totalPages;
if (value != null) {
result
..add('total_pages')
..add(serializers.serialize(value, specifiedType: const FullType(int)));
..add(
serializers.serialize(value, specifiedType: const FullType(int)),
);
}
return result;
}
@@ -68,12 +74,18 @@ class _$SearchPhotosResponseSerializer
switch (key) {
case 'total':
result.total =
serializers.deserialize(value, specifiedType: const FullType(int))
serializers.deserialize(
value,
specifiedType: const FullType(int),
)
as int?;
break;
case 'total_pages':
result.totalPages =
serializers.deserialize(value, specifiedType: const FullType(int))
serializers.deserialize(
value,
specifiedType: const FullType(int),
)
as int?;
break;
case 'results':
@@ -106,8 +118,11 @@ class _$SearchPhotosResponse extends SearchPhotosResponse {
void Function(SearchPhotosResponseBuilder)? updates,
]) => (new SearchPhotosResponseBuilder()..update(updates))._build();
_$SearchPhotosResponse._({this.total, this.totalPages, required this.results})
: super._() {
_$SearchPhotosResponse._({
this.total,
this.totalPages,
required this.results,
}) : super._() {
BuiltValueNullFieldError.checkNotNull(
results,
r'SearchPhotosResponse',

View File

@@ -98,8 +98,9 @@ class _$Tags extends Tags {
@override
String toString() {
return (newBuiltValueToStringHelper(r'Tags')
..add('title', title)).toString();
return (newBuiltValueToStringHelper(
r'Tags',
)..add('title', title)).toString();
}
}
@@ -139,7 +140,11 @@ class TagsBuilder implements Builder<Tags, TagsBuilder> {
final _$result =
_$v ??
new _$Tags._(
title: BuiltValueNullFieldError.checkNotNull(title, r'Tags', 'title'),
title: BuiltValueNullFieldError.checkNotNull(
title,
r'Tags',
'title',
),
);
replace(_$result);
return _$result;

View File

@@ -31,7 +31,10 @@ class _$UrlsSerializer implements StructuredSerializer<Urls> {
result
..add('raw')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
value = object.full;
@@ -39,7 +42,10 @@ class _$UrlsSerializer implements StructuredSerializer<Urls> {
result
..add('full')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
value = object.regular;
@@ -47,7 +53,10 @@ class _$UrlsSerializer implements StructuredSerializer<Urls> {
result
..add('regular')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
value = object.small;
@@ -55,7 +64,10 @@ class _$UrlsSerializer implements StructuredSerializer<Urls> {
result
..add('small')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
value = object.thumb;
@@ -63,7 +75,10 @@ class _$UrlsSerializer implements StructuredSerializer<Urls> {
result
..add('thumb')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
return result;

View File

@@ -26,14 +26,20 @@ class _$UserSerializer implements StructuredSerializer<User> {
}) {
final result = <Object?>[
'id',
serializers.serialize(object.id, specifiedType: const FullType(String)),
serializers.serialize(
object.id,
specifiedType: const FullType(String),
),
'username',
serializers.serialize(
object.username,
specifiedType: const FullType(String),
),
'name',
serializers.serialize(object.name, specifiedType: const FullType(String)),
serializers.serialize(
object.name,
specifiedType: const FullType(String),
),
];
Object? value;
value = object.updatedAt;
@@ -41,7 +47,10 @@ class _$UserSerializer implements StructuredSerializer<User> {
result
..add('updated_at')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
value = object.portfolioUrl;
@@ -49,7 +58,10 @@ class _$UserSerializer implements StructuredSerializer<User> {
result
..add('portfolio_url')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
value = object.bio;
@@ -57,7 +69,10 @@ class _$UserSerializer implements StructuredSerializer<User> {
result
..add('bio')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
value = object.location;
@@ -65,33 +80,45 @@ class _$UserSerializer implements StructuredSerializer<User> {
result
..add('location')
..add(
serializers.serialize(value, specifiedType: const FullType(String)),
serializers.serialize(
value,
specifiedType: const FullType(String),
),
);
}
value = object.totalLikes;
if (value != null) {
result
..add('total_likes')
..add(serializers.serialize(value, specifiedType: const FullType(int)));
..add(
serializers.serialize(value, specifiedType: const FullType(int)),
);
}
value = object.totalPhotos;
if (value != null) {
result
..add('total_photos')
..add(serializers.serialize(value, specifiedType: const FullType(int)));
..add(
serializers.serialize(value, specifiedType: const FullType(int)),
);
}
value = object.totalCollections;
if (value != null) {
result
..add('total_collections')
..add(serializers.serialize(value, specifiedType: const FullType(int)));
..add(
serializers.serialize(value, specifiedType: const FullType(int)),
);
}
value = object.links;
if (value != null) {
result
..add('links')
..add(
serializers.serialize(value, specifiedType: const FullType(Links)),
serializers.serialize(
value,
specifiedType: const FullType(Links),
),
);
}
return result;
@@ -169,17 +196,26 @@ class _$UserSerializer implements StructuredSerializer<User> {
break;
case 'total_likes':
result.totalLikes =
serializers.deserialize(value, specifiedType: const FullType(int))
serializers.deserialize(
value,
specifiedType: const FullType(int),
)
as int?;
break;
case 'total_photos':
result.totalPhotos =
serializers.deserialize(value, specifiedType: const FullType(int))
serializers.deserialize(
value,
specifiedType: const FullType(int),
)
as int?;
break;
case 'total_collections':
result.totalCollections =
serializers.deserialize(value, specifiedType: const FullType(int))
serializers.deserialize(
value,
specifiedType: const FullType(int),
)
as int?;
break;
case 'links':
@@ -324,7 +360,8 @@ class UserBuilder implements Builder<User, UserBuilder> {
String? _portfolioUrl;
String? get portfolioUrl => _$this._portfolioUrl;
set portfolioUrl(String? portfolioUrl) => _$this._portfolioUrl = portfolioUrl;
set portfolioUrl(String? portfolioUrl) =>
_$this._portfolioUrl = portfolioUrl;
String? _bio;
String? get bio => _$this._bio;
@@ -399,7 +436,11 @@ class UserBuilder implements Builder<User, UserBuilder> {
r'User',
'username',
),
name: BuiltValueNullFieldError.checkNotNull(name, r'User', 'name'),
name: BuiltValueNullFieldError.checkNotNull(
name,
r'User',
'name',
),
portfolioUrl: portfolioUrl,
bio: bio,
location: location,

View File

@@ -37,20 +37,18 @@ class _PhotoDetailsState extends State<PhotoDetails> {
uri: Uri.parse(
'https://unsplash.com/@${widget.photo.user!.username}?utm_source=$unsplashAppName&utm_medium=referral',
),
builder:
(context, followLink) => TextButton(
onPressed: followLink,
child: Text(widget.photo.user!.name),
),
builder: (context, followLink) => TextButton(
onPressed: followLink,
child: Text(widget.photo.user!.name),
),
),
const Text(' on '),
Link(
uri: _unsplashHomepage,
builder:
(context, followLink) => TextButton(
onPressed: followLink,
child: const Text('Unsplash'),
),
builder: (context, followLink) => TextButton(
onPressed: followLink,
child: const Text('Unsplash'),
),
),
],
);

View File

@@ -55,13 +55,12 @@ class _PhotoSearchDialogState extends State<PhotoSearchDialog> {
child: const Text('CANCEL'),
),
TextButton(
onPressed:
_searchEnabled
? () {
widget.callback(_controller.text);
Navigator.of(context).pop();
}
: null,
onPressed: _searchEnabled
? () {
widget.callback(_controller.text);
Navigator.of(context).pop();
}
: null,
child: const Text('SEARCH'),
),
],

View File

@@ -29,16 +29,15 @@ class PolicyDialog extends StatelessWidget {
fontWeight: FontWeight.bold,
color: Colors.lightBlue,
),
recognizer:
TapGestureRecognizer()
..onTap = () async {
final url = Uri.parse(
'https://policies.google.com/terms',
);
if (await url_launcher.canLaunchUrl(url)) {
await url_launcher.launchUrl(url);
}
},
recognizer: TapGestureRecognizer()
..onTap = () async {
final url = Uri.parse(
'https://policies.google.com/terms',
);
if (await url_launcher.canLaunchUrl(url)) {
await url_launcher.launchUrl(url);
}
},
),
],
),
@@ -55,14 +54,13 @@ class PolicyDialog extends StatelessWidget {
fontWeight: FontWeight.bold,
color: Colors.lightBlue,
),
recognizer:
TapGestureRecognizer()
..onTap = () async {
final url = Uri.parse('https://unsplash.com/terms');
if (await url_launcher.canLaunchUrl(url)) {
await url_launcher.launchUrl(url);
}
},
recognizer: TapGestureRecognizer()
..onTap = () async {
final url = Uri.parse('https://unsplash.com/terms');
if (await url_launcher.canLaunchUrl(url)) {
await url_launcher.launchUrl(url);
}
},
),
],
),

View File

@@ -144,7 +144,9 @@ class _SplitState extends State<Split> {
child: DecoratedBox(
decoration: BoxDecoration(
color: Theme.of(context).dividerColor,
borderRadius: BorderRadius.circular(Split.dividerMainAxisSize),
borderRadius: BorderRadius.circular(
Split.dividerMainAxisSize,
),
),
child: SizedBox(
height: isHorizontal ? 2.0 : Split.dividerMainAxisSize - 2.0,

View File

@@ -69,13 +69,12 @@ class _UnsplashDialog extends StatelessWidget {
children: [
TextSpan(
text: 'Unsplash',
recognizer:
TapGestureRecognizer()
..onTap = () async {
if (!await launchUrl(_unsplashHomepage)) {
throw 'Could not launch $_unsplashHomepage';
}
},
recognizer: TapGestureRecognizer()
..onTap = () async {
if (!await launchUrl(_unsplashHomepage)) {
throw 'Could not launch $_unsplashHomepage';
}
},
style: const TextStyle(color: Colors.blue),
),
const TextSpan(
@@ -88,16 +87,18 @@ class _UnsplashDialog extends StatelessWidget {
),
TextSpan(
text: 'how Unsplash collects and uses data',
recognizer:
TapGestureRecognizer()
..onTap = () async {
if (!await launchUrl(_unsplashPrivacyPolicy)) {
throw 'Could not launch $_unsplashPrivacyPolicy';
}
},
recognizer: TapGestureRecognizer()
..onTap = () async {
if (!await launchUrl(_unsplashPrivacyPolicy)) {
throw 'Could not launch $_unsplashPrivacyPolicy';
}
},
style: const TextStyle(color: Colors.blue),
),
const TextSpan(text: '.', style: TextStyle(color: Colors.grey)),
const TextSpan(
text: '.',
style: TextStyle(color: Colors.grey),
),
],
),
),

View File

@@ -46,34 +46,33 @@ class _UnsplashSearchContentState extends State<UnsplashSearchContent> {
),
),
secondChild: Center(
child:
photoSearchModel.selectedPhoto != null
? PhotoDetails(
photo: photoSearchModel.selectedPhoto!,
onPhotoSave: (photo) async {
final saveLocation = await getSaveLocation(
suggestedName: '${photo.id}.jpg',
acceptedTypeGroups: [
const XTypeGroup(
label: 'JPG',
extensions: ['jpg'],
mimeTypes: ['image/jpeg'],
),
],
child: photoSearchModel.selectedPhoto != null
? PhotoDetails(
photo: photoSearchModel.selectedPhoto!,
onPhotoSave: (photo) async {
final saveLocation = await getSaveLocation(
suggestedName: '${photo.id}.jpg',
acceptedTypeGroups: [
const XTypeGroup(
label: 'JPG',
extensions: ['jpg'],
mimeTypes: ['image/jpeg'],
),
],
);
if (saveLocation != null) {
final fileData = await photoSearchModel.download(
photo: photo,
);
if (saveLocation != null) {
final fileData = await photoSearchModel.download(
photo: photo,
);
final photoFile = XFile.fromData(
fileData,
mimeType: 'image/jpeg',
);
await photoFile.saveTo(saveLocation.path);
}
},
)
: Container(),
final photoFile = XFile.fromData(
fileData,
mimeType: 'image/jpeg',
);
await photoFile.saveTo(saveLocation.path);
}
},
)
: Container(),
),
);
}
@@ -87,28 +86,27 @@ class _UnsplashSearchContentState extends State<UnsplashSearchContent> {
return TreeNode(
content: Expanded(child: Text(searchEntry.query)),
children:
searchEntry.photos
.map<TreeNode>(
(photo) => TreeNode(
content: Expanded(
child: Semantics(
button: true,
onTap: () => selectPhoto(photo),
label: labelForPhoto(photo),
excludeSemantics: true,
child: InkWell(
onTap: () => selectPhoto(photo),
child: Padding(
padding: const EdgeInsets.all(12),
child: Text(labelForPhoto(photo)),
),
),
children: searchEntry.photos
.map<TreeNode>(
(photo) => TreeNode(
content: Expanded(
child: Semantics(
button: true,
onTap: () => selectPhoto(photo),
label: labelForPhoto(photo),
excludeSemantics: true,
child: InkWell(
onTap: () => selectPhoto(photo),
child: Padding(
padding: const EdgeInsets.all(12),
child: Text(labelForPhoto(photo)),
),
),
),
)
.toList(),
),
),
)
.toList(),
);
}
}

View File

@@ -1,10 +1,11 @@
name: desktop_photo_search
name: desktop_photo_search_material
description: Search for Photos, using the Unsplash API.
publish_to: 'none'
version: 1.0.0+1
resolution: workspace
environment:
sdk: ^3.7.0-0
sdk: ^3.9.0-0
dependencies:
built_collection: ^5.1.1
@@ -20,7 +21,6 @@ dependencies:
git:
url: https://github.com/google/flutter-desktop-embedding.git
path: plugins/menubar
ref: 6c66ad23ee79749f30a8eece542cf54eaf157ed8
provider: ^6.0.5
transparent_image: ^2.0.1
url_launcher: ^6.1.12
@@ -29,7 +29,6 @@ dependencies:
git:
url: https://github.com/google/flutter-desktop-embedding.git
path: plugins/window_size
ref: 6c66ad23ee79749f30a8eece542cf54eaf157ed8
dev_dependencies:
analysis_defaults:

View File

@@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:desktop_photo_search/src/unsplash/photo.dart';
import 'package:desktop_photo_search/src/unsplash/search_photos_response.dart';
import 'package:desktop_photo_search/src/unsplash/unsplash.dart';
import 'package:desktop_photo_search/src/unsplash/user.dart';
import 'package:desktop_photo_search_material/src/unsplash/photo.dart';
import 'package:desktop_photo_search_material/src/unsplash/search_photos_response.dart';
import 'package:desktop_photo_search_material/src/unsplash/unsplash.dart';
import 'package:desktop_photo_search_material/src/unsplash/user.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:http/http.dart';
import 'package:http/testing.dart';

View File

@@ -4,10 +4,10 @@
import 'dart:typed_data';
import 'package:desktop_photo_search/src/model/photo_search_model.dart';
import 'package:desktop_photo_search/src/unsplash/photo.dart';
import 'package:desktop_photo_search/src/unsplash/search_photos_response.dart';
import 'package:desktop_photo_search/src/unsplash/unsplash.dart';
import 'package:desktop_photo_search_material/src/model/photo_search_model.dart';
import 'package:desktop_photo_search_material/src/unsplash/photo.dart';
import 'package:desktop_photo_search_material/src/unsplash/search_photos_response.dart';
import 'package:desktop_photo_search_material/src/unsplash/unsplash.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:provider/provider.dart';