Desktop photo search (#174)
@ -0,0 +1,37 @@
|
|||||||
|
# Miscellaneous
|
||||||
|
*.class
|
||||||
|
*.log
|
||||||
|
*.pyc
|
||||||
|
*.swp
|
||||||
|
.DS_Store
|
||||||
|
.atom/
|
||||||
|
.buildlog/
|
||||||
|
.history
|
||||||
|
.svn/
|
||||||
|
|
||||||
|
# IntelliJ related
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# The .vscode folder contains launch configuration and tasks you configure in
|
||||||
|
# VS Code which you may wish to be included in version control, so this line
|
||||||
|
# is commented out by default.
|
||||||
|
#.vscode/
|
||||||
|
|
||||||
|
# Flutter/Dart/Pub related
|
||||||
|
**/doc/api/
|
||||||
|
.dart_tool/
|
||||||
|
.flutter-plugins
|
||||||
|
.flutter-plugins-dependencies
|
||||||
|
.packages
|
||||||
|
.pub-cache/
|
||||||
|
.pub/
|
||||||
|
/build/
|
||||||
|
|
||||||
|
# Web related
|
||||||
|
lib/generated_plugin_registrant.dart
|
||||||
|
|
||||||
|
# Exceptions to above rules.
|
||||||
|
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
|
@ -0,0 +1,10 @@
|
|||||||
|
# This file tracks properties of this Flutter project.
|
||||||
|
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||||
|
#
|
||||||
|
# This file should be version controlled and should not be manually edited.
|
||||||
|
|
||||||
|
version:
|
||||||
|
revision: 7caef218b55acac803aa67e7393e97f75ec70c5c
|
||||||
|
channel: master
|
||||||
|
|
||||||
|
project_type: app
|
@ -0,0 +1,56 @@
|
|||||||
|
# Photo Search app
|
||||||
|
|
||||||
|
This macOS application enables you to search [Unsplash](https://unsplash.com/)
|
||||||
|
for photographs that interest you. To use it, you need to add an
|
||||||
|
**Access Key** from [Unsplash API](https://unsplash.com/developers) to
|
||||||
|
[unsplash_access_key.dart](lib/unsplash_access_key.dart).
|
||||||
|
|
||||||
|
## A quick tour of the code
|
||||||
|
|
||||||
|
This Flutter project builds a desktop application. It utilises the following
|
||||||
|
desktop specific plugins:
|
||||||
|
|
||||||
|
- [file_choser] to enable the application user to select where to save a photo
|
||||||
|
from the Unsplash API.
|
||||||
|
- [menubar] for exposing Image Search functionality through the menu bar.
|
||||||
|
- [url_launcher_fde] and [url_launcher] plugin, which are used to open external links.
|
||||||
|
|
||||||
|
The Unsplash API client entry point is in the [Unsplash] class, and is built
|
||||||
|
atop [http], [built_value] and [built_collection] for JSON Rest API access.
|
||||||
|
|
||||||
|
The [DataTreeNode] and widget family, along with the [Split] widget capture
|
||||||
|
desktop file explorer master/detail view idioms.
|
||||||
|
|
||||||
|
## macOS Network and File entitlements
|
||||||
|
|
||||||
|
To access the network, macOS requires applications enable the
|
||||||
|
[com.apple.security.network.client entitlement][macOS-client]. For this
|
||||||
|
sample, this entitlement is required to access the Unsplash API.
|
||||||
|
|
||||||
|
Likewise, to save a Photo to the local file system using the `file_choser` plugin requires the
|
||||||
|
[com.apple.security.files.user-selected.read-write entitlement][macOS-read-write].
|
||||||
|
|
||||||
|
Please see [macOS Signing and Security][macOS-security] for more detail.
|
||||||
|
|
||||||
|
## Flutter Desktop is not in Flutter Stable Release Channel
|
||||||
|
|
||||||
|
This sample is an initial preview, intended to enable developers to preview what is
|
||||||
|
under development. As such, it is currently only available for use on the `master` channel
|
||||||
|
of Flutter. Please see [Flutter build release channels][flutter_channels] for more detail,
|
||||||
|
and how to switch between Flutter release channels.
|
||||||
|
|
||||||
|
[DataTreeNode]: lib/src/widgets/data_tree.dart
|
||||||
|
[Split]: lib/src/widgets/split.dart
|
||||||
|
[Unsplash]: lib/src/unsplash/unsplash.dart
|
||||||
|
|
||||||
|
[built_collection]: https://pub.dev/packages/built_collection
|
||||||
|
[built_value]: https://pub.dev/packages/built_value
|
||||||
|
[file_choser]: https://github.com/google/flutter-desktop-embedding/tree/master/plugins/file_chooser
|
||||||
|
[flutter_channels]: https://github.com/flutter/flutter/wiki/Flutter-build-release-channels
|
||||||
|
[http]: https://pub.dev/packages/http
|
||||||
|
[macOS-client]: https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_network_client
|
||||||
|
[macOS-read-write]: https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_files_user-selected_read-write
|
||||||
|
[macOS-security]: https://github.com/google/flutter-desktop-embedding/blob/master/macOS-Security.md
|
||||||
|
[menubar]: https://github.com/google/flutter-desktop-embedding/tree/master/plugins/menubar
|
||||||
|
[url_launcher]: https://pub.dev/packages/url_launcher
|
||||||
|
[url_launcher_fde]: https://github.com/google/flutter-desktop-embedding/tree/master/plugins/flutter_plugins/url_launcher_fde
|
@ -0,0 +1,30 @@
|
|||||||
|
include: package:pedantic/analysis_options.1.8.0.yaml
|
||||||
|
|
||||||
|
analyzer:
|
||||||
|
strong-mode:
|
||||||
|
implicit-casts: false
|
||||||
|
implicit-dynamic: false
|
||||||
|
|
||||||
|
linter:
|
||||||
|
rules:
|
||||||
|
- avoid_types_on_closure_parameters
|
||||||
|
- avoid_void_async
|
||||||
|
- await_only_futures
|
||||||
|
- camel_case_types
|
||||||
|
- cancel_subscriptions
|
||||||
|
- close_sinks
|
||||||
|
- constant_identifier_names
|
||||||
|
- control_flow_in_finally
|
||||||
|
- empty_statements
|
||||||
|
- hash_and_equals
|
||||||
|
- implementation_imports
|
||||||
|
- non_constant_identifier_names
|
||||||
|
- package_api_docs
|
||||||
|
- package_names
|
||||||
|
- package_prefixed_library_names
|
||||||
|
- test_types_in_equals
|
||||||
|
- throw_in_finally
|
||||||
|
- unnecessary_brace_in_string_interps
|
||||||
|
- unnecessary_getters_setters
|
||||||
|
- unnecessary_new
|
||||||
|
- unnecessary_statements
|
@ -0,0 +1,15 @@
|
|||||||
|
targets:
|
||||||
|
$default:
|
||||||
|
builders:
|
||||||
|
built_value_generator|built_value:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
builders:
|
||||||
|
built_value:
|
||||||
|
target: ":built_value_generator"
|
||||||
|
import: "package:built_value_generator/builder.dart"
|
||||||
|
builder_factories: ["builtValue"]
|
||||||
|
build_extensions: {".dart": [".built_value.g.part"]}
|
||||||
|
auto_apply: dependents
|
||||||
|
build_to: cache
|
||||||
|
applies_builders: ["source_gen|combining_builder"]
|
@ -0,0 +1,122 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:file_chooser/file_chooser.dart' as file_choser;
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
|
import 'package:menubar/menubar.dart' as menubar;
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
import 'src/model/photo_search_model.dart';
|
||||||
|
import 'src/unsplash/unsplash.dart';
|
||||||
|
import 'src/widgets/data_tree.dart';
|
||||||
|
import 'src/widgets/photo_details.dart';
|
||||||
|
import 'src/widgets/photo_search_dialog.dart';
|
||||||
|
import 'src/widgets/split.dart';
|
||||||
|
import 'unsplash_access_key.dart';
|
||||||
|
|
||||||
|
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}');
|
||||||
|
});
|
||||||
|
|
||||||
|
if (unsplashAccessKey.isEmpty) {
|
||||||
|
Logger('main').severe('Unsplash Access Key is required. '
|
||||||
|
'Please add to `lib/unsplash_access_key.dart`.');
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
runApp(
|
||||||
|
ChangeNotifierProvider<PhotoSearchModel>(
|
||||||
|
create: (context) => PhotoSearchModel(
|
||||||
|
Unsplash(accessKey: unsplashAccessKey),
|
||||||
|
),
|
||||||
|
child: UnsplashSearchApp(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class UnsplashSearchApp extends StatelessWidget {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return MaterialApp(
|
||||||
|
title: 'Photo Search',
|
||||||
|
theme: ThemeData(
|
||||||
|
primarySwatch: Colors.orange,
|
||||||
|
),
|
||||||
|
home: const UnsplashHomePage(title: 'Photo Search'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UnsplashHomePage extends StatelessWidget {
|
||||||
|
const UnsplashHomePage({@required this.title});
|
||||||
|
final String title;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final photoSearchModel = Provider.of<PhotoSearchModel>(context);
|
||||||
|
menubar.setApplicationMenu([
|
||||||
|
menubar.Submenu(label: 'Search', children: [
|
||||||
|
menubar.MenuItem(
|
||||||
|
label: 'Search ...',
|
||||||
|
onClicked: () {
|
||||||
|
showDialog<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (context) =>
|
||||||
|
PhotoSearchDialog(photoSearchModel.addSearch),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
])
|
||||||
|
]);
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text(title),
|
||||||
|
),
|
||||||
|
body: photoSearchModel.entries.isNotEmpty
|
||||||
|
? Split(
|
||||||
|
axis: Axis.horizontal,
|
||||||
|
initialFirstFraction: 0.4,
|
||||||
|
firstChild: DataTree(photoSearchModel.entries),
|
||||||
|
secondChild: Center(
|
||||||
|
child: photoSearchModel.selectedPhoto != null
|
||||||
|
? PhotoDetails(
|
||||||
|
photo: photoSearchModel.selectedPhoto,
|
||||||
|
onPhotoSave: (photo) async {
|
||||||
|
final result = await file_choser.showSavePanel(
|
||||||
|
suggestedFileName: '${photo.id}.jpg',
|
||||||
|
allowedFileTypes: ['jpg'],
|
||||||
|
);
|
||||||
|
if (!result.canceled) {
|
||||||
|
final bytes =
|
||||||
|
await photoSearchModel.download(photo: photo);
|
||||||
|
await File(result.paths[0]).writeAsBytes(bytes);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
: Container(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: const Center(
|
||||||
|
child: Text('Search for Photos using the Fab button'),
|
||||||
|
),
|
||||||
|
floatingActionButton: FloatingActionButton(
|
||||||
|
onPressed: () => showDialog<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => PhotoSearchDialog(photoSearchModel.addSearch),
|
||||||
|
),
|
||||||
|
tooltip: 'Search for a photo',
|
||||||
|
child: Icon(Icons.search),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
|
||||||
|
import '../unsplash/photo.dart';
|
||||||
|
import '../unsplash/unsplash.dart';
|
||||||
|
import '../widgets/data_tree.dart' show Entry;
|
||||||
|
import 'search.dart';
|
||||||
|
|
||||||
|
class _PhotoEntry extends Entry {
|
||||||
|
_PhotoEntry(this._photo, this._model) : super('Photo by ${_photo.user.name}');
|
||||||
|
|
||||||
|
final Photo _photo;
|
||||||
|
final PhotoSearchModel _model;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get isSelected => false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
set isSelected(bool selected) {
|
||||||
|
_model._setSelectedPhoto(_photo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SearchEntry extends Entry {
|
||||||
|
_SearchEntry(String query, List<Photo> photos, PhotoSearchModel model)
|
||||||
|
: super(
|
||||||
|
query,
|
||||||
|
List<Entry>.unmodifiable(
|
||||||
|
photos.map<Entry>((photo) => _PhotoEntry(photo, model)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class PhotoSearchModel extends ChangeNotifier {
|
||||||
|
PhotoSearchModel(this._client);
|
||||||
|
final Unsplash _client;
|
||||||
|
|
||||||
|
List<Entry> get entries => List.unmodifiable(_entries);
|
||||||
|
final List<Entry> _entries = <Entry>[];
|
||||||
|
|
||||||
|
Photo get selectedPhoto => _selectedPhoto;
|
||||||
|
void _setSelectedPhoto(Photo photo) {
|
||||||
|
_selectedPhoto = photo;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
Photo _selectedPhoto;
|
||||||
|
|
||||||
|
Future<void> addSearch(String query) async {
|
||||||
|
final result = await _client.searchPhotos(
|
||||||
|
query: query,
|
||||||
|
orientation: SearchPhotosOrientation.portrait,
|
||||||
|
);
|
||||||
|
final search = Search((s) {
|
||||||
|
s
|
||||||
|
..query = query
|
||||||
|
..results.addAll(result.results);
|
||||||
|
});
|
||||||
|
|
||||||
|
_entries.add(_SearchEntry(query, search.results.toList(), this));
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Uint8List> download({@required Photo photo}) =>
|
||||||
|
_client.download(photo);
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:built_collection/built_collection.dart';
|
||||||
|
import 'package:built_value/built_value.dart';
|
||||||
|
import 'package:built_value/serializer.dart';
|
||||||
|
|
||||||
|
import '../serializers.dart';
|
||||||
|
import '../unsplash/photo.dart';
|
||||||
|
|
||||||
|
part 'search.g.dart';
|
||||||
|
|
||||||
|
abstract class Search implements Built<Search, SearchBuilder> {
|
||||||
|
factory Search([void Function(SearchBuilder) updates]) = _$Search;
|
||||||
|
Search._();
|
||||||
|
|
||||||
|
@BuiltValueField(wireName: 'query')
|
||||||
|
String get query;
|
||||||
|
|
||||||
|
@BuiltValueField(wireName: 'results')
|
||||||
|
BuiltList<Photo> get results;
|
||||||
|
|
||||||
|
String toJson() {
|
||||||
|
return json.encode(serializers.serializeWith(Search.serializer, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Search fromJson(String jsonString) {
|
||||||
|
return serializers.deserializeWith(
|
||||||
|
Search.serializer, json.decode(jsonString));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Serializer<Search> get serializer => _$searchSerializer;
|
||||||
|
}
|
@ -0,0 +1,167 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'search.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// BuiltValueGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
Serializer<Search> _$searchSerializer = new _$SearchSerializer();
|
||||||
|
|
||||||
|
class _$SearchSerializer implements StructuredSerializer<Search> {
|
||||||
|
@override
|
||||||
|
final Iterable<Type> types = const [Search, _$Search];
|
||||||
|
@override
|
||||||
|
final String wireName = 'Search';
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<Object> serialize(Serializers serializers, Search object,
|
||||||
|
{FullType specifiedType = FullType.unspecified}) {
|
||||||
|
final result = <Object>[
|
||||||
|
'query',
|
||||||
|
serializers.serialize(object.query,
|
||||||
|
specifiedType: const FullType(String)),
|
||||||
|
'results',
|
||||||
|
serializers.serialize(object.results,
|
||||||
|
specifiedType:
|
||||||
|
const FullType(BuiltList, const [const FullType(Photo)])),
|
||||||
|
];
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Search deserialize(Serializers serializers, Iterable<Object> serialized,
|
||||||
|
{FullType specifiedType = FullType.unspecified}) {
|
||||||
|
final result = new SearchBuilder();
|
||||||
|
|
||||||
|
final iterator = serialized.iterator;
|
||||||
|
while (iterator.moveNext()) {
|
||||||
|
final key = iterator.current as String;
|
||||||
|
iterator.moveNext();
|
||||||
|
final dynamic value = iterator.current;
|
||||||
|
switch (key) {
|
||||||
|
case 'query':
|
||||||
|
result.query = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'results':
|
||||||
|
result.results.replace(serializers.deserialize(value,
|
||||||
|
specifiedType:
|
||||||
|
const FullType(BuiltList, const [const FullType(Photo)]))
|
||||||
|
as BuiltList<dynamic>);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _$Search extends Search {
|
||||||
|
@override
|
||||||
|
final String query;
|
||||||
|
@override
|
||||||
|
final BuiltList<Photo> results;
|
||||||
|
|
||||||
|
factory _$Search([void Function(SearchBuilder) updates]) =>
|
||||||
|
(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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Search rebuild(void Function(SearchBuilder) updates) =>
|
||||||
|
(toBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
@override
|
||||||
|
SearchBuilder toBuilder() => new SearchBuilder()..replace(this);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(other, this)) return true;
|
||||||
|
return other is Search && query == other.query && results == other.results;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return $jf($jc($jc(0, query.hashCode), results.hashCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (newBuiltValueToStringHelper('Search')
|
||||||
|
..add('query', query)
|
||||||
|
..add('results', results))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SearchBuilder implements Builder<Search, SearchBuilder> {
|
||||||
|
_$Search _$v;
|
||||||
|
|
||||||
|
String _query;
|
||||||
|
String get query => _$this._query;
|
||||||
|
set query(String query) => _$this._query = query;
|
||||||
|
|
||||||
|
ListBuilder<Photo> _results;
|
||||||
|
ListBuilder<Photo> get results =>
|
||||||
|
_$this._results ??= new ListBuilder<Photo>();
|
||||||
|
set results(ListBuilder<Photo> results) => _$this._results = results;
|
||||||
|
|
||||||
|
SearchBuilder();
|
||||||
|
|
||||||
|
SearchBuilder get _$this {
|
||||||
|
if (_$v != null) {
|
||||||
|
_query = _$v.query;
|
||||||
|
_results = _$v.results?.toBuilder();
|
||||||
|
_$v = null;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void replace(Search other) {
|
||||||
|
if (other == null) {
|
||||||
|
throw new ArgumentError.notNull('other');
|
||||||
|
}
|
||||||
|
_$v = other as _$Search;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void update(void Function(SearchBuilder) updates) {
|
||||||
|
if (updates != null) updates(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
_$Search build() {
|
||||||
|
_$Search _$result;
|
||||||
|
try {
|
||||||
|
_$result = _$v ?? new _$Search._(query: query, results: results.build());
|
||||||
|
} catch (_) {
|
||||||
|
String _$failedField;
|
||||||
|
try {
|
||||||
|
_$failedField = 'results';
|
||||||
|
results.build();
|
||||||
|
} catch (e) {
|
||||||
|
throw new BuiltValueNestedFieldError(
|
||||||
|
'Search', _$failedField, e.toString());
|
||||||
|
}
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
replace(_$result);
|
||||||
|
return _$result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore_for_file: always_put_control_body_on_new_line,always_specify_types,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,lines_longer_than_80_chars,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new
|
@ -0,0 +1,27 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'package:built_value/serializer.dart';
|
||||||
|
import 'package:built_value/standard_json_plugin.dart';
|
||||||
|
import 'package:built_collection/built_collection.dart';
|
||||||
|
|
||||||
|
import 'model/search.dart';
|
||||||
|
import 'unsplash/api_error.dart';
|
||||||
|
import 'unsplash/current_user_collections.dart';
|
||||||
|
import 'unsplash/exif.dart';
|
||||||
|
import 'unsplash/links.dart';
|
||||||
|
import 'unsplash/location.dart';
|
||||||
|
import 'unsplash/photo.dart';
|
||||||
|
import 'unsplash/position.dart';
|
||||||
|
import 'unsplash/search_photos_response.dart';
|
||||||
|
import 'unsplash/tags.dart';
|
||||||
|
import 'unsplash/urls.dart';
|
||||||
|
import 'unsplash/user.dart';
|
||||||
|
|
||||||
|
part 'serializers.g.dart';
|
||||||
|
|
||||||
|
//add all of the built value types that require serialization
|
||||||
|
@SerializersFor([Search, ApiError, Photo, SearchPhotosResponse])
|
||||||
|
final Serializers serializers =
|
||||||
|
(_$serializers.toBuilder()..addPlugin(StandardJsonPlugin())).build();
|
@ -0,0 +1,44 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'serializers.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// BuiltValueGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
Serializers _$serializers = (new Serializers().toBuilder()
|
||||||
|
..add(ApiError.serializer)
|
||||||
|
..add(CurrentUserCollections.serializer)
|
||||||
|
..add(Exif.serializer)
|
||||||
|
..add(Links.serializer)
|
||||||
|
..add(Location.serializer)
|
||||||
|
..add(Photo.serializer)
|
||||||
|
..add(Position.serializer)
|
||||||
|
..add(Search.serializer)
|
||||||
|
..add(SearchPhotosResponse.serializer)
|
||||||
|
..add(Tags.serializer)
|
||||||
|
..add(Urls.serializer)
|
||||||
|
..add(User.serializer)
|
||||||
|
..addBuilderFactory(
|
||||||
|
const FullType(BuiltList, const [const FullType(Photo)]),
|
||||||
|
() => new ListBuilder<Photo>())
|
||||||
|
..addBuilderFactory(
|
||||||
|
const FullType(BuiltList, const [const FullType(Photo)]),
|
||||||
|
() => new ListBuilder<Photo>())
|
||||||
|
..addBuilderFactory(
|
||||||
|
const FullType(BuiltList, const [const FullType(String)]),
|
||||||
|
() => new ListBuilder<String>())
|
||||||
|
..addBuilderFactory(
|
||||||
|
const FullType(BuiltList, const [const FullType(Tags)]),
|
||||||
|
() => new ListBuilder<Tags>())
|
||||||
|
..addBuilderFactory(
|
||||||
|
const FullType(
|
||||||
|
BuiltList, const [const FullType(CurrentUserCollections)]),
|
||||||
|
() => new ListBuilder<CurrentUserCollections>()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// ignore_for_file: always_put_control_body_on_new_line,always_specify_types,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,lines_longer_than_80_chars,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new
|
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:built_collection/built_collection.dart';
|
||||||
|
import 'package:built_value/built_value.dart';
|
||||||
|
import 'package:built_value/serializer.dart';
|
||||||
|
|
||||||
|
import '../serializers.dart';
|
||||||
|
|
||||||
|
part 'api_error.g.dart';
|
||||||
|
|
||||||
|
abstract class ApiError implements Built<ApiError, ApiErrorBuilder> {
|
||||||
|
factory ApiError([void Function(ApiErrorBuilder) updates]) = _$ApiError;
|
||||||
|
|
||||||
|
ApiError._();
|
||||||
|
|
||||||
|
@BuiltValueField(wireName: 'errors')
|
||||||
|
BuiltList<String> get errors;
|
||||||
|
|
||||||
|
String toJson() {
|
||||||
|
return json.encode(serializers.serializeWith(ApiError.serializer, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
static ApiError fromJson(String jsonString) {
|
||||||
|
return serializers.deserializeWith(
|
||||||
|
ApiError.serializer, json.decode(jsonString));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Serializer<ApiError> get serializer => _$apiErrorSerializer;
|
||||||
|
}
|
@ -0,0 +1,148 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'api_error.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// BuiltValueGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
Serializer<ApiError> _$apiErrorSerializer = new _$ApiErrorSerializer();
|
||||||
|
|
||||||
|
class _$ApiErrorSerializer implements StructuredSerializer<ApiError> {
|
||||||
|
@override
|
||||||
|
final Iterable<Type> types = const [ApiError, _$ApiError];
|
||||||
|
@override
|
||||||
|
final String wireName = 'ApiError';
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<Object> serialize(Serializers serializers, ApiError object,
|
||||||
|
{FullType specifiedType = FullType.unspecified}) {
|
||||||
|
final result = <Object>[
|
||||||
|
'errors',
|
||||||
|
serializers.serialize(object.errors,
|
||||||
|
specifiedType:
|
||||||
|
const FullType(BuiltList, const [const FullType(String)])),
|
||||||
|
];
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
ApiError deserialize(Serializers serializers, Iterable<Object> serialized,
|
||||||
|
{FullType specifiedType = FullType.unspecified}) {
|
||||||
|
final result = new ApiErrorBuilder();
|
||||||
|
|
||||||
|
final iterator = serialized.iterator;
|
||||||
|
while (iterator.moveNext()) {
|
||||||
|
final key = iterator.current as String;
|
||||||
|
iterator.moveNext();
|
||||||
|
final dynamic value = iterator.current;
|
||||||
|
switch (key) {
|
||||||
|
case 'errors':
|
||||||
|
result.errors.replace(serializers.deserialize(value,
|
||||||
|
specifiedType:
|
||||||
|
const FullType(BuiltList, const [const FullType(String)]))
|
||||||
|
as BuiltList<dynamic>);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _$ApiError extends ApiError {
|
||||||
|
@override
|
||||||
|
final BuiltList<String> errors;
|
||||||
|
|
||||||
|
factory _$ApiError([void Function(ApiErrorBuilder) updates]) =>
|
||||||
|
(new ApiErrorBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
_$ApiError._({this.errors}) : super._() {
|
||||||
|
if (errors == null) {
|
||||||
|
throw new BuiltValueNullFieldError('ApiError', 'errors');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
ApiError rebuild(void Function(ApiErrorBuilder) updates) =>
|
||||||
|
(toBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
@override
|
||||||
|
ApiErrorBuilder toBuilder() => new ApiErrorBuilder()..replace(this);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(other, this)) return true;
|
||||||
|
return other is ApiError && errors == other.errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return $jf($jc(0, errors.hashCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (newBuiltValueToStringHelper('ApiError')..add('errors', errors))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ApiErrorBuilder implements Builder<ApiError, ApiErrorBuilder> {
|
||||||
|
_$ApiError _$v;
|
||||||
|
|
||||||
|
ListBuilder<String> _errors;
|
||||||
|
ListBuilder<String> get errors =>
|
||||||
|
_$this._errors ??= new ListBuilder<String>();
|
||||||
|
set errors(ListBuilder<String> errors) => _$this._errors = errors;
|
||||||
|
|
||||||
|
ApiErrorBuilder();
|
||||||
|
|
||||||
|
ApiErrorBuilder get _$this {
|
||||||
|
if (_$v != null) {
|
||||||
|
_errors = _$v.errors?.toBuilder();
|
||||||
|
_$v = null;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void replace(ApiError other) {
|
||||||
|
if (other == null) {
|
||||||
|
throw new ArgumentError.notNull('other');
|
||||||
|
}
|
||||||
|
_$v = other as _$ApiError;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void update(void Function(ApiErrorBuilder) updates) {
|
||||||
|
if (updates != null) updates(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
_$ApiError build() {
|
||||||
|
_$ApiError _$result;
|
||||||
|
try {
|
||||||
|
_$result = _$v ?? new _$ApiError._(errors: errors.build());
|
||||||
|
} catch (_) {
|
||||||
|
String _$failedField;
|
||||||
|
try {
|
||||||
|
_$failedField = 'errors';
|
||||||
|
errors.build();
|
||||||
|
} catch (e) {
|
||||||
|
throw new BuiltValueNestedFieldError(
|
||||||
|
'ApiError', _$failedField, e.toString());
|
||||||
|
}
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
replace(_$result);
|
||||||
|
return _$result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore_for_file: always_put_control_body_on_new_line,always_specify_types,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,lines_longer_than_80_chars,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new
|
@ -0,0 +1,49 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:built_value/built_value.dart';
|
||||||
|
import 'package:built_value/serializer.dart';
|
||||||
|
|
||||||
|
import '../serializers.dart';
|
||||||
|
|
||||||
|
part 'current_user_collections.g.dart';
|
||||||
|
|
||||||
|
abstract class CurrentUserCollections
|
||||||
|
implements Built<CurrentUserCollections, CurrentUserCollectionsBuilder> {
|
||||||
|
factory CurrentUserCollections(
|
||||||
|
[void Function(CurrentUserCollectionsBuilder) updates]) =
|
||||||
|
_$CurrentUserCollections;
|
||||||
|
|
||||||
|
CurrentUserCollections._();
|
||||||
|
|
||||||
|
@BuiltValueField(wireName: 'id')
|
||||||
|
int get id;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'title')
|
||||||
|
String get title;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'published_at')
|
||||||
|
String get publishedAt;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'updated_at')
|
||||||
|
String get updatedAt;
|
||||||
|
|
||||||
|
String toJson() {
|
||||||
|
return json.encode(
|
||||||
|
serializers.serializeWith(CurrentUserCollections.serializer, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
static CurrentUserCollections fromJson(String jsonString) {
|
||||||
|
return serializers.deserializeWith(
|
||||||
|
CurrentUserCollections.serializer, json.decode(jsonString));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Serializer<CurrentUserCollections> get serializer =>
|
||||||
|
_$currentUserCollectionsSerializer;
|
||||||
|
}
|
@ -0,0 +1,208 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'current_user_collections.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// BuiltValueGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
Serializer<CurrentUserCollections> _$currentUserCollectionsSerializer =
|
||||||
|
new _$CurrentUserCollectionsSerializer();
|
||||||
|
|
||||||
|
class _$CurrentUserCollectionsSerializer
|
||||||
|
implements StructuredSerializer<CurrentUserCollections> {
|
||||||
|
@override
|
||||||
|
final Iterable<Type> types = const [
|
||||||
|
CurrentUserCollections,
|
||||||
|
_$CurrentUserCollections
|
||||||
|
];
|
||||||
|
@override
|
||||||
|
final String wireName = 'CurrentUserCollections';
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<Object> serialize(
|
||||||
|
Serializers serializers, CurrentUserCollections object,
|
||||||
|
{FullType specifiedType = FullType.unspecified}) {
|
||||||
|
final result = <Object>[
|
||||||
|
'id',
|
||||||
|
serializers.serialize(object.id, specifiedType: const FullType(int)),
|
||||||
|
];
|
||||||
|
if (object.title != null) {
|
||||||
|
result
|
||||||
|
..add('title')
|
||||||
|
..add(serializers.serialize(object.title,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
if (object.publishedAt != null) {
|
||||||
|
result
|
||||||
|
..add('published_at')
|
||||||
|
..add(serializers.serialize(object.publishedAt,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
if (object.updatedAt != null) {
|
||||||
|
result
|
||||||
|
..add('updated_at')
|
||||||
|
..add(serializers.serialize(object.updatedAt,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
CurrentUserCollections deserialize(
|
||||||
|
Serializers serializers, Iterable<Object> serialized,
|
||||||
|
{FullType specifiedType = FullType.unspecified}) {
|
||||||
|
final result = new CurrentUserCollectionsBuilder();
|
||||||
|
|
||||||
|
final iterator = serialized.iterator;
|
||||||
|
while (iterator.moveNext()) {
|
||||||
|
final key = iterator.current as String;
|
||||||
|
iterator.moveNext();
|
||||||
|
final dynamic value = iterator.current;
|
||||||
|
switch (key) {
|
||||||
|
case 'id':
|
||||||
|
result.id = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(int)) as int;
|
||||||
|
break;
|
||||||
|
case 'title':
|
||||||
|
result.title = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'published_at':
|
||||||
|
result.publishedAt = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'updated_at':
|
||||||
|
result.updatedAt = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _$CurrentUserCollections extends CurrentUserCollections {
|
||||||
|
@override
|
||||||
|
final int id;
|
||||||
|
@override
|
||||||
|
final String title;
|
||||||
|
@override
|
||||||
|
final String publishedAt;
|
||||||
|
@override
|
||||||
|
final String updatedAt;
|
||||||
|
|
||||||
|
factory _$CurrentUserCollections(
|
||||||
|
[void Function(CurrentUserCollectionsBuilder) updates]) =>
|
||||||
|
(new CurrentUserCollectionsBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
_$CurrentUserCollections._(
|
||||||
|
{this.id, this.title, this.publishedAt, this.updatedAt})
|
||||||
|
: super._() {
|
||||||
|
if (id == null) {
|
||||||
|
throw new BuiltValueNullFieldError('CurrentUserCollections', 'id');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
CurrentUserCollections rebuild(
|
||||||
|
void Function(CurrentUserCollectionsBuilder) updates) =>
|
||||||
|
(toBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
@override
|
||||||
|
CurrentUserCollectionsBuilder toBuilder() =>
|
||||||
|
new CurrentUserCollectionsBuilder()..replace(this);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(other, this)) return true;
|
||||||
|
return other is CurrentUserCollections &&
|
||||||
|
id == other.id &&
|
||||||
|
title == other.title &&
|
||||||
|
publishedAt == other.publishedAt &&
|
||||||
|
updatedAt == other.updatedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return $jf($jc(
|
||||||
|
$jc($jc($jc(0, id.hashCode), title.hashCode), publishedAt.hashCode),
|
||||||
|
updatedAt.hashCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (newBuiltValueToStringHelper('CurrentUserCollections')
|
||||||
|
..add('id', id)
|
||||||
|
..add('title', title)
|
||||||
|
..add('publishedAt', publishedAt)
|
||||||
|
..add('updatedAt', updatedAt))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CurrentUserCollectionsBuilder
|
||||||
|
implements Builder<CurrentUserCollections, CurrentUserCollectionsBuilder> {
|
||||||
|
_$CurrentUserCollections _$v;
|
||||||
|
|
||||||
|
int _id;
|
||||||
|
int get id => _$this._id;
|
||||||
|
set id(int id) => _$this._id = id;
|
||||||
|
|
||||||
|
String _title;
|
||||||
|
String get title => _$this._title;
|
||||||
|
set title(String title) => _$this._title = title;
|
||||||
|
|
||||||
|
String _publishedAt;
|
||||||
|
String get publishedAt => _$this._publishedAt;
|
||||||
|
set publishedAt(String publishedAt) => _$this._publishedAt = publishedAt;
|
||||||
|
|
||||||
|
String _updatedAt;
|
||||||
|
String get updatedAt => _$this._updatedAt;
|
||||||
|
set updatedAt(String updatedAt) => _$this._updatedAt = updatedAt;
|
||||||
|
|
||||||
|
CurrentUserCollectionsBuilder();
|
||||||
|
|
||||||
|
CurrentUserCollectionsBuilder get _$this {
|
||||||
|
if (_$v != null) {
|
||||||
|
_id = _$v.id;
|
||||||
|
_title = _$v.title;
|
||||||
|
_publishedAt = _$v.publishedAt;
|
||||||
|
_updatedAt = _$v.updatedAt;
|
||||||
|
_$v = null;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void replace(CurrentUserCollections other) {
|
||||||
|
if (other == null) {
|
||||||
|
throw new ArgumentError.notNull('other');
|
||||||
|
}
|
||||||
|
_$v = other as _$CurrentUserCollections;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void update(void Function(CurrentUserCollectionsBuilder) updates) {
|
||||||
|
if (updates != null) updates(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
_$CurrentUserCollections build() {
|
||||||
|
final _$result = _$v ??
|
||||||
|
new _$CurrentUserCollections._(
|
||||||
|
id: id,
|
||||||
|
title: title,
|
||||||
|
publishedAt: publishedAt,
|
||||||
|
updatedAt: updatedAt);
|
||||||
|
replace(_$result);
|
||||||
|
return _$result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore_for_file: always_put_control_body_on_new_line,always_specify_types,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,lines_longer_than_80_chars,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new
|
@ -0,0 +1,53 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:built_value/built_value.dart';
|
||||||
|
import 'package:built_value/serializer.dart';
|
||||||
|
|
||||||
|
import '../serializers.dart';
|
||||||
|
|
||||||
|
part 'exif.g.dart';
|
||||||
|
|
||||||
|
abstract class Exif implements Built<Exif, ExifBuilder> {
|
||||||
|
factory Exif([void Function(ExifBuilder) updates]) = _$Exif;
|
||||||
|
|
||||||
|
Exif._();
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'make')
|
||||||
|
String get make;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'model')
|
||||||
|
String get model;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'exposure_time')
|
||||||
|
String get exposureTime;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'aperture')
|
||||||
|
String get aperture;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'focal_length')
|
||||||
|
String get focalLength;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'iso')
|
||||||
|
int get iso;
|
||||||
|
|
||||||
|
String toJson() {
|
||||||
|
return json.encode(serializers.serializeWith(Exif.serializer, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Exif fromJson(String jsonString) {
|
||||||
|
return serializers.deserializeWith(
|
||||||
|
Exif.serializer, json.decode(jsonString));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Serializer<Exif> get serializer => _$exifSerializer;
|
||||||
|
}
|
@ -0,0 +1,246 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'exif.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// BuiltValueGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
Serializer<Exif> _$exifSerializer = new _$ExifSerializer();
|
||||||
|
|
||||||
|
class _$ExifSerializer implements StructuredSerializer<Exif> {
|
||||||
|
@override
|
||||||
|
final Iterable<Type> types = const [Exif, _$Exif];
|
||||||
|
@override
|
||||||
|
final String wireName = 'Exif';
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<Object> serialize(Serializers serializers, Exif object,
|
||||||
|
{FullType specifiedType = FullType.unspecified}) {
|
||||||
|
final result = <Object>[];
|
||||||
|
if (object.make != null) {
|
||||||
|
result
|
||||||
|
..add('make')
|
||||||
|
..add(serializers.serialize(object.make,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
if (object.model != null) {
|
||||||
|
result
|
||||||
|
..add('model')
|
||||||
|
..add(serializers.serialize(object.model,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
if (object.exposureTime != null) {
|
||||||
|
result
|
||||||
|
..add('exposure_time')
|
||||||
|
..add(serializers.serialize(object.exposureTime,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
if (object.aperture != null) {
|
||||||
|
result
|
||||||
|
..add('aperture')
|
||||||
|
..add(serializers.serialize(object.aperture,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
if (object.focalLength != null) {
|
||||||
|
result
|
||||||
|
..add('focal_length')
|
||||||
|
..add(serializers.serialize(object.focalLength,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
if (object.iso != null) {
|
||||||
|
result
|
||||||
|
..add('iso')
|
||||||
|
..add(serializers.serialize(object.iso,
|
||||||
|
specifiedType: const FullType(int)));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Exif deserialize(Serializers serializers, Iterable<Object> serialized,
|
||||||
|
{FullType specifiedType = FullType.unspecified}) {
|
||||||
|
final result = new ExifBuilder();
|
||||||
|
|
||||||
|
final iterator = serialized.iterator;
|
||||||
|
while (iterator.moveNext()) {
|
||||||
|
final key = iterator.current as String;
|
||||||
|
iterator.moveNext();
|
||||||
|
final dynamic value = iterator.current;
|
||||||
|
switch (key) {
|
||||||
|
case 'make':
|
||||||
|
result.make = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'model':
|
||||||
|
result.model = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'exposure_time':
|
||||||
|
result.exposureTime = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'aperture':
|
||||||
|
result.aperture = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'focal_length':
|
||||||
|
result.focalLength = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'iso':
|
||||||
|
result.iso = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(int)) as int;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _$Exif extends Exif {
|
||||||
|
@override
|
||||||
|
final String make;
|
||||||
|
@override
|
||||||
|
final String model;
|
||||||
|
@override
|
||||||
|
final String exposureTime;
|
||||||
|
@override
|
||||||
|
final String aperture;
|
||||||
|
@override
|
||||||
|
final String focalLength;
|
||||||
|
@override
|
||||||
|
final int iso;
|
||||||
|
|
||||||
|
factory _$Exif([void Function(ExifBuilder) updates]) =>
|
||||||
|
(new ExifBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
_$Exif._(
|
||||||
|
{this.make,
|
||||||
|
this.model,
|
||||||
|
this.exposureTime,
|
||||||
|
this.aperture,
|
||||||
|
this.focalLength,
|
||||||
|
this.iso})
|
||||||
|
: super._();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Exif rebuild(void Function(ExifBuilder) updates) =>
|
||||||
|
(toBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
@override
|
||||||
|
ExifBuilder toBuilder() => new ExifBuilder()..replace(this);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(other, this)) return true;
|
||||||
|
return other is Exif &&
|
||||||
|
make == other.make &&
|
||||||
|
model == other.model &&
|
||||||
|
exposureTime == other.exposureTime &&
|
||||||
|
aperture == other.aperture &&
|
||||||
|
focalLength == other.focalLength &&
|
||||||
|
iso == other.iso;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return $jf($jc(
|
||||||
|
$jc(
|
||||||
|
$jc(
|
||||||
|
$jc($jc($jc(0, make.hashCode), model.hashCode),
|
||||||
|
exposureTime.hashCode),
|
||||||
|
aperture.hashCode),
|
||||||
|
focalLength.hashCode),
|
||||||
|
iso.hashCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (newBuiltValueToStringHelper('Exif')
|
||||||
|
..add('make', make)
|
||||||
|
..add('model', model)
|
||||||
|
..add('exposureTime', exposureTime)
|
||||||
|
..add('aperture', aperture)
|
||||||
|
..add('focalLength', focalLength)
|
||||||
|
..add('iso', iso))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ExifBuilder implements Builder<Exif, ExifBuilder> {
|
||||||
|
_$Exif _$v;
|
||||||
|
|
||||||
|
String _make;
|
||||||
|
String get make => _$this._make;
|
||||||
|
set make(String make) => _$this._make = make;
|
||||||
|
|
||||||
|
String _model;
|
||||||
|
String get model => _$this._model;
|
||||||
|
set model(String model) => _$this._model = model;
|
||||||
|
|
||||||
|
String _exposureTime;
|
||||||
|
String get exposureTime => _$this._exposureTime;
|
||||||
|
set exposureTime(String exposureTime) => _$this._exposureTime = exposureTime;
|
||||||
|
|
||||||
|
String _aperture;
|
||||||
|
String get aperture => _$this._aperture;
|
||||||
|
set aperture(String aperture) => _$this._aperture = aperture;
|
||||||
|
|
||||||
|
String _focalLength;
|
||||||
|
String get focalLength => _$this._focalLength;
|
||||||
|
set focalLength(String focalLength) => _$this._focalLength = focalLength;
|
||||||
|
|
||||||
|
int _iso;
|
||||||
|
int get iso => _$this._iso;
|
||||||
|
set iso(int iso) => _$this._iso = iso;
|
||||||
|
|
||||||
|
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;
|
||||||
|
_$v = null;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void replace(Exif other) {
|
||||||
|
if (other == null) {
|
||||||
|
throw new ArgumentError.notNull('other');
|
||||||
|
}
|
||||||
|
_$v = other as _$Exif;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void update(void Function(ExifBuilder) updates) {
|
||||||
|
if (updates != null) updates(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
_$Exif build() {
|
||||||
|
final _$result = _$v ??
|
||||||
|
new _$Exif._(
|
||||||
|
make: make,
|
||||||
|
model: model,
|
||||||
|
exposureTime: exposureTime,
|
||||||
|
aperture: aperture,
|
||||||
|
focalLength: focalLength,
|
||||||
|
iso: iso);
|
||||||
|
replace(_$result);
|
||||||
|
return _$result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore_for_file: always_put_control_body_on_new_line,always_specify_types,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,lines_longer_than_80_chars,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new
|
@ -0,0 +1,45 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:built_value/built_value.dart';
|
||||||
|
import 'package:built_value/serializer.dart';
|
||||||
|
|
||||||
|
import '../serializers.dart';
|
||||||
|
|
||||||
|
part 'links.g.dart';
|
||||||
|
|
||||||
|
abstract class Links implements Built<Links, LinksBuilder> {
|
||||||
|
factory Links([void Function(LinksBuilder) updates]) = _$Links;
|
||||||
|
|
||||||
|
Links._();
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'self')
|
||||||
|
String get self;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'html')
|
||||||
|
String get html;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'download')
|
||||||
|
String get download;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'download_location')
|
||||||
|
String get downloadLocation;
|
||||||
|
|
||||||
|
String toJson() {
|
||||||
|
return json.encode(serializers.serializeWith(Links.serializer, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Links fromJson(String jsonString) {
|
||||||
|
return serializers.deserializeWith(
|
||||||
|
Links.serializer, json.decode(jsonString));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Serializer<Links> get serializer => _$linksSerializer;
|
||||||
|
}
|
@ -0,0 +1,196 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'links.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// BuiltValueGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
Serializer<Links> _$linksSerializer = new _$LinksSerializer();
|
||||||
|
|
||||||
|
class _$LinksSerializer implements StructuredSerializer<Links> {
|
||||||
|
@override
|
||||||
|
final Iterable<Type> types = const [Links, _$Links];
|
||||||
|
@override
|
||||||
|
final String wireName = 'Links';
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<Object> serialize(Serializers serializers, Links object,
|
||||||
|
{FullType specifiedType = FullType.unspecified}) {
|
||||||
|
final result = <Object>[];
|
||||||
|
if (object.self != null) {
|
||||||
|
result
|
||||||
|
..add('self')
|
||||||
|
..add(serializers.serialize(object.self,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
if (object.html != null) {
|
||||||
|
result
|
||||||
|
..add('html')
|
||||||
|
..add(serializers.serialize(object.html,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
if (object.download != null) {
|
||||||
|
result
|
||||||
|
..add('download')
|
||||||
|
..add(serializers.serialize(object.download,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
if (object.downloadLocation != null) {
|
||||||
|
result
|
||||||
|
..add('download_location')
|
||||||
|
..add(serializers.serialize(object.downloadLocation,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Links deserialize(Serializers serializers, Iterable<Object> serialized,
|
||||||
|
{FullType specifiedType = FullType.unspecified}) {
|
||||||
|
final result = new LinksBuilder();
|
||||||
|
|
||||||
|
final iterator = serialized.iterator;
|
||||||
|
while (iterator.moveNext()) {
|
||||||
|
final key = iterator.current as String;
|
||||||
|
iterator.moveNext();
|
||||||
|
final dynamic value = iterator.current;
|
||||||
|
switch (key) {
|
||||||
|
case 'self':
|
||||||
|
result.self = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'html':
|
||||||
|
result.html = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'download':
|
||||||
|
result.download = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'download_location':
|
||||||
|
result.downloadLocation = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _$Links extends Links {
|
||||||
|
@override
|
||||||
|
final String self;
|
||||||
|
@override
|
||||||
|
final String html;
|
||||||
|
@override
|
||||||
|
final String download;
|
||||||
|
@override
|
||||||
|
final String downloadLocation;
|
||||||
|
|
||||||
|
factory _$Links([void Function(LinksBuilder) updates]) =>
|
||||||
|
(new LinksBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
_$Links._({this.self, this.html, this.download, this.downloadLocation})
|
||||||
|
: super._();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Links rebuild(void Function(LinksBuilder) updates) =>
|
||||||
|
(toBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
@override
|
||||||
|
LinksBuilder toBuilder() => new LinksBuilder()..replace(this);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(other, this)) return true;
|
||||||
|
return other is Links &&
|
||||||
|
self == other.self &&
|
||||||
|
html == other.html &&
|
||||||
|
download == other.download &&
|
||||||
|
downloadLocation == other.downloadLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return $jf($jc(
|
||||||
|
$jc($jc($jc(0, self.hashCode), html.hashCode), download.hashCode),
|
||||||
|
downloadLocation.hashCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (newBuiltValueToStringHelper('Links')
|
||||||
|
..add('self', self)
|
||||||
|
..add('html', html)
|
||||||
|
..add('download', download)
|
||||||
|
..add('downloadLocation', downloadLocation))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LinksBuilder implements Builder<Links, LinksBuilder> {
|
||||||
|
_$Links _$v;
|
||||||
|
|
||||||
|
String _self;
|
||||||
|
String get self => _$this._self;
|
||||||
|
set self(String self) => _$this._self = self;
|
||||||
|
|
||||||
|
String _html;
|
||||||
|
String get html => _$this._html;
|
||||||
|
set html(String html) => _$this._html = html;
|
||||||
|
|
||||||
|
String _download;
|
||||||
|
String get download => _$this._download;
|
||||||
|
set download(String download) => _$this._download = download;
|
||||||
|
|
||||||
|
String _downloadLocation;
|
||||||
|
String get downloadLocation => _$this._downloadLocation;
|
||||||
|
set downloadLocation(String downloadLocation) =>
|
||||||
|
_$this._downloadLocation = downloadLocation;
|
||||||
|
|
||||||
|
LinksBuilder();
|
||||||
|
|
||||||
|
LinksBuilder get _$this {
|
||||||
|
if (_$v != null) {
|
||||||
|
_self = _$v.self;
|
||||||
|
_html = _$v.html;
|
||||||
|
_download = _$v.download;
|
||||||
|
_downloadLocation = _$v.downloadLocation;
|
||||||
|
_$v = null;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void replace(Links other) {
|
||||||
|
if (other == null) {
|
||||||
|
throw new ArgumentError.notNull('other');
|
||||||
|
}
|
||||||
|
_$v = other as _$Links;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void update(void Function(LinksBuilder) updates) {
|
||||||
|
if (updates != null) updates(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
_$Links build() {
|
||||||
|
final _$result = _$v ??
|
||||||
|
new _$Links._(
|
||||||
|
self: self,
|
||||||
|
html: html,
|
||||||
|
download: download,
|
||||||
|
downloadLocation: downloadLocation);
|
||||||
|
replace(_$result);
|
||||||
|
return _$result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore_for_file: always_put_control_body_on_new_line,always_specify_types,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,lines_longer_than_80_chars,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new
|
@ -0,0 +1,42 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:built_value/built_value.dart';
|
||||||
|
import 'package:built_value/serializer.dart';
|
||||||
|
|
||||||
|
import '../serializers.dart';
|
||||||
|
import 'position.dart';
|
||||||
|
|
||||||
|
part 'location.g.dart';
|
||||||
|
|
||||||
|
abstract class Location implements Built<Location, LocationBuilder> {
|
||||||
|
factory Location([void Function(LocationBuilder) updates]) = _$Location;
|
||||||
|
|
||||||
|
Location._();
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'city')
|
||||||
|
String get city;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'country')
|
||||||
|
String get country;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'position')
|
||||||
|
Position get position;
|
||||||
|
|
||||||
|
String toJson() {
|
||||||
|
return json.encode(serializers.serializeWith(Location.serializer, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Location fromJson(String jsonString) {
|
||||||
|
return serializers.deserializeWith(
|
||||||
|
Location.serializer, json.decode(jsonString));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Serializer<Location> get serializer => _$locationSerializer;
|
||||||
|
}
|
@ -0,0 +1,184 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'location.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// BuiltValueGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
Serializer<Location> _$locationSerializer = new _$LocationSerializer();
|
||||||
|
|
||||||
|
class _$LocationSerializer implements StructuredSerializer<Location> {
|
||||||
|
@override
|
||||||
|
final Iterable<Type> types = const [Location, _$Location];
|
||||||
|
@override
|
||||||
|
final String wireName = 'Location';
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<Object> serialize(Serializers serializers, Location object,
|
||||||
|
{FullType specifiedType = FullType.unspecified}) {
|
||||||
|
final result = <Object>[];
|
||||||
|
if (object.city != null) {
|
||||||
|
result
|
||||||
|
..add('city')
|
||||||
|
..add(serializers.serialize(object.city,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
if (object.country != null) {
|
||||||
|
result
|
||||||
|
..add('country')
|
||||||
|
..add(serializers.serialize(object.country,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
if (object.position != null) {
|
||||||
|
result
|
||||||
|
..add('position')
|
||||||
|
..add(serializers.serialize(object.position,
|
||||||
|
specifiedType: const FullType(Position)));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Location deserialize(Serializers serializers, Iterable<Object> serialized,
|
||||||
|
{FullType specifiedType = FullType.unspecified}) {
|
||||||
|
final result = new LocationBuilder();
|
||||||
|
|
||||||
|
final iterator = serialized.iterator;
|
||||||
|
while (iterator.moveNext()) {
|
||||||
|
final key = iterator.current as String;
|
||||||
|
iterator.moveNext();
|
||||||
|
final dynamic value = iterator.current;
|
||||||
|
switch (key) {
|
||||||
|
case 'city':
|
||||||
|
result.city = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'country':
|
||||||
|
result.country = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'position':
|
||||||
|
result.position.replace(serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(Position)) as Position);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _$Location extends Location {
|
||||||
|
@override
|
||||||
|
final String city;
|
||||||
|
@override
|
||||||
|
final String country;
|
||||||
|
@override
|
||||||
|
final Position position;
|
||||||
|
|
||||||
|
factory _$Location([void Function(LocationBuilder) updates]) =>
|
||||||
|
(new LocationBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
_$Location._({this.city, this.country, this.position}) : super._();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Location rebuild(void Function(LocationBuilder) updates) =>
|
||||||
|
(toBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
@override
|
||||||
|
LocationBuilder toBuilder() => new LocationBuilder()..replace(this);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(other, this)) return true;
|
||||||
|
return other is Location &&
|
||||||
|
city == other.city &&
|
||||||
|
country == other.country &&
|
||||||
|
position == other.position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return $jf(
|
||||||
|
$jc($jc($jc(0, city.hashCode), country.hashCode), position.hashCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (newBuiltValueToStringHelper('Location')
|
||||||
|
..add('city', city)
|
||||||
|
..add('country', country)
|
||||||
|
..add('position', position))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LocationBuilder implements Builder<Location, LocationBuilder> {
|
||||||
|
_$Location _$v;
|
||||||
|
|
||||||
|
String _city;
|
||||||
|
String get city => _$this._city;
|
||||||
|
set city(String city) => _$this._city = city;
|
||||||
|
|
||||||
|
String _country;
|
||||||
|
String get country => _$this._country;
|
||||||
|
set country(String country) => _$this._country = country;
|
||||||
|
|
||||||
|
PositionBuilder _position;
|
||||||
|
PositionBuilder get position => _$this._position ??= new PositionBuilder();
|
||||||
|
set position(PositionBuilder position) => _$this._position = position;
|
||||||
|
|
||||||
|
LocationBuilder();
|
||||||
|
|
||||||
|
LocationBuilder get _$this {
|
||||||
|
if (_$v != null) {
|
||||||
|
_city = _$v.city;
|
||||||
|
_country = _$v.country;
|
||||||
|
_position = _$v.position?.toBuilder();
|
||||||
|
_$v = null;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void replace(Location other) {
|
||||||
|
if (other == null) {
|
||||||
|
throw new ArgumentError.notNull('other');
|
||||||
|
}
|
||||||
|
_$v = other as _$Location;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void update(void Function(LocationBuilder) updates) {
|
||||||
|
if (updates != null) updates(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
_$Location build() {
|
||||||
|
_$Location _$result;
|
||||||
|
try {
|
||||||
|
_$result = _$v ??
|
||||||
|
new _$Location._(
|
||||||
|
city: city, country: country, position: _position?.build());
|
||||||
|
} catch (_) {
|
||||||
|
String _$failedField;
|
||||||
|
try {
|
||||||
|
_$failedField = 'position';
|
||||||
|
_position?.build();
|
||||||
|
} catch (e) {
|
||||||
|
throw new BuiltValueNestedFieldError(
|
||||||
|
'Location', _$failedField, e.toString());
|
||||||
|
}
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
replace(_$result);
|
||||||
|
return _$result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore_for_file: always_put_control_body_on_new_line,always_specify_types,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,lines_longer_than_80_chars,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new
|
@ -0,0 +1,104 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:built_collection/built_collection.dart';
|
||||||
|
import 'package:built_value/built_value.dart';
|
||||||
|
import 'package:built_value/serializer.dart';
|
||||||
|
|
||||||
|
import '../serializers.dart';
|
||||||
|
import 'current_user_collections.dart';
|
||||||
|
import 'exif.dart';
|
||||||
|
import 'links.dart';
|
||||||
|
import 'location.dart';
|
||||||
|
import 'tags.dart';
|
||||||
|
import 'urls.dart';
|
||||||
|
import 'user.dart';
|
||||||
|
|
||||||
|
part 'photo.g.dart';
|
||||||
|
|
||||||
|
abstract class Photo implements Built<Photo, PhotoBuilder> {
|
||||||
|
factory Photo([void Function(PhotoBuilder) updates]) = _$Photo;
|
||||||
|
|
||||||
|
Photo._();
|
||||||
|
|
||||||
|
@BuiltValueField(wireName: 'id')
|
||||||
|
String get id;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'created_at')
|
||||||
|
String get createdAt;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'updated_at')
|
||||||
|
String get updatedAt;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'width')
|
||||||
|
int get width;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'height')
|
||||||
|
int get height;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'color')
|
||||||
|
String get color;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'downloads')
|
||||||
|
int get downloads;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'likes')
|
||||||
|
int get likes;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'liked_by_user')
|
||||||
|
bool get likedByUser;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'description')
|
||||||
|
String get description;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'exif')
|
||||||
|
Exif get exif;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'location')
|
||||||
|
Location get location;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'tags')
|
||||||
|
BuiltList<Tags> get tags;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'current_user_collections')
|
||||||
|
BuiltList<CurrentUserCollections> get currentUserCollections;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'urls')
|
||||||
|
Urls get urls;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'links')
|
||||||
|
Links get links;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'user')
|
||||||
|
User get user;
|
||||||
|
|
||||||
|
String toJson() {
|
||||||
|
return json.encode(serializers.serializeWith(Photo.serializer, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Photo fromJson(String jsonString) {
|
||||||
|
return serializers.deserializeWith(
|
||||||
|
Photo.serializer, json.decode(jsonString));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Serializer<Photo> get serializer => _$photoSerializer;
|
||||||
|
}
|
@ -0,0 +1,543 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'photo.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// BuiltValueGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
Serializer<Photo> _$photoSerializer = new _$PhotoSerializer();
|
||||||
|
|
||||||
|
class _$PhotoSerializer implements StructuredSerializer<Photo> {
|
||||||
|
@override
|
||||||
|
final Iterable<Type> types = const [Photo, _$Photo];
|
||||||
|
@override
|
||||||
|
final String wireName = 'Photo';
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<Object> serialize(Serializers serializers, Photo object,
|
||||||
|
{FullType specifiedType = FullType.unspecified}) {
|
||||||
|
final result = <Object>[
|
||||||
|
'id',
|
||||||
|
serializers.serialize(object.id, specifiedType: const FullType(String)),
|
||||||
|
];
|
||||||
|
if (object.createdAt != null) {
|
||||||
|
result
|
||||||
|
..add('created_at')
|
||||||
|
..add(serializers.serialize(object.createdAt,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
if (object.updatedAt != null) {
|
||||||
|
result
|
||||||
|
..add('updated_at')
|
||||||
|
..add(serializers.serialize(object.updatedAt,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
if (object.width != null) {
|
||||||
|
result
|
||||||
|
..add('width')
|
||||||
|
..add(serializers.serialize(object.width,
|
||||||
|
specifiedType: const FullType(int)));
|
||||||
|
}
|
||||||
|
if (object.height != null) {
|
||||||
|
result
|
||||||
|
..add('height')
|
||||||
|
..add(serializers.serialize(object.height,
|
||||||
|
specifiedType: const FullType(int)));
|
||||||
|
}
|
||||||
|
if (object.color != null) {
|
||||||
|
result
|
||||||
|
..add('color')
|
||||||
|
..add(serializers.serialize(object.color,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
if (object.downloads != null) {
|
||||||
|
result
|
||||||
|
..add('downloads')
|
||||||
|
..add(serializers.serialize(object.downloads,
|
||||||
|
specifiedType: const FullType(int)));
|
||||||
|
}
|
||||||
|
if (object.likes != null) {
|
||||||
|
result
|
||||||
|
..add('likes')
|
||||||
|
..add(serializers.serialize(object.likes,
|
||||||
|
specifiedType: const FullType(int)));
|
||||||
|
}
|
||||||
|
if (object.likedByUser != null) {
|
||||||
|
result
|
||||||
|
..add('liked_by_user')
|
||||||
|
..add(serializers.serialize(object.likedByUser,
|
||||||
|
specifiedType: const FullType(bool)));
|
||||||
|
}
|
||||||
|
if (object.description != null) {
|
||||||
|
result
|
||||||
|
..add('description')
|
||||||
|
..add(serializers.serialize(object.description,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
if (object.exif != null) {
|
||||||
|
result
|
||||||
|
..add('exif')
|
||||||
|
..add(serializers.serialize(object.exif,
|
||||||
|
specifiedType: const FullType(Exif)));
|
||||||
|
}
|
||||||
|
if (object.location != null) {
|
||||||
|
result
|
||||||
|
..add('location')
|
||||||
|
..add(serializers.serialize(object.location,
|
||||||
|
specifiedType: const FullType(Location)));
|
||||||
|
}
|
||||||
|
if (object.tags != null) {
|
||||||
|
result
|
||||||
|
..add('tags')
|
||||||
|
..add(serializers.serialize(object.tags,
|
||||||
|
specifiedType:
|
||||||
|
const FullType(BuiltList, const [const FullType(Tags)])));
|
||||||
|
}
|
||||||
|
if (object.currentUserCollections != null) {
|
||||||
|
result
|
||||||
|
..add('current_user_collections')
|
||||||
|
..add(serializers.serialize(object.currentUserCollections,
|
||||||
|
specifiedType: const FullType(
|
||||||
|
BuiltList, const [const FullType(CurrentUserCollections)])));
|
||||||
|
}
|
||||||
|
if (object.urls != null) {
|
||||||
|
result
|
||||||
|
..add('urls')
|
||||||
|
..add(serializers.serialize(object.urls,
|
||||||
|
specifiedType: const FullType(Urls)));
|
||||||
|
}
|
||||||
|
if (object.links != null) {
|
||||||
|
result
|
||||||
|
..add('links')
|
||||||
|
..add(serializers.serialize(object.links,
|
||||||
|
specifiedType: const FullType(Links)));
|
||||||
|
}
|
||||||
|
if (object.user != null) {
|
||||||
|
result
|
||||||
|
..add('user')
|
||||||
|
..add(serializers.serialize(object.user,
|
||||||
|
specifiedType: const FullType(User)));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Photo deserialize(Serializers serializers, Iterable<Object> serialized,
|
||||||
|
{FullType specifiedType = FullType.unspecified}) {
|
||||||
|
final result = new PhotoBuilder();
|
||||||
|
|
||||||
|
final iterator = serialized.iterator;
|
||||||
|
while (iterator.moveNext()) {
|
||||||
|
final key = iterator.current as String;
|
||||||
|
iterator.moveNext();
|
||||||
|
final dynamic value = iterator.current;
|
||||||
|
switch (key) {
|
||||||
|
case 'id':
|
||||||
|
result.id = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'created_at':
|
||||||
|
result.createdAt = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'updated_at':
|
||||||
|
result.updatedAt = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'width':
|
||||||
|
result.width = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(int)) as int;
|
||||||
|
break;
|
||||||
|
case 'height':
|
||||||
|
result.height = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(int)) as int;
|
||||||
|
break;
|
||||||
|
case 'color':
|
||||||
|
result.color = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'downloads':
|
||||||
|
result.downloads = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(int)) as int;
|
||||||
|
break;
|
||||||
|
case 'likes':
|
||||||
|
result.likes = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(int)) as int;
|
||||||
|
break;
|
||||||
|
case 'liked_by_user':
|
||||||
|
result.likedByUser = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(bool)) as bool;
|
||||||
|
break;
|
||||||
|
case 'description':
|
||||||
|
result.description = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'exif':
|
||||||
|
result.exif.replace(serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(Exif)) as Exif);
|
||||||
|
break;
|
||||||
|
case 'location':
|
||||||
|
result.location.replace(serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(Location)) as Location);
|
||||||
|
break;
|
||||||
|
case 'tags':
|
||||||
|
result.tags.replace(serializers.deserialize(value,
|
||||||
|
specifiedType:
|
||||||
|
const FullType(BuiltList, const [const FullType(Tags)]))
|
||||||
|
as BuiltList<dynamic>);
|
||||||
|
break;
|
||||||
|
case 'current_user_collections':
|
||||||
|
result.currentUserCollections.replace(serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(BuiltList, const [
|
||||||
|
const FullType(CurrentUserCollections)
|
||||||
|
])) as BuiltList<dynamic>);
|
||||||
|
break;
|
||||||
|
case 'urls':
|
||||||
|
result.urls.replace(serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(Urls)) as Urls);
|
||||||
|
break;
|
||||||
|
case 'links':
|
||||||
|
result.links.replace(serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(Links)) as Links);
|
||||||
|
break;
|
||||||
|
case 'user':
|
||||||
|
result.user.replace(serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(User)) as User);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _$Photo extends Photo {
|
||||||
|
@override
|
||||||
|
final String id;
|
||||||
|
@override
|
||||||
|
final String createdAt;
|
||||||
|
@override
|
||||||
|
final String updatedAt;
|
||||||
|
@override
|
||||||
|
final int width;
|
||||||
|
@override
|
||||||
|
final int height;
|
||||||
|
@override
|
||||||
|
final String color;
|
||||||
|
@override
|
||||||
|
final int downloads;
|
||||||
|
@override
|
||||||
|
final int likes;
|
||||||
|
@override
|
||||||
|
final bool likedByUser;
|
||||||
|
@override
|
||||||
|
final String description;
|
||||||
|
@override
|
||||||
|
final Exif exif;
|
||||||
|
@override
|
||||||
|
final Location location;
|
||||||
|
@override
|
||||||
|
final BuiltList<Tags> tags;
|
||||||
|
@override
|
||||||
|
final BuiltList<CurrentUserCollections> currentUserCollections;
|
||||||
|
@override
|
||||||
|
final Urls urls;
|
||||||
|
@override
|
||||||
|
final Links links;
|
||||||
|
@override
|
||||||
|
final User user;
|
||||||
|
|
||||||
|
factory _$Photo([void Function(PhotoBuilder) updates]) =>
|
||||||
|
(new PhotoBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
_$Photo._(
|
||||||
|
{this.id,
|
||||||
|
this.createdAt,
|
||||||
|
this.updatedAt,
|
||||||
|
this.width,
|
||||||
|
this.height,
|
||||||
|
this.color,
|
||||||
|
this.downloads,
|
||||||
|
this.likes,
|
||||||
|
this.likedByUser,
|
||||||
|
this.description,
|
||||||
|
this.exif,
|
||||||
|
this.location,
|
||||||
|
this.tags,
|
||||||
|
this.currentUserCollections,
|
||||||
|
this.urls,
|
||||||
|
this.links,
|
||||||
|
this.user})
|
||||||
|
: super._() {
|
||||||
|
if (id == null) {
|
||||||
|
throw new BuiltValueNullFieldError('Photo', 'id');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Photo rebuild(void Function(PhotoBuilder) updates) =>
|
||||||
|
(toBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
@override
|
||||||
|
PhotoBuilder toBuilder() => new PhotoBuilder()..replace(this);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(other, this)) return true;
|
||||||
|
return other is Photo &&
|
||||||
|
id == other.id &&
|
||||||
|
createdAt == other.createdAt &&
|
||||||
|
updatedAt == other.updatedAt &&
|
||||||
|
width == other.width &&
|
||||||
|
height == other.height &&
|
||||||
|
color == other.color &&
|
||||||
|
downloads == other.downloads &&
|
||||||
|
likes == other.likes &&
|
||||||
|
likedByUser == other.likedByUser &&
|
||||||
|
description == other.description &&
|
||||||
|
exif == other.exif &&
|
||||||
|
location == other.location &&
|
||||||
|
tags == other.tags &&
|
||||||
|
currentUserCollections == other.currentUserCollections &&
|
||||||
|
urls == other.urls &&
|
||||||
|
links == other.links &&
|
||||||
|
user == other.user;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return $jf($jc(
|
||||||
|
$jc(
|
||||||
|
$jc(
|
||||||
|
$jc(
|
||||||
|
$jc(
|
||||||
|
$jc(
|
||||||
|
$jc(
|
||||||
|
$jc(
|
||||||
|
$jc(
|
||||||
|
$jc(
|
||||||
|
$jc(
|
||||||
|
$jc(
|
||||||
|
$jc(
|
||||||
|
$jc(
|
||||||
|
$jc(
|
||||||
|
$jc(
|
||||||
|
$jc(
|
||||||
|
0,
|
||||||
|
id
|
||||||
|
.hashCode),
|
||||||
|
createdAt
|
||||||
|
.hashCode),
|
||||||
|
updatedAt
|
||||||
|
.hashCode),
|
||||||
|
width.hashCode),
|
||||||
|
height.hashCode),
|
||||||
|
color.hashCode),
|
||||||
|
downloads.hashCode),
|
||||||
|
likes.hashCode),
|
||||||
|
likedByUser.hashCode),
|
||||||
|
description.hashCode),
|
||||||
|
exif.hashCode),
|
||||||
|
location.hashCode),
|
||||||
|
tags.hashCode),
|
||||||
|
currentUserCollections.hashCode),
|
||||||
|
urls.hashCode),
|
||||||
|
links.hashCode),
|
||||||
|
user.hashCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (newBuiltValueToStringHelper('Photo')
|
||||||
|
..add('id', id)
|
||||||
|
..add('createdAt', createdAt)
|
||||||
|
..add('updatedAt', updatedAt)
|
||||||
|
..add('width', width)
|
||||||
|
..add('height', height)
|
||||||
|
..add('color', color)
|
||||||
|
..add('downloads', downloads)
|
||||||
|
..add('likes', likes)
|
||||||
|
..add('likedByUser', likedByUser)
|
||||||
|
..add('description', description)
|
||||||
|
..add('exif', exif)
|
||||||
|
..add('location', location)
|
||||||
|
..add('tags', tags)
|
||||||
|
..add('currentUserCollections', currentUserCollections)
|
||||||
|
..add('urls', urls)
|
||||||
|
..add('links', links)
|
||||||
|
..add('user', user))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PhotoBuilder implements Builder<Photo, PhotoBuilder> {
|
||||||
|
_$Photo _$v;
|
||||||
|
|
||||||
|
String _id;
|
||||||
|
String get id => _$this._id;
|
||||||
|
set id(String id) => _$this._id = id;
|
||||||
|
|
||||||
|
String _createdAt;
|
||||||
|
String get createdAt => _$this._createdAt;
|
||||||
|
set createdAt(String createdAt) => _$this._createdAt = createdAt;
|
||||||
|
|
||||||
|
String _updatedAt;
|
||||||
|
String get updatedAt => _$this._updatedAt;
|
||||||
|
set updatedAt(String updatedAt) => _$this._updatedAt = updatedAt;
|
||||||
|
|
||||||
|
int _width;
|
||||||
|
int get width => _$this._width;
|
||||||
|
set width(int width) => _$this._width = width;
|
||||||
|
|
||||||
|
int _height;
|
||||||
|
int get height => _$this._height;
|
||||||
|
set height(int height) => _$this._height = height;
|
||||||
|
|
||||||
|
String _color;
|
||||||
|
String get color => _$this._color;
|
||||||
|
set color(String color) => _$this._color = color;
|
||||||
|
|
||||||
|
int _downloads;
|
||||||
|
int get downloads => _$this._downloads;
|
||||||
|
set downloads(int downloads) => _$this._downloads = downloads;
|
||||||
|
|
||||||
|
int _likes;
|
||||||
|
int get likes => _$this._likes;
|
||||||
|
set likes(int likes) => _$this._likes = likes;
|
||||||
|
|
||||||
|
bool _likedByUser;
|
||||||
|
bool get likedByUser => _$this._likedByUser;
|
||||||
|
set likedByUser(bool likedByUser) => _$this._likedByUser = likedByUser;
|
||||||
|
|
||||||
|
String _description;
|
||||||
|
String get description => _$this._description;
|
||||||
|
set description(String description) => _$this._description = description;
|
||||||
|
|
||||||
|
ExifBuilder _exif;
|
||||||
|
ExifBuilder get exif => _$this._exif ??= new ExifBuilder();
|
||||||
|
set exif(ExifBuilder exif) => _$this._exif = exif;
|
||||||
|
|
||||||
|
LocationBuilder _location;
|
||||||
|
LocationBuilder get location => _$this._location ??= new LocationBuilder();
|
||||||
|
set location(LocationBuilder location) => _$this._location = location;
|
||||||
|
|
||||||
|
ListBuilder<Tags> _tags;
|
||||||
|
ListBuilder<Tags> get tags => _$this._tags ??= new ListBuilder<Tags>();
|
||||||
|
set tags(ListBuilder<Tags> tags) => _$this._tags = tags;
|
||||||
|
|
||||||
|
ListBuilder<CurrentUserCollections> _currentUserCollections;
|
||||||
|
ListBuilder<CurrentUserCollections> get currentUserCollections =>
|
||||||
|
_$this._currentUserCollections ??=
|
||||||
|
new ListBuilder<CurrentUserCollections>();
|
||||||
|
set currentUserCollections(
|
||||||
|
ListBuilder<CurrentUserCollections> currentUserCollections) =>
|
||||||
|
_$this._currentUserCollections = currentUserCollections;
|
||||||
|
|
||||||
|
UrlsBuilder _urls;
|
||||||
|
UrlsBuilder get urls => _$this._urls ??= new UrlsBuilder();
|
||||||
|
set urls(UrlsBuilder urls) => _$this._urls = urls;
|
||||||
|
|
||||||
|
LinksBuilder _links;
|
||||||
|
LinksBuilder get links => _$this._links ??= new LinksBuilder();
|
||||||
|
set links(LinksBuilder links) => _$this._links = links;
|
||||||
|
|
||||||
|
UserBuilder _user;
|
||||||
|
UserBuilder get user => _$this._user ??= new UserBuilder();
|
||||||
|
set user(UserBuilder user) => _$this._user = user;
|
||||||
|
|
||||||
|
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();
|
||||||
|
_$v = null;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void replace(Photo other) {
|
||||||
|
if (other == null) {
|
||||||
|
throw new ArgumentError.notNull('other');
|
||||||
|
}
|
||||||
|
_$v = other as _$Photo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void update(void Function(PhotoBuilder) updates) {
|
||||||
|
if (updates != null) updates(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
_$Photo build() {
|
||||||
|
_$Photo _$result;
|
||||||
|
try {
|
||||||
|
_$result = _$v ??
|
||||||
|
new _$Photo._(
|
||||||
|
id: id,
|
||||||
|
createdAt: createdAt,
|
||||||
|
updatedAt: updatedAt,
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
color: color,
|
||||||
|
downloads: downloads,
|
||||||
|
likes: likes,
|
||||||
|
likedByUser: likedByUser,
|
||||||
|
description: description,
|
||||||
|
exif: _exif?.build(),
|
||||||
|
location: _location?.build(),
|
||||||
|
tags: _tags?.build(),
|
||||||
|
currentUserCollections: _currentUserCollections?.build(),
|
||||||
|
urls: _urls?.build(),
|
||||||
|
links: _links?.build(),
|
||||||
|
user: _user?.build());
|
||||||
|
} catch (_) {
|
||||||
|
String _$failedField;
|
||||||
|
try {
|
||||||
|
_$failedField = 'exif';
|
||||||
|
_exif?.build();
|
||||||
|
_$failedField = 'location';
|
||||||
|
_location?.build();
|
||||||
|
_$failedField = 'tags';
|
||||||
|
_tags?.build();
|
||||||
|
_$failedField = 'currentUserCollections';
|
||||||
|
_currentUserCollections?.build();
|
||||||
|
_$failedField = 'urls';
|
||||||
|
_urls?.build();
|
||||||
|
_$failedField = 'links';
|
||||||
|
_links?.build();
|
||||||
|
_$failedField = 'user';
|
||||||
|
_user?.build();
|
||||||
|
} catch (e) {
|
||||||
|
throw new BuiltValueNestedFieldError(
|
||||||
|
'Photo', _$failedField, e.toString());
|
||||||
|
}
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
replace(_$result);
|
||||||
|
return _$result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore_for_file: always_put_control_body_on_new_line,always_specify_types,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,lines_longer_than_80_chars,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new
|
@ -0,0 +1,35 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:built_value/built_value.dart';
|
||||||
|
import 'package:built_value/serializer.dart';
|
||||||
|
|
||||||
|
import '../serializers.dart';
|
||||||
|
|
||||||
|
part 'position.g.dart';
|
||||||
|
|
||||||
|
abstract class Position implements Built<Position, PositionBuilder> {
|
||||||
|
factory Position([void Function(PositionBuilder) updates]) = _$Position;
|
||||||
|
|
||||||
|
Position._();
|
||||||
|
|
||||||
|
@BuiltValueField(wireName: 'latitude')
|
||||||
|
double get latitude;
|
||||||
|
|
||||||
|
@BuiltValueField(wireName: 'longitude')
|
||||||
|
double get longitude;
|
||||||
|
|
||||||
|
String toJson() {
|
||||||
|
return json.encode(serializers.serializeWith(Position.serializer, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Position fromJson(String jsonString) {
|
||||||
|
return serializers.deserializeWith(
|
||||||
|
Position.serializer, json.decode(jsonString));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Serializer<Position> get serializer => _$positionSerializer;
|
||||||
|
}
|
@ -0,0 +1,153 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'position.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// BuiltValueGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
Serializer<Position> _$positionSerializer = new _$PositionSerializer();
|
||||||
|
|
||||||
|
class _$PositionSerializer implements StructuredSerializer<Position> {
|
||||||
|
@override
|
||||||
|
final Iterable<Type> types = const [Position, _$Position];
|
||||||
|
@override
|
||||||
|
final String wireName = 'Position';
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<Object> serialize(Serializers serializers, Position object,
|
||||||
|
{FullType specifiedType = FullType.unspecified}) {
|
||||||
|
final result = <Object>[
|
||||||
|
'latitude',
|
||||||
|
serializers.serialize(object.latitude,
|
||||||
|
specifiedType: const FullType(double)),
|
||||||
|
'longitude',
|
||||||
|
serializers.serialize(object.longitude,
|
||||||
|
specifiedType: const FullType(double)),
|
||||||
|
];
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Position deserialize(Serializers serializers, Iterable<Object> serialized,
|
||||||
|
{FullType specifiedType = FullType.unspecified}) {
|
||||||
|
final result = new PositionBuilder();
|
||||||
|
|
||||||
|
final iterator = serialized.iterator;
|
||||||
|
while (iterator.moveNext()) {
|
||||||
|
final key = iterator.current as String;
|
||||||
|
iterator.moveNext();
|
||||||
|
final dynamic value = iterator.current;
|
||||||
|
switch (key) {
|
||||||
|
case 'latitude':
|
||||||
|
result.latitude = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(double)) as double;
|
||||||
|
break;
|
||||||
|
case 'longitude':
|
||||||
|
result.longitude = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(double)) as double;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _$Position extends Position {
|
||||||
|
@override
|
||||||
|
final double latitude;
|
||||||
|
@override
|
||||||
|
final double longitude;
|
||||||
|
|
||||||
|
factory _$Position([void Function(PositionBuilder) updates]) =>
|
||||||
|
(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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Position rebuild(void Function(PositionBuilder) updates) =>
|
||||||
|
(toBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
@override
|
||||||
|
PositionBuilder toBuilder() => new PositionBuilder()..replace(this);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(other, this)) return true;
|
||||||
|
return other is Position &&
|
||||||
|
latitude == other.latitude &&
|
||||||
|
longitude == other.longitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return $jf($jc($jc(0, latitude.hashCode), longitude.hashCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (newBuiltValueToStringHelper('Position')
|
||||||
|
..add('latitude', latitude)
|
||||||
|
..add('longitude', longitude))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PositionBuilder implements Builder<Position, PositionBuilder> {
|
||||||
|
_$Position _$v;
|
||||||
|
|
||||||
|
double _latitude;
|
||||||
|
double get latitude => _$this._latitude;
|
||||||
|
set latitude(double latitude) => _$this._latitude = latitude;
|
||||||
|
|
||||||
|
double _longitude;
|
||||||
|
double get longitude => _$this._longitude;
|
||||||
|
set longitude(double longitude) => _$this._longitude = longitude;
|
||||||
|
|
||||||
|
PositionBuilder();
|
||||||
|
|
||||||
|
PositionBuilder get _$this {
|
||||||
|
if (_$v != null) {
|
||||||
|
_latitude = _$v.latitude;
|
||||||
|
_longitude = _$v.longitude;
|
||||||
|
_$v = null;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void replace(Position other) {
|
||||||
|
if (other == null) {
|
||||||
|
throw new ArgumentError.notNull('other');
|
||||||
|
}
|
||||||
|
_$v = other as _$Position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void update(void Function(PositionBuilder) updates) {
|
||||||
|
if (updates != null) updates(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
_$Position build() {
|
||||||
|
final _$result =
|
||||||
|
_$v ?? new _$Position._(latitude: latitude, longitude: longitude);
|
||||||
|
replace(_$result);
|
||||||
|
return _$result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore_for_file: always_put_control_body_on_new_line,always_specify_types,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,lines_longer_than_80_chars,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new
|
@ -0,0 +1,47 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:built_collection/built_collection.dart';
|
||||||
|
import 'package:built_value/built_value.dart';
|
||||||
|
import 'package:built_value/serializer.dart';
|
||||||
|
|
||||||
|
import '../serializers.dart';
|
||||||
|
import 'photo.dart';
|
||||||
|
|
||||||
|
part 'search_photos_response.g.dart';
|
||||||
|
|
||||||
|
abstract class SearchPhotosResponse
|
||||||
|
implements Built<SearchPhotosResponse, SearchPhotosResponseBuilder> {
|
||||||
|
factory SearchPhotosResponse(
|
||||||
|
[void Function(SearchPhotosResponseBuilder) updates]) =
|
||||||
|
_$SearchPhotosResponse;
|
||||||
|
|
||||||
|
SearchPhotosResponse._();
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'total')
|
||||||
|
int get total;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'total_pages')
|
||||||
|
int get totalPages;
|
||||||
|
|
||||||
|
@BuiltValueField(wireName: 'results')
|
||||||
|
BuiltList<Photo> get results;
|
||||||
|
|
||||||
|
String toJson() {
|
||||||
|
return json.encode(
|
||||||
|
serializers.serializeWith(SearchPhotosResponse.serializer, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
static SearchPhotosResponse fromJson(String jsonString) {
|
||||||
|
return serializers.deserializeWith(
|
||||||
|
SearchPhotosResponse.serializer, json.decode(jsonString));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Serializer<SearchPhotosResponse> get serializer =>
|
||||||
|
_$searchPhotosResponseSerializer;
|
||||||
|
}
|
@ -0,0 +1,202 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'search_photos_response.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// BuiltValueGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
Serializer<SearchPhotosResponse> _$searchPhotosResponseSerializer =
|
||||||
|
new _$SearchPhotosResponseSerializer();
|
||||||
|
|
||||||
|
class _$SearchPhotosResponseSerializer
|
||||||
|
implements StructuredSerializer<SearchPhotosResponse> {
|
||||||
|
@override
|
||||||
|
final Iterable<Type> types = const [
|
||||||
|
SearchPhotosResponse,
|
||||||
|
_$SearchPhotosResponse
|
||||||
|
];
|
||||||
|
@override
|
||||||
|
final String wireName = 'SearchPhotosResponse';
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<Object> serialize(
|
||||||
|
Serializers serializers, SearchPhotosResponse object,
|
||||||
|
{FullType specifiedType = FullType.unspecified}) {
|
||||||
|
final result = <Object>[
|
||||||
|
'results',
|
||||||
|
serializers.serialize(object.results,
|
||||||
|
specifiedType:
|
||||||
|
const FullType(BuiltList, const [const FullType(Photo)])),
|
||||||
|
];
|
||||||
|
if (object.total != null) {
|
||||||
|
result
|
||||||
|
..add('total')
|
||||||
|
..add(serializers.serialize(object.total,
|
||||||
|
specifiedType: const FullType(int)));
|
||||||
|
}
|
||||||
|
if (object.totalPages != null) {
|
||||||
|
result
|
||||||
|
..add('total_pages')
|
||||||
|
..add(serializers.serialize(object.totalPages,
|
||||||
|
specifiedType: const FullType(int)));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
SearchPhotosResponse deserialize(
|
||||||
|
Serializers serializers, Iterable<Object> serialized,
|
||||||
|
{FullType specifiedType = FullType.unspecified}) {
|
||||||
|
final result = new SearchPhotosResponseBuilder();
|
||||||
|
|
||||||
|
final iterator = serialized.iterator;
|
||||||
|
while (iterator.moveNext()) {
|
||||||
|
final key = iterator.current as String;
|
||||||
|
iterator.moveNext();
|
||||||
|
final dynamic value = iterator.current;
|
||||||
|
switch (key) {
|
||||||
|
case 'total':
|
||||||
|
result.total = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(int)) as int;
|
||||||
|
break;
|
||||||
|
case 'total_pages':
|
||||||
|
result.totalPages = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(int)) as int;
|
||||||
|
break;
|
||||||
|
case 'results':
|
||||||
|
result.results.replace(serializers.deserialize(value,
|
||||||
|
specifiedType:
|
||||||
|
const FullType(BuiltList, const [const FullType(Photo)]))
|
||||||
|
as BuiltList<dynamic>);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _$SearchPhotosResponse extends SearchPhotosResponse {
|
||||||
|
@override
|
||||||
|
final int total;
|
||||||
|
@override
|
||||||
|
final int totalPages;
|
||||||
|
@override
|
||||||
|
final BuiltList<Photo> results;
|
||||||
|
|
||||||
|
factory _$SearchPhotosResponse(
|
||||||
|
[void Function(SearchPhotosResponseBuilder) updates]) =>
|
||||||
|
(new SearchPhotosResponseBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
_$SearchPhotosResponse._({this.total, this.totalPages, this.results})
|
||||||
|
: super._() {
|
||||||
|
if (results == null) {
|
||||||
|
throw new BuiltValueNullFieldError('SearchPhotosResponse', 'results');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
SearchPhotosResponse rebuild(
|
||||||
|
void Function(SearchPhotosResponseBuilder) updates) =>
|
||||||
|
(toBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
@override
|
||||||
|
SearchPhotosResponseBuilder toBuilder() =>
|
||||||
|
new SearchPhotosResponseBuilder()..replace(this);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(other, this)) return true;
|
||||||
|
return other is SearchPhotosResponse &&
|
||||||
|
total == other.total &&
|
||||||
|
totalPages == other.totalPages &&
|
||||||
|
results == other.results;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return $jf($jc(
|
||||||
|
$jc($jc(0, total.hashCode), totalPages.hashCode), results.hashCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (newBuiltValueToStringHelper('SearchPhotosResponse')
|
||||||
|
..add('total', total)
|
||||||
|
..add('totalPages', totalPages)
|
||||||
|
..add('results', results))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SearchPhotosResponseBuilder
|
||||||
|
implements Builder<SearchPhotosResponse, SearchPhotosResponseBuilder> {
|
||||||
|
_$SearchPhotosResponse _$v;
|
||||||
|
|
||||||
|
int _total;
|
||||||
|
int get total => _$this._total;
|
||||||
|
set total(int total) => _$this._total = total;
|
||||||
|
|
||||||
|
int _totalPages;
|
||||||
|
int get totalPages => _$this._totalPages;
|
||||||
|
set totalPages(int totalPages) => _$this._totalPages = totalPages;
|
||||||
|
|
||||||
|
ListBuilder<Photo> _results;
|
||||||
|
ListBuilder<Photo> get results =>
|
||||||
|
_$this._results ??= new ListBuilder<Photo>();
|
||||||
|
set results(ListBuilder<Photo> results) => _$this._results = results;
|
||||||
|
|
||||||
|
SearchPhotosResponseBuilder();
|
||||||
|
|
||||||
|
SearchPhotosResponseBuilder get _$this {
|
||||||
|
if (_$v != null) {
|
||||||
|
_total = _$v.total;
|
||||||
|
_totalPages = _$v.totalPages;
|
||||||
|
_results = _$v.results?.toBuilder();
|
||||||
|
_$v = null;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void replace(SearchPhotosResponse other) {
|
||||||
|
if (other == null) {
|
||||||
|
throw new ArgumentError.notNull('other');
|
||||||
|
}
|
||||||
|
_$v = other as _$SearchPhotosResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void update(void Function(SearchPhotosResponseBuilder) updates) {
|
||||||
|
if (updates != null) updates(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
_$SearchPhotosResponse build() {
|
||||||
|
_$SearchPhotosResponse _$result;
|
||||||
|
try {
|
||||||
|
_$result = _$v ??
|
||||||
|
new _$SearchPhotosResponse._(
|
||||||
|
total: total, totalPages: totalPages, results: results.build());
|
||||||
|
} catch (_) {
|
||||||
|
String _$failedField;
|
||||||
|
try {
|
||||||
|
_$failedField = 'results';
|
||||||
|
results.build();
|
||||||
|
} catch (e) {
|
||||||
|
throw new BuiltValueNestedFieldError(
|
||||||
|
'SearchPhotosResponse', _$failedField, e.toString());
|
||||||
|
}
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
replace(_$result);
|
||||||
|
return _$result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore_for_file: always_put_control_body_on_new_line,always_specify_types,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,lines_longer_than_80_chars,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new
|
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:built_value/built_value.dart';
|
||||||
|
import 'package:built_value/serializer.dart';
|
||||||
|
|
||||||
|
import '../serializers.dart';
|
||||||
|
|
||||||
|
part 'tags.g.dart';
|
||||||
|
|
||||||
|
abstract class Tags implements Built<Tags, TagsBuilder> {
|
||||||
|
factory Tags([void Function(TagsBuilder) updates]) = _$Tags;
|
||||||
|
|
||||||
|
Tags._();
|
||||||
|
|
||||||
|
@BuiltValueField(wireName: 'title')
|
||||||
|
String get title;
|
||||||
|
|
||||||
|
String toJson() {
|
||||||
|
return json.encode(serializers.serializeWith(Tags.serializer, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Tags fromJson(String jsonString) {
|
||||||
|
return serializers.deserializeWith(
|
||||||
|
Tags.serializer, json.decode(jsonString));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Serializer<Tags> get serializer => _$tagsSerializer;
|
||||||
|
}
|
@ -0,0 +1,131 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'tags.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// BuiltValueGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
Serializer<Tags> _$tagsSerializer = new _$TagsSerializer();
|
||||||
|
|
||||||
|
class _$TagsSerializer implements StructuredSerializer<Tags> {
|
||||||
|
@override
|
||||||
|
final Iterable<Type> types = const [Tags, _$Tags];
|
||||||
|
@override
|
||||||
|
final String wireName = 'Tags';
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<Object> serialize(Serializers serializers, Tags object,
|
||||||
|
{FullType specifiedType = FullType.unspecified}) {
|
||||||
|
final result = <Object>[
|
||||||
|
'title',
|
||||||
|
serializers.serialize(object.title,
|
||||||
|
specifiedType: const FullType(String)),
|
||||||
|
];
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Tags deserialize(Serializers serializers, Iterable<Object> serialized,
|
||||||
|
{FullType specifiedType = FullType.unspecified}) {
|
||||||
|
final result = new TagsBuilder();
|
||||||
|
|
||||||
|
final iterator = serialized.iterator;
|
||||||
|
while (iterator.moveNext()) {
|
||||||
|
final key = iterator.current as String;
|
||||||
|
iterator.moveNext();
|
||||||
|
final dynamic value = iterator.current;
|
||||||
|
switch (key) {
|
||||||
|
case 'title':
|
||||||
|
result.title = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _$Tags extends Tags {
|
||||||
|
@override
|
||||||
|
final String title;
|
||||||
|
|
||||||
|
factory _$Tags([void Function(TagsBuilder) updates]) =>
|
||||||
|
(new TagsBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
_$Tags._({this.title}) : super._() {
|
||||||
|
if (title == null) {
|
||||||
|
throw new BuiltValueNullFieldError('Tags', 'title');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Tags rebuild(void Function(TagsBuilder) updates) =>
|
||||||
|
(toBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
@override
|
||||||
|
TagsBuilder toBuilder() => new TagsBuilder()..replace(this);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(other, this)) return true;
|
||||||
|
return other is Tags && title == other.title;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return $jf($jc(0, title.hashCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (newBuiltValueToStringHelper('Tags')..add('title', title))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TagsBuilder implements Builder<Tags, TagsBuilder> {
|
||||||
|
_$Tags _$v;
|
||||||
|
|
||||||
|
String _title;
|
||||||
|
String get title => _$this._title;
|
||||||
|
set title(String title) => _$this._title = title;
|
||||||
|
|
||||||
|
TagsBuilder();
|
||||||
|
|
||||||
|
TagsBuilder get _$this {
|
||||||
|
if (_$v != null) {
|
||||||
|
_title = _$v.title;
|
||||||
|
_$v = null;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void replace(Tags other) {
|
||||||
|
if (other == null) {
|
||||||
|
throw new ArgumentError.notNull('other');
|
||||||
|
}
|
||||||
|
_$v = other as _$Tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void update(void Function(TagsBuilder) updates) {
|
||||||
|
if (updates != null) updates(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
_$Tags build() {
|
||||||
|
final _$result = _$v ?? new _$Tags._(title: title);
|
||||||
|
replace(_$result);
|
||||||
|
return _$result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore_for_file: always_put_control_body_on_new_line,always_specify_types,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,lines_longer_than_80_chars,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new
|
@ -0,0 +1,122 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
import 'package:pedantic/pedantic.dart';
|
||||||
|
|
||||||
|
import 'api_error.dart';
|
||||||
|
import 'photo.dart';
|
||||||
|
import 'search_photos_response.dart';
|
||||||
|
|
||||||
|
final _unsplashBaseUrl = Uri.parse('https://api.unsplash.com/');
|
||||||
|
|
||||||
|
/// Unsplash API Client. Requires an
|
||||||
|
/// [Unsplash API](https://unsplash.com/developers) `accessKey` to make
|
||||||
|
/// requests to the Unsplash API.
|
||||||
|
class Unsplash {
|
||||||
|
Unsplash({
|
||||||
|
@required String accessKey,
|
||||||
|
http.BaseClient httpClient,
|
||||||
|
}) : assert(accessKey != null, 'accessKey must not be null'),
|
||||||
|
_accessKey = accessKey,
|
||||||
|
_client = httpClient ?? http.Client();
|
||||||
|
|
||||||
|
final String _accessKey;
|
||||||
|
final http.Client _client;
|
||||||
|
final _log = Logger('Unsplash');
|
||||||
|
|
||||||
|
Future<SearchPhotosResponse> searchPhotos({
|
||||||
|
@required String query,
|
||||||
|
num page = 1,
|
||||||
|
num perPage = 10,
|
||||||
|
List<num> collections = const [],
|
||||||
|
SearchPhotosOrientation orientation,
|
||||||
|
}) async {
|
||||||
|
final searchPhotosUrl = _unsplashBaseUrl
|
||||||
|
.replace(path: '/search/photos', queryParameters: <String, String>{
|
||||||
|
'query': query,
|
||||||
|
if (page != 1) 'page': '$page',
|
||||||
|
if (perPage != 10) 'per_page': '$perPage',
|
||||||
|
if (collections != null && collections.isNotEmpty)
|
||||||
|
'collections': '${collections.join(',')}',
|
||||||
|
if (orientation == SearchPhotosOrientation.landscape)
|
||||||
|
'orientation': 'landscape',
|
||||||
|
if (orientation == SearchPhotosOrientation.portrait)
|
||||||
|
'orientation': 'portrait',
|
||||||
|
if (orientation == SearchPhotosOrientation.squarish)
|
||||||
|
'orientation': 'squarish',
|
||||||
|
});
|
||||||
|
_log.info('GET $searchPhotosUrl');
|
||||||
|
|
||||||
|
final response = await _client.get(
|
||||||
|
searchPhotosUrl,
|
||||||
|
headers: {
|
||||||
|
'Accept-Version': 'v1',
|
||||||
|
'Authorization': 'Client-ID $_accessKey',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
dynamic body;
|
||||||
|
try {
|
||||||
|
body = json.decode(response.body);
|
||||||
|
} catch (e) {
|
||||||
|
throw UnsplashException('Invalid JSON received');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (body is Map &&
|
||||||
|
body['errors'] is List &&
|
||||||
|
body['errors'].isNotEmpty as bool) {
|
||||||
|
final apiError = ApiError.fromJson(response.body);
|
||||||
|
throw UnsplashException(apiError.errors.join(', '));
|
||||||
|
}
|
||||||
|
|
||||||
|
return SearchPhotosResponse.fromJson(
|
||||||
|
response.body,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Uint8List> download(Photo photo) async {
|
||||||
|
// For detail on how downloading photos from Unsplash, please see
|
||||||
|
// 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: {
|
||||||
|
'Accept-Version': 'v1',
|
||||||
|
'Authorization': 'Client-ID $_accessKey',
|
||||||
|
});
|
||||||
|
|
||||||
|
_log.info('GET ${photo.links.downloadLocation}');
|
||||||
|
unawaited(http.get(photo.links.downloadLocation, headers: {
|
||||||
|
'Accept-Version': 'v1',
|
||||||
|
'Authorization': 'Client-ID $_accessKey',
|
||||||
|
}));
|
||||||
|
|
||||||
|
return futureBytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SearchPhotosOrientation {
|
||||||
|
landscape,
|
||||||
|
portrait,
|
||||||
|
squarish,
|
||||||
|
}
|
||||||
|
|
||||||
|
class UnsplashException implements Exception {
|
||||||
|
UnsplashException([this.message]);
|
||||||
|
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
if (message == null) {
|
||||||
|
return 'UnsplashException';
|
||||||
|
}
|
||||||
|
return 'UnsplashException: $message';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:built_value/built_value.dart';
|
||||||
|
import 'package:built_value/serializer.dart';
|
||||||
|
|
||||||
|
import '../serializers.dart';
|
||||||
|
|
||||||
|
part 'urls.g.dart';
|
||||||
|
|
||||||
|
abstract class Urls implements Built<Urls, UrlsBuilder> {
|
||||||
|
factory Urls([void Function(UrlsBuilder b) updates]) = _$Urls;
|
||||||
|
|
||||||
|
Urls._();
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'raw')
|
||||||
|
String get raw;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'full')
|
||||||
|
String get full;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'regular')
|
||||||
|
String get regular;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'small')
|
||||||
|
String get small;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'thumb')
|
||||||
|
String get thumb;
|
||||||
|
|
||||||
|
String toJson() {
|
||||||
|
return json.encode(serializers.serializeWith(Urls.serializer, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Urls fromJson(String jsonString) {
|
||||||
|
return serializers.deserializeWith(
|
||||||
|
Urls.serializer, json.decode(jsonString));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Serializer<Urls> get serializer => _$urlsSerializer;
|
||||||
|
}
|
@ -0,0 +1,212 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'urls.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// BuiltValueGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
Serializer<Urls> _$urlsSerializer = new _$UrlsSerializer();
|
||||||
|
|
||||||
|
class _$UrlsSerializer implements StructuredSerializer<Urls> {
|
||||||
|
@override
|
||||||
|
final Iterable<Type> types = const [Urls, _$Urls];
|
||||||
|
@override
|
||||||
|
final String wireName = 'Urls';
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<Object> serialize(Serializers serializers, Urls object,
|
||||||
|
{FullType specifiedType = FullType.unspecified}) {
|
||||||
|
final result = <Object>[];
|
||||||
|
if (object.raw != null) {
|
||||||
|
result
|
||||||
|
..add('raw')
|
||||||
|
..add(serializers.serialize(object.raw,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
if (object.full != null) {
|
||||||
|
result
|
||||||
|
..add('full')
|
||||||
|
..add(serializers.serialize(object.full,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
if (object.regular != null) {
|
||||||
|
result
|
||||||
|
..add('regular')
|
||||||
|
..add(serializers.serialize(object.regular,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
if (object.small != null) {
|
||||||
|
result
|
||||||
|
..add('small')
|
||||||
|
..add(serializers.serialize(object.small,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
if (object.thumb != null) {
|
||||||
|
result
|
||||||
|
..add('thumb')
|
||||||
|
..add(serializers.serialize(object.thumb,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Urls deserialize(Serializers serializers, Iterable<Object> serialized,
|
||||||
|
{FullType specifiedType = FullType.unspecified}) {
|
||||||
|
final result = new UrlsBuilder();
|
||||||
|
|
||||||
|
final iterator = serialized.iterator;
|
||||||
|
while (iterator.moveNext()) {
|
||||||
|
final key = iterator.current as String;
|
||||||
|
iterator.moveNext();
|
||||||
|
final dynamic value = iterator.current;
|
||||||
|
switch (key) {
|
||||||
|
case 'raw':
|
||||||
|
result.raw = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'full':
|
||||||
|
result.full = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'regular':
|
||||||
|
result.regular = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'small':
|
||||||
|
result.small = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'thumb':
|
||||||
|
result.thumb = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _$Urls extends Urls {
|
||||||
|
@override
|
||||||
|
final String raw;
|
||||||
|
@override
|
||||||
|
final String full;
|
||||||
|
@override
|
||||||
|
final String regular;
|
||||||
|
@override
|
||||||
|
final String small;
|
||||||
|
@override
|
||||||
|
final String thumb;
|
||||||
|
|
||||||
|
factory _$Urls([void Function(UrlsBuilder) updates]) =>
|
||||||
|
(new UrlsBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
_$Urls._({this.raw, this.full, this.regular, this.small, this.thumb})
|
||||||
|
: super._();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Urls rebuild(void Function(UrlsBuilder) updates) =>
|
||||||
|
(toBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
@override
|
||||||
|
UrlsBuilder toBuilder() => new UrlsBuilder()..replace(this);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(other, this)) return true;
|
||||||
|
return other is Urls &&
|
||||||
|
raw == other.raw &&
|
||||||
|
full == other.full &&
|
||||||
|
regular == other.regular &&
|
||||||
|
small == other.small &&
|
||||||
|
thumb == other.thumb;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return $jf($jc(
|
||||||
|
$jc($jc($jc($jc(0, raw.hashCode), full.hashCode), regular.hashCode),
|
||||||
|
small.hashCode),
|
||||||
|
thumb.hashCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (newBuiltValueToStringHelper('Urls')
|
||||||
|
..add('raw', raw)
|
||||||
|
..add('full', full)
|
||||||
|
..add('regular', regular)
|
||||||
|
..add('small', small)
|
||||||
|
..add('thumb', thumb))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UrlsBuilder implements Builder<Urls, UrlsBuilder> {
|
||||||
|
_$Urls _$v;
|
||||||
|
|
||||||
|
String _raw;
|
||||||
|
String get raw => _$this._raw;
|
||||||
|
set raw(String raw) => _$this._raw = raw;
|
||||||
|
|
||||||
|
String _full;
|
||||||
|
String get full => _$this._full;
|
||||||
|
set full(String full) => _$this._full = full;
|
||||||
|
|
||||||
|
String _regular;
|
||||||
|
String get regular => _$this._regular;
|
||||||
|
set regular(String regular) => _$this._regular = regular;
|
||||||
|
|
||||||
|
String _small;
|
||||||
|
String get small => _$this._small;
|
||||||
|
set small(String small) => _$this._small = small;
|
||||||
|
|
||||||
|
String _thumb;
|
||||||
|
String get thumb => _$this._thumb;
|
||||||
|
set thumb(String thumb) => _$this._thumb = thumb;
|
||||||
|
|
||||||
|
UrlsBuilder();
|
||||||
|
|
||||||
|
UrlsBuilder get _$this {
|
||||||
|
if (_$v != null) {
|
||||||
|
_raw = _$v.raw;
|
||||||
|
_full = _$v.full;
|
||||||
|
_regular = _$v.regular;
|
||||||
|
_small = _$v.small;
|
||||||
|
_thumb = _$v.thumb;
|
||||||
|
_$v = null;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void replace(Urls other) {
|
||||||
|
if (other == null) {
|
||||||
|
throw new ArgumentError.notNull('other');
|
||||||
|
}
|
||||||
|
_$v = other as _$Urls;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void update(void Function(UrlsBuilder) updates) {
|
||||||
|
if (updates != null) updates(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
_$Urls build() {
|
||||||
|
final _$result = _$v ??
|
||||||
|
new _$Urls._(
|
||||||
|
raw: raw, full: full, regular: regular, small: small, thumb: thumb);
|
||||||
|
replace(_$result);
|
||||||
|
return _$result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore_for_file: always_put_control_body_on_new_line,always_specify_types,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,lines_longer_than_80_chars,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new
|
@ -0,0 +1,71 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:built_value/built_value.dart';
|
||||||
|
import 'package:built_value/serializer.dart';
|
||||||
|
|
||||||
|
import '../serializers.dart';
|
||||||
|
import 'links.dart';
|
||||||
|
|
||||||
|
part 'user.g.dart';
|
||||||
|
|
||||||
|
abstract class User implements Built<User, UserBuilder> {
|
||||||
|
factory User([void Function(UserBuilder) updates]) = _$User;
|
||||||
|
|
||||||
|
User._();
|
||||||
|
|
||||||
|
@BuiltValueField(wireName: 'id')
|
||||||
|
String get id;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'updated_at')
|
||||||
|
String get updatedAt;
|
||||||
|
|
||||||
|
@BuiltValueField(wireName: 'username')
|
||||||
|
String get username;
|
||||||
|
|
||||||
|
@BuiltValueField(wireName: 'name')
|
||||||
|
String get name;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'portfolio_url')
|
||||||
|
String get portfolioUrl;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'bio')
|
||||||
|
String get bio;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'location')
|
||||||
|
String get location;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'total_likes')
|
||||||
|
int get totalLikes;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'total_photos')
|
||||||
|
int get totalPhotos;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'total_collections')
|
||||||
|
int get totalCollections;
|
||||||
|
|
||||||
|
@nullable
|
||||||
|
@BuiltValueField(wireName: 'links')
|
||||||
|
Links get links;
|
||||||
|
|
||||||
|
String toJson() {
|
||||||
|
return json.encode(serializers.serializeWith(User.serializer, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
static User fromJson(String jsonString) {
|
||||||
|
return serializers.deserializeWith(
|
||||||
|
User.serializer, json.decode(jsonString));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Serializer<User> get serializer => _$userSerializer;
|
||||||
|
}
|
@ -0,0 +1,377 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'user.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// BuiltValueGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
Serializer<User> _$userSerializer = new _$UserSerializer();
|
||||||
|
|
||||||
|
class _$UserSerializer implements StructuredSerializer<User> {
|
||||||
|
@override
|
||||||
|
final Iterable<Type> types = const [User, _$User];
|
||||||
|
@override
|
||||||
|
final String wireName = 'User';
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<Object> serialize(Serializers serializers, User object,
|
||||||
|
{FullType specifiedType = FullType.unspecified}) {
|
||||||
|
final result = <Object>[
|
||||||
|
'id',
|
||||||
|
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)),
|
||||||
|
];
|
||||||
|
if (object.updatedAt != null) {
|
||||||
|
result
|
||||||
|
..add('updated_at')
|
||||||
|
..add(serializers.serialize(object.updatedAt,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
if (object.portfolioUrl != null) {
|
||||||
|
result
|
||||||
|
..add('portfolio_url')
|
||||||
|
..add(serializers.serialize(object.portfolioUrl,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
if (object.bio != null) {
|
||||||
|
result
|
||||||
|
..add('bio')
|
||||||
|
..add(serializers.serialize(object.bio,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
if (object.location != null) {
|
||||||
|
result
|
||||||
|
..add('location')
|
||||||
|
..add(serializers.serialize(object.location,
|
||||||
|
specifiedType: const FullType(String)));
|
||||||
|
}
|
||||||
|
if (object.totalLikes != null) {
|
||||||
|
result
|
||||||
|
..add('total_likes')
|
||||||
|
..add(serializers.serialize(object.totalLikes,
|
||||||
|
specifiedType: const FullType(int)));
|
||||||
|
}
|
||||||
|
if (object.totalPhotos != null) {
|
||||||
|
result
|
||||||
|
..add('total_photos')
|
||||||
|
..add(serializers.serialize(object.totalPhotos,
|
||||||
|
specifiedType: const FullType(int)));
|
||||||
|
}
|
||||||
|
if (object.totalCollections != null) {
|
||||||
|
result
|
||||||
|
..add('total_collections')
|
||||||
|
..add(serializers.serialize(object.totalCollections,
|
||||||
|
specifiedType: const FullType(int)));
|
||||||
|
}
|
||||||
|
if (object.links != null) {
|
||||||
|
result
|
||||||
|
..add('links')
|
||||||
|
..add(serializers.serialize(object.links,
|
||||||
|
specifiedType: const FullType(Links)));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
User deserialize(Serializers serializers, Iterable<Object> serialized,
|
||||||
|
{FullType specifiedType = FullType.unspecified}) {
|
||||||
|
final result = new UserBuilder();
|
||||||
|
|
||||||
|
final iterator = serialized.iterator;
|
||||||
|
while (iterator.moveNext()) {
|
||||||
|
final key = iterator.current as String;
|
||||||
|
iterator.moveNext();
|
||||||
|
final dynamic value = iterator.current;
|
||||||
|
switch (key) {
|
||||||
|
case 'id':
|
||||||
|
result.id = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'updated_at':
|
||||||
|
result.updatedAt = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'username':
|
||||||
|
result.username = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'name':
|
||||||
|
result.name = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'portfolio_url':
|
||||||
|
result.portfolioUrl = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'bio':
|
||||||
|
result.bio = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'location':
|
||||||
|
result.location = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(String)) as String;
|
||||||
|
break;
|
||||||
|
case 'total_likes':
|
||||||
|
result.totalLikes = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(int)) as int;
|
||||||
|
break;
|
||||||
|
case 'total_photos':
|
||||||
|
result.totalPhotos = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(int)) as int;
|
||||||
|
break;
|
||||||
|
case 'total_collections':
|
||||||
|
result.totalCollections = serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(int)) as int;
|
||||||
|
break;
|
||||||
|
case 'links':
|
||||||
|
result.links.replace(serializers.deserialize(value,
|
||||||
|
specifiedType: const FullType(Links)) as Links);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _$User extends User {
|
||||||
|
@override
|
||||||
|
final String id;
|
||||||
|
@override
|
||||||
|
final String updatedAt;
|
||||||
|
@override
|
||||||
|
final String username;
|
||||||
|
@override
|
||||||
|
final String name;
|
||||||
|
@override
|
||||||
|
final String portfolioUrl;
|
||||||
|
@override
|
||||||
|
final String bio;
|
||||||
|
@override
|
||||||
|
final String location;
|
||||||
|
@override
|
||||||
|
final int totalLikes;
|
||||||
|
@override
|
||||||
|
final int totalPhotos;
|
||||||
|
@override
|
||||||
|
final int totalCollections;
|
||||||
|
@override
|
||||||
|
final Links links;
|
||||||
|
|
||||||
|
factory _$User([void Function(UserBuilder) updates]) =>
|
||||||
|
(new UserBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
_$User._(
|
||||||
|
{this.id,
|
||||||
|
this.updatedAt,
|
||||||
|
this.username,
|
||||||
|
this.name,
|
||||||
|
this.portfolioUrl,
|
||||||
|
this.bio,
|
||||||
|
this.location,
|
||||||
|
this.totalLikes,
|
||||||
|
this.totalPhotos,
|
||||||
|
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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
User rebuild(void Function(UserBuilder) updates) =>
|
||||||
|
(toBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
@override
|
||||||
|
UserBuilder toBuilder() => new UserBuilder()..replace(this);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(other, this)) return true;
|
||||||
|
return other is User &&
|
||||||
|
id == other.id &&
|
||||||
|
updatedAt == other.updatedAt &&
|
||||||
|
username == other.username &&
|
||||||
|
name == other.name &&
|
||||||
|
portfolioUrl == other.portfolioUrl &&
|
||||||
|
bio == other.bio &&
|
||||||
|
location == other.location &&
|
||||||
|
totalLikes == other.totalLikes &&
|
||||||
|
totalPhotos == other.totalPhotos &&
|
||||||
|
totalCollections == other.totalCollections &&
|
||||||
|
links == other.links;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return $jf($jc(
|
||||||
|
$jc(
|
||||||
|
$jc(
|
||||||
|
$jc(
|
||||||
|
$jc(
|
||||||
|
$jc(
|
||||||
|
$jc(
|
||||||
|
$jc(
|
||||||
|
$jc(
|
||||||
|
$jc($jc(0, id.hashCode),
|
||||||
|
updatedAt.hashCode),
|
||||||
|
username.hashCode),
|
||||||
|
name.hashCode),
|
||||||
|
portfolioUrl.hashCode),
|
||||||
|
bio.hashCode),
|
||||||
|
location.hashCode),
|
||||||
|
totalLikes.hashCode),
|
||||||
|
totalPhotos.hashCode),
|
||||||
|
totalCollections.hashCode),
|
||||||
|
links.hashCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (newBuiltValueToStringHelper('User')
|
||||||
|
..add('id', id)
|
||||||
|
..add('updatedAt', updatedAt)
|
||||||
|
..add('username', username)
|
||||||
|
..add('name', name)
|
||||||
|
..add('portfolioUrl', portfolioUrl)
|
||||||
|
..add('bio', bio)
|
||||||
|
..add('location', location)
|
||||||
|
..add('totalLikes', totalLikes)
|
||||||
|
..add('totalPhotos', totalPhotos)
|
||||||
|
..add('totalCollections', totalCollections)
|
||||||
|
..add('links', links))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UserBuilder implements Builder<User, UserBuilder> {
|
||||||
|
_$User _$v;
|
||||||
|
|
||||||
|
String _id;
|
||||||
|
String get id => _$this._id;
|
||||||
|
set id(String id) => _$this._id = id;
|
||||||
|
|
||||||
|
String _updatedAt;
|
||||||
|
String get updatedAt => _$this._updatedAt;
|
||||||
|
set updatedAt(String updatedAt) => _$this._updatedAt = updatedAt;
|
||||||
|
|
||||||
|
String _username;
|
||||||
|
String get username => _$this._username;
|
||||||
|
set username(String username) => _$this._username = username;
|
||||||
|
|
||||||
|
String _name;
|
||||||
|
String get name => _$this._name;
|
||||||
|
set name(String name) => _$this._name = name;
|
||||||
|
|
||||||
|
String _portfolioUrl;
|
||||||
|
String get portfolioUrl => _$this._portfolioUrl;
|
||||||
|
set portfolioUrl(String portfolioUrl) => _$this._portfolioUrl = portfolioUrl;
|
||||||
|
|
||||||
|
String _bio;
|
||||||
|
String get bio => _$this._bio;
|
||||||
|
set bio(String bio) => _$this._bio = bio;
|
||||||
|
|
||||||
|
String _location;
|
||||||
|
String get location => _$this._location;
|
||||||
|
set location(String location) => _$this._location = location;
|
||||||
|
|
||||||
|
int _totalLikes;
|
||||||
|
int get totalLikes => _$this._totalLikes;
|
||||||
|
set totalLikes(int totalLikes) => _$this._totalLikes = totalLikes;
|
||||||
|
|
||||||
|
int _totalPhotos;
|
||||||
|
int get totalPhotos => _$this._totalPhotos;
|
||||||
|
set totalPhotos(int totalPhotos) => _$this._totalPhotos = totalPhotos;
|
||||||
|
|
||||||
|
int _totalCollections;
|
||||||
|
int get totalCollections => _$this._totalCollections;
|
||||||
|
set totalCollections(int totalCollections) =>
|
||||||
|
_$this._totalCollections = totalCollections;
|
||||||
|
|
||||||
|
LinksBuilder _links;
|
||||||
|
LinksBuilder get links => _$this._links ??= new LinksBuilder();
|
||||||
|
set links(LinksBuilder links) => _$this._links = links;
|
||||||
|
|
||||||
|
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();
|
||||||
|
_$v = null;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void replace(User other) {
|
||||||
|
if (other == null) {
|
||||||
|
throw new ArgumentError.notNull('other');
|
||||||
|
}
|
||||||
|
_$v = other as _$User;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void update(void Function(UserBuilder) updates) {
|
||||||
|
if (updates != null) updates(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
_$User build() {
|
||||||
|
_$User _$result;
|
||||||
|
try {
|
||||||
|
_$result = _$v ??
|
||||||
|
new _$User._(
|
||||||
|
id: id,
|
||||||
|
updatedAt: updatedAt,
|
||||||
|
username: username,
|
||||||
|
name: name,
|
||||||
|
portfolioUrl: portfolioUrl,
|
||||||
|
bio: bio,
|
||||||
|
location: location,
|
||||||
|
totalLikes: totalLikes,
|
||||||
|
totalPhotos: totalPhotos,
|
||||||
|
totalCollections: totalCollections,
|
||||||
|
links: _links?.build());
|
||||||
|
} catch (_) {
|
||||||
|
String _$failedField;
|
||||||
|
try {
|
||||||
|
_$failedField = 'links';
|
||||||
|
_links?.build();
|
||||||
|
} catch (e) {
|
||||||
|
throw new BuiltValueNestedFieldError(
|
||||||
|
'User', _$failedField, e.toString());
|
||||||
|
}
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
replace(_$result);
|
||||||
|
return _$result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore_for_file: always_put_control_body_on_new_line,always_specify_types,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,lines_longer_than_80_chars,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new
|
@ -0,0 +1,350 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/scheduler.dart';
|
||||||
|
|
||||||
|
class DataTreeRule extends StatelessWidget {
|
||||||
|
const DataTreeRule({Key key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
height: 2,
|
||||||
|
color: Theme.of(context).colorScheme.onBackground.withOpacity(0.1),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DataTreeInkWell extends StatefulWidget {
|
||||||
|
const DataTreeInkWell({Key key, this.onTap, this.isSelected, this.child})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
final VoidCallback onTap;
|
||||||
|
final bool isSelected;
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
|
@override
|
||||||
|
_DataTreeInkWellState createState() => _DataTreeInkWellState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DataTreeInkWellState extends State<DataTreeInkWell>
|
||||||
|
with SingleTickerProviderStateMixin {
|
||||||
|
AnimationController controller;
|
||||||
|
Animation selectionColor;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
controller = AnimationController(
|
||||||
|
duration: const Duration(milliseconds: 100), vsync: this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
controller.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didUpdateWidget(DataTreeInkWell oldWidget) {
|
||||||
|
super.didUpdateWidget(oldWidget);
|
||||||
|
if (widget.isSelected) {
|
||||||
|
controller.forward();
|
||||||
|
} else {
|
||||||
|
controller.reverse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final ColorScheme colorScheme = Theme.of(context).colorScheme;
|
||||||
|
|
||||||
|
final Animation<Color> backgroundColor = controller
|
||||||
|
.drive(CurveTween(curve: Curves.fastOutSlowIn))
|
||||||
|
.drive(ColorTween(
|
||||||
|
begin: colorScheme.primary.withOpacity(0.0),
|
||||||
|
end: colorScheme.primary.withOpacity(0.08),
|
||||||
|
));
|
||||||
|
|
||||||
|
final Animation<Color> iconColor = controller
|
||||||
|
.drive(CurveTween(curve: Curves.fastOutSlowIn))
|
||||||
|
.drive(ColorTween(
|
||||||
|
begin: colorScheme.onBackground.withOpacity(0.54),
|
||||||
|
end: colorScheme.onBackground.withOpacity(0.87),
|
||||||
|
));
|
||||||
|
|
||||||
|
return AnimatedBuilder(
|
||||||
|
animation: controller,
|
||||||
|
builder: (context, child) {
|
||||||
|
return IconTheme(
|
||||||
|
data: IconThemeData(color: iconColor.value),
|
||||||
|
child: Container(
|
||||||
|
color: backgroundColor.value,
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: InkWell(
|
||||||
|
onTap: widget.onTap,
|
||||||
|
splashFactory: InkRipple.splashFactory,
|
||||||
|
splashColor: colorScheme.primary.withOpacity(0.14),
|
||||||
|
highlightColor: Colors.transparent,
|
||||||
|
child: widget.child,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DataTreeNode extends StatefulWidget {
|
||||||
|
const DataTreeNode({
|
||||||
|
Key key,
|
||||||
|
this.leading,
|
||||||
|
@required this.title,
|
||||||
|
this.backgroundColor,
|
||||||
|
this.onExpansionChanged,
|
||||||
|
this.onSelectionChanged,
|
||||||
|
this.children = const <Widget>[],
|
||||||
|
this.initiallyExpanded = false,
|
||||||
|
this.indent = 0,
|
||||||
|
this.height = 36,
|
||||||
|
}) : assert(initiallyExpanded != null),
|
||||||
|
assert(indent != null && indent >= 0),
|
||||||
|
super(key: key);
|
||||||
|
|
||||||
|
final Widget leading;
|
||||||
|
final Widget title;
|
||||||
|
final ValueChanged<bool> onExpansionChanged;
|
||||||
|
final ValueChanged<bool> onSelectionChanged;
|
||||||
|
final List<Widget> children;
|
||||||
|
final Color backgroundColor;
|
||||||
|
final bool initiallyExpanded;
|
||||||
|
final double indent;
|
||||||
|
final double height;
|
||||||
|
|
||||||
|
@override
|
||||||
|
_DataTreeNodeState createState() => _DataTreeNodeState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DataTreeNodeState extends State<DataTreeNode>
|
||||||
|
with SingleTickerProviderStateMixin {
|
||||||
|
static final Animatable<double> _easeInTween =
|
||||||
|
CurveTween(curve: Curves.easeIn);
|
||||||
|
static final Animatable<double> _halfTween =
|
||||||
|
Tween<double>(begin: 0.0, end: 0.25);
|
||||||
|
|
||||||
|
AnimationController _controller;
|
||||||
|
Animation<double> _iconTurns;
|
||||||
|
Animation<double> _heightFactor;
|
||||||
|
|
||||||
|
bool _isExpanded = false;
|
||||||
|
bool _isSelected = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_controller = AnimationController(
|
||||||
|
duration: const Duration(milliseconds: 200), vsync: this);
|
||||||
|
_heightFactor = _controller.drive(_easeInTween);
|
||||||
|
_iconTurns = _controller.drive(_halfTween.chain(_easeInTween));
|
||||||
|
_isExpanded = (PageStorage.of(context)?.readState(context) ??
|
||||||
|
widget.initiallyExpanded) as bool;
|
||||||
|
if (_isExpanded) {
|
||||||
|
_controller.value = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_controller.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handleNodeTap() {
|
||||||
|
setState(() {
|
||||||
|
_isExpanded = !_isExpanded;
|
||||||
|
if (_isExpanded) {
|
||||||
|
_controller.forward();
|
||||||
|
} else {
|
||||||
|
_controller.reverse().then<void>((value) {
|
||||||
|
if (!mounted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setState(() {
|
||||||
|
// Rebuild without widget.children.
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
PageStorage.of(context)?.writeState(context, _isExpanded);
|
||||||
|
});
|
||||||
|
if (widget.onExpansionChanged != null) {
|
||||||
|
widget.onExpansionChanged(_isExpanded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handleLeafTap() {
|
||||||
|
_isSelected = !_isSelected;
|
||||||
|
if (widget.onSelectionChanged != null) {
|
||||||
|
widget.onSelectionChanged(_isSelected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildChildren(BuildContext context, Widget child) {
|
||||||
|
return Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: <Widget>[
|
||||||
|
DataTreeInkWell(
|
||||||
|
onTap: _handleNodeTap,
|
||||||
|
isSelected: _isExpanded,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: <Widget>[
|
||||||
|
SizedBox(width: widget.indent),
|
||||||
|
RotationTransition(
|
||||||
|
turns: _iconTurns,
|
||||||
|
child: Icon(
|
||||||
|
Icons.arrow_right,
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Icon(
|
||||||
|
Icons.folder,
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 16),
|
||||||
|
widget.title,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (child != null) // If child == null, then this DataNode is closed.
|
||||||
|
const DataTreeRule(),
|
||||||
|
if (child != null)
|
||||||
|
ClipRect(
|
||||||
|
child: Align(
|
||||||
|
alignment: Alignment.topLeft,
|
||||||
|
heightFactor: _heightFactor.value,
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final ColorScheme colorScheme = Theme.of(context).colorScheme;
|
||||||
|
final Color textColor = colorScheme.onBackground.withOpacity(0.87);
|
||||||
|
|
||||||
|
final bool closed = !_isExpanded && _controller.isDismissed;
|
||||||
|
|
||||||
|
return widget.children.isEmpty
|
||||||
|
// Leaf node.
|
||||||
|
? DataTreeInkWell(
|
||||||
|
onTap: _handleLeafTap,
|
||||||
|
isSelected: _isSelected,
|
||||||
|
child: Row(
|
||||||
|
children: <Widget>[
|
||||||
|
SizedBox(width: widget.indent),
|
||||||
|
Icon(
|
||||||
|
Icons.web_asset,
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 16),
|
||||||
|
DefaultTextStyle(
|
||||||
|
style: Theme.of(context).textTheme.body1.copyWith(
|
||||||
|
color: textColor,
|
||||||
|
),
|
||||||
|
child: widget.title,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
// Not a leaf node.
|
||||||
|
: AnimatedBuilder(
|
||||||
|
animation: _controller.view,
|
||||||
|
builder: _buildChildren,
|
||||||
|
child: closed
|
||||||
|
? null
|
||||||
|
: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: <Widget>[
|
||||||
|
for (int index = 0;
|
||||||
|
index < (widget.children.length * 2) - 1;
|
||||||
|
index += 1)
|
||||||
|
(index % 2 == 1)
|
||||||
|
? const DataTreeRule()
|
||||||
|
: widget.children[index ~/ 2],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// One entry in the multilevel list displayed by this app.
|
||||||
|
class Entry {
|
||||||
|
Entry(this.title, [this.children = const <Entry>[]]);
|
||||||
|
final String title;
|
||||||
|
final List<Entry> children;
|
||||||
|
bool isSelected = false;
|
||||||
|
bool isEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A visualization of one Entry based on DataTreeNode.
|
||||||
|
class EntryItem extends StatefulWidget {
|
||||||
|
const EntryItem({Key key, this.entry}) : super(key: key);
|
||||||
|
|
||||||
|
final Entry entry;
|
||||||
|
|
||||||
|
@override
|
||||||
|
_EntryItemState createState() => _EntryItemState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _EntryItemState extends State<EntryItem> {
|
||||||
|
Widget _buildNodes(Entry root, double indent) {
|
||||||
|
return DataTreeNode(
|
||||||
|
key: PageStorageKey<Entry>(root),
|
||||||
|
onSelectionChanged: (isSelected) {
|
||||||
|
setState(() {
|
||||||
|
root.isSelected = isSelected;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
title: Container(
|
||||||
|
alignment: AlignmentDirectional.centerStart,
|
||||||
|
height: 36,
|
||||||
|
child: Text(root.title),
|
||||||
|
),
|
||||||
|
indent: indent,
|
||||||
|
children: root.children.map<Widget>((entry) {
|
||||||
|
return _buildNodes(entry, indent + 28);
|
||||||
|
}).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return _buildNodes(widget.entry, 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DataTree extends StatelessWidget {
|
||||||
|
DataTree(this.entries)
|
||||||
|
: assert(entries != null),
|
||||||
|
assert(entries.isNotEmpty);
|
||||||
|
final List<Entry> entries;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => ListView.builder(
|
||||||
|
itemCount: entries.length * 2 - 1,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
if (index % 2 == 1) {
|
||||||
|
return const DataTreeRule();
|
||||||
|
}
|
||||||
|
return EntryItem(
|
||||||
|
entry: entries[index ~/ 2],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,126 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// 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 '../../unsplash_access_key.dart';
|
||||||
|
import '../unsplash/photo.dart';
|
||||||
|
|
||||||
|
final _unsplashHomepage = Uri.encodeFull(
|
||||||
|
'https://unsplash.com/?utm_source=$unsplashAppName&utm_medium=referral');
|
||||||
|
|
||||||
|
typedef PhotoDetailsPhotoSaveCallback = void Function(Photo);
|
||||||
|
|
||||||
|
class PhotoDetails extends StatefulWidget {
|
||||||
|
const PhotoDetails({
|
||||||
|
@required this.photo,
|
||||||
|
@required this.onPhotoSave,
|
||||||
|
});
|
||||||
|
final Photo photo;
|
||||||
|
final PhotoDetailsPhotoSaveCallback onPhotoSave;
|
||||||
|
|
||||||
|
@override
|
||||||
|
_PhotoDetailsState createState() => _PhotoDetailsState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PhotoDetailsState extends State<PhotoDetails>
|
||||||
|
with SingleTickerProviderStateMixin {
|
||||||
|
Widget _buildPhotoAttribution(BuildContext context) {
|
||||||
|
return RichText(
|
||||||
|
text: TextSpan(
|
||||||
|
style: Theme.of(context).textTheme.body1,
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SingleChildScrollView(
|
||||||
|
child: Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Card(
|
||||||
|
shape: ContinuousRectangleBorder(
|
||||||
|
side: BorderSide(color: Colors.black12),
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
),
|
||||||
|
child: AnimatedSize(
|
||||||
|
vsync: this,
|
||||||
|
duration: Duration(milliseconds: 750),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(16, 16, 16, 40),
|
||||||
|
child: ConstrainedBox(
|
||||||
|
constraints: BoxConstraints(
|
||||||
|
minWidth: 400,
|
||||||
|
minHeight: 400,
|
||||||
|
),
|
||||||
|
child: FadeInImage.memoryNetwork(
|
||||||
|
placeholder: kTransparentImage,
|
||||||
|
image: widget.photo.urls.small,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 4),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
_buildPhotoAttribution(context),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
IconButton(
|
||||||
|
visualDensity: VisualDensity.compact,
|
||||||
|
icon: Icon(Icons.cloud_download),
|
||||||
|
onPressed: () => widget.onPhotoSave(widget.photo),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 48),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
typedef PhotoSearchDialogCallback = void Function(String searchQuery);
|
||||||
|
|
||||||
|
class PhotoSearchDialog extends StatefulWidget {
|
||||||
|
const PhotoSearchDialog(this.callback);
|
||||||
|
final PhotoSearchDialogCallback callback;
|
||||||
|
@override
|
||||||
|
State<PhotoSearchDialog> createState() => _PhotoSearchDialogState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PhotoSearchDialogState extends State<PhotoSearchDialog> {
|
||||||
|
final _controller = TextEditingController();
|
||||||
|
bool _searchEnabled = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_controller.addListener(() {
|
||||||
|
setState(() {
|
||||||
|
_searchEnabled = _controller.text.isNotEmpty;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_controller.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => AlertDialog(
|
||||||
|
title: const Text('Photo Search'),
|
||||||
|
content: TextField(
|
||||||
|
autofocus: true,
|
||||||
|
controller: _controller,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
hintText: 'Search query',
|
||||||
|
),
|
||||||
|
onSubmitted: (content) {
|
||||||
|
if (content.isNotEmpty) {
|
||||||
|
widget.callback(content);
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
actions: <Widget>[
|
||||||
|
FlatButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: Text('Cancel'.toUpperCase()),
|
||||||
|
),
|
||||||
|
FlatButton(
|
||||||
|
onPressed: _searchEnabled
|
||||||
|
? () {
|
||||||
|
widget.callback(_controller.text);
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
child: Text('Search'.toUpperCase()),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,194 @@
|
|||||||
|
// Copyright 2019 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:flutter/gestures.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
/// A widget that takes two children, lays them out along [axis], and allows
|
||||||
|
/// the user to resize them.
|
||||||
|
///
|
||||||
|
/// The user can customize the amount of space allocated to each child by
|
||||||
|
/// dragging a divider between them.
|
||||||
|
///
|
||||||
|
/// [initialFirstFraction] defines how much space to give the [firstChild]
|
||||||
|
/// when first building this widget. [secondChild] will take the remaining
|
||||||
|
/// space.
|
||||||
|
///
|
||||||
|
/// The user can drag the widget with key [dividerKey] to change
|
||||||
|
/// the space allocated between [firstChild] and [secondChild].
|
||||||
|
// TODO(djshuckerow): introduce support for a minimum fraction a child
|
||||||
|
// is allowed.
|
||||||
|
class Split extends StatefulWidget {
|
||||||
|
/// Builds a split oriented along [axis].
|
||||||
|
const Split({
|
||||||
|
Key key,
|
||||||
|
@required this.axis,
|
||||||
|
@required this.firstChild,
|
||||||
|
@required this.secondChild,
|
||||||
|
double initialFirstFraction,
|
||||||
|
}) : initialFirstFraction = initialFirstFraction ?? 0.5,
|
||||||
|
assert(axis != null),
|
||||||
|
assert(firstChild != null),
|
||||||
|
assert(secondChild != null),
|
||||||
|
super(key: key);
|
||||||
|
|
||||||
|
/// The main axis the children will lay out on.
|
||||||
|
///
|
||||||
|
/// If [Axis.horizontal], the children will be placed in a [Row]
|
||||||
|
/// and they will be horizontally resizable.
|
||||||
|
///
|
||||||
|
/// If [Axis.vertical], the children will be placed in a [Column]
|
||||||
|
/// and they will be vertically resizable.
|
||||||
|
///
|
||||||
|
/// Cannot be null.
|
||||||
|
final Axis axis;
|
||||||
|
|
||||||
|
/// The child that will be laid out first along [axis].
|
||||||
|
final Widget firstChild;
|
||||||
|
|
||||||
|
/// The child that will be laid out last along [axis].
|
||||||
|
final Widget secondChild;
|
||||||
|
|
||||||
|
/// The fraction of the layout to allocate to [firstChild].
|
||||||
|
///
|
||||||
|
/// [secondChild] will receive a fraction of `1 - initialFirstFraction`.
|
||||||
|
final double initialFirstFraction;
|
||||||
|
|
||||||
|
/// The key passed to the divider between [firstChild] and [secondChild].
|
||||||
|
///
|
||||||
|
/// Visible to grab it in tests.
|
||||||
|
@visibleForTesting
|
||||||
|
Key get dividerKey => Key('$this dividerKey');
|
||||||
|
|
||||||
|
/// The size of the divider between [firstChild] and [secondChild] in
|
||||||
|
/// logical pixels (dp, not px).
|
||||||
|
static const double dividerMainAxisSize = 10;
|
||||||
|
|
||||||
|
static Axis axisFor(BuildContext context, double horizontalAspectRatio) {
|
||||||
|
final screenSize = MediaQuery.of(context).size;
|
||||||
|
final aspectRatio = screenSize.width / screenSize.height;
|
||||||
|
if (aspectRatio >= horizontalAspectRatio) {
|
||||||
|
return Axis.horizontal;
|
||||||
|
}
|
||||||
|
return Axis.vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() => _SplitState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SplitState extends State<Split> {
|
||||||
|
double firstFraction;
|
||||||
|
|
||||||
|
double get secondFraction => 1 - firstFraction;
|
||||||
|
|
||||||
|
bool get isHorizontal => widget.axis == Axis.horizontal;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
firstFraction = widget.initialFirstFraction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return LayoutBuilder(builder: _buildLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildLayout(BuildContext context, BoxConstraints constraints) {
|
||||||
|
final width = constraints.maxWidth;
|
||||||
|
final height = constraints.maxHeight;
|
||||||
|
final axisSize = isHorizontal ? width : height;
|
||||||
|
final crossAxisSize = isHorizontal ? height : width;
|
||||||
|
const halfDivider = Split.dividerMainAxisSize / 2.0;
|
||||||
|
|
||||||
|
// Determine what fraction to give each child, including enough space to
|
||||||
|
// display the divider.
|
||||||
|
double firstSize = axisSize * firstFraction;
|
||||||
|
double secondSize = axisSize * secondFraction;
|
||||||
|
|
||||||
|
// Clamp the sizes to be sure there is enough space for the dividers.
|
||||||
|
firstSize = firstSize.clamp(halfDivider, axisSize - halfDivider) as double;
|
||||||
|
secondSize =
|
||||||
|
secondSize.clamp(halfDivider, axisSize - halfDivider) as double;
|
||||||
|
|
||||||
|
// Remove space from each child to place the divider in the middle.
|
||||||
|
firstSize = firstSize - halfDivider;
|
||||||
|
secondSize = secondSize - halfDivider;
|
||||||
|
|
||||||
|
void updateSpacing(DragUpdateDetails dragDetails) {
|
||||||
|
final delta = isHorizontal ? dragDetails.delta.dx : dragDetails.delta.dy;
|
||||||
|
final fractionalDelta = delta / axisSize;
|
||||||
|
setState(() {
|
||||||
|
// Update the fraction of space consumed by the children,
|
||||||
|
// being sure not to allocate any negative space.
|
||||||
|
firstFraction += fractionalDelta;
|
||||||
|
firstFraction = firstFraction.clamp(0.0, 1.0) as double;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(https://github.com/flutter/flutter/issues/43747): use an icon.
|
||||||
|
// The material icon for a drag handle is not currently available.
|
||||||
|
// For now, draw an indicator that is 3 lines running in the direction
|
||||||
|
// of the main axis, like a hamburger menu.
|
||||||
|
// TODO(https://github.com/flutter/devtools/issues/1265): update mouse
|
||||||
|
// to indicate that this is resizable.
|
||||||
|
final dragIndicator = Flex(
|
||||||
|
direction: isHorizontal ? Axis.vertical : Axis.horizontal,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
for (var i = 0; i < min(crossAxisSize / 6.0, 3).floor(); i++)
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: isHorizontal ? 2.0 : 0.0,
|
||||||
|
horizontal: isHorizontal ? 0.0 : 2.0,
|
||||||
|
),
|
||||||
|
child: DecoratedBox(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).dividerColor,
|
||||||
|
borderRadius: BorderRadius.circular(Split.dividerMainAxisSize),
|
||||||
|
),
|
||||||
|
child: SizedBox(
|
||||||
|
height: isHorizontal ? 2.0 : Split.dividerMainAxisSize - 2.0,
|
||||||
|
width: isHorizontal ? Split.dividerMainAxisSize - 2.0 : 2.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
final children = [
|
||||||
|
SizedBox(
|
||||||
|
width: isHorizontal ? firstSize : width,
|
||||||
|
height: isHorizontal ? height : firstSize,
|
||||||
|
child: widget.firstChild,
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
key: widget.dividerKey,
|
||||||
|
behavior: HitTestBehavior.translucent,
|
||||||
|
onHorizontalDragUpdate: isHorizontal ? updateSpacing : null,
|
||||||
|
onVerticalDragUpdate: isHorizontal ? null : updateSpacing,
|
||||||
|
// DartStartBehavior.down is needed to keep the mouse pointer stuck to
|
||||||
|
// the drag bar. There still appears to be a few frame lag before the
|
||||||
|
// drag action triggers which is't ideal but isn't a launch blocker.
|
||||||
|
dragStartBehavior: DragStartBehavior.down,
|
||||||
|
child: SizedBox(
|
||||||
|
width: isHorizontal ? Split.dividerMainAxisSize : width,
|
||||||
|
height: isHorizontal ? height : Split.dividerMainAxisSize,
|
||||||
|
child: Center(
|
||||||
|
child: dragIndicator,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: isHorizontal ? secondSize : width,
|
||||||
|
height: isHorizontal ? height : secondSize,
|
||||||
|
child: widget.secondChild,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
return Flex(direction: widget.axis, children: children);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// TODO: Retrieve an API Access Key from https://unsplash.com/developers
|
||||||
|
const String unsplashAccessKey = '';
|
||||||
|
|
||||||
|
// The application name for the above API Access Key.
|
||||||
|
const unsplashAppName = '';
|
@ -0,0 +1,6 @@
|
|||||||
|
# Flutter-related
|
||||||
|
**/Flutter/ephemeral/
|
||||||
|
**/Pods/
|
||||||
|
|
||||||
|
# Xcode-related
|
||||||
|
**/xcuserdata/
|
@ -0,0 +1,2 @@
|
|||||||
|
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||||
|
#include "ephemeral/Flutter-Generated.xcconfig"
|
@ -0,0 +1,2 @@
|
|||||||
|
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||||
|
#include "ephemeral/Flutter-Generated.xcconfig"
|
@ -0,0 +1,16 @@
|
|||||||
|
//
|
||||||
|
// Generated file. Do not edit.
|
||||||
|
//
|
||||||
|
|
||||||
|
import FlutterMacOS
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
import file_chooser
|
||||||
|
import menubar
|
||||||
|
import url_launcher_macos
|
||||||
|
|
||||||
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
|
FileChooserPlugin.register(with: registry.registrar(forPlugin: "FileChooserPlugin"))
|
||||||
|
MenubarPlugin.register(with: registry.registrar(forPlugin: "MenubarPlugin"))
|
||||||
|
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
platform :osx, '10.11'
|
||||||
|
|
||||||
|
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||||
|
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||||
|
|
||||||
|
project 'Runner', {
|
||||||
|
'Debug' => :debug,
|
||||||
|
'Profile' => :release,
|
||||||
|
'Release' => :release,
|
||||||
|
}
|
||||||
|
|
||||||
|
def parse_KV_file(file, separator='=')
|
||||||
|
file_abs_path = File.expand_path(file)
|
||||||
|
if !File.exists? file_abs_path
|
||||||
|
return [];
|
||||||
|
end
|
||||||
|
pods_ary = []
|
||||||
|
skip_line_start_symbols = ["#", "/"]
|
||||||
|
File.foreach(file_abs_path) { |line|
|
||||||
|
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
|
||||||
|
plugin = line.split(pattern=separator)
|
||||||
|
if plugin.length == 2
|
||||||
|
podname = plugin[0].strip()
|
||||||
|
path = plugin[1].strip()
|
||||||
|
podpath = File.expand_path("#{path}", file_abs_path)
|
||||||
|
pods_ary.push({:name => podname, :path => podpath});
|
||||||
|
else
|
||||||
|
puts "Invalid plugin specification: #{line}"
|
||||||
|
end
|
||||||
|
}
|
||||||
|
return pods_ary
|
||||||
|
end
|
||||||
|
|
||||||
|
def pubspec_supports_macos(file)
|
||||||
|
file_abs_path = File.expand_path(file)
|
||||||
|
if !File.exists? file_abs_path
|
||||||
|
return false;
|
||||||
|
end
|
||||||
|
File.foreach(file_abs_path) { |line|
|
||||||
|
return true if line =~ /^\s*macos:/
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
target 'Runner' do
|
||||||
|
use_frameworks!
|
||||||
|
use_modular_headers!
|
||||||
|
|
||||||
|
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
|
||||||
|
# referring to absolute paths on developers' machines.
|
||||||
|
ephemeral_dir = File.join('Flutter', 'ephemeral')
|
||||||
|
symlink_dir = File.join(ephemeral_dir, '.symlinks')
|
||||||
|
symlink_plugins_dir = File.join(symlink_dir, 'plugins')
|
||||||
|
system("rm -rf #{symlink_dir}")
|
||||||
|
system("mkdir -p #{symlink_plugins_dir}")
|
||||||
|
|
||||||
|
# Flutter Pods
|
||||||
|
generated_xcconfig = parse_KV_file(File.join(ephemeral_dir, 'Flutter-Generated.xcconfig'))
|
||||||
|
if generated_xcconfig.empty?
|
||||||
|
puts "Flutter-Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first."
|
||||||
|
end
|
||||||
|
generated_xcconfig.map { |p|
|
||||||
|
if p[:name] == 'FLUTTER_FRAMEWORK_DIR'
|
||||||
|
symlink = File.join(symlink_dir, 'flutter')
|
||||||
|
File.symlink(File.dirname(p[:path]), symlink)
|
||||||
|
pod 'FlutterMacOS', :path => File.join(symlink, File.basename(p[:path]))
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
# Plugin Pods
|
||||||
|
plugin_pods = parse_KV_file('../.flutter-plugins')
|
||||||
|
plugin_pods.map { |p|
|
||||||
|
symlink = File.join(symlink_plugins_dir, p[:name])
|
||||||
|
File.symlink(p[:path], symlink)
|
||||||
|
if pubspec_supports_macos(File.join(symlink, 'pubspec.yaml'))
|
||||||
|
pod p[:name], :path => File.join(symlink, 'macos')
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
|
||||||
|
install! 'cocoapods', :disable_input_output_paths => true
|
@ -0,0 +1,34 @@
|
|||||||
|
PODS:
|
||||||
|
- file_chooser (0.0.2):
|
||||||
|
- FlutterMacOS
|
||||||
|
- FlutterMacOS (1.0.0)
|
||||||
|
- menubar (0.0.2):
|
||||||
|
- FlutterMacOS
|
||||||
|
- url_launcher_macos (0.0.1):
|
||||||
|
- FlutterMacOS
|
||||||
|
|
||||||
|
DEPENDENCIES:
|
||||||
|
- file_chooser (from `Flutter/ephemeral/.symlinks/plugins/file_chooser/macos`)
|
||||||
|
- FlutterMacOS (from `Flutter/ephemeral/.symlinks/flutter/darwin-x64`)
|
||||||
|
- menubar (from `Flutter/ephemeral/.symlinks/plugins/menubar/macos`)
|
||||||
|
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
|
||||||
|
|
||||||
|
EXTERNAL SOURCES:
|
||||||
|
file_chooser:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/file_chooser/macos
|
||||||
|
FlutterMacOS:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/flutter/darwin-x64
|
||||||
|
menubar:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/menubar/macos
|
||||||
|
url_launcher_macos:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
|
||||||
|
|
||||||
|
SPEC CHECKSUMS:
|
||||||
|
file_chooser: 24432cf5dc836722b05c11c2a0a30d19c3c9b996
|
||||||
|
FlutterMacOS: 15bea8a44d2fa024068daa0140371c020b4b6ff9
|
||||||
|
menubar: 4e3d461d62d775540277ce6639acafe2a111a231
|
||||||
|
url_launcher_macos: 77182d012b6b515c0955d24ed22b38f79b82a99d
|
||||||
|
|
||||||
|
PODFILE CHECKSUM: d8ba9b3e9e93c62c74a660b46c6fcb09f03991a7
|
||||||
|
|
||||||
|
COCOAPODS: 1.8.4
|
@ -0,0 +1,656 @@
|
|||||||
|
// !$*UTF8*$!
|
||||||
|
{
|
||||||
|
archiveVersion = 1;
|
||||||
|
classes = {
|
||||||
|
};
|
||||||
|
objectVersion = 51;
|
||||||
|
objects = {
|
||||||
|
|
||||||
|
/* Begin PBXAggregateTarget section */
|
||||||
|
33CC111A2044C6BA0003C045 /* Flutter Assemble */ = {
|
||||||
|
isa = PBXAggregateTarget;
|
||||||
|
buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */;
|
||||||
|
buildPhases = (
|
||||||
|
33CC111E2044C6BF0003C045 /* ShellScript */,
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = "Flutter Assemble";
|
||||||
|
productName = FLX;
|
||||||
|
};
|
||||||
|
/* End PBXAggregateTarget section */
|
||||||
|
|
||||||
|
/* Begin PBXBuildFile section */
|
||||||
|
335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; };
|
||||||
|
33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; };
|
||||||
|
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
|
||||||
|
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
|
||||||
|
33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
|
||||||
|
33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; };
|
||||||
|
33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
|
990488F4C467BB319BE84EEE /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8CA9B03A69D73D1FB7426AAD /* Pods_Runner.framework */; };
|
||||||
|
D73912F022F37F9E000D13A0 /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; };
|
||||||
|
D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 33CC10E52044A3C60003C045 /* Project object */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = 33CC111A2044C6BA0003C045;
|
||||||
|
remoteInfo = FLX;
|
||||||
|
};
|
||||||
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
|
33CC110E2044A8840003C045 /* Bundle Framework */ = {
|
||||||
|
isa = PBXCopyFilesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
dstPath = "";
|
||||||
|
dstSubfolderSpec = 10;
|
||||||
|
files = (
|
||||||
|
D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */,
|
||||||
|
33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */,
|
||||||
|
);
|
||||||
|
name = "Bundle Framework";
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXFileReference section */
|
||||||
|
30800270447E6C112F71B5A2 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; };
|
||||||
|
335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; };
|
||||||
|
33CC10ED2044A3C60003C045 /* Photo Search.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Photo Search.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
|
33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = "<group>"; };
|
||||||
|
33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
|
||||||
|
33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = "<group>"; };
|
||||||
|
33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = "<group>"; };
|
||||||
|
33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
33D1A10322148B71006C7A3E /* FlutterMacOS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FlutterMacOS.framework; path = Flutter/ephemeral/FlutterMacOS.framework; sourceTree = SOURCE_ROOT; };
|
||||||
|
33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = "<group>"; };
|
||||||
|
33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; };
|
||||||
|
33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
|
||||||
|
6874C7348F87E58F46720BF4 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
|
||||||
|
8CA9B03A69D73D1FB7426AAD /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
|
||||||
|
D73912EF22F37F9E000D13A0 /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/ephemeral/App.framework; sourceTree = SOURCE_ROOT; };
|
||||||
|
F2B5091A1DEA6D9237ACA748 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
33CC10EA2044A3C60003C045 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
D73912F022F37F9E000D13A0 /* App.framework in Frameworks */,
|
||||||
|
33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */,
|
||||||
|
990488F4C467BB319BE84EEE /* Pods_Runner.framework in Frameworks */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXGroup section */
|
||||||
|
33BA886A226E78AF003329D5 /* Configs */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
33E5194F232828860026EE4D /* AppInfo.xcconfig */,
|
||||||
|
9740EEB21CF90195004384FC /* Debug.xcconfig */,
|
||||||
|
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
|
||||||
|
333000ED22D3DE5D00554162 /* Warnings.xcconfig */,
|
||||||
|
);
|
||||||
|
path = Configs;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
33CC10E42044A3C60003C045 = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
33FAB671232836740065AC1E /* Runner */,
|
||||||
|
33CEB47122A05771004F2AC0 /* Flutter */,
|
||||||
|
33CC10EE2044A3C60003C045 /* Products */,
|
||||||
|
D73912EC22F37F3D000D13A0 /* Frameworks */,
|
||||||
|
BF229184A4E8E7AA3EE10F9D /* Pods */,
|
||||||
|
);
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
33CC10EE2044A3C60003C045 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
33CC10ED2044A3C60003C045 /* Photo Search.app */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
33CC11242044D66E0003C045 /* Resources */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
33CC10F22044A3C60003C045 /* Assets.xcassets */,
|
||||||
|
33CC10F42044A3C60003C045 /* MainMenu.xib */,
|
||||||
|
33CC10F72044A3C60003C045 /* Info.plist */,
|
||||||
|
);
|
||||||
|
name = Resources;
|
||||||
|
path = ..;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
33CEB47122A05771004F2AC0 /* Flutter */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */,
|
||||||
|
33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */,
|
||||||
|
33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */,
|
||||||
|
33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */,
|
||||||
|
D73912EF22F37F9E000D13A0 /* App.framework */,
|
||||||
|
33D1A10322148B71006C7A3E /* FlutterMacOS.framework */,
|
||||||
|
);
|
||||||
|
path = Flutter;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
33FAB671232836740065AC1E /* Runner */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
33CC10F02044A3C60003C045 /* AppDelegate.swift */,
|
||||||
|
33CC11122044BFA00003C045 /* MainFlutterWindow.swift */,
|
||||||
|
33E51913231747F40026EE4D /* DebugProfile.entitlements */,
|
||||||
|
33E51914231749380026EE4D /* Release.entitlements */,
|
||||||
|
33CC11242044D66E0003C045 /* Resources */,
|
||||||
|
33BA886A226E78AF003329D5 /* Configs */,
|
||||||
|
);
|
||||||
|
path = Runner;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
BF229184A4E8E7AA3EE10F9D /* Pods */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
F2B5091A1DEA6D9237ACA748 /* Pods-Runner.debug.xcconfig */,
|
||||||
|
30800270447E6C112F71B5A2 /* Pods-Runner.release.xcconfig */,
|
||||||
|
6874C7348F87E58F46720BF4 /* Pods-Runner.profile.xcconfig */,
|
||||||
|
);
|
||||||
|
path = Pods;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
D73912EC22F37F3D000D13A0 /* Frameworks */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
8CA9B03A69D73D1FB7426AAD /* Pods_Runner.framework */,
|
||||||
|
);
|
||||||
|
name = Frameworks;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXGroup section */
|
||||||
|
|
||||||
|
/* Begin PBXNativeTarget section */
|
||||||
|
33CC10EC2044A3C60003C045 /* Runner */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||||
|
buildPhases = (
|
||||||
|
4DC401FC85DF0A3149D2CECF /* [CP] Check Pods Manifest.lock */,
|
||||||
|
33CC10E92044A3C60003C045 /* Sources */,
|
||||||
|
33CC10EA2044A3C60003C045 /* Frameworks */,
|
||||||
|
33CC10EB2044A3C60003C045 /* Resources */,
|
||||||
|
33CC110E2044A8840003C045 /* Bundle Framework */,
|
||||||
|
3399D490228B24CF009A79C7 /* ShellScript */,
|
||||||
|
A00F8189E692D536E087EEAD /* [CP] Embed Pods Frameworks */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
33CC11202044C79F0003C045 /* PBXTargetDependency */,
|
||||||
|
);
|
||||||
|
name = Runner;
|
||||||
|
productName = Runner;
|
||||||
|
productReference = 33CC10ED2044A3C60003C045 /* Photo Search.app */;
|
||||||
|
productType = "com.apple.product-type.application";
|
||||||
|
};
|
||||||
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
|
/* Begin PBXProject section */
|
||||||
|
33CC10E52044A3C60003C045 /* Project object */ = {
|
||||||
|
isa = PBXProject;
|
||||||
|
attributes = {
|
||||||
|
LastSwiftUpdateCheck = 0920;
|
||||||
|
LastUpgradeCheck = 1120;
|
||||||
|
ORGANIZATIONNAME = "The Flutter Authors";
|
||||||
|
TargetAttributes = {
|
||||||
|
33CC10EC2044A3C60003C045 = {
|
||||||
|
CreatedOnToolsVersion = 9.2;
|
||||||
|
LastSwiftMigration = 1100;
|
||||||
|
ProvisioningStyle = Automatic;
|
||||||
|
SystemCapabilities = {
|
||||||
|
com.apple.Sandbox = {
|
||||||
|
enabled = 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
33CC111A2044C6BA0003C045 = {
|
||||||
|
CreatedOnToolsVersion = 9.2;
|
||||||
|
ProvisioningStyle = Manual;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */;
|
||||||
|
compatibilityVersion = "Xcode 8.0";
|
||||||
|
developmentRegion = en;
|
||||||
|
hasScannedForEncodings = 0;
|
||||||
|
knownRegions = (
|
||||||
|
en,
|
||||||
|
Base,
|
||||||
|
);
|
||||||
|
mainGroup = 33CC10E42044A3C60003C045;
|
||||||
|
productRefGroup = 33CC10EE2044A3C60003C045 /* Products */;
|
||||||
|
projectDirPath = "";
|
||||||
|
projectRoot = "";
|
||||||
|
targets = (
|
||||||
|
33CC10EC2044A3C60003C045 /* Runner */,
|
||||||
|
33CC111A2044C6BA0003C045 /* Flutter Assemble */,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
/* End PBXProject section */
|
||||||
|
|
||||||
|
/* Begin PBXResourcesBuildPhase section */
|
||||||
|
33CC10EB2044A3C60003C045 /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */,
|
||||||
|
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXShellScriptBuildPhase section */
|
||||||
|
3399D490228B24CF009A79C7 /* ShellScript */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
|
outputFileListPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename\n";
|
||||||
|
};
|
||||||
|
33CC111E2044C6BF0003C045 /* ShellScript */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
Flutter/ephemeral/FlutterInputs.xcfilelist,
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
Flutter/ephemeral/tripwire,
|
||||||
|
);
|
||||||
|
outputFileListPaths = (
|
||||||
|
Flutter/ephemeral/FlutterOutputs.xcfilelist,
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh\ntouch Flutter/ephemeral/tripwire\n";
|
||||||
|
};
|
||||||
|
4DC401FC85DF0A3149D2CECF /* [CP] Check Pods Manifest.lock */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||||
|
"${PODS_ROOT}/Manifest.lock",
|
||||||
|
);
|
||||||
|
name = "[CP] Check Pods Manifest.lock";
|
||||||
|
outputFileListPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
|
A00F8189E692D536E087EEAD /* [CP] Embed Pods Frameworks */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
|
name = "[CP] Embed Pods Frameworks";
|
||||||
|
outputFileListPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
33CC10E92044A3C60003C045 /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */,
|
||||||
|
33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */,
|
||||||
|
335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXTargetDependency section */
|
||||||
|
33CC11202044C79F0003C045 /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */;
|
||||||
|
targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
|
/* End PBXTargetDependency section */
|
||||||
|
|
||||||
|
/* Begin PBXVariantGroup section */
|
||||||
|
33CC10F42044A3C60003C045 /* MainMenu.xib */ = {
|
||||||
|
isa = PBXVariantGroup;
|
||||||
|
children = (
|
||||||
|
33CC10F52044A3C60003C045 /* Base */,
|
||||||
|
);
|
||||||
|
name = MainMenu.xib;
|
||||||
|
path = Runner;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXVariantGroup section */
|
||||||
|
|
||||||
|
/* Begin XCBuildConfiguration section */
|
||||||
|
338D0CE9231458BD00FA5F75 /* Profile */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CODE_SIGN_IDENTITY = "-";
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
|
SDKROOT = macosx;
|
||||||
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||||
|
};
|
||||||
|
name = Profile;
|
||||||
|
};
|
||||||
|
338D0CEA231458BD00FA5F75 /* Profile */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
|
||||||
|
CODE_SIGN_IDENTITY = "-";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"$(PROJECT_DIR)/Flutter/ephemeral",
|
||||||
|
);
|
||||||
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/../Frameworks",
|
||||||
|
);
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
};
|
||||||
|
name = Profile;
|
||||||
|
};
|
||||||
|
338D0CEB231458BD00FA5F75 /* Profile */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CODE_SIGN_STYLE = Manual;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
};
|
||||||
|
name = Profile;
|
||||||
|
};
|
||||||
|
33CC10F92044A3C60003C045 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CODE_SIGN_IDENTITY = "-";
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_TESTABILITY = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
"DEBUG=1",
|
||||||
|
"$(inherited)",
|
||||||
|
);
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
|
SDKROOT = macosx;
|
||||||
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
33CC10FA2044A3C60003C045 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CODE_SIGN_IDENTITY = "-";
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
|
SDKROOT = macosx;
|
||||||
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
33CC10FC2044A3C60003C045 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
|
||||||
|
CODE_SIGN_IDENTITY = "-";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"$(PROJECT_DIR)/Flutter/ephemeral",
|
||||||
|
);
|
||||||
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/../Frameworks",
|
||||||
|
);
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
33CC10FD2044A3C60003C045 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements;
|
||||||
|
CODE_SIGN_IDENTITY = "-";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"$(PROJECT_DIR)/Flutter/ephemeral",
|
||||||
|
);
|
||||||
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/../Frameworks",
|
||||||
|
);
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
33CC111C2044C6BA0003C045 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CODE_SIGN_STYLE = Manual;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
33CC111D2044C6BA0003C045 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
|
/* Begin XCConfigurationList section */
|
||||||
|
33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
33CC10F92044A3C60003C045 /* Debug */,
|
||||||
|
33CC10FA2044A3C60003C045 /* Release */,
|
||||||
|
338D0CE9231458BD00FA5F75 /* Profile */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
33CC10FC2044A3C60003C045 /* Debug */,
|
||||||
|
33CC10FD2044A3C60003C045 /* Release */,
|
||||||
|
338D0CEA231458BD00FA5F75 /* Profile */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
33CC111C2044C6BA0003C045 /* Debug */,
|
||||||
|
33CC111D2044C6BA0003C045 /* Release */,
|
||||||
|
338D0CEB231458BD00FA5F75 /* Profile */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
/* End XCConfigurationList section */
|
||||||
|
};
|
||||||
|
rootObject = 33CC10E52044A3C60003C045 /* Project object */;
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Workspace
|
||||||
|
version = "1.0">
|
||||||
|
<FileRef
|
||||||
|
location = "self:/Users/stuartmorgan/src/embedder-opensource/flutter-desktop-embedding/example/macos/Runner.xcodeproj">
|
||||||
|
</FileRef>
|
||||||
|
</Workspace>
|
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>IDEDidComputeMac32BitWarning</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
@ -0,0 +1,97 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Scheme
|
||||||
|
LastUpgradeVersion = "1120"
|
||||||
|
version = "1.3">
|
||||||
|
<BuildAction
|
||||||
|
parallelizeBuildables = "YES"
|
||||||
|
buildImplicitDependencies = "YES">
|
||||||
|
<BuildActionEntries>
|
||||||
|
<BuildActionEntry
|
||||||
|
buildForTesting = "YES"
|
||||||
|
buildForRunning = "YES"
|
||||||
|
buildForProfiling = "YES"
|
||||||
|
buildForArchiving = "YES"
|
||||||
|
buildForAnalyzing = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
|
||||||
|
BuildableName = "Photo Search.app"
|
||||||
|
BlueprintName = "Runner"
|
||||||
|
ReferencedContainer = "container:Runner.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildActionEntry>
|
||||||
|
</BuildActionEntries>
|
||||||
|
</BuildAction>
|
||||||
|
<TestAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
|
<MacroExpansion>
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
|
||||||
|
BuildableName = "Photo Search.app"
|
||||||
|
BlueprintName = "Runner"
|
||||||
|
ReferencedContainer = "container:Runner.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</MacroExpansion>
|
||||||
|
<Testables>
|
||||||
|
<TestableReference
|
||||||
|
skipped = "NO">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "00380F9121DF178D00097171"
|
||||||
|
BuildableName = "RunnerUITests.xctest"
|
||||||
|
BlueprintName = "RunnerUITests"
|
||||||
|
ReferencedContainer = "container:Runner.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</TestableReference>
|
||||||
|
</Testables>
|
||||||
|
</TestAction>
|
||||||
|
<LaunchAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
launchStyle = "0"
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
|
debugDocumentVersioning = "YES"
|
||||||
|
debugServiceExtension = "internal"
|
||||||
|
allowLocationSimulation = "YES">
|
||||||
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
|
||||||
|
BuildableName = "Photo Search.app"
|
||||||
|
BlueprintName = "Runner"
|
||||||
|
ReferencedContainer = "container:Runner.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildableProductRunnable>
|
||||||
|
</LaunchAction>
|
||||||
|
<ProfileAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
savedToolIdentifier = ""
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
debugDocumentVersioning = "YES">
|
||||||
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
|
||||||
|
BuildableName = "Photo Search.app"
|
||||||
|
BlueprintName = "Runner"
|
||||||
|
ReferencedContainer = "container:Runner.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildableProductRunnable>
|
||||||
|
</ProfileAction>
|
||||||
|
<AnalyzeAction
|
||||||
|
buildConfiguration = "Debug">
|
||||||
|
</AnalyzeAction>
|
||||||
|
<ArchiveAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
revealArchiveInOrganizer = "YES">
|
||||||
|
</ArchiveAction>
|
||||||
|
</Scheme>
|
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Workspace
|
||||||
|
version = "1.0">
|
||||||
|
<FileRef
|
||||||
|
location = "group:Runner.xcodeproj">
|
||||||
|
</FileRef>
|
||||||
|
<FileRef
|
||||||
|
location = "group:Pods/Pods.xcodeproj">
|
||||||
|
</FileRef>
|
||||||
|
</Workspace>
|
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>IDEDidComputeMac32BitWarning</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
@ -0,0 +1,13 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import Cocoa
|
||||||
|
import FlutterMacOS
|
||||||
|
|
||||||
|
@NSApplicationMain
|
||||||
|
class AppDelegate: FlutterAppDelegate {
|
||||||
|
override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"size" : "16x16",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "app_icon_16.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "16x16",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "app_icon_32.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "32x32",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "app_icon_32.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "32x32",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "app_icon_64.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "128x128",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "app_icon_128.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "128x128",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "app_icon_256.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "256x256",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "app_icon_256.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "256x256",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "app_icon_512.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "512x512",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "app_icon_512.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "512x512",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "app_icon_1024.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 1.8 KiB |
@ -0,0 +1,339 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="macosx"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
</dependencies>
|
||||||
|
<objects>
|
||||||
|
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||||
|
<connections>
|
||||||
|
<outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/>
|
||||||
|
</connections>
|
||||||
|
</customObject>
|
||||||
|
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||||
|
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||||
|
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="Runner" customModuleProvider="target">
|
||||||
|
<connections>
|
||||||
|
<outlet property="applicationMenu" destination="uQy-DD-JDr" id="XBo-yE-nKs"/>
|
||||||
|
<outlet property="mainFlutterWindow" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/>
|
||||||
|
</connections>
|
||||||
|
</customObject>
|
||||||
|
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
|
||||||
|
<menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
|
||||||
|
<items>
|
||||||
|
<menuItem title="APP_NAME" id="1Xt-HY-uBw">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<menu key="submenu" title="APP_NAME" systemMenu="apple" id="uQy-DD-JDr">
|
||||||
|
<items>
|
||||||
|
<menuItem title="About APP_NAME" id="5kV-Vb-QxS">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="orderFrontStandardAboutPanel:" target="-1" id="Exp-CZ-Vem"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
|
||||||
|
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
|
||||||
|
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
|
||||||
|
<menuItem title="Services" id="NMo-om-nkz">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
|
||||||
|
<menuItem title="Hide APP_NAME" keyEquivalent="h" id="Olw-nP-bQN">
|
||||||
|
<connections>
|
||||||
|
<action selector="hide:" target="-1" id="PnN-Uc-m68"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="hideOtherApplications:" target="-1" id="VT4-aY-XCT"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Show All" id="Kd2-mp-pUS">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="unhideAllApplications:" target="-1" id="Dhg-Le-xox"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
|
||||||
|
<menuItem title="Quit APP_NAME" keyEquivalent="q" id="4sb-4s-VLi">
|
||||||
|
<connections>
|
||||||
|
<action selector="terminate:" target="-1" id="Te7-pn-YzF"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
</items>
|
||||||
|
</menu>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Edit" id="5QF-Oa-p0T">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<menu key="submenu" title="Edit" id="W48-6f-4Dl">
|
||||||
|
<items>
|
||||||
|
<menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
|
||||||
|
<connections>
|
||||||
|
<action selector="undo:" target="-1" id="M6e-cu-g7V"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
|
||||||
|
<connections>
|
||||||
|
<action selector="redo:" target="-1" id="oIA-Rs-6OD"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
|
||||||
|
<menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
|
||||||
|
<connections>
|
||||||
|
<action selector="cut:" target="-1" id="YJe-68-I9s"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
|
||||||
|
<connections>
|
||||||
|
<action selector="copy:" target="-1" id="G1f-GL-Joy"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
|
||||||
|
<connections>
|
||||||
|
<action selector="paste:" target="-1" id="UvS-8e-Qdg"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="pasteAsPlainText:" target="-1" id="cEh-KX-wJQ"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Delete" id="pa3-QI-u2k">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="delete:" target="-1" id="0Mk-Ml-PaM"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
|
||||||
|
<connections>
|
||||||
|
<action selector="selectAll:" target="-1" id="VNm-Mi-diN"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
|
||||||
|
<menuItem title="Find" id="4EN-yA-p0u">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<menu key="submenu" title="Find" id="1b7-l0-nxx">
|
||||||
|
<items>
|
||||||
|
<menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
|
||||||
|
<connections>
|
||||||
|
<action selector="performFindPanelAction:" target="-1" id="cD7-Qs-BN4"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="performFindPanelAction:" target="-1" id="WD3-Gg-5AJ"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
|
||||||
|
<connections>
|
||||||
|
<action selector="performFindPanelAction:" target="-1" id="NDo-RZ-v9R"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
|
||||||
|
<connections>
|
||||||
|
<action selector="performFindPanelAction:" target="-1" id="HOh-sY-3ay"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
|
||||||
|
<connections>
|
||||||
|
<action selector="performFindPanelAction:" target="-1" id="U76-nv-p5D"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
|
||||||
|
<connections>
|
||||||
|
<action selector="centerSelectionInVisibleArea:" target="-1" id="IOG-6D-g5B"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
</items>
|
||||||
|
</menu>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
|
||||||
|
<items>
|
||||||
|
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
|
||||||
|
<connections>
|
||||||
|
<action selector="showGuessPanel:" target="-1" id="vFj-Ks-hy3"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
|
||||||
|
<connections>
|
||||||
|
<action selector="checkSpelling:" target="-1" id="fz7-VC-reM"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
|
||||||
|
<menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="toggleContinuousSpellChecking:" target="-1" id="7w6-Qz-0kB"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="toggleGrammarChecking:" target="-1" id="muD-Qn-j4w"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="toggleAutomaticSpellingCorrection:" target="-1" id="2lM-Qi-WAP"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
</items>
|
||||||
|
</menu>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Substitutions" id="9ic-FL-obx">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
|
||||||
|
<items>
|
||||||
|
<menuItem title="Show Substitutions" id="z6F-FW-3nz">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="orderFrontSubstitutionsPanel:" target="-1" id="oku-mr-iSq"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
|
||||||
|
<menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="toggleSmartInsertDelete:" target="-1" id="3IJ-Se-DZD"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Smart Quotes" id="hQb-2v-fYv">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="ptq-xd-QOA"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Smart Dashes" id="rgM-f4-ycn">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="toggleAutomaticDashSubstitution:" target="-1" id="oCt-pO-9gS"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Smart Links" id="cwL-P1-jid">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="toggleAutomaticLinkDetection:" target="-1" id="Gip-E3-Fov"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Data Detectors" id="tRr-pd-1PS">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="toggleAutomaticDataDetection:" target="-1" id="R1I-Nq-Kbl"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Text Replacement" id="HFQ-gK-NFA">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="toggleAutomaticTextReplacement:" target="-1" id="DvP-Fe-Py6"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
</items>
|
||||||
|
</menu>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Transformations" id="2oI-Rn-ZJC">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<menu key="submenu" title="Transformations" id="c8a-y6-VQd">
|
||||||
|
<items>
|
||||||
|
<menuItem title="Make Upper Case" id="vmV-6d-7jI">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="uppercaseWord:" target="-1" id="sPh-Tk-edu"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Make Lower Case" id="d9M-CD-aMd">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="lowercaseWord:" target="-1" id="iUZ-b5-hil"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Capitalize" id="UEZ-Bs-lqG">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="capitalizeWord:" target="-1" id="26H-TL-nsh"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
</items>
|
||||||
|
</menu>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Speech" id="xrE-MZ-jX0">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<menu key="submenu" title="Speech" id="3rS-ZA-NoH">
|
||||||
|
<items>
|
||||||
|
<menuItem title="Start Speaking" id="Ynk-f8-cLZ">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="startSpeaking:" target="-1" id="654-Ng-kyl"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Stop Speaking" id="Oyz-dy-DGm">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="stopSpeaking:" target="-1" id="dX8-6p-jy9"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
</items>
|
||||||
|
</menu>
|
||||||
|
</menuItem>
|
||||||
|
</items>
|
||||||
|
</menu>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="View" id="H8h-7b-M4v">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<menu key="submenu" title="View" id="HyV-fh-RgO">
|
||||||
|
<items>
|
||||||
|
<menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="toggleFullScreen:" target="-1" id="dU3-MA-1Rq"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
</items>
|
||||||
|
</menu>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Window" id="aUF-d1-5bR">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
|
||||||
|
<items>
|
||||||
|
<menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
|
||||||
|
<connections>
|
||||||
|
<action selector="performMiniaturize:" target="-1" id="VwT-WD-YPe"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Zoom" id="R4o-n2-Eq4">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="performZoom:" target="-1" id="DIl-cC-cCs"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
|
||||||
|
<menuItem title="Bring All to Front" id="LE2-aR-0XJ">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="arrangeInFront:" target="-1" id="DRN-fu-gQh"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
</items>
|
||||||
|
</menu>
|
||||||
|
</menuItem>
|
||||||
|
</items>
|
||||||
|
<point key="canvasLocation" x="142" y="-258"/>
|
||||||
|
</menu>
|
||||||
|
<window title="APP_NAME" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g" customClass="MainFlutterWindow" customModule="Runner" customModuleProvider="target">
|
||||||
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||||
|
<rect key="contentRect" x="335" y="390" width="800" height="600"/>
|
||||||
|
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1577"/>
|
||||||
|
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="800" height="600"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
</view>
|
||||||
|
</window>
|
||||||
|
</objects>
|
||||||
|
</document>
|
@ -0,0 +1,14 @@
|
|||||||
|
// Application-level settings for the Runner target.
|
||||||
|
//
|
||||||
|
// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the
|
||||||
|
// future. If not, the values below would default to using the project name when this becomes a
|
||||||
|
// 'flutter create' template.
|
||||||
|
|
||||||
|
// The application's name. By default this is also the title of the Flutter window.
|
||||||
|
PRODUCT_NAME = Photo Search
|
||||||
|
|
||||||
|
// The application's bundle identifier
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = com.example.photoSearch
|
||||||
|
|
||||||
|
// The copyright displayed in application information
|
||||||
|
PRODUCT_COPYRIGHT = Copyright © 2019 com.example. All rights reserved.
|
@ -0,0 +1,2 @@
|
|||||||
|
#include "../../Flutter/Flutter-Debug.xcconfig"
|
||||||
|
#include "Warnings.xcconfig"
|
@ -0,0 +1,2 @@
|
|||||||
|
#include "../../Flutter/Flutter-Release.xcconfig"
|
||||||
|
#include "Warnings.xcconfig"
|
@ -0,0 +1,13 @@
|
|||||||
|
WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES
|
||||||
|
CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES
|
||||||
|
CLANG_WARN_PRAGMA_PACK = YES
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES
|
||||||
|
CLANG_WARN_COMMA = YES
|
||||||
|
GCC_WARN_STRICT_SELECTOR_MATCH = YES
|
||||||
|
CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES
|
||||||
|
GCC_WARN_SHADOW = YES
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES
|
@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>com.apple.security.app-sandbox</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.cs.allow-jit</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.files.user-selected.read-write</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.network.client</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.network.server</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
@ -0,0 +1,32 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string></string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>$(PRODUCT_NAME)</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>$(FLUTTER_BUILD_NAME)</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||||
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||||
|
<key>NSHumanReadableCopyright</key>
|
||||||
|
<string>$(PRODUCT_COPYRIGHT)</string>
|
||||||
|
<key>NSMainNibFile</key>
|
||||||
|
<string>MainMenu</string>
|
||||||
|
<key>NSPrincipalClass</key>
|
||||||
|
<string>NSApplication</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
@ -0,0 +1,19 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import Cocoa
|
||||||
|
import FlutterMacOS
|
||||||
|
|
||||||
|
class MainFlutterWindow: NSWindow {
|
||||||
|
override func awakeFromNib() {
|
||||||
|
let flutterViewController = FlutterViewController.init()
|
||||||
|
let windowFrame = self.frame
|
||||||
|
self.contentViewController = flutterViewController
|
||||||
|
self.setFrame(windowFrame, display: true)
|
||||||
|
|
||||||
|
RegisterGeneratedPlugins(registry: flutterViewController)
|
||||||
|
|
||||||
|
super.awakeFromNib()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>com.apple.security.app-sandbox</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.files.user-selected.read-write</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.network.client</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
@ -0,0 +1,681 @@
|
|||||||
|
# Generated by pub
|
||||||
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
|
packages:
|
||||||
|
analysis_server_lib:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: analysis_server_lib
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.8"
|
||||||
|
analyzer:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: analyzer
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.38.5"
|
||||||
|
analyzer_plugin:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: analyzer_plugin
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.1"
|
||||||
|
archive:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: archive
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.11"
|
||||||
|
args:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: args
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.5.2"
|
||||||
|
async:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description:
|
||||||
|
name: async
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.4.0"
|
||||||
|
boolean_selector:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: boolean_selector
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.5"
|
||||||
|
build:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description:
|
||||||
|
name: build
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.2"
|
||||||
|
build_config:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: build_config
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.4.1+1"
|
||||||
|
build_daemon:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: build_daemon
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.2"
|
||||||
|
build_resolvers:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: build_resolvers
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.1"
|
||||||
|
build_runner:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description:
|
||||||
|
name: build_runner
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.7.2"
|
||||||
|
build_runner_core:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: build_runner_core
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "4.2.0"
|
||||||
|
built_collection:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: built_collection
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "4.3.0"
|
||||||
|
built_value:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: built_value
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "7.0.0"
|
||||||
|
built_value_generator:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description:
|
||||||
|
name: built_value_generator
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "7.0.0"
|
||||||
|
charcode:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: charcode
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.2"
|
||||||
|
checked_yaml:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: checked_yaml
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.2"
|
||||||
|
cli_util:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: cli_util
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.3+2"
|
||||||
|
code_builder:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: code_builder
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "3.2.1"
|
||||||
|
collection:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: collection
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.14.11"
|
||||||
|
convert:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: convert
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.1"
|
||||||
|
coverage:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: coverage
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.13.3+3"
|
||||||
|
crypto:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: crypto
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.3"
|
||||||
|
csslib:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: csslib
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.16.1"
|
||||||
|
cupertino_icons:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: cupertino_icons
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.3"
|
||||||
|
dart_style:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: dart_style
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.3"
|
||||||
|
file_chooser:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
path: "plugins/file_chooser"
|
||||||
|
ref: HEAD
|
||||||
|
resolved-ref: ab3b14f7231289dc66b7ad21c607cb90dd896fc0
|
||||||
|
url: "https://github.com/google/flutter-desktop-embedding.git"
|
||||||
|
source: git
|
||||||
|
version: "0.1.0"
|
||||||
|
fixnum:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: fixnum
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.10.11"
|
||||||
|
flutter:
|
||||||
|
dependency: "direct main"
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
|
flutter_test:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
|
flutter_web_plugins:
|
||||||
|
dependency: transitive
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
|
front_end:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: front_end
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.27"
|
||||||
|
glob:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: glob
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.0"
|
||||||
|
graphs:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: graphs
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.0"
|
||||||
|
grinder:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description:
|
||||||
|
name: grinder
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.8.3+1"
|
||||||
|
html:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: html
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.14.0+3"
|
||||||
|
http:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: http
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.12.0+2"
|
||||||
|
http_multi_server:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: http_multi_server
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.0"
|
||||||
|
http_parser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: http_parser
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.3"
|
||||||
|
image:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.4"
|
||||||
|
intl:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: intl
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.15.8"
|
||||||
|
io:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: io
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.3.3"
|
||||||
|
js:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: js
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.6.1+1"
|
||||||
|
json_annotation:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: json_annotation
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.0"
|
||||||
|
kernel:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: kernel
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.3.27"
|
||||||
|
logging:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: logging
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.11.3+2"
|
||||||
|
matcher:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: matcher
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.12.6"
|
||||||
|
menubar:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
path: "plugins/menubar"
|
||||||
|
ref: HEAD
|
||||||
|
resolved-ref: ab3b14f7231289dc66b7ad21c607cb90dd896fc0
|
||||||
|
url: "https://github.com/google/flutter-desktop-embedding.git"
|
||||||
|
source: git
|
||||||
|
version: "0.0.1"
|
||||||
|
meta:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: meta
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.8"
|
||||||
|
mime:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: mime
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.9.6+3"
|
||||||
|
multi_server_socket:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: multi_server_socket
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.2"
|
||||||
|
node_interop:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: node_interop
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.3"
|
||||||
|
node_io:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: node_io
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.1+2"
|
||||||
|
node_preamble:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: node_preamble
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.8"
|
||||||
|
package_config:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: package_config
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.0"
|
||||||
|
package_resolver:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: package_resolver
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.10"
|
||||||
|
path:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.6.4"
|
||||||
|
pedantic:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: pedantic
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.8.0+1"
|
||||||
|
petitparser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: petitparser
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.4.0"
|
||||||
|
pool:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pool
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.0"
|
||||||
|
provider:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: provider
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "3.2.0"
|
||||||
|
pub_semver:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pub_semver
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.2"
|
||||||
|
pubspec_parse:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pubspec_parse
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.5"
|
||||||
|
quiver:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: quiver
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.5"
|
||||||
|
shelf:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shelf
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.7.5"
|
||||||
|
shelf_packages_handler:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shelf_packages_handler
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.4"
|
||||||
|
shelf_static:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shelf_static
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.8"
|
||||||
|
shelf_web_socket:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shelf_web_socket
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.3"
|
||||||
|
sky_engine:
|
||||||
|
dependency: transitive
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.99"
|
||||||
|
source_gen:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description:
|
||||||
|
name: source_gen
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.9.4+6"
|
||||||
|
source_map_stack_trace:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: source_map_stack_trace
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.5"
|
||||||
|
source_maps:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: source_maps
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.10.8"
|
||||||
|
source_span:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: source_span
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.5.5"
|
||||||
|
stack_trace:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: stack_trace
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.9.3"
|
||||||
|
stream_channel:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: stream_channel
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.0"
|
||||||
|
stream_transform:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: stream_transform
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.0.20"
|
||||||
|
string_scanner:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: string_scanner
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.5"
|
||||||
|
term_glyph:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: term_glyph
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.0"
|
||||||
|
test:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description:
|
||||||
|
name: test
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.9.4"
|
||||||
|
test_api:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: test_api
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.11"
|
||||||
|
test_core:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: test_core
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.15"
|
||||||
|
timing:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: timing
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.1+2"
|
||||||
|
transparent_image:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: transparent_image
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.0"
|
||||||
|
tuneup:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description:
|
||||||
|
name: tuneup
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.3.6+1"
|
||||||
|
typed_data:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: typed_data
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.6"
|
||||||
|
url_launcher:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: url_launcher
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "5.3.0"
|
||||||
|
url_launcher_macos:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: url_launcher_macos
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.0.1"
|
||||||
|
url_launcher_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_platform_interface
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.1"
|
||||||
|
url_launcher_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_web
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.0+1"
|
||||||
|
uuid:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: uuid
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.4"
|
||||||
|
vector_math:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: vector_math
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.8"
|
||||||
|
vm_service:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: vm_service
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.3"
|
||||||
|
watcher:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: watcher
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.9.7+13"
|
||||||
|
web_socket_channel:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: web_socket_channel
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.0"
|
||||||
|
xml:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: xml
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "3.5.0"
|
||||||
|
yaml:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: yaml
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.0"
|
||||||
|
sdks:
|
||||||
|
dart: ">=2.7.0-dev <3.0.0"
|
||||||
|
flutter: ">=1.13.1-pre <2.0.0"
|
@ -0,0 +1,45 @@
|
|||||||
|
name: desktop_photo_search
|
||||||
|
description: Search for Photos, using the Unsplash API.
|
||||||
|
version: 1.0.0+1
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: ^2.7.0-dev
|
||||||
|
flutter: ^1.13.1-pre
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
flutter:
|
||||||
|
sdk: flutter
|
||||||
|
built_collection: ^4.3.0
|
||||||
|
built_value: ^7.0.0
|
||||||
|
cupertino_icons: ^0.1.2
|
||||||
|
file_chooser:
|
||||||
|
git:
|
||||||
|
url: https://github.com/google/flutter-desktop-embedding.git
|
||||||
|
path: plugins/file_chooser
|
||||||
|
logging: ^0.11.3+2
|
||||||
|
menubar:
|
||||||
|
git:
|
||||||
|
url: https://github.com/google/flutter-desktop-embedding.git
|
||||||
|
path: plugins/menubar
|
||||||
|
meta: ^1.1.8
|
||||||
|
pedantic: ^1.8.0
|
||||||
|
provider: ^3.2.0
|
||||||
|
transparent_image: ^1.0.0
|
||||||
|
uuid: ^2.0.4
|
||||||
|
url_launcher: ^5.3.0
|
||||||
|
url_launcher_macos: ^0.0.1
|
||||||
|
|
||||||
|
dev_dependencies:
|
||||||
|
flutter_test:
|
||||||
|
sdk: flutter
|
||||||
|
async: ^2.4.0
|
||||||
|
build: ^1.2.2
|
||||||
|
build_runner: ^1.7.2
|
||||||
|
built_value_generator: ^7.0.0
|
||||||
|
grinder: ^0.8.3
|
||||||
|
source_gen: ^0.9.4
|
||||||
|
test: ^1.9.4
|
||||||
|
tuneup: ^0.3.6
|
||||||
|
|
||||||
|
flutter:
|
||||||
|
uses-material-design: true
|
@ -0,0 +1,347 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// 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:http/http.dart';
|
||||||
|
import 'package:http/testing.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
test('Photo.fromJson', () {
|
||||||
|
const input = '''
|
||||||
|
{
|
||||||
|
"id": "Dwu85P9SOIk",
|
||||||
|
"created_at": "2016-05-03T11:00:28-04:00",
|
||||||
|
"updated_at": "2016-07-10T11:00:01-05:00",
|
||||||
|
"width": 2448,
|
||||||
|
"height": 3264,
|
||||||
|
"color": "#6E633A",
|
||||||
|
"downloads": 1345,
|
||||||
|
"likes": 24,
|
||||||
|
"liked_by_user": false,
|
||||||
|
"description": "A man drinking a coffee.",
|
||||||
|
"exif": {
|
||||||
|
"make": "Canon",
|
||||||
|
"model": "Canon EOS 40D",
|
||||||
|
"exposure_time": "0.011111111111111112",
|
||||||
|
"aperture": "4.970854",
|
||||||
|
"focal_length": "37",
|
||||||
|
"iso": 100
|
||||||
|
},
|
||||||
|
"location": {
|
||||||
|
"city": "Montreal",
|
||||||
|
"country": "Canada",
|
||||||
|
"position": {
|
||||||
|
"latitude": 45.4732984,
|
||||||
|
"longitude": -73.6384879
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
{ "title": "man" },
|
||||||
|
{ "title": "drinking" },
|
||||||
|
{ "title": "coffee" }
|
||||||
|
],
|
||||||
|
"current_user_collections": [
|
||||||
|
{
|
||||||
|
"id": 206,
|
||||||
|
"title": "Makers: Cat and Ben",
|
||||||
|
"published_at": "2016-01-12T18:16:09-05:00",
|
||||||
|
"updated_at": "2016-07-10T11:00:01-05:00",
|
||||||
|
"cover_photo": null,
|
||||||
|
"user": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"urls": {
|
||||||
|
"raw": "https://images.unsplash.com/photo-1417325384643-aac51acc9e5d",
|
||||||
|
"full": "https://images.unsplash.com/photo-1417325384643-aac51acc9e5d?q=75&fm=jpg",
|
||||||
|
"regular": "https://images.unsplash.com/photo-1417325384643-aac51acc9e5d?q=75&fm=jpg&w=1080&fit=max",
|
||||||
|
"small": "https://images.unsplash.com/photo-1417325384643-aac51acc9e5d?q=75&fm=jpg&w=400&fit=max",
|
||||||
|
"thumb": "https://images.unsplash.com/photo-1417325384643-aac51acc9e5d?q=75&fm=jpg&w=200&fit=max"
|
||||||
|
},
|
||||||
|
"links": {
|
||||||
|
"self": "https://api.unsplash.com/photos/Dwu85P9SOIk",
|
||||||
|
"html": "https://unsplash.com/photos/Dwu85P9SOIk",
|
||||||
|
"download": "https://unsplash.com/photos/Dwu85P9SOIk/download",
|
||||||
|
"download_location": "https://api.unsplash.com/photos/Dwu85P9SOIk/download"
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"id": "QPxL2MGqfrw",
|
||||||
|
"updated_at": "2016-07-10T11:00:01-05:00",
|
||||||
|
"username": "exampleuser",
|
||||||
|
"name": "Joe Example",
|
||||||
|
"portfolio_url": "https://example.com/",
|
||||||
|
"bio": "Just an everyday Joe",
|
||||||
|
"location": "Montreal",
|
||||||
|
"total_likes": 5,
|
||||||
|
"total_photos": 10,
|
||||||
|
"total_collections": 13,
|
||||||
|
"links": {
|
||||||
|
"self": "https://api.unsplash.com/users/exampleuser",
|
||||||
|
"html": "https://unsplash.com/exampleuser",
|
||||||
|
"photos": "https://api.unsplash.com/users/exampleuser/photos",
|
||||||
|
"likes": "https://api.unsplash.com/users/exampleuser/likes",
|
||||||
|
"portfolio": "https://api.unsplash.com/users/exampleuser/portfolio"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
final photo = Photo.fromJson(input);
|
||||||
|
expect(photo.id, 'Dwu85P9SOIk');
|
||||||
|
expect(photo.createdAt, '2016-05-03T11:00:28-04:00');
|
||||||
|
expect(photo.updatedAt, '2016-07-10T11:00:01-05:00');
|
||||||
|
expect(photo.width, 2448);
|
||||||
|
expect(photo.height, 3264);
|
||||||
|
expect(photo.color, '#6E633A');
|
||||||
|
expect(photo.downloads, 1345);
|
||||||
|
expect(photo.likedByUser, false);
|
||||||
|
expect(photo.exif.make, 'Canon');
|
||||||
|
expect(photo.exif.iso, 100);
|
||||||
|
expect(photo.location.city, 'Montreal');
|
||||||
|
expect(photo.location.country, 'Canada');
|
||||||
|
expect(photo.location.position.latitude, 45.4732984);
|
||||||
|
expect(photo.location.position.longitude, -73.6384879);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('User.fromJson', () {
|
||||||
|
const input = '''
|
||||||
|
{
|
||||||
|
"id": "pXhwzz1JtQU",
|
||||||
|
"updated_at": "2016-07-10T11:00:01-05:00",
|
||||||
|
"username": "jimmyexample",
|
||||||
|
"name": "James Example",
|
||||||
|
"first_name": "James",
|
||||||
|
"last_name": "Example",
|
||||||
|
"instagram_username": "instantgrammer",
|
||||||
|
"twitter_username": "jimmy",
|
||||||
|
"portfolio_url": null,
|
||||||
|
"bio": "The user's bio",
|
||||||
|
"location": "Montreal, Qc",
|
||||||
|
"total_likes": 20,
|
||||||
|
"total_photos": 10,
|
||||||
|
"total_collections": 5,
|
||||||
|
"followed_by_user": false,
|
||||||
|
"followers_count": 300,
|
||||||
|
"following_count": 25,
|
||||||
|
"downloads": 225974,
|
||||||
|
"profile_image": {
|
||||||
|
"small": "https://images.unsplash.com/face-springmorning.jpg?q=80&fm=jpg&crop=faces&fit=crop&h=32&w=32",
|
||||||
|
"medium": "https://images.unsplash.com/face-springmorning.jpg?q=80&fm=jpg&crop=faces&fit=crop&h=64&w=64",
|
||||||
|
"large": "https://images.unsplash.com/face-springmorning.jpg?q=80&fm=jpg&crop=faces&fit=crop&h=128&w=128"
|
||||||
|
},
|
||||||
|
"badge": {
|
||||||
|
"title": "Book contributor",
|
||||||
|
"primary": true,
|
||||||
|
"slug": "book-contributor",
|
||||||
|
"link": "https://book.unsplash.com"
|
||||||
|
},
|
||||||
|
"links": {
|
||||||
|
"self": "https://api.unsplash.com/users/jimmyexample",
|
||||||
|
"html": "https://unsplash.com/jimmyexample",
|
||||||
|
"photos": "https://api.unsplash.com/users/jimmyexample/photos",
|
||||||
|
"likes": "https://api.unsplash.com/users/jimmyexample/likes",
|
||||||
|
"portfolio": "https://api.unsplash.com/users/jimmyexample/portfolio"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
final user = User.fromJson(input);
|
||||||
|
expect(user.id, 'pXhwzz1JtQU');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('SearchPhotosResponse.fromJson', () {
|
||||||
|
const input = '''
|
||||||
|
{
|
||||||
|
"total": 133,
|
||||||
|
"total_pages": 7,
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"id": "eOLpJytrbsQ",
|
||||||
|
"created_at": "2014-11-18T14:35:36-05:00",
|
||||||
|
"width": 4000,
|
||||||
|
"height": 3000,
|
||||||
|
"color": "#A7A2A1",
|
||||||
|
"likes": 286,
|
||||||
|
"liked_by_user": false,
|
||||||
|
"description": "A man drinking a coffee.",
|
||||||
|
"user": {
|
||||||
|
"id": "Ul0QVz12Goo",
|
||||||
|
"username": "ugmonk",
|
||||||
|
"name": "Jeff Sheldon",
|
||||||
|
"first_name": "Jeff",
|
||||||
|
"last_name": "Sheldon",
|
||||||
|
"instagram_username": "instantgrammer",
|
||||||
|
"twitter_username": "ugmonk",
|
||||||
|
"portfolio_url": "http://ugmonk.com/",
|
||||||
|
"profile_image": {
|
||||||
|
"small": "https://images.unsplash.com/profile-1441298803695-accd94000cac?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&fit=crop&h=32&w=32&s=7cfe3b93750cb0c93e2f7caec08b5a41",
|
||||||
|
"medium": "https://images.unsplash.com/profile-1441298803695-accd94000cac?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&fit=crop&h=64&w=64&s=5a9dc749c43ce5bd60870b129a40902f",
|
||||||
|
"large": "https://images.unsplash.com/profile-1441298803695-accd94000cac?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&fit=crop&h=128&w=128&s=32085a077889586df88bfbe406692202"
|
||||||
|
},
|
||||||
|
"links": {
|
||||||
|
"self": "https://api.unsplash.com/users/ugmonk",
|
||||||
|
"html": "http://unsplash.com/@ugmonk",
|
||||||
|
"photos": "https://api.unsplash.com/users/ugmonk/photos",
|
||||||
|
"likes": "https://api.unsplash.com/users/ugmonk/likes"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"current_user_collections": [],
|
||||||
|
"urls": {
|
||||||
|
"raw": "https://images.unsplash.com/photo-1416339306562-f3d12fefd36f",
|
||||||
|
"full": "https://hd.unsplash.com/photo-1416339306562-f3d12fefd36f",
|
||||||
|
"regular": "https://images.unsplash.com/photo-1416339306562-f3d12fefd36f?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&s=92f3e02f63678acc8416d044e189f515",
|
||||||
|
"small": "https://images.unsplash.com/photo-1416339306562-f3d12fefd36f?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&s=263af33585f9d32af39d165b000845eb",
|
||||||
|
"thumb": "https://images.unsplash.com/photo-1416339306562-f3d12fefd36f?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&s=8aae34cf35df31a592f0bef16e6342ef"
|
||||||
|
},
|
||||||
|
"links": {
|
||||||
|
"self": "https://api.unsplash.com/photos/eOLpJytrbsQ",
|
||||||
|
"html": "http://unsplash.com/photos/eOLpJytrbsQ",
|
||||||
|
"download": "http://unsplash.com/photos/eOLpJytrbsQ/download"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
final response = SearchPhotosResponse.fromJson(input);
|
||||||
|
expect(response.total, 133);
|
||||||
|
expect(response.totalPages, 7);
|
||||||
|
expect(response.results[0].id, 'eOLpJytrbsQ');
|
||||||
|
expect(response.results[0].user.id, 'Ul0QVz12Goo');
|
||||||
|
});
|
||||||
|
|
||||||
|
group('Unsplash API client', () {
|
||||||
|
test('handles success', () async {
|
||||||
|
const searchPhotosResponseBody = '''
|
||||||
|
{
|
||||||
|
"total": 133,
|
||||||
|
"total_pages": 7,
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"id": "eOLpJytrbsQ",
|
||||||
|
"created_at": "2014-11-18T14:35:36-05:00",
|
||||||
|
"width": 4000,
|
||||||
|
"height": 3000,
|
||||||
|
"color": "#A7A2A1",
|
||||||
|
"likes": 286,
|
||||||
|
"liked_by_user": false,
|
||||||
|
"description": "A man drinking a coffee.",
|
||||||
|
"user": {
|
||||||
|
"id": "Ul0QVz12Goo",
|
||||||
|
"username": "ugmonk",
|
||||||
|
"name": "Jeff Sheldon",
|
||||||
|
"first_name": "Jeff",
|
||||||
|
"last_name": "Sheldon",
|
||||||
|
"instagram_username": "instantgrammer",
|
||||||
|
"twitter_username": "ugmonk",
|
||||||
|
"portfolio_url": "http://ugmonk.com/",
|
||||||
|
"profile_image": {
|
||||||
|
"small": "https://images.unsplash.com/profile-1441298803695-accd94000cac?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&fit=crop&h=32&w=32&s=7cfe3b93750cb0c93e2f7caec08b5a41",
|
||||||
|
"medium": "https://images.unsplash.com/profile-1441298803695-accd94000cac?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&fit=crop&h=64&w=64&s=5a9dc749c43ce5bd60870b129a40902f",
|
||||||
|
"large": "https://images.unsplash.com/profile-1441298803695-accd94000cac?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&fit=crop&h=128&w=128&s=32085a077889586df88bfbe406692202"
|
||||||
|
},
|
||||||
|
"links": {
|
||||||
|
"self": "https://api.unsplash.com/users/ugmonk",
|
||||||
|
"html": "http://unsplash.com/@ugmonk",
|
||||||
|
"photos": "https://api.unsplash.com/users/ugmonk/photos",
|
||||||
|
"likes": "https://api.unsplash.com/users/ugmonk/likes"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"current_user_collections": [],
|
||||||
|
"urls": {
|
||||||
|
"raw": "https://images.unsplash.com/photo-1416339306562-f3d12fefd36f",
|
||||||
|
"full": "https://hd.unsplash.com/photo-1416339306562-f3d12fefd36f",
|
||||||
|
"regular": "https://images.unsplash.com/photo-1416339306562-f3d12fefd36f?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&s=92f3e02f63678acc8416d044e189f515",
|
||||||
|
"small": "https://images.unsplash.com/photo-1416339306562-f3d12fefd36f?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&s=263af33585f9d32af39d165b000845eb",
|
||||||
|
"thumb": "https://images.unsplash.com/photo-1416339306562-f3d12fefd36f?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&s=8aae34cf35df31a592f0bef16e6342ef"
|
||||||
|
},
|
||||||
|
"links": {
|
||||||
|
"self": "https://api.unsplash.com/photos/eOLpJytrbsQ",
|
||||||
|
"html": "http://unsplash.com/photos/eOLpJytrbsQ",
|
||||||
|
"download": "http://unsplash.com/photos/eOLpJytrbsQ/download"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
final httpClient = MockClient((req) async {
|
||||||
|
return Response(
|
||||||
|
searchPhotosResponseBody,
|
||||||
|
200,
|
||||||
|
request: req,
|
||||||
|
headers: {'content-type': 'application/json'},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
final unsplashClient = Unsplash(
|
||||||
|
accessKey: 'not-an-access-key',
|
||||||
|
httpClient: httpClient,
|
||||||
|
);
|
||||||
|
|
||||||
|
final response = await unsplashClient.searchPhotos(query: 'red');
|
||||||
|
|
||||||
|
expect(response.total, 133);
|
||||||
|
expect(response.totalPages, 7);
|
||||||
|
expect(response.results[0].id, 'eOLpJytrbsQ');
|
||||||
|
expect(response.results[0].user.id, 'Ul0QVz12Goo');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('handles failure', () async {
|
||||||
|
const apiError =
|
||||||
|
'{"errors":["OAuth error: The access token is invalid"]}';
|
||||||
|
|
||||||
|
final httpClient = MockClient((req) async {
|
||||||
|
return Response(
|
||||||
|
apiError,
|
||||||
|
401,
|
||||||
|
request: req,
|
||||||
|
headers: {'content-type': 'application/json'},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
final unsplashClient = Unsplash(
|
||||||
|
accessKey: 'not-an-access-key',
|
||||||
|
httpClient: httpClient,
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await unsplashClient.searchPhotos(query: 'red');
|
||||||
|
fail('UnsplashException should have been thrown');
|
||||||
|
} on UnsplashException catch (e) {
|
||||||
|
expect(e.toString(),
|
||||||
|
'UnsplashException: OAuth error: The access token is invalid');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('handles broken JSON', () async {
|
||||||
|
const apiError = '{"tot'; // truncated JSON.
|
||||||
|
|
||||||
|
final httpClient = MockClient((req) async {
|
||||||
|
return Response(
|
||||||
|
apiError,
|
||||||
|
401,
|
||||||
|
request: req,
|
||||||
|
headers: {'content-type': 'application/json'},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
final unsplashClient = Unsplash(
|
||||||
|
accessKey: 'not-an-access-key',
|
||||||
|
httpClient: httpClient,
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await unsplashClient.searchPhotos(query: 'red');
|
||||||
|
fail('UnsplashException should have been thrown');
|
||||||
|
} on UnsplashException catch (e) {
|
||||||
|
expect(e.toString(),
|
||||||
|
'UnsplashException: Invalid JSON received');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,130 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:desktop_photo_search/src/unsplash/photo.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:desktop_photo_search/src/model/photo_search_model.dart';
|
||||||
|
import 'package:desktop_photo_search/src/unsplash/search_photos_response.dart';
|
||||||
|
import 'package:desktop_photo_search/src/unsplash/unsplash.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class FakeUnsplash implements Unsplash {
|
||||||
|
static const searchPhotosResponse = '''
|
||||||
|
{
|
||||||
|
"total": 133,
|
||||||
|
"total_pages": 7,
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"id": "eOLpJytrbsQ",
|
||||||
|
"created_at": "2014-11-18T14:35:36-05:00",
|
||||||
|
"width": 4000,
|
||||||
|
"height": 3000,
|
||||||
|
"color": "#A7A2A1",
|
||||||
|
"likes": 286,
|
||||||
|
"liked_by_user": false,
|
||||||
|
"description": "A man drinking a coffee.",
|
||||||
|
"user": {
|
||||||
|
"id": "Ul0QVz12Goo",
|
||||||
|
"username": "ugmonk",
|
||||||
|
"name": "Jeff Sheldon",
|
||||||
|
"first_name": "Jeff",
|
||||||
|
"last_name": "Sheldon",
|
||||||
|
"instagram_username": "instantgrammer",
|
||||||
|
"twitter_username": "ugmonk",
|
||||||
|
"portfolio_url": "http://ugmonk.com/",
|
||||||
|
"profile_image": {
|
||||||
|
"small": "https://images.unsplash.com/profile-1441298803695-accd94000cac?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&fit=crop&h=32&w=32&s=7cfe3b93750cb0c93e2f7caec08b5a41",
|
||||||
|
"medium": "https://images.unsplash.com/profile-1441298803695-accd94000cac?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&fit=crop&h=64&w=64&s=5a9dc749c43ce5bd60870b129a40902f",
|
||||||
|
"large": "https://images.unsplash.com/profile-1441298803695-accd94000cac?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&fit=crop&h=128&w=128&s=32085a077889586df88bfbe406692202"
|
||||||
|
},
|
||||||
|
"links": {
|
||||||
|
"self": "https://api.unsplash.com/users/ugmonk",
|
||||||
|
"html": "http://unsplash.com/@ugmonk",
|
||||||
|
"photos": "https://api.unsplash.com/users/ugmonk/photos",
|
||||||
|
"likes": "https://api.unsplash.com/users/ugmonk/likes"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"current_user_collections": [],
|
||||||
|
"urls": {
|
||||||
|
"raw": "https://images.unsplash.com/photo-1416339306562-f3d12fefd36f",
|
||||||
|
"full": "https://hd.unsplash.com/photo-1416339306562-f3d12fefd36f",
|
||||||
|
"regular": "https://images.unsplash.com/photo-1416339306562-f3d12fefd36f?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&s=92f3e02f63678acc8416d044e189f515",
|
||||||
|
"small": "https://images.unsplash.com/photo-1416339306562-f3d12fefd36f?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&s=263af33585f9d32af39d165b000845eb",
|
||||||
|
"thumb": "https://images.unsplash.com/photo-1416339306562-f3d12fefd36f?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&s=8aae34cf35df31a592f0bef16e6342ef"
|
||||||
|
},
|
||||||
|
"links": {
|
||||||
|
"self": "https://api.unsplash.com/photos/eOLpJytrbsQ",
|
||||||
|
"html": "http://unsplash.com/photos/eOLpJytrbsQ",
|
||||||
|
"download": "http://unsplash.com/photos/eOLpJytrbsQ/download"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<SearchPhotosResponse> searchPhotos(
|
||||||
|
{String query,
|
||||||
|
num page = 1,
|
||||||
|
num perPage = 10,
|
||||||
|
List<num> collections = const [],
|
||||||
|
SearchPhotosOrientation orientation}) async {
|
||||||
|
return SearchPhotosResponse.fromJson(searchPhotosResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Uint8List> download(Photo photo) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fabKey = Key('fab');
|
||||||
|
|
||||||
|
class PhotoSearchModelTester extends StatelessWidget {
|
||||||
|
const PhotoSearchModelTester(this.query);
|
||||||
|
final String query;
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return MaterialApp(
|
||||||
|
home: FlatButton(
|
||||||
|
key: fabKey,
|
||||||
|
onPressed: () async {
|
||||||
|
await Provider.of<PhotoSearchModel>(context).addSearch(query);
|
||||||
|
},
|
||||||
|
child: const Text('Search for a Photo'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('search_list', () {
|
||||||
|
testWidgets('starts empty', (tester) async {
|
||||||
|
final unsplashSearches = PhotoSearchModel(FakeUnsplash());
|
||||||
|
final testWidget = ChangeNotifierProvider<PhotoSearchModel>(
|
||||||
|
create: (context) => unsplashSearches,
|
||||||
|
child: const PhotoSearchModelTester('clouds'),
|
||||||
|
);
|
||||||
|
await tester.pumpWidget(testWidget);
|
||||||
|
expect(unsplashSearches.entries.length, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('addSearch adds searches', (tester) async {
|
||||||
|
final unsplashSearches = PhotoSearchModel(FakeUnsplash());
|
||||||
|
final testWidget = ChangeNotifierProvider<PhotoSearchModel>(
|
||||||
|
create: (context) => unsplashSearches,
|
||||||
|
child: const PhotoSearchModelTester('clouds'),
|
||||||
|
);
|
||||||
|
await tester.pumpWidget(testWidget);
|
||||||
|
await tester.tap(find.byKey(fabKey));
|
||||||
|
await tester.tap(find.byKey(fabKey));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
expect(unsplashSearches.entries.length, 2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
// Copyright 2019 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:async/async.dart' show StreamGroup;
|
||||||
|
import 'package:grinder/grinder.dart';
|
||||||
|
|
||||||
|
void main(List<String> args) => grind(args);
|
||||||
|
|
||||||
|
@DefaultTask()
|
||||||
|
@Depends(pubGet, generateJsonBindings, analyzeSource, test)
|
||||||
|
void build() {}
|
||||||
|
|
||||||
|
@Task()
|
||||||
|
Future<void> pubGet() async => _logProcessOutput(
|
||||||
|
Process.start(
|
||||||
|
'flutter',
|
||||||
|
['pub', 'get'],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
@Task()
|
||||||
|
Future<void> generateJsonBindings() async => _logProcessOutput(
|
||||||
|
Process.start(
|
||||||
|
'flutter',
|
||||||
|
['pub', 'run', 'build_runner', 'build', '--delete-conflicting-outputs'],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
@Task()
|
||||||
|
Future<void> watch() async => _logProcessOutput(
|
||||||
|
Process.start(
|
||||||
|
'flutter',
|
||||||
|
['pub', 'run', 'build_runner', 'watch'],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
@Task()
|
||||||
|
Future<void> analyzeSource() async => _logProcessOutput(
|
||||||
|
Process.start(
|
||||||
|
'flutter',
|
||||||
|
['pub', 'run', 'tuneup'],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
@Task()
|
||||||
|
Future<void> test() async => _logProcessOutput(
|
||||||
|
Process.start(
|
||||||
|
'flutter',
|
||||||
|
['test'],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
@Task()
|
||||||
|
Future<void> clean() => _logProcessOutput(
|
||||||
|
Process.start(
|
||||||
|
'flutter',
|
||||||
|
['clean'],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
Future<void> _logProcessOutput(Future<Process> proc) async {
|
||||||
|
final process = await proc;
|
||||||
|
final output = StreamGroup.merge([process.stdout, process.stderr]);
|
||||||
|
await for (final message in output) {
|
||||||
|
log(utf8.decode(message));
|
||||||
|
}
|
||||||
|
}
|