Skip to content
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

feat: Budget Duration #556

Merged
merged 17 commits into from Oct 19, 2021
Merged

Conversation

ianshade
Copy link
Contributor

@ianshade ianshade commented Aug 17, 2021

  • What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)
    A feature called Budget Duration

  • What is the current behavior? (You can also link to an open issue here)

  • What is the new behavior (if this is a feature change)?
    Parts have a new optional property called budgetDuration.
    In a Segment that has any Part with budgetDuration set, an Editorial Marker will be displayed on the segment timeline, as a dashed vertical line, indicating the budget duration of the entire Segment (sum of budgetDurations of its Parts).
    In said Segment, the SegmentDuration component will display the segment's budget duration, and count down from it when the segment becomes live. The duration will go negative when the segment is playing longer than its budget.
    If a segment with budget duration is on air, Part Counters on the next Segments are based on budget duration of the current segment, instead of expected durations of the parts that are left.

  • Other information:

Status

  • Code documentation for the relevant parts in the code have been added/updated by the PR author
  • The functionality has been tested by the PR author
  • The functionality has been tested by NRK

@codecov-commenter
Copy link

codecov-commenter commented Aug 17, 2021

Codecov Report

Merging #556 (7dd3330) into release38 (124af32) will increase coverage by 15.06%.
The diff coverage is n/a.

Impacted file tree graph

@@              Coverage Diff               @@
##           release38     #556       +/-   ##
==============================================
+ Coverage      67.39%   82.46%   +15.06%     
==============================================
  Files            264       12      -252     
  Lines          18374     1015    -17359     
  Branches        4083      210     -3873     
==============================================
- Hits           12384      837    -11547     
+ Misses          5949      177     -5772     
+ Partials          41        1       -40     
Impacted Files Coverage Δ
meteor/lib/rundown/rundownTiming.ts
meteor/lib/collections/Parts.ts
meteor/server/api/blueprints/context/lib.ts
meteor/lib/collections/AdLibPieces.ts
meteor/lib/collections/PackageInfos.ts
meteor/server/security/organization.ts
meteor/lib/collections/RundownPlaylists.ts
...client/ui/RundownList/DisplayFormattedTimeInner.ts
meteor/server/api/ingest/commit.ts
meteor/lib/check.ts
... and 242 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 124af32...7dd3330. Read the comment docs.

@nytamin nytamin added Contribution from TV 2 Danmark Contributions sponsored by TV 2 Danmark (tv2.dk) ✨ enhancement New feature or request labels Aug 27, 2021
@nytamin nytamin requested a review from jstarpl August 27, 2021 11:32
prevents issus in a future merge with tv2:feat/rundown-view-customization
@nytamin
Copy link
Contributor

nytamin commented Sep 8, 2021

It would be good if another unit test be added into meteor/lib/rundown/__tests__/rundownTiming.test.ts, to support this functionality.

@nytamin nytamin added the 👍 Accepted This PR is accepted by the Product Owner label Sep 8, 2021
probably a bad merge from times when `findPartInstanceInMapOrWrapToTemporary` did not exist
@ianshade
Copy link
Contributor Author

ianshade commented Sep 8, 2021

I added a test case. Note: this feature currently affects only the partCountdown. It does not affect remainingPlaylistDuration, totalPlaylistDuration, etc. but it's subject to change in future PRs

Copy link
Member

@jstarpl jstarpl left a comment

Choose a reason for hiding this comment

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

I'm really confused by some of the implementation & some parts can be definitely implemented in a more straightforward fashion & reducing the amount of inter-dependency between the components.

@@ -6,6 +6,8 @@ import { PartUi } from '../../SegmentTimeline/SegmentTimelineContainer'

interface ISegmentDurationProps {
parts: PartUi[]
budgetDuration?: number
playedOutDuration: number
Copy link
Member

Choose a reason for hiding this comment

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

What this is used for definitely needs a comment. I would expect SegmentDuration component to figure out the playedOutDuration of given parts on it's own, so maybe this should be called playedOutDurationOverride or something like that? Same for budgetDuration, since calculating the budget was also something that used to be only done internally.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed those properties in favor of timingDurations

isLastInSegment={false}
isAfterLastValidInSegmentAndItsLive={false}
isBudgetGap={true}
part={{
Copy link
Member

Choose a reason for hiding this comment

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

As is, this will create a new part object for every render of the component, even though this object is essentially constant through the lifetime of the component. This needs to be converted to a constant that gets reused on every render.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in a7a9c6c

onContextMenu?: (contextMenuContext: IContextMenuContext) => void
isLastInSegment: boolean
isAfterLastValidInSegmentAndItsLive: boolean
isLastSegment: boolean
isBudgetGap: boolean
Copy link
Member

Choose a reason for hiding this comment

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

I think this can be made optional. isBudgetGap is specified as true in just one single line. Makes no sense to keep writing isBudgetGap=false all the time.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in b46f8ae

@@ -421,11 +423,11 @@ export const SourceLayerItem = withTranslation()(
}

private mountResizeObserver() {
if (this.props.isLiveLine && !this._resizeObserver && this.state.itemElement) {
if (this.props.isLiveLine && !this._resizeObserver && this.itemElement) {
Copy link
Member

Choose a reason for hiding this comment

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

Why isn't this using the state anymore? Using state is definitely safer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Storing refs in state doesn't play well with componentDidMount, where we're using this ref

@@ -615,6 +622,21 @@ export const SegmentTimelineContainer = translateWithTracker<IProps, IState, ITr
window.removeEventListener('resize', this.onWindowResize)
}

private getSegmentBudgetDuration(): number | undefined {
Copy link
Member

Choose a reason for hiding this comment

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

I'm somewhat confused. So RundownTimingCalculator seems to already be doing almost the same thing, and yet then the Segment component seems to be doing it again? And then it feels like it only does that to pass that information forward to components that have access to the timing context anyway, so they could just get it from the Calculator. Or am I missing something?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

SegmentTimelineContainer's tracker seems to be a better place to do it, which adresses #556 (comment) as well.
Why can't the value come from RundownTimingCalculator? It could but we would need to do an extra comparison every time SegmentTimelineClass receives its HR time event.

@@ -794,11 +816,14 @@ export const SegmentTimelineContainer = translateWithTracker<IProps, IState, ITr
? partOffset + e.detail.currentTime - virtualStartedPlayback + lastTakeOffset
: partOffset + lastTakeOffset

const budgetDuration = this.getSegmentBudgetDuration()
Copy link
Member

@jstarpl jstarpl Sep 17, 2021

Choose a reason for hiding this comment

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

Why do this in the onAirLineRefresh()? This is going to happen on every tick, yet getSegmentBudgetDuration() only depends on semi-constant budgetDuration on the PartInstance. Wouldn't it make more sense to calculate that reactively in the tracker, which already depends on those PartInstances, so it's going to refresh if/when they change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved to the tracker

@jstarpl
Copy link
Member

jstarpl commented Sep 29, 2021

@ianshade Can you look into the PR review? I guess you would like this merged into Release 38.

@ianshade
Copy link
Contributor Author

We found an issue causing this to break the fit-to-viewport zoom feature. We're still working on a fix

@jstarpl jstarpl self-requested a review October 13, 2021 08:32
Copy link
Member

@jstarpl jstarpl left a comment

Choose a reason for hiding this comment

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

I think this looks OK.

@jstarpl jstarpl changed the base branch from release37 to release38 October 18, 2021 13:15
@jstarpl jstarpl merged commit 4b7627d into nrkno:release38 Oct 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
👍 Accepted This PR is accepted by the Product Owner Contribution from TV 2 Danmark Contributions sponsored by TV 2 Danmark (tv2.dk) ✨ enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants