diff --git a/app/src/component/mediaPlayer/view.js b/app/src/component/mediaPlayer/view.js
index 2caafc3..6033f2d 100644
--- a/app/src/component/mediaPlayer/view.js
+++ b/app/src/component/mediaPlayer/view.js
@@ -93,9 +93,8 @@ class MediaPlayer extends React.PureComponent {
}
if (this.state.firstPlay) {
- if (NativeModules.Mixpanel) {
- const { uri } = this.props;
- NativeModules.Mixpanel.track('Play', { Uri: uri });
+ if (this.props.onPlaybackStarted) {
+ this.props.onPlaybackStarted();
}
this.setState({ firstPlay: false });
this.hidePlayerControls();
diff --git a/app/src/page/file/view.js b/app/src/page/file/view.js
index dece2a0..a1be260 100644
--- a/app/src/page/file/view.js
+++ b/app/src/page/file/view.js
@@ -1,5 +1,6 @@
import React from 'react';
import { Lbry, normalizeURI } from 'lbry-redux';
+import { Lbryio } from 'lbryinc';
import {
ActivityIndicator,
Alert,
@@ -38,11 +39,14 @@ class FilePage extends React.PureComponent {
player = null;
+ startTime = null;
+
constructor(props) {
super(props);
this.state = {
+ fileViewLogged: false,
mediaLoaded: false,
- autoplayMedia: false,
+ autoPlayMedia: false,
downloadButtonShown: false,
downloadPressed: false,
fullscreenMode: false,
@@ -73,7 +77,7 @@ class FilePage extends React.PureComponent {
}
}
- componentDidUpdate() {
+ componentDidUpdate(prevProps) {
this.fetchFileInfo(this.props);
const { isResolvingUri, resolveUri, claim, navigation } = this.props;
const { uri } = navigation.state.params;
@@ -81,6 +85,18 @@ class FilePage extends React.PureComponent {
if (!isResolvingUri && claim === undefined && 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) {
@@ -127,7 +143,7 @@ class FilePage extends React.PureComponent {
{ text: 'No' },
{ text: 'Yes', onPress: () => {
deleteFile(fileInfo.outpoint, true);
- this.setState({ downloadPressed: false, mediaLoaded: false });
+ this.setState({ downloadPressed: false, fileViewLogged: false, mediaLoaded: false });
}}
],
{ cancelable: true }
@@ -144,7 +160,7 @@ class FilePage extends React.PureComponent {
{ text: 'No' },
{ text: 'Yes', onPress: () => {
stopDownload(navigation.state.params.uri, fileInfo);
- this.setState({ downloadPressed: false, mediaLoaded: false });
+ this.setState({ downloadPressed: false, fileViewLogged: false, mediaLoaded: false });
} }
],
{ 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() {
const {
claim,
@@ -320,7 +379,10 @@ class FilePage extends React.PureComponent {
style={filePageStyle.downloadButton}
openFile={openFile}
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 })} />}
{!fileInfo && }
@@ -331,25 +393,21 @@ class FilePage extends React.PureComponent {
this.setState({ playerBgHeight: evt.nativeEvent.layout.height });
}
}} />}
- {canLoadMedia && fileInfo && { this.player = ref; }}
- uri={uri}
- style={playerStyle}
- autoPlay={this.state.autoPlayMedia}
- onFullscreenToggled={this.handleFullscreenToggle}
- onMediaLoaded={() => {
- this.setState({ mediaLoaded: true });
- window.currentMediaInfo = {
- title: title,
- channel: channelName
- };
- }}
- onLayout={(evt) => {
- if (!this.state.playerHeight) {
- this.setState({ playerHeight: evt.nativeEvent.layout.height });
- }
- }}
- />}
+ {canLoadMedia && fileInfo && { this.player = ref; }}
+ uri={uri}
+ style={playerStyle}
+ autoPlay={this.state.autoPlayMedia}
+ onFullscreenToggled={this.handleFullscreenToggle}
+ onLayout={(evt) => {
+ if (!this.state.playerHeight) {
+ this.setState({ playerHeight: evt.nativeEvent.layout.height });
+ }
+ }}
+ onMediaLoaded={() => this.onMediaLoaded(title, channelName)}
+ onPlaybackStarted={this.onPlaybackStarted}
+ />}
{ showActions &&
diff --git a/app/src/redux/actions/file.js b/app/src/redux/actions/file.js
index 06a9555..ec10e47 100644
--- a/app/src/redux/actions/file.js
+++ b/app/src/redux/actions/file.js
@@ -9,7 +9,7 @@ import {
makeSelectMetadataForUri,
selectDownloadingByOutpoint,
} from 'lbry-redux';
-import { Lbryio, doClaimEligiblePurchaseRewards } from 'lbryinc';
+import { doClaimEligiblePurchaseRewards } from 'lbryinc';
import { Alert, NativeModules } from 'react-native';
import Constants from '../../constants';
@@ -140,16 +140,8 @@ export function doStopDownloadingFile(uri, fileInfo) {
export function doDownloadFile(uri, streamInfo) {
return dispatch => {
- const { outpoint, claim_id: claimId } = streamInfo;
+ const { outpoint } = streamInfo;
dispatch(doStartDownload(uri, outpoint));
-
- // log the view
- Lbryio.call('file', 'view', {
- uri,
- outpoint,
- claim_id: claimId
- }).catch(() => {});
-
dispatch(doClaimEligiblePurchaseRewards());
};
}