Skip to content

Conversation

@domesticmouse
Copy link
Contributor

Adding a desktop sample app.

@domesticmouse
Copy link
Contributor Author

FYI @csells

Copy link
Contributor

@redbrogdon redbrogdon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some drive-by comments. I'll try to get back to this ASAP.

@override
Widget build(BuildContext context) {
final photoSearchModel = Provider.of<PhotoSearchModel>(context);
menubar.setApplicationMenu([
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this something that could/should be moved out of the build method? The fact that the widget's being built doesn't necessarily imply it's actively on the screen.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The menu action has an implicit linkage to this window through the callback's construction of a dialog in the window. The only way I can see to make this work is for this code to be run during build, so that it has access to the build context for showDialog. Happy to take guidance if my understanding of this constraint is incorrect.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, the need for a context weirds things up. I was mostly operating on my "build methods should avoid side effects wherever possible" instincts.

This reminds me of a situation I went to Hans for advice on: I wanted a network refresh for some data to be kicked off whenever the app navigated to a widget (DetailsScreen, I think it was). I had the update call initiating in a build method, but IIRC Hans suggested having my own Route object to do it.

At the moment, I don't have any real advice to offer, so stick with what you've got. I'm curious now, though, and I may ask Hans about it next week. 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fun part is that the menu will change depending on which window is selected for input in the user's window stack, which is independent of the repaint cycle.

final PhotoDetailsPhotoSaveCallback onPhotoSave;

@override
Widget build(BuildContext context) => SingleChildScrollView(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Generally, arrow syntax should be used for simple one-liners. While it works here, it increase rightward drift of the code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Converted back to block syntax

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can break this out into builder methods and/or subsidiary widgets. Thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Broken out some of the content into a builder method, and added some animation to make the initial transition from no loaded image to loaded image less janky.

@override
Widget build(BuildContext context) {
final photoSearchModel = Provider.of<PhotoSearchModel>(context);
menubar.setApplicationMenu([
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, the need for a context weirds things up. I was mostly operating on my "build methods should avoid side effects wherever possible" instincts.

This reminds me of a situation I went to Hans for advice on: I wanted a network refresh for some data to be kicked off whenever the app navigated to a widget (DetailsScreen, I think it was). I had the update call initiating in a build method, but IIRC Hans suggested having my own Route object to do it.

At the moment, I don't have any real advice to offer, so stick with what you've got. I'm curious now, though, and I may ask Hans about it next week. 😄


if (body is Map && body['errors'] is List && body['errors'].isNotEmpty) {
final apiError = ApiError.fromJson(response.body);
throw UnsplashException(apiError.errors.join(', '));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider trapping other issues (json failing to parse on line 64, for instance) and returning this exception class as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added handling for invalid JSON response

@@ -0,0 +1,350 @@
// Copyright 2019 The Flutter team. All rights reserved.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this something you wrote in concert with Hans, or is it something he did for a different project that also works here?

Copy link
Contributor Author

@domesticmouse domesticmouse Dec 10, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code was lifted and adapted from a gist put together by @HansMuller.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @csells, the original idea for this sample was to showcase both Split and DataTree, but I fear the complexity of the DataTree in this sample is working against our larger goals of making Flutter on desktop approachable. Would you be ok with taking DataTree out and replacing it with something simpler? The upside is that we get a path to introducing shared preferences to store favorited photos.

@@ -0,0 +1,194 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has a different author name than the others. Is it pulled from something else?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, it's @DaveShuckerow's code, and lifted and adapted from Flutter DevTool Widget Inspector, if memory serves.

@domesticmouse domesticmouse merged commit f07b4a9 into flutter:master Dec 10, 2019
@domesticmouse domesticmouse deleted the desktop_photo_search branch December 10, 2019 20:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants