-
Notifications
You must be signed in to change notification settings - Fork 481
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New export ux #28795
New export ux #28795
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tweaked some strings
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strings LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks awesome! I have a couple nits, and two larger comments:
First, I am super concerned about the size and complexity of the ExportAllowedDialog component. Can it be broken up into multiple components? Perhaps reconceived as a generic "dialog with multiple pages" component, and then the implementation logic moved into individual Components representing each page in sequence?
Second, looks like there are quite a few places in this using hardcoded English strings. Can these all be pulled out into i18n strings?
<p style={styles.title}>{titleText}</p> | ||
</div> | ||
<div style={styles.section}> | ||
<p style={styles.p} dangerouslySetInnerHTML={{__html: headerText}} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
prefer using the UnsafeRenderedMarkdown component when we want to format strings
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just played with it now and it isn't really working. I can't put it inside a <p>
tag. When I put it inside a <div>
, it loses the styles I applied. Plus it instantiates a markdown processor that I don't need. Seems like a good idea to have a reusable component, but it doesn't seem like the right fit for this scenario.
} = this.getActionButtonInfo(); | ||
const showShareWarning = | ||
!this.props.canShareSocial && | ||
(this.props.appType === 'applab' || this.props.appType === 'gamelab'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a specific reason why weblab
is included in the "sharing enabled" logic, but not here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question. This copied the logic from ShareAllowedDialog
- out of caution, I suggested to @ryansloan that we stick with the same logic for exporting. But I didn't try to revisit that logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That said, I should probably just remove the weblab
references since we don't plan to support exporting weblab sites as mobile apps.
|
||
export default connect( | ||
state => ({ | ||
allowExportExpo: state.pageConstants.allowExportExpo || false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't the || false
here redundant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It ensures that we satisfy a PropTypes
requirement
return <ExportAllowedDialog {...otherProps} />; | ||
} | ||
|
||
return <ShareDisallowedDialog />; // TODO: re-use or create ExportDisallowedDialog? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd very much prefer to either create an ExportDisallowedDialog
or rename ShareDisallowedDialog
to something more generic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I figured out a way to eliminate the extra component altogether. Trying to mimic the layers of warnings in the share dialog has been a little challenging. There are so many that have been bolted on!
I'm ok with doing that, though I'd prefer to do it after we lock in on a design (post student testing).
As this is only exposed by applab/gamelab, I'm following the pattern that we use throughout those apps where we do use hardcoded strings and do not use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very cool! I'm not quite ready to approve. I know this is still behind an experiment, but I'd like to see at least an initial test for each bit of new business logic. Specifically:
ExportAllowedDialog
'spublishExpoExport
andpublishAndGenerateApk
methods.ExportDialog
's decision about whether export is allowed.ProjectHeader
andProjectBackedHeader
's newincludeExportInProjectHeader
props.- The new
/sms/send_download
route.
study: 'finish-dialog-export', | ||
study_group: 'v1', | ||
event: 'project-export', | ||
project_id: dashboard.project && dashboard.project.getCurrentId(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can import project
directly without referring to the dashboard global, and it'll work just as well.
return; | ||
} | ||
|
||
await this.publishExpoExport(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it weird, from a student perspective, that generating the APK here could result in us showing this Expo error?
Failed to publish project to Expo. Please try again later.
There's a slight action-at-a-distance pattern here by depending on the state changes caused by publishExpoExport
. I also suspect that this await
is likely, but not guaranteed, to wait until the async setState
calls in publishExpoExport
complete.
I might call exportApp
directly from publishAndGenerateApk
, trading a little duplication for more control over what we do with the Expo results.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is really good feedback. My solution is a little different from what you proposed, because I know that for the iOS case, I need to do publishExpoExport()
, but not the rest of the steps in publishAndGenerateApk()
, so I want to keep them separate.
I've changed publishExpoExport()
to return an object (essentially the exportResult
or a similarly shaped object for the "already exported" or failure cases). This way we don't rely on the async setState()
as a method to pass the results in this chained async scenario.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds great. 👍
case 'publish': | ||
return this.renderPublishPage(); | ||
case 'generating': | ||
return this.renderGeneratingPage(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Calling out a personal preference for subcomponents over helper render methods, but that's easy to fix later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Understood, I'd be happy to revisit this later.
@@ -30,7 +27,6 @@ $(document).ready(function() | |||
}); | |||
|
|||
var petition; | |||
$(document).ready(function() | |||
{ | |||
$(document).ready(function() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did this file change at all, or just get Prettier run on it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just prettier. somewhat on accident, but I decided to leave it since this now seems to match our preferred style.
return { | ||
...state, | ||
...initialState, | ||
isOpen: true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like overkill.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
overkill meaning using redux to track whether the dialog is open? I agree that it is odd, but I started by following the share dialog and reduced most of the code away. I decided to keep this part because it allows us to use the dialog in a more "modeless" fashion (where you could close it while the export is underway, and open it back up later). I'm still in discussions with @ryansloan over the UI metaphor we'd use to enable that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I specifically meant ...state, ...initialState, isOpen: true
when there's only the one property here. I think I see the spirit of the thing though. 😁
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Updates look great. Thanks for adding good tests!
Merging since #28886 has been merged to staging, resolving these unrelated failures that I was seeing above... |
exportExpo
experiment flag)sms_download
entry point so we can send Twilio SMS messages for this scenario like this: