-
Notifications
You must be signed in to change notification settings - Fork 1
Add detail player to film detail page #581
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
Conversation
Release 1.9.18 -> main
Release 1.9.19
Release 1.9.20
Release 1.9.21
Release 1.9.22
Release 1.9.23
Release 1.9.24
Release 1.9.25
| {{showPricingButtons := isFilm || isSeason || isBundle}} | ||
|
|
||
| {{showPlayButton := isFilm || isSeason || isEpisode}} | ||
| {{showPlayButton := isFilm || isSeason || isEpisode && config("is_creator", "false") == "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.
This config should be more specific about what it does, e.g. use_detail_page_player because we might want to use this on non-creator sites.
site/static/js/main.js
Outdated
| container.classList[action]('detail-player-theatre-mode'); | ||
| container.querySelector('detail-player').scrollIntoView({ behavior: 'smooth', block: 'start' }); | ||
| document.querySelector('.meta-detail-bg').classList[action]('meta-detail-bg--lights-out'); | ||
| document.querySelector('.poster-wrapper').classList[action]('d-none'); |
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.
The toggle method on classList does this: el.classList.toggle('detail-player-theatre-mode', isTheatreMode)
| }); | ||
| window.addEventListener('message', e => { | ||
| if (e.data.event == 's72-checkout:close') { | ||
| if (element.classList.contains('try-unlock')) { |
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's usually better to use component state rather than DOM elements as the source of truth for a React component.
Using component state means that any changes will queue up a re-render, if necessary, and the render function tells the framework how it wants the DOM to look.
It seems to me that when the shopping session completed event occurs, it should retrigger the same logic to set canBeWatched and maybe a purchaseCompleted flag, and then in the render it can add the appropriate classes to the DOM elements to trigger animations.
Was there a reason it was necessary to bypass component renders 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.
yeah I have no idea why I did this instead of using state
sam-shift72
left a comment
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.
Looks good. I see the CSS still refers to it as meta-detail-creator but perhaps that's fine until the paint dries on the detail player, comments etc.
| getCanBeWatched(callback) { | ||
| this.app.availabilityService.getAvailability(this.props.slug).then(a => { | ||
| if (a) { callback(a.canBeWatched) } | ||
| }); |
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 okay, but it would be nicer to stay "inside" the promise, e.g.
canBeWatched() {
return this.app.availabilityService.getAvailability(this.props.slug)
.then(a => a?.canBeWatched ?? false)
.catch(() => false)
}
componentDidMount() {
bus.subscribe(..., async () => {
if (await this.canBeWatched()) {
this.setState(...)
}
});
}Caveat: I only recently upgraded core-template from using the old buble compiler to babel to get support for modern JS features, but optional chaining (?., ??) and async/await can make this kind of code much simpler
| ); | ||
| } | ||
|
|
||
| playIcon() { |
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 I mentioned this in the Relish PR but it would be more idiomatic React to refactor these to be separate components rather than render-functions. Its not a big deal though and it's an easy tidy up later.
| documentReady(app); | ||
| }); | ||
|
|
||
| window.addEventListener('message', e => { |
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 could be added to the componentDidMount of the detail player component instead? That would keep the code together.
Even if we were building a proper SPA we'd add this event listener when the detail player mounts, and then unsubscribe in componentDidUnmount, but our Relish components are all sloppy about that
| {{showPricingButtons := isFilm || isSeason || isBundle}} | ||
|
|
||
| {{showPlayButton := isFilm || isSeason || isEpisode}} | ||
| {{showPlayButton := isFilm || isSeason || isEpisode && config("use_detail_page_player", "false") == "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.
It's best to add parens to conditions like this to communicate which of these you mean:
isFilm || isSeason || (isEpisode && !useDetailPlayer)(isFilm || isSeason || isEpisode) && !useDetailPlayer
I don't know the intricacies of CloudyKit Jet's parser, but in most languages && has higher precedence over ||, so the code as written is case 1 ("only show the play button for episodes if we're not using detail player")
Adding a variable like {{useDetailPlayer := config(...) == "true" }} and will help make it more readable too.
sam-shift72
left a comment
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.
Added @l0ud0gg to get his thoughts but I think this nearly looks good to merge.
site/templates/film/title.jet
Outdated
| @@ -1,8 +1,8 @@ | |||
| {{block filmTitle(title,class,element="h1")}} | |||
| {{block filmTitle(title, class, element = "h1", forceText = 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.
It's not immediately obvious what forceText means. Perhaps this parameter should be useTitleImage = true and then it can be useTitleImage=!useDetailPlayer when invoking the block
| {{showPlayButton := isFilm || isSeason || isEpisode}} | ||
| {{useDetailPlayer := config("use_detail_page_player", "false") == "true"}} | ||
|
|
||
| {{showPlayButton := (isFilm || isSeason || isEpisode) && !useDetailPlayer }} |
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.
When the detail player is enabled, this gets rid of the play CTA from carousel items which isn't desirable. Maybe this should be && (isCarousel || !useDetailPlayer)
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.
ah good catch
l0ud0gg
left a comment
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.
looks good as man. just left one comment on a edge case but i think we can just write a basic wiki page outlining the feature and that it requires that config if need be.
| > | ||
| {this.placeholderBG()} | ||
| <div class="detail-player-placeholder-overlay"> | ||
| {state.canBeWatched && this.playButton() } |
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.
We found a bug here when a site does not have the "disable_anonymous_watch_now" meta config set. It will display a play button for anonymous users and if clicked will open the sign in page within the detail player iframe. For now its prolly fine as we can ensure this config is a prereq for this feature, but might do some wierd things otherwise for other business models.
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.
yeah there are a bunch of edge cases that still need to be sorted with this feature before it's ready for widespread deployment but I don't think they're blockers for merge.
|
i did a little bit of side-by-side regression testing on tvoddemo (with this feature disabled) and I didn't notice any responsive layout issues so should be safe to merge from that pov |
ADO card: ☑️ AB#XXXX
Elab notes/AC: 📃 Detail Page Video Player - Google Docs
Description of work
Implementation of detail player on film detail page
Config settings/Toggles required for the feature to work
use_detail_page_player = trueadds player to film detail pageAffected Clients
Checklist