mirror of
https://github.com/flutter/samples.git
synced 2025-11-13 10:59:04 +00:00
Update desktop_photo_search to use url_launcher's Link (#780)
This commit is contained in:
@@ -128,7 +128,7 @@ class UnsplashHomePage extends StatelessWidget {
|
||||
await photoSearchModel.download(photo: photo);
|
||||
final photoFile = XFile.fromData(fileData,
|
||||
mimeType: 'image/jpeg');
|
||||
photoFile.saveTo(path);
|
||||
await photoFile.saveTo(path);
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
@@ -43,7 +43,7 @@ class _$SearchSerializer implements StructuredSerializer<Search> {
|
||||
while (iterator.moveNext()) {
|
||||
final key = iterator.current as String;
|
||||
iterator.moveNext();
|
||||
final dynamic value = iterator.current;
|
||||
final Object value = iterator.current;
|
||||
switch (key) {
|
||||
case 'query':
|
||||
result.query = serializers.deserialize(value,
|
||||
@@ -72,12 +72,8 @@ class _$Search extends Search {
|
||||
(new SearchBuilder()..update(updates)).build();
|
||||
|
||||
_$Search._({this.query, this.results}) : super._() {
|
||||
if (query == null) {
|
||||
throw new BuiltValueNullFieldError('Search', 'query');
|
||||
}
|
||||
if (results == null) {
|
||||
throw new BuiltValueNullFieldError('Search', 'results');
|
||||
}
|
||||
BuiltValueNullFieldError.checkNotNull(query, 'Search', 'query');
|
||||
BuiltValueNullFieldError.checkNotNull(results, 'Search', 'results');
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -122,9 +118,10 @@ class SearchBuilder implements Builder<Search, SearchBuilder> {
|
||||
SearchBuilder();
|
||||
|
||||
SearchBuilder get _$this {
|
||||
if (_$v != null) {
|
||||
_query = _$v.query;
|
||||
_results = _$v.results?.toBuilder();
|
||||
final $v = _$v;
|
||||
if ($v != null) {
|
||||
_query = $v.query;
|
||||
_results = $v.results.toBuilder();
|
||||
_$v = null;
|
||||
}
|
||||
return this;
|
||||
@@ -132,9 +129,7 @@ class SearchBuilder implements Builder<Search, SearchBuilder> {
|
||||
|
||||
@override
|
||||
void replace(Search other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentError.notNull('other');
|
||||
}
|
||||
ArgumentError.checkNotNull(other, 'other');
|
||||
_$v = other as _$Search;
|
||||
}
|
||||
|
||||
@@ -147,7 +142,11 @@ class SearchBuilder implements Builder<Search, SearchBuilder> {
|
||||
_$Search build() {
|
||||
_$Search _$result;
|
||||
try {
|
||||
_$result = _$v ?? new _$Search._(query: query, results: results.build());
|
||||
_$result = _$v ??
|
||||
new _$Search._(
|
||||
query: BuiltValueNullFieldError.checkNotNull(
|
||||
query, 'Search', 'query'),
|
||||
results: results.build());
|
||||
} catch (_) {
|
||||
String _$failedField;
|
||||
try {
|
||||
|
||||
@@ -40,7 +40,7 @@ class _$ApiErrorSerializer implements StructuredSerializer<ApiError> {
|
||||
while (iterator.moveNext()) {
|
||||
final key = iterator.current as String;
|
||||
iterator.moveNext();
|
||||
final dynamic value = iterator.current;
|
||||
final Object value = iterator.current;
|
||||
switch (key) {
|
||||
case 'errors':
|
||||
result.errors.replace(serializers.deserialize(value,
|
||||
@@ -63,9 +63,7 @@ class _$ApiError extends ApiError {
|
||||
(new ApiErrorBuilder()..update(updates)).build();
|
||||
|
||||
_$ApiError._({this.errors}) : super._() {
|
||||
if (errors == null) {
|
||||
throw new BuiltValueNullFieldError('ApiError', 'errors');
|
||||
}
|
||||
BuiltValueNullFieldError.checkNotNull(errors, 'ApiError', 'errors');
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -104,8 +102,9 @@ class ApiErrorBuilder implements Builder<ApiError, ApiErrorBuilder> {
|
||||
ApiErrorBuilder();
|
||||
|
||||
ApiErrorBuilder get _$this {
|
||||
if (_$v != null) {
|
||||
_errors = _$v.errors?.toBuilder();
|
||||
final $v = _$v;
|
||||
if ($v != null) {
|
||||
_errors = $v.errors.toBuilder();
|
||||
_$v = null;
|
||||
}
|
||||
return this;
|
||||
@@ -113,9 +112,7 @@ class ApiErrorBuilder implements Builder<ApiError, ApiErrorBuilder> {
|
||||
|
||||
@override
|
||||
void replace(ApiError other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentError.notNull('other');
|
||||
}
|
||||
ArgumentError.checkNotNull(other, 'other');
|
||||
_$v = other as _$ApiError;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,22 +31,26 @@ class _$CurrentUserCollectionsSerializer
|
||||
'id',
|
||||
serializers.serialize(object.id, specifiedType: const FullType(int)),
|
||||
];
|
||||
if (object.title != null) {
|
||||
Object value;
|
||||
value = object.title;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('title')
|
||||
..add(serializers.serialize(object.title,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
if (object.publishedAt != null) {
|
||||
value = object.publishedAt;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('published_at')
|
||||
..add(serializers.serialize(object.publishedAt,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
if (object.updatedAt != null) {
|
||||
value = object.updatedAt;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('updated_at')
|
||||
..add(serializers.serialize(object.updatedAt,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
return result;
|
||||
@@ -62,7 +66,7 @@ class _$CurrentUserCollectionsSerializer
|
||||
while (iterator.moveNext()) {
|
||||
final key = iterator.current as String;
|
||||
iterator.moveNext();
|
||||
final dynamic value = iterator.current;
|
||||
final Object value = iterator.current;
|
||||
switch (key) {
|
||||
case 'id':
|
||||
result.id = serializers.deserialize(value,
|
||||
@@ -104,9 +108,7 @@ class _$CurrentUserCollections extends CurrentUserCollections {
|
||||
_$CurrentUserCollections._(
|
||||
{this.id, this.title, this.publishedAt, this.updatedAt})
|
||||
: super._() {
|
||||
if (id == null) {
|
||||
throw new BuiltValueNullFieldError('CurrentUserCollections', 'id');
|
||||
}
|
||||
BuiltValueNullFieldError.checkNotNull(id, 'CurrentUserCollections', 'id');
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -169,11 +171,12 @@ class CurrentUserCollectionsBuilder
|
||||
CurrentUserCollectionsBuilder();
|
||||
|
||||
CurrentUserCollectionsBuilder get _$this {
|
||||
if (_$v != null) {
|
||||
_id = _$v.id;
|
||||
_title = _$v.title;
|
||||
_publishedAt = _$v.publishedAt;
|
||||
_updatedAt = _$v.updatedAt;
|
||||
final $v = _$v;
|
||||
if ($v != null) {
|
||||
_id = $v.id;
|
||||
_title = $v.title;
|
||||
_publishedAt = $v.publishedAt;
|
||||
_updatedAt = $v.updatedAt;
|
||||
_$v = null;
|
||||
}
|
||||
return this;
|
||||
@@ -181,9 +184,7 @@ class CurrentUserCollectionsBuilder
|
||||
|
||||
@override
|
||||
void replace(CurrentUserCollections other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentError.notNull('other');
|
||||
}
|
||||
ArgumentError.checkNotNull(other, 'other');
|
||||
_$v = other as _$CurrentUserCollections;
|
||||
}
|
||||
|
||||
@@ -196,7 +197,8 @@ class CurrentUserCollectionsBuilder
|
||||
_$CurrentUserCollections build() {
|
||||
final _$result = _$v ??
|
||||
new _$CurrentUserCollections._(
|
||||
id: id,
|
||||
id: BuiltValueNullFieldError.checkNotNull(
|
||||
id, 'CurrentUserCollections', 'id'),
|
||||
title: title,
|
||||
publishedAt: publishedAt,
|
||||
updatedAt: updatedAt);
|
||||
|
||||
@@ -22,41 +22,47 @@ class _$ExifSerializer implements StructuredSerializer<Exif> {
|
||||
Iterable<Object> serialize(Serializers serializers, Exif object,
|
||||
{FullType specifiedType = FullType.unspecified}) {
|
||||
final result = <Object>[];
|
||||
if (object.make != null) {
|
||||
Object value;
|
||||
value = object.make;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('make')
|
||||
..add(serializers.serialize(object.make,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
if (object.model != null) {
|
||||
value = object.model;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('model')
|
||||
..add(serializers.serialize(object.model,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
if (object.exposureTime != null) {
|
||||
value = object.exposureTime;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('exposure_time')
|
||||
..add(serializers.serialize(object.exposureTime,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
if (object.aperture != null) {
|
||||
value = object.aperture;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('aperture')
|
||||
..add(serializers.serialize(object.aperture,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
if (object.focalLength != null) {
|
||||
value = object.focalLength;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('focal_length')
|
||||
..add(serializers.serialize(object.focalLength,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
if (object.iso != null) {
|
||||
value = object.iso;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('iso')
|
||||
..add(serializers.serialize(object.iso,
|
||||
specifiedType: const FullType(int)));
|
||||
..add(serializers.serialize(value, specifiedType: const FullType(int)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -70,7 +76,7 @@ class _$ExifSerializer implements StructuredSerializer<Exif> {
|
||||
while (iterator.moveNext()) {
|
||||
final key = iterator.current as String;
|
||||
iterator.moveNext();
|
||||
final dynamic value = iterator.current;
|
||||
final Object value = iterator.current;
|
||||
switch (key) {
|
||||
case 'make':
|
||||
result.make = serializers.deserialize(value,
|
||||
@@ -203,13 +209,14 @@ class ExifBuilder implements Builder<Exif, ExifBuilder> {
|
||||
ExifBuilder();
|
||||
|
||||
ExifBuilder get _$this {
|
||||
if (_$v != null) {
|
||||
_make = _$v.make;
|
||||
_model = _$v.model;
|
||||
_exposureTime = _$v.exposureTime;
|
||||
_aperture = _$v.aperture;
|
||||
_focalLength = _$v.focalLength;
|
||||
_iso = _$v.iso;
|
||||
final $v = _$v;
|
||||
if ($v != null) {
|
||||
_make = $v.make;
|
||||
_model = $v.model;
|
||||
_exposureTime = $v.exposureTime;
|
||||
_aperture = $v.aperture;
|
||||
_focalLength = $v.focalLength;
|
||||
_iso = $v.iso;
|
||||
_$v = null;
|
||||
}
|
||||
return this;
|
||||
@@ -217,9 +224,7 @@ class ExifBuilder implements Builder<Exif, ExifBuilder> {
|
||||
|
||||
@override
|
||||
void replace(Exif other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentError.notNull('other');
|
||||
}
|
||||
ArgumentError.checkNotNull(other, 'other');
|
||||
_$v = other as _$Exif;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,28 +22,33 @@ class _$LinksSerializer implements StructuredSerializer<Links> {
|
||||
Iterable<Object> serialize(Serializers serializers, Links object,
|
||||
{FullType specifiedType = FullType.unspecified}) {
|
||||
final result = <Object>[];
|
||||
if (object.self != null) {
|
||||
Object value;
|
||||
value = object.self;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('self')
|
||||
..add(serializers.serialize(object.self,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
if (object.html != null) {
|
||||
value = object.html;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('html')
|
||||
..add(serializers.serialize(object.html,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
if (object.download != null) {
|
||||
value = object.download;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('download')
|
||||
..add(serializers.serialize(object.download,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
if (object.downloadLocation != null) {
|
||||
value = object.downloadLocation;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('download_location')
|
||||
..add(serializers.serialize(object.downloadLocation,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
return result;
|
||||
@@ -58,7 +63,7 @@ class _$LinksSerializer implements StructuredSerializer<Links> {
|
||||
while (iterator.moveNext()) {
|
||||
final key = iterator.current as String;
|
||||
iterator.moveNext();
|
||||
final dynamic value = iterator.current;
|
||||
final Object value = iterator.current;
|
||||
switch (key) {
|
||||
case 'self':
|
||||
result.self = serializers.deserialize(value,
|
||||
@@ -157,11 +162,12 @@ class LinksBuilder implements Builder<Links, LinksBuilder> {
|
||||
LinksBuilder();
|
||||
|
||||
LinksBuilder get _$this {
|
||||
if (_$v != null) {
|
||||
_self = _$v.self;
|
||||
_html = _$v.html;
|
||||
_download = _$v.download;
|
||||
_downloadLocation = _$v.downloadLocation;
|
||||
final $v = _$v;
|
||||
if ($v != null) {
|
||||
_self = $v.self;
|
||||
_html = $v.html;
|
||||
_download = $v.download;
|
||||
_downloadLocation = $v.downloadLocation;
|
||||
_$v = null;
|
||||
}
|
||||
return this;
|
||||
@@ -169,9 +175,7 @@ class LinksBuilder implements Builder<Links, LinksBuilder> {
|
||||
|
||||
@override
|
||||
void replace(Links other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentError.notNull('other');
|
||||
}
|
||||
ArgumentError.checkNotNull(other, 'other');
|
||||
_$v = other as _$Links;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,22 +22,26 @@ class _$LocationSerializer implements StructuredSerializer<Location> {
|
||||
Iterable<Object> serialize(Serializers serializers, Location object,
|
||||
{FullType specifiedType = FullType.unspecified}) {
|
||||
final result = <Object>[];
|
||||
if (object.city != null) {
|
||||
Object value;
|
||||
value = object.city;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('city')
|
||||
..add(serializers.serialize(object.city,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
if (object.country != null) {
|
||||
value = object.country;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('country')
|
||||
..add(serializers.serialize(object.country,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
if (object.position != null) {
|
||||
value = object.position;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('position')
|
||||
..add(serializers.serialize(object.position,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(Position)));
|
||||
}
|
||||
return result;
|
||||
@@ -52,7 +56,7 @@ class _$LocationSerializer implements StructuredSerializer<Location> {
|
||||
while (iterator.moveNext()) {
|
||||
final key = iterator.current as String;
|
||||
iterator.moveNext();
|
||||
final dynamic value = iterator.current;
|
||||
final Object value = iterator.current;
|
||||
switch (key) {
|
||||
case 'city':
|
||||
result.city = serializers.deserialize(value,
|
||||
@@ -136,10 +140,11 @@ class LocationBuilder implements Builder<Location, LocationBuilder> {
|
||||
LocationBuilder();
|
||||
|
||||
LocationBuilder get _$this {
|
||||
if (_$v != null) {
|
||||
_city = _$v.city;
|
||||
_country = _$v.country;
|
||||
_position = _$v.position?.toBuilder();
|
||||
final $v = _$v;
|
||||
if ($v != null) {
|
||||
_city = $v.city;
|
||||
_country = $v.country;
|
||||
_position = $v.position?.toBuilder();
|
||||
_$v = null;
|
||||
}
|
||||
return this;
|
||||
@@ -147,9 +152,7 @@ class LocationBuilder implements Builder<Location, LocationBuilder> {
|
||||
|
||||
@override
|
||||
void replace(Location other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentError.notNull('other');
|
||||
}
|
||||
ArgumentError.checkNotNull(other, 'other');
|
||||
_$v = other as _$Location;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,103 +25,116 @@ class _$PhotoSerializer implements StructuredSerializer<Photo> {
|
||||
'id',
|
||||
serializers.serialize(object.id, specifiedType: const FullType(String)),
|
||||
];
|
||||
if (object.createdAt != null) {
|
||||
Object value;
|
||||
value = object.createdAt;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('created_at')
|
||||
..add(serializers.serialize(object.createdAt,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
if (object.updatedAt != null) {
|
||||
value = object.updatedAt;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('updated_at')
|
||||
..add(serializers.serialize(object.updatedAt,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
if (object.width != null) {
|
||||
value = object.width;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('width')
|
||||
..add(serializers.serialize(object.width,
|
||||
specifiedType: const FullType(int)));
|
||||
..add(serializers.serialize(value, specifiedType: const FullType(int)));
|
||||
}
|
||||
if (object.height != null) {
|
||||
value = object.height;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('height')
|
||||
..add(serializers.serialize(object.height,
|
||||
specifiedType: const FullType(int)));
|
||||
..add(serializers.serialize(value, specifiedType: const FullType(int)));
|
||||
}
|
||||
if (object.color != null) {
|
||||
value = object.color;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('color')
|
||||
..add(serializers.serialize(object.color,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
if (object.downloads != null) {
|
||||
value = object.downloads;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('downloads')
|
||||
..add(serializers.serialize(object.downloads,
|
||||
specifiedType: const FullType(int)));
|
||||
..add(serializers.serialize(value, specifiedType: const FullType(int)));
|
||||
}
|
||||
if (object.likes != null) {
|
||||
value = object.likes;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('likes')
|
||||
..add(serializers.serialize(object.likes,
|
||||
specifiedType: const FullType(int)));
|
||||
..add(serializers.serialize(value, specifiedType: const FullType(int)));
|
||||
}
|
||||
if (object.likedByUser != null) {
|
||||
value = object.likedByUser;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('liked_by_user')
|
||||
..add(serializers.serialize(object.likedByUser,
|
||||
specifiedType: const FullType(bool)));
|
||||
..add(
|
||||
serializers.serialize(value, specifiedType: const FullType(bool)));
|
||||
}
|
||||
if (object.description != null) {
|
||||
value = object.description;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('description')
|
||||
..add(serializers.serialize(object.description,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
if (object.exif != null) {
|
||||
value = object.exif;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('exif')
|
||||
..add(serializers.serialize(object.exif,
|
||||
specifiedType: const FullType(Exif)));
|
||||
..add(
|
||||
serializers.serialize(value, specifiedType: const FullType(Exif)));
|
||||
}
|
||||
if (object.location != null) {
|
||||
value = object.location;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('location')
|
||||
..add(serializers.serialize(object.location,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(Location)));
|
||||
}
|
||||
if (object.tags != null) {
|
||||
value = object.tags;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('tags')
|
||||
..add(serializers.serialize(object.tags,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType:
|
||||
const FullType(BuiltList, const [const FullType(Tags)])));
|
||||
}
|
||||
if (object.currentUserCollections != null) {
|
||||
value = object.currentUserCollections;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('current_user_collections')
|
||||
..add(serializers.serialize(object.currentUserCollections,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(
|
||||
BuiltList, const [const FullType(CurrentUserCollections)])));
|
||||
}
|
||||
if (object.urls != null) {
|
||||
value = object.urls;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('urls')
|
||||
..add(serializers.serialize(object.urls,
|
||||
specifiedType: const FullType(Urls)));
|
||||
..add(
|
||||
serializers.serialize(value, specifiedType: const FullType(Urls)));
|
||||
}
|
||||
if (object.links != null) {
|
||||
value = object.links;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('links')
|
||||
..add(serializers.serialize(object.links,
|
||||
specifiedType: const FullType(Links)));
|
||||
..add(
|
||||
serializers.serialize(value, specifiedType: const FullType(Links)));
|
||||
}
|
||||
if (object.user != null) {
|
||||
value = object.user;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('user')
|
||||
..add(serializers.serialize(object.user,
|
||||
specifiedType: const FullType(User)));
|
||||
..add(
|
||||
serializers.serialize(value, specifiedType: const FullType(User)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -135,7 +148,7 @@ class _$PhotoSerializer implements StructuredSerializer<Photo> {
|
||||
while (iterator.moveNext()) {
|
||||
final key = iterator.current as String;
|
||||
iterator.moveNext();
|
||||
final dynamic value = iterator.current;
|
||||
final Object value = iterator.current;
|
||||
switch (key) {
|
||||
case 'id':
|
||||
result.id = serializers.deserialize(value,
|
||||
@@ -274,9 +287,7 @@ class _$Photo extends Photo {
|
||||
this.links,
|
||||
this.user})
|
||||
: super._() {
|
||||
if (id == null) {
|
||||
throw new BuiltValueNullFieldError('Photo', 'id');
|
||||
}
|
||||
BuiltValueNullFieldError.checkNotNull(id, 'Photo', 'id');
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -453,24 +464,25 @@ class PhotoBuilder implements Builder<Photo, PhotoBuilder> {
|
||||
PhotoBuilder();
|
||||
|
||||
PhotoBuilder get _$this {
|
||||
if (_$v != null) {
|
||||
_id = _$v.id;
|
||||
_createdAt = _$v.createdAt;
|
||||
_updatedAt = _$v.updatedAt;
|
||||
_width = _$v.width;
|
||||
_height = _$v.height;
|
||||
_color = _$v.color;
|
||||
_downloads = _$v.downloads;
|
||||
_likes = _$v.likes;
|
||||
_likedByUser = _$v.likedByUser;
|
||||
_description = _$v.description;
|
||||
_exif = _$v.exif?.toBuilder();
|
||||
_location = _$v.location?.toBuilder();
|
||||
_tags = _$v.tags?.toBuilder();
|
||||
_currentUserCollections = _$v.currentUserCollections?.toBuilder();
|
||||
_urls = _$v.urls?.toBuilder();
|
||||
_links = _$v.links?.toBuilder();
|
||||
_user = _$v.user?.toBuilder();
|
||||
final $v = _$v;
|
||||
if ($v != null) {
|
||||
_id = $v.id;
|
||||
_createdAt = $v.createdAt;
|
||||
_updatedAt = $v.updatedAt;
|
||||
_width = $v.width;
|
||||
_height = $v.height;
|
||||
_color = $v.color;
|
||||
_downloads = $v.downloads;
|
||||
_likes = $v.likes;
|
||||
_likedByUser = $v.likedByUser;
|
||||
_description = $v.description;
|
||||
_exif = $v.exif?.toBuilder();
|
||||
_location = $v.location?.toBuilder();
|
||||
_tags = $v.tags?.toBuilder();
|
||||
_currentUserCollections = $v.currentUserCollections?.toBuilder();
|
||||
_urls = $v.urls?.toBuilder();
|
||||
_links = $v.links?.toBuilder();
|
||||
_user = $v.user?.toBuilder();
|
||||
_$v = null;
|
||||
}
|
||||
return this;
|
||||
@@ -478,9 +490,7 @@ class PhotoBuilder implements Builder<Photo, PhotoBuilder> {
|
||||
|
||||
@override
|
||||
void replace(Photo other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentError.notNull('other');
|
||||
}
|
||||
ArgumentError.checkNotNull(other, 'other');
|
||||
_$v = other as _$Photo;
|
||||
}
|
||||
|
||||
@@ -495,7 +505,7 @@ class PhotoBuilder implements Builder<Photo, PhotoBuilder> {
|
||||
try {
|
||||
_$result = _$v ??
|
||||
new _$Photo._(
|
||||
id: id,
|
||||
id: BuiltValueNullFieldError.checkNotNull(id, 'Photo', 'id'),
|
||||
createdAt: createdAt,
|
||||
updatedAt: updatedAt,
|
||||
width: width,
|
||||
|
||||
@@ -42,7 +42,7 @@ class _$PositionSerializer implements StructuredSerializer<Position> {
|
||||
while (iterator.moveNext()) {
|
||||
final key = iterator.current as String;
|
||||
iterator.moveNext();
|
||||
final dynamic value = iterator.current;
|
||||
final Object value = iterator.current;
|
||||
switch (key) {
|
||||
case 'latitude':
|
||||
result.latitude = serializers.deserialize(value,
|
||||
@@ -69,12 +69,8 @@ class _$Position extends Position {
|
||||
(new PositionBuilder()..update(updates)).build();
|
||||
|
||||
_$Position._({this.latitude, this.longitude}) : super._() {
|
||||
if (latitude == null) {
|
||||
throw new BuiltValueNullFieldError('Position', 'latitude');
|
||||
}
|
||||
if (longitude == null) {
|
||||
throw new BuiltValueNullFieldError('Position', 'longitude');
|
||||
}
|
||||
BuiltValueNullFieldError.checkNotNull(latitude, 'Position', 'latitude');
|
||||
BuiltValueNullFieldError.checkNotNull(longitude, 'Position', 'longitude');
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -120,9 +116,10 @@ class PositionBuilder implements Builder<Position, PositionBuilder> {
|
||||
PositionBuilder();
|
||||
|
||||
PositionBuilder get _$this {
|
||||
if (_$v != null) {
|
||||
_latitude = _$v.latitude;
|
||||
_longitude = _$v.longitude;
|
||||
final $v = _$v;
|
||||
if ($v != null) {
|
||||
_latitude = $v.latitude;
|
||||
_longitude = $v.longitude;
|
||||
_$v = null;
|
||||
}
|
||||
return this;
|
||||
@@ -130,9 +127,7 @@ class PositionBuilder implements Builder<Position, PositionBuilder> {
|
||||
|
||||
@override
|
||||
void replace(Position other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentError.notNull('other');
|
||||
}
|
||||
ArgumentError.checkNotNull(other, 'other');
|
||||
_$v = other as _$Position;
|
||||
}
|
||||
|
||||
@@ -143,8 +138,12 @@ class PositionBuilder implements Builder<Position, PositionBuilder> {
|
||||
|
||||
@override
|
||||
_$Position build() {
|
||||
final _$result =
|
||||
_$v ?? new _$Position._(latitude: latitude, longitude: longitude);
|
||||
final _$result = _$v ??
|
||||
new _$Position._(
|
||||
latitude: BuiltValueNullFieldError.checkNotNull(
|
||||
latitude, 'Position', 'latitude'),
|
||||
longitude: BuiltValueNullFieldError.checkNotNull(
|
||||
longitude, 'Position', 'longitude'));
|
||||
replace(_$result);
|
||||
return _$result;
|
||||
}
|
||||
|
||||
@@ -33,17 +33,18 @@ class _$SearchPhotosResponseSerializer
|
||||
specifiedType:
|
||||
const FullType(BuiltList, const [const FullType(Photo)])),
|
||||
];
|
||||
if (object.total != null) {
|
||||
Object value;
|
||||
value = object.total;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('total')
|
||||
..add(serializers.serialize(object.total,
|
||||
specifiedType: const FullType(int)));
|
||||
..add(serializers.serialize(value, specifiedType: const FullType(int)));
|
||||
}
|
||||
if (object.totalPages != null) {
|
||||
value = object.totalPages;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('total_pages')
|
||||
..add(serializers.serialize(object.totalPages,
|
||||
specifiedType: const FullType(int)));
|
||||
..add(serializers.serialize(value, specifiedType: const FullType(int)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -58,7 +59,7 @@ class _$SearchPhotosResponseSerializer
|
||||
while (iterator.moveNext()) {
|
||||
final key = iterator.current as String;
|
||||
iterator.moveNext();
|
||||
final dynamic value = iterator.current;
|
||||
final Object value = iterator.current;
|
||||
switch (key) {
|
||||
case 'total':
|
||||
result.total = serializers.deserialize(value,
|
||||
@@ -95,9 +96,8 @@ class _$SearchPhotosResponse extends SearchPhotosResponse {
|
||||
|
||||
_$SearchPhotosResponse._({this.total, this.totalPages, this.results})
|
||||
: super._() {
|
||||
if (results == null) {
|
||||
throw new BuiltValueNullFieldError('SearchPhotosResponse', 'results');
|
||||
}
|
||||
BuiltValueNullFieldError.checkNotNull(
|
||||
results, 'SearchPhotosResponse', 'results');
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -154,10 +154,11 @@ class SearchPhotosResponseBuilder
|
||||
SearchPhotosResponseBuilder();
|
||||
|
||||
SearchPhotosResponseBuilder get _$this {
|
||||
if (_$v != null) {
|
||||
_total = _$v.total;
|
||||
_totalPages = _$v.totalPages;
|
||||
_results = _$v.results?.toBuilder();
|
||||
final $v = _$v;
|
||||
if ($v != null) {
|
||||
_total = $v.total;
|
||||
_totalPages = $v.totalPages;
|
||||
_results = $v.results.toBuilder();
|
||||
_$v = null;
|
||||
}
|
||||
return this;
|
||||
@@ -165,9 +166,7 @@ class SearchPhotosResponseBuilder
|
||||
|
||||
@override
|
||||
void replace(SearchPhotosResponse other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentError.notNull('other');
|
||||
}
|
||||
ArgumentError.checkNotNull(other, 'other');
|
||||
_$v = other as _$SearchPhotosResponse;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ class _$TagsSerializer implements StructuredSerializer<Tags> {
|
||||
while (iterator.moveNext()) {
|
||||
final key = iterator.current as String;
|
||||
iterator.moveNext();
|
||||
final dynamic value = iterator.current;
|
||||
final Object value = iterator.current;
|
||||
switch (key) {
|
||||
case 'title':
|
||||
result.title = serializers.deserialize(value,
|
||||
@@ -60,9 +60,7 @@ class _$Tags extends Tags {
|
||||
(new TagsBuilder()..update(updates)).build();
|
||||
|
||||
_$Tags._({this.title}) : super._() {
|
||||
if (title == null) {
|
||||
throw new BuiltValueNullFieldError('Tags', 'title');
|
||||
}
|
||||
BuiltValueNullFieldError.checkNotNull(title, 'Tags', 'title');
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -100,8 +98,9 @@ class TagsBuilder implements Builder<Tags, TagsBuilder> {
|
||||
TagsBuilder();
|
||||
|
||||
TagsBuilder get _$this {
|
||||
if (_$v != null) {
|
||||
_title = _$v.title;
|
||||
final $v = _$v;
|
||||
if ($v != null) {
|
||||
_title = $v.title;
|
||||
_$v = null;
|
||||
}
|
||||
return this;
|
||||
@@ -109,9 +108,7 @@ class TagsBuilder implements Builder<Tags, TagsBuilder> {
|
||||
|
||||
@override
|
||||
void replace(Tags other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentError.notNull('other');
|
||||
}
|
||||
ArgumentError.checkNotNull(other, 'other');
|
||||
_$v = other as _$Tags;
|
||||
}
|
||||
|
||||
@@ -122,7 +119,10 @@ class TagsBuilder implements Builder<Tags, TagsBuilder> {
|
||||
|
||||
@override
|
||||
_$Tags build() {
|
||||
final _$result = _$v ?? new _$Tags._(title: title);
|
||||
final _$result = _$v ??
|
||||
new _$Tags._(
|
||||
title:
|
||||
BuiltValueNullFieldError.checkNotNull(title, 'Tags', 'title'));
|
||||
replace(_$result);
|
||||
return _$result;
|
||||
}
|
||||
|
||||
@@ -86,13 +86,13 @@ class Unsplash {
|
||||
// https://help.unsplash.com/en/articles/2511258-guideline-triggering-a-download
|
||||
|
||||
_log.info('GET ${photo.urls.full}');
|
||||
final futureBytes = http.readBytes(photo.urls.full, headers: {
|
||||
final futureBytes = http.readBytes(Uri.parse(photo.urls.full), headers: {
|
||||
'Accept-Version': 'v1',
|
||||
'Authorization': 'Client-ID $_accessKey',
|
||||
});
|
||||
|
||||
_log.info('GET ${photo.links.downloadLocation}');
|
||||
unawaited(http.get(photo.links.downloadLocation, headers: {
|
||||
unawaited(http.get(Uri.parse(photo.links.downloadLocation), headers: {
|
||||
'Accept-Version': 'v1',
|
||||
'Authorization': 'Client-ID $_accessKey',
|
||||
}));
|
||||
|
||||
@@ -22,34 +22,40 @@ class _$UrlsSerializer implements StructuredSerializer<Urls> {
|
||||
Iterable<Object> serialize(Serializers serializers, Urls object,
|
||||
{FullType specifiedType = FullType.unspecified}) {
|
||||
final result = <Object>[];
|
||||
if (object.raw != null) {
|
||||
Object value;
|
||||
value = object.raw;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('raw')
|
||||
..add(serializers.serialize(object.raw,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
if (object.full != null) {
|
||||
value = object.full;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('full')
|
||||
..add(serializers.serialize(object.full,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
if (object.regular != null) {
|
||||
value = object.regular;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('regular')
|
||||
..add(serializers.serialize(object.regular,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
if (object.small != null) {
|
||||
value = object.small;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('small')
|
||||
..add(serializers.serialize(object.small,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
if (object.thumb != null) {
|
||||
value = object.thumb;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('thumb')
|
||||
..add(serializers.serialize(object.thumb,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
return result;
|
||||
@@ -64,7 +70,7 @@ class _$UrlsSerializer implements StructuredSerializer<Urls> {
|
||||
while (iterator.moveNext()) {
|
||||
final key = iterator.current as String;
|
||||
iterator.moveNext();
|
||||
final dynamic value = iterator.current;
|
||||
final Object value = iterator.current;
|
||||
switch (key) {
|
||||
case 'raw':
|
||||
result.raw = serializers.deserialize(value,
|
||||
@@ -175,12 +181,13 @@ class UrlsBuilder implements Builder<Urls, UrlsBuilder> {
|
||||
UrlsBuilder();
|
||||
|
||||
UrlsBuilder get _$this {
|
||||
if (_$v != null) {
|
||||
_raw = _$v.raw;
|
||||
_full = _$v.full;
|
||||
_regular = _$v.regular;
|
||||
_small = _$v.small;
|
||||
_thumb = _$v.thumb;
|
||||
final $v = _$v;
|
||||
if ($v != null) {
|
||||
_raw = $v.raw;
|
||||
_full = $v.full;
|
||||
_regular = $v.regular;
|
||||
_small = $v.small;
|
||||
_thumb = $v.thumb;
|
||||
_$v = null;
|
||||
}
|
||||
return this;
|
||||
@@ -188,9 +195,7 @@ class UrlsBuilder implements Builder<Urls, UrlsBuilder> {
|
||||
|
||||
@override
|
||||
void replace(Urls other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentError.notNull('other');
|
||||
}
|
||||
ArgumentError.checkNotNull(other, 'other');
|
||||
_$v = other as _$Urls;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,53 +30,59 @@ class _$UserSerializer implements StructuredSerializer<User> {
|
||||
'name',
|
||||
serializers.serialize(object.name, specifiedType: const FullType(String)),
|
||||
];
|
||||
if (object.updatedAt != null) {
|
||||
Object value;
|
||||
value = object.updatedAt;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('updated_at')
|
||||
..add(serializers.serialize(object.updatedAt,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
if (object.portfolioUrl != null) {
|
||||
value = object.portfolioUrl;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('portfolio_url')
|
||||
..add(serializers.serialize(object.portfolioUrl,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
if (object.bio != null) {
|
||||
value = object.bio;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('bio')
|
||||
..add(serializers.serialize(object.bio,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
if (object.location != null) {
|
||||
value = object.location;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('location')
|
||||
..add(serializers.serialize(object.location,
|
||||
..add(serializers.serialize(value,
|
||||
specifiedType: const FullType(String)));
|
||||
}
|
||||
if (object.totalLikes != null) {
|
||||
value = object.totalLikes;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('total_likes')
|
||||
..add(serializers.serialize(object.totalLikes,
|
||||
specifiedType: const FullType(int)));
|
||||
..add(serializers.serialize(value, specifiedType: const FullType(int)));
|
||||
}
|
||||
if (object.totalPhotos != null) {
|
||||
value = object.totalPhotos;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('total_photos')
|
||||
..add(serializers.serialize(object.totalPhotos,
|
||||
specifiedType: const FullType(int)));
|
||||
..add(serializers.serialize(value, specifiedType: const FullType(int)));
|
||||
}
|
||||
if (object.totalCollections != null) {
|
||||
value = object.totalCollections;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('total_collections')
|
||||
..add(serializers.serialize(object.totalCollections,
|
||||
specifiedType: const FullType(int)));
|
||||
..add(serializers.serialize(value, specifiedType: const FullType(int)));
|
||||
}
|
||||
if (object.links != null) {
|
||||
value = object.links;
|
||||
if (value != null) {
|
||||
result
|
||||
..add('links')
|
||||
..add(serializers.serialize(object.links,
|
||||
specifiedType: const FullType(Links)));
|
||||
..add(
|
||||
serializers.serialize(value, specifiedType: const FullType(Links)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -90,7 +96,7 @@ class _$UserSerializer implements StructuredSerializer<User> {
|
||||
while (iterator.moveNext()) {
|
||||
final key = iterator.current as String;
|
||||
iterator.moveNext();
|
||||
final dynamic value = iterator.current;
|
||||
final Object value = iterator.current;
|
||||
switch (key) {
|
||||
case 'id':
|
||||
result.id = serializers.deserialize(value,
|
||||
@@ -183,15 +189,9 @@ class _$User extends User {
|
||||
this.totalCollections,
|
||||
this.links})
|
||||
: super._() {
|
||||
if (id == null) {
|
||||
throw new BuiltValueNullFieldError('User', 'id');
|
||||
}
|
||||
if (username == null) {
|
||||
throw new BuiltValueNullFieldError('User', 'username');
|
||||
}
|
||||
if (name == null) {
|
||||
throw new BuiltValueNullFieldError('User', 'name');
|
||||
}
|
||||
BuiltValueNullFieldError.checkNotNull(id, 'User', 'id');
|
||||
BuiltValueNullFieldError.checkNotNull(username, 'User', 'username');
|
||||
BuiltValueNullFieldError.checkNotNull(name, 'User', 'name');
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -311,18 +311,19 @@ class UserBuilder implements Builder<User, UserBuilder> {
|
||||
UserBuilder();
|
||||
|
||||
UserBuilder get _$this {
|
||||
if (_$v != null) {
|
||||
_id = _$v.id;
|
||||
_updatedAt = _$v.updatedAt;
|
||||
_username = _$v.username;
|
||||
_name = _$v.name;
|
||||
_portfolioUrl = _$v.portfolioUrl;
|
||||
_bio = _$v.bio;
|
||||
_location = _$v.location;
|
||||
_totalLikes = _$v.totalLikes;
|
||||
_totalPhotos = _$v.totalPhotos;
|
||||
_totalCollections = _$v.totalCollections;
|
||||
_links = _$v.links?.toBuilder();
|
||||
final $v = _$v;
|
||||
if ($v != null) {
|
||||
_id = $v.id;
|
||||
_updatedAt = $v.updatedAt;
|
||||
_username = $v.username;
|
||||
_name = $v.name;
|
||||
_portfolioUrl = $v.portfolioUrl;
|
||||
_bio = $v.bio;
|
||||
_location = $v.location;
|
||||
_totalLikes = $v.totalLikes;
|
||||
_totalPhotos = $v.totalPhotos;
|
||||
_totalCollections = $v.totalCollections;
|
||||
_links = $v.links?.toBuilder();
|
||||
_$v = null;
|
||||
}
|
||||
return this;
|
||||
@@ -330,9 +331,7 @@ class UserBuilder implements Builder<User, UserBuilder> {
|
||||
|
||||
@override
|
||||
void replace(User other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentError.notNull('other');
|
||||
}
|
||||
ArgumentError.checkNotNull(other, 'other');
|
||||
_$v = other as _$User;
|
||||
}
|
||||
|
||||
@@ -347,10 +346,11 @@ class UserBuilder implements Builder<User, UserBuilder> {
|
||||
try {
|
||||
_$result = _$v ??
|
||||
new _$User._(
|
||||
id: id,
|
||||
id: BuiltValueNullFieldError.checkNotNull(id, 'User', 'id'),
|
||||
updatedAt: updatedAt,
|
||||
username: username,
|
||||
name: name,
|
||||
username: BuiltValueNullFieldError.checkNotNull(
|
||||
username, 'User', 'username'),
|
||||
name: BuiltValueNullFieldError.checkNotNull(name, 'User', 'name'),
|
||||
portfolioUrl: portfolioUrl,
|
||||
bio: bio,
|
||||
location: location,
|
||||
|
||||
@@ -3,15 +3,14 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:transparent_image/transparent_image.dart';
|
||||
import 'package:url_launcher/url_launcher.dart' as url_launcher;
|
||||
import 'package:url_launcher/link.dart';
|
||||
|
||||
import '../../unsplash_access_key.dart';
|
||||
import '../unsplash/photo.dart';
|
||||
|
||||
final _unsplashHomepage = Uri.encodeFull(
|
||||
final _unsplashHomepage = Uri.parse(
|
||||
'https://unsplash.com/?utm_source=$unsplashAppName&utm_medium=referral');
|
||||
|
||||
typedef PhotoDetailsPhotoSaveCallback = void Function(Photo);
|
||||
@@ -31,43 +30,26 @@ class PhotoDetails extends StatefulWidget {
|
||||
class _PhotoDetailsState extends State<PhotoDetails>
|
||||
with TickerProviderStateMixin {
|
||||
Widget _buildPhotoAttribution(BuildContext context) {
|
||||
return Expanded(
|
||||
child: RichText(
|
||||
overflow: TextOverflow.fade,
|
||||
text: TextSpan(
|
||||
style: Theme.of(context).textTheme.bodyText2,
|
||||
children: [
|
||||
const TextSpan(text: 'Photo by '),
|
||||
TextSpan(
|
||||
text: widget.photo.user.name,
|
||||
style: const TextStyle(
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () async {
|
||||
final url = Uri.encodeFull(
|
||||
'https://unsplash.com/@${widget.photo.user.username}?utm_source=$unsplashAppName&utm_medium=referral');
|
||||
if (await url_launcher.canLaunch(url)) {
|
||||
await url_launcher.launch(url);
|
||||
}
|
||||
},
|
||||
),
|
||||
const TextSpan(text: ' on '),
|
||||
TextSpan(
|
||||
text: 'Unsplash',
|
||||
style: const TextStyle(
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () async {
|
||||
if (await url_launcher.canLaunch(_unsplashHomepage)) {
|
||||
await url_launcher.launch(_unsplashHomepage);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
return Row(
|
||||
children: [
|
||||
Text('Photo by '),
|
||||
Link(
|
||||
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),
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(' on '),
|
||||
Link(
|
||||
uri: _unsplashHomepage,
|
||||
builder: (context, followLink) => TextButton(
|
||||
onPressed: followLink,
|
||||
child: Text('Unsplash'),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user