add time to start (in seconds) to Play track event for new downloads #269
3 changed files with 86 additions and 37 deletions
|
@ -93,9 +93,8 @@ class MediaPlayer extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.state.firstPlay) {
|
if (this.state.firstPlay) {
|
||||||
if (NativeModules.Mixpanel) {
|
if (this.props.onPlaybackStarted) {
|
||||||
const { uri } = this.props;
|
this.props.onPlaybackStarted();
|
||||||
NativeModules.Mixpanel.track('Play', { Uri: uri });
|
|
||||||
}
|
}
|
||||||
this.setState({ firstPlay: false });
|
this.setState({ firstPlay: false });
|
||||||
this.hidePlayerControls();
|
this.hidePlayerControls();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Lbry, normalizeURI } from 'lbry-redux';
|
import { Lbry, normalizeURI } from 'lbry-redux';
|
||||||
|
import { Lbryio } from 'lbryinc';
|
||||||
import {
|
import {
|
||||||
ActivityIndicator,
|
ActivityIndicator,
|
||||||
Alert,
|
Alert,
|
||||||
|
@ -38,11 +39,14 @@ class FilePage extends React.PureComponent {
|
||||||
|
|
||||||
player = null;
|
player = null;
|
||||||
|
|
||||||
|
startTime = null;
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
|
fileViewLogged: false,
|
||||||
mediaLoaded: false,
|
mediaLoaded: false,
|
||||||
autoplayMedia: false,
|
autoPlayMedia: false,
|
||||||
downloadButtonShown: false,
|
downloadButtonShown: false,
|
||||||
downloadPressed: false,
|
downloadPressed: false,
|
||||||
fullscreenMode: false,
|
fullscreenMode: false,
|
||||||
|
@ -73,7 +77,7 @@ class FilePage extends React.PureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate(prevProps) {
|
||||||
this.fetchFileInfo(this.props);
|
this.fetchFileInfo(this.props);
|
||||||
const { isResolvingUri, resolveUri, claim, navigation } = this.props;
|
const { isResolvingUri, resolveUri, claim, navigation } = this.props;
|
||||||
const { uri } = navigation.state.params;
|
const { uri } = navigation.state.params;
|
||||||
|
@ -81,6 +85,18 @@ class FilePage extends React.PureComponent {
|
||||||
if (!isResolvingUri && claim === undefined && uri) {
|
if (!isResolvingUri && claim === undefined && uri) {
|
||||||
resolveUri(uri);
|
resolveUri(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const prevFileInfo = prevProps.fileInfo;
|
||||||
|
const { fileInfo, contentType } = this.props;
|
||||||
|
if (!prevFileInfo && fileInfo) {
|
||||||
|
// started downloading
|
||||||
|
const mediaType = Lbry.getMediaType(contentType);
|
||||||
|
const isPlayable = mediaType === 'video' || mediaType === 'audio';
|
||||||
|
// If the media is playable, file/view will be done in onPlaybackStarted
|
||||||
|
if (!isPlayable && !this.state.fileViewLogged) {
|
||||||
|
this.logFileView(uri, fileInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchFileInfo(props) {
|
fetchFileInfo(props) {
|
||||||
|
@ -127,7 +143,7 @@ class FilePage extends React.PureComponent {
|
||||||
{ text: 'No' },
|
{ text: 'No' },
|
||||||
{ text: 'Yes', onPress: () => {
|
{ text: 'Yes', onPress: () => {
|
||||||
deleteFile(fileInfo.outpoint, true);
|
deleteFile(fileInfo.outpoint, true);
|
||||||
this.setState({ downloadPressed: false, mediaLoaded: false });
|
this.setState({ downloadPressed: false, fileViewLogged: false, mediaLoaded: false });
|
||||||
}}
|
}}
|
||||||
],
|
],
|
||||||
{ cancelable: true }
|
{ cancelable: true }
|
||||||
|
@ -144,7 +160,7 @@ class FilePage extends React.PureComponent {
|
||||||
{ text: 'No' },
|
{ text: 'No' },
|
||||||
{ text: 'Yes', onPress: () => {
|
{ text: 'Yes', onPress: () => {
|
||||||
stopDownload(navigation.state.params.uri, fileInfo);
|
stopDownload(navigation.state.params.uri, fileInfo);
|
||||||
this.setState({ downloadPressed: false, mediaLoaded: false });
|
this.setState({ downloadPressed: false, fileViewLogged: false, mediaLoaded: false });
|
||||||
} }
|
} }
|
||||||
],
|
],
|
||||||
{ cancelable: true }
|
{ cancelable: true }
|
||||||
|
@ -220,6 +236,49 @@ class FilePage extends React.PureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMediaLoaded = (title, channelName) => {
|
||||||
|
this.setState({ mediaLoaded: true });
|
||||||
|
window.currentMediaInfo = {
|
||||||
|
title: title,
|
||||||
|
channel: channelName
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
onPlaybackStarted = () => {
|
||||||
|
let timeToStartMillis, timeToStart;
|
||||||
|
if (this.startTime) {
|
||||||
|
timeToStartMillis = Date.now() - this.startTime;
|
||||||
|
timeToStart = Math.ceil(timeToStartMillis / 1000);
|
||||||
|
this.startTime = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { fileInfo, navigation } = this.props;
|
||||||
|
const { uri } = navigation.state.params;
|
||||||
|
this.logFileView(uri, fileInfo, timeToStartMillis);
|
||||||
|
|
||||||
|
let payload = { 'Uri': uri };
|
||||||
|
if (!isNaN(timeToStart)) {
|
||||||
|
payload['Time to Start (seconds)'] = timeToStart;
|
||||||
|
payload['Time to Start (ms)'] = timeToStartMillis;
|
||||||
|
}
|
||||||
|
NativeModules.Mixpanel.track('Play', payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
logFileView = (uri, fileInfo, timeToStart) => {
|
||||||
|
const { outpoint, claim_id: claimId } = fileInfo;
|
||||||
|
const params = {
|
||||||
|
uri,
|
||||||
|
outpoint,
|
||||||
|
claim_id: claimId
|
||||||
|
};
|
||||||
|
if (!isNaN(timeToStart)) {
|
||||||
|
params.time_to_start = timeToStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
Lbryio.call('file', 'view', params).catch(() => {});
|
||||||
|
this.setState({ fileViewLogged: true });
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
claim,
|
claim,
|
||||||
|
@ -320,7 +379,10 @@ class FilePage extends React.PureComponent {
|
||||||
style={filePageStyle.downloadButton}
|
style={filePageStyle.downloadButton}
|
||||||
openFile={openFile}
|
openFile={openFile}
|
||||||
isPlayable={isPlayable}
|
isPlayable={isPlayable}
|
||||||
onPlay={() => this.setState({ downloadPressed: true, autoPlayMedia: true })}
|
onPlay={() => {
|
||||||
|
this.startTime = Date.now();
|
||||||
|
this.setState({ downloadPressed: true, autoPlayMedia: true });
|
||||||
|
}}
|
||||||
onButtonLayout={() => this.setState({ downloadButtonShown: true })} />}
|
onButtonLayout={() => this.setState({ downloadButtonShown: true })} />}
|
||||||
{!fileInfo && <FilePrice uri={uri} style={filePageStyle.filePriceContainer} textStyle={filePageStyle.filePriceText} />}
|
{!fileInfo && <FilePrice uri={uri} style={filePageStyle.filePriceContainer} textStyle={filePageStyle.filePriceText} />}
|
||||||
</View>
|
</View>
|
||||||
|
@ -331,24 +393,20 @@ class FilePage extends React.PureComponent {
|
||||||
this.setState({ playerBgHeight: evt.nativeEvent.layout.height });
|
this.setState({ playerBgHeight: evt.nativeEvent.layout.height });
|
||||||
}
|
}
|
||||||
}} />}
|
}} />}
|
||||||
{canLoadMedia && fileInfo && <MediaPlayer fileInfo={fileInfo}
|
{canLoadMedia && fileInfo && <MediaPlayer
|
||||||
|
fileInfo={fileInfo}
|
||||||
ref={(ref) => { this.player = ref; }}
|
ref={(ref) => { this.player = ref; }}
|
||||||
uri={uri}
|
uri={uri}
|
||||||
style={playerStyle}
|
style={playerStyle}
|
||||||
autoPlay={this.state.autoPlayMedia}
|
autoPlay={this.state.autoPlayMedia}
|
||||||
onFullscreenToggled={this.handleFullscreenToggle}
|
onFullscreenToggled={this.handleFullscreenToggle}
|
||||||
onMediaLoaded={() => {
|
|
||||||
this.setState({ mediaLoaded: true });
|
|
||||||
window.currentMediaInfo = {
|
|
||||||
title: title,
|
|
||||||
channel: channelName
|
|
||||||
};
|
|
||||||
}}
|
|
||||||
onLayout={(evt) => {
|
onLayout={(evt) => {
|
||||||
if (!this.state.playerHeight) {
|
if (!this.state.playerHeight) {
|
||||||
this.setState({ playerHeight: evt.nativeEvent.layout.height });
|
this.setState({ playerHeight: evt.nativeEvent.layout.height });
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
onMediaLoaded={() => this.onMediaLoaded(title, channelName)}
|
||||||
|
onPlaybackStarted={this.onPlaybackStarted}
|
||||||
/>}
|
/>}
|
||||||
|
|
||||||
{ showActions &&
|
{ showActions &&
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
makeSelectMetadataForUri,
|
makeSelectMetadataForUri,
|
||||||
selectDownloadingByOutpoint,
|
selectDownloadingByOutpoint,
|
||||||
} from 'lbry-redux';
|
} from 'lbry-redux';
|
||||||
import { Lbryio, doClaimEligiblePurchaseRewards } from 'lbryinc';
|
import { doClaimEligiblePurchaseRewards } from 'lbryinc';
|
||||||
import { Alert, NativeModules } from 'react-native';
|
import { Alert, NativeModules } from 'react-native';
|
||||||
import Constants from '../../constants';
|
import Constants from '../../constants';
|
||||||
|
|
||||||
|
@ -140,16 +140,8 @@ export function doStopDownloadingFile(uri, fileInfo) {
|
||||||
|
|
||||||
export function doDownloadFile(uri, streamInfo) {
|
export function doDownloadFile(uri, streamInfo) {
|
||||||
return dispatch => {
|
return dispatch => {
|
||||||
const { outpoint, claim_id: claimId } = streamInfo;
|
const { outpoint } = streamInfo;
|
||||||
dispatch(doStartDownload(uri, outpoint));
|
dispatch(doStartDownload(uri, outpoint));
|
||||||
|
|
||||||
// log the view
|
|
||||||
Lbryio.call('file', 'view', {
|
|
||||||
uri,
|
|
||||||
outpoint,
|
|
||||||
claim_id: claimId
|
|
||||||
}).catch(() => {});
|
|
||||||
|
|
||||||
dispatch(doClaimEligiblePurchaseRewards());
|
dispatch(doClaimEligiblePurchaseRewards());
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue