Recsys: add flow and fix uncovered issues
This commit is contained in:
parent
d5c964c208
commit
e3e675455a
4 changed files with 71 additions and 21 deletions
|
@ -15,6 +15,7 @@
|
|||
[options]
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIgnore
|
||||
module.name_mapper='^constants\(.*\)$' -> '<PROJECT_ROOT>/ui/constants\1'
|
||||
module.name_mapper='^contexts\(.*\)$' -> '<PROJECT_ROOT>/ui/contexts\1'
|
||||
module.name_mapper='^util\(.*\)$' -> '<PROJECT_ROOT>/ui/util\1'
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// @flow
|
||||
import { RECSYS_ENDPOINT } from 'config';
|
||||
import { selectUser } from 'redux/selectors/user';
|
||||
import { makeSelectRecommendedRecsysIdForClaimId } from 'redux/selectors/search';
|
||||
|
@ -10,6 +11,7 @@ import { makeSelectClaimForUri } from 'redux/selectors/claims';
|
|||
import { selectPlayingUri, selectPrimaryUri } from 'redux/selectors/content';
|
||||
import { selectClientSetting, selectDaemonSettings } from 'redux/selectors/settings';
|
||||
import { selectIsSubscribedForClaimId } from 'redux/selectors/subscriptions';
|
||||
// $FlowFixMe: cannot resolve..
|
||||
import { history } from 'ui/store';
|
||||
|
||||
const recsysEndpoint = RECSYS_ENDPOINT;
|
||||
|
@ -28,7 +30,7 @@ const getClaimIdsFromUris = (uris) => {
|
|||
: [];
|
||||
};
|
||||
|
||||
const recsys = {
|
||||
const recsys: Recsys = {
|
||||
entries: {},
|
||||
debug: false,
|
||||
/**
|
||||
|
@ -36,23 +38,9 @@ const recsys = {
|
|||
* Entries are Created either when recommendedContent loads, or when recommendedContent is clicked.
|
||||
* If recommended content is clicked, An Entry with parentUuid is created.
|
||||
* On page load, find an empty entry with your claimId, or create a new entry and record to it.
|
||||
* The entry will be populated with the following:
|
||||
* - parentUuid // optional
|
||||
* - Uuid
|
||||
* - claimId
|
||||
* - recommendedClaims [] // optionally empty
|
||||
* - playerEvents [] // optionally empty
|
||||
* - recommendedClaimsIndexClicked [] // optionally empty
|
||||
* - UserId
|
||||
* - pageLoadedAt
|
||||
* - isEmbed
|
||||
* - pageExitedAt
|
||||
* - autoplay
|
||||
* - recsysId // optional
|
||||
*/
|
||||
|
||||
/**
|
||||
* Function: onClickedRecommended()
|
||||
* Called when RecommendedContent was clicked.
|
||||
* Adds index of clicked recommendation to parent entry
|
||||
* Adds new Entry with parentUuid for destination page
|
||||
|
@ -61,20 +49,23 @@ const recsys = {
|
|||
*/
|
||||
onClickedRecommended: function (parentClaimId, newClaimId) {
|
||||
const parentEntry = recsys.entries[parentClaimId] ? recsys.entries[parentClaimId] : null;
|
||||
const parentUuid = parentEntry['uuid'];
|
||||
const parentRecommendedClaims = parentEntry['recClaimIds'] || [];
|
||||
const parentClickedIndexes = parentEntry['recClickedVideoIdx'] || [];
|
||||
const parentUuid = parentEntry ? parentEntry['uuid'] : '';
|
||||
const parentRecommendedClaims = parentEntry ? parentEntry['recClaimIds'] : [];
|
||||
const parentClickedIndexes = parentEntry ? parentEntry['recClickedVideoIdx'] : [];
|
||||
const indexClicked = parentRecommendedClaims.indexOf(newClaimId);
|
||||
|
||||
if (parentUuid) {
|
||||
recsys.createRecsysEntry(newClaimId, parentUuid);
|
||||
}
|
||||
|
||||
parentClickedIndexes.push(indexClicked);
|
||||
recsys.log('onClickedRecommended', { parentClaimId, newClaimId });
|
||||
// recsys.log('onClickedRecommended', { parentClaimId, newClaimId });
|
||||
recsys.log('onClickedRecommended', newClaimId);
|
||||
},
|
||||
|
||||
/**
|
||||
* Page was loaded. Get or Create entry and populate it with default data, plus recommended content, recsysId, etc.
|
||||
* Page was loaded. Get or Create entry and populate it with default data,
|
||||
* plus recommended content, recsysId, etc.
|
||||
* Called from recommendedContent component
|
||||
*/
|
||||
onRecsLoaded: function (claimId, uris, uuid = '') {
|
||||
|
@ -86,6 +77,13 @@ const recsys = {
|
|||
const claimIds = getClaimIdsFromUris(uris);
|
||||
recsys.entries[claimId]['recsysId'] = makeSelectRecommendedRecsysIdForClaimId(claimId)(state) || recsysId;
|
||||
recsys.entries[claimId]['pageLoadedAt'] = Date.now();
|
||||
|
||||
// It is possible that `claimIds` include `null | undefined` entries
|
||||
// instead of all being strings. I don't know if we should filter it,
|
||||
// or change the `recClaimIds` definition. Leaving as is for now since
|
||||
// any changes could affect existing recsys data set.
|
||||
// -----------
|
||||
// $FlowFixMe:
|
||||
recsys.entries[claimId]['recClaimIds'] = claimIds;
|
||||
}
|
||||
recsys.log('onRecsLoaded', claimId);
|
||||
|
@ -104,6 +102,7 @@ const recsys = {
|
|||
const userId = user ? user.id : null;
|
||||
|
||||
// Make a stub entry that will be filled out on page load
|
||||
// $FlowIgnore: not everything is defined since this is a stub
|
||||
recsys.entries[claimId] = {
|
||||
uuid: uuid || Uuidv4(),
|
||||
claimId: claimId,
|
||||
|
@ -115,10 +114,13 @@ const recsys = {
|
|||
};
|
||||
|
||||
if (parentUuid) {
|
||||
// $FlowFixMe: 'uid' should be a number, not null.
|
||||
recsys.entries[claimId].uid = userId || null;
|
||||
recsys.entries[claimId].parentUuid = parentUuid;
|
||||
} else {
|
||||
// $FlowFixMe: 'uid' should be a number, not null.
|
||||
recsys.entries[claimId].uid = userId;
|
||||
// $FlowFixMe: 'recsysId' should be a number, not null.
|
||||
recsys.entries[claimId].recsysId = null;
|
||||
recsys.entries[claimId].recClaimIds = [];
|
||||
}
|
||||
|
@ -249,7 +251,7 @@ const recsys = {
|
|||
const state = window.store.getState();
|
||||
const playingUri = selectPlayingUri(state);
|
||||
const actualPlayingUri = playingUri && playingUri.uri;
|
||||
const claim = makeSelectClaimForUri(actualPlayingUri)(state);
|
||||
const claim = makeSelectClaimForUri(actualPlayingUri || '')(state);
|
||||
const playingClaimId = claim ? claim.claim_id : null;
|
||||
// const primaryUri = selectPrimaryUri(state);
|
||||
const floatingPlayer = selectClientSetting(state, SETTINGS.FLOATING_PLAYER);
|
||||
|
|
2
flow-typed/Claim.js
vendored
2
flow-typed/Claim.js
vendored
|
@ -58,6 +58,8 @@ declare type GenericClaim = {
|
|||
},
|
||||
};
|
||||
|
||||
declare type ClaimId = string;
|
||||
|
||||
declare type GenericMetadata = {
|
||||
title?: string,
|
||||
description?: string,
|
||||
|
|
45
flow-typed/recsys.js
vendored
Normal file
45
flow-typed/recsys.js
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
declare type Recsys = {
|
||||
entries: { [ClaimId]: RecsysEntry },
|
||||
debug: boolean,
|
||||
onClickedRecommended: (parentClaimId: ClaimId, newClaimId: ClaimId) => void,
|
||||
onRecsLoaded: (claimId: ClaimId, uris: Array<string>, uuid: string) => void,
|
||||
createRecsysEntry: (claimId: ClaimId, parentUuid?: ?string, uuid?: string) => void,
|
||||
sendRecsysEntry: (claimId: ClaimId, isTentative?: boolean) => ?Promise<?Response>,
|
||||
onRecsysPlayerEvent: (claimId: ClaimId, event: RecsysPlaybackEvent, isEmbedded: boolean) => void,
|
||||
log: (callName: string, claimId: ClaimId) => void,
|
||||
onPlayerDispose: (claimId: ClaimId, isEmbedded: boolean, totalPlayingTime: number) => void,
|
||||
onNavigate: () => void,
|
||||
};
|
||||
|
||||
declare type RecsysEntry = {
|
||||
uuid: string,
|
||||
parentUuid?: string,
|
||||
claimId: string,
|
||||
uid?: number,
|
||||
deviceId?: number,
|
||||
pageLoadedAt: number, // UNIX timestamp (in UTC)
|
||||
pageExitedAt: number, // UNIX timestamp (in UTC)
|
||||
events: Array<RecsysPlaybackEvent>,
|
||||
recsysId: string, // Recommender that produced recs
|
||||
recClaimIds: Array<string>, // Recommendations
|
||||
recClickedVideoIdx: Array<number>, // Video clicked index
|
||||
isEmbed: boolean,
|
||||
remoteIp: any, // [bytes] Caller IP address
|
||||
tentative: boolean, // Visibility change rather than tab close
|
||||
autoplay: boolean, // Was the last human action before this?
|
||||
commentPulls: number, // How many comment pull calls did the user request?
|
||||
recorded_at: number,
|
||||
user_agent: string,
|
||||
accept_lang: string,
|
||||
tokenVerified: boolean,
|
||||
totalPlayTime: number,
|
||||
finalPlayPosition: number,
|
||||
incognito: number, // User not logged in.
|
||||
isResumedSend: boolean, // Data sent after browser is re-opened.
|
||||
};
|
||||
|
||||
declare type RecsysPlaybackEvent = {
|
||||
event: number, // 0 = start, 1 = stop, 2 = scrub, 3 = speed, 4 = end_of_play
|
||||
offset: number, // Where playback was at time of event
|
||||
arg: number,
|
||||
};
|
Loading…
Reference in a new issue