app plays embed in iframe
make player full screen and prepared for overlay actions small changes cleanup
This commit is contained in:
parent
77a05caa3b
commit
33672a789b
17 changed files with 156 additions and 32 deletions
|
@ -1,16 +1,10 @@
|
|||
const { getHtml } = require('./html');
|
||||
const { generateStreamUrl, generateDownloadUrl } = require('../../ui/util/lbrytv');
|
||||
const { generateDownloadUrl } = require('../../ui/util/lbrytv');
|
||||
const { LBRY_TV_API } = require('../../config');
|
||||
const Router = require('@koa/router');
|
||||
const send = require('koa-send');
|
||||
|
||||
const router = new Router();
|
||||
|
||||
router.get(`/$/embed/:claimName/:claimId`, async ctx => {
|
||||
const { claimName, claimId } = ctx.params;
|
||||
const streamUrl = generateStreamUrl(claimName, claimId);
|
||||
ctx.redirect(streamUrl);
|
||||
});
|
||||
|
||||
router.get(`/$/download/:claimName/:claimId`, async ctx => {
|
||||
const { claimName, claimId } = ctx.params;
|
||||
const downloadUrl = generateDownloadUrl(claimName, claimId);
|
||||
|
|
|
@ -912,6 +912,7 @@
|
|||
"%claimsInChannel% publish": "%claimsInChannel% publish",
|
||||
"Publishing": "Publishing",
|
||||
"Update published": "Update published",
|
||||
<<<<<<< HEAD
|
||||
"Delete this file from my computer": "Delete this file from my computer",
|
||||
"Are you sure you'd like to remove %title% from LBRY?": "Are you sure you'd like to remove %title% from LBRY?",
|
||||
"This will increase the overall bid amount for %title%, which will boost its ability to be discovered while active.": "This will increase the overall bid amount for %title%, which will boost its ability to be discovered while active.",
|
||||
|
@ -919,3 +920,7 @@
|
|||
"You deposited %amount% LBC as a support!": "You deposited %amount% LBC as a support!",
|
||||
"LBRY Link": "LBRY Link"
|
||||
}
|
||||
=======
|
||||
"Install Now": "Install Now"
|
||||
}
|
||||
>>>>>>> app plays embed in iframe
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { doToast } from 'lbry-redux';
|
||||
import EmbedArea from './view';
|
||||
import EmbedTextArea from './view';
|
||||
|
||||
export default connect(
|
||||
null,
|
||||
{
|
||||
doToast,
|
||||
}
|
||||
)(EmbedArea);
|
||||
)(EmbedTextArea);
|
|
@ -13,7 +13,7 @@ type Props = {
|
|||
claim: Claim,
|
||||
};
|
||||
|
||||
export default function EmbedArea(props: Props) {
|
||||
export default function EmbedTextArea(props: Props) {
|
||||
const { doToast, snackMessage, label, claim } = props;
|
||||
const { claim_id: claimId, name } = claim;
|
||||
const input = useRef();
|
|
@ -31,6 +31,7 @@ type Props = {
|
|||
mediaType: string,
|
||||
isText: true,
|
||||
streamingUrl: string,
|
||||
embedUrl?: string,
|
||||
contentType: string,
|
||||
claim: StreamClaim,
|
||||
currentTheme: string,
|
||||
|
@ -102,12 +103,23 @@ class FileRender extends React.PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
renderViewer() {
|
||||
const { mediaType, currentTheme, claim, contentType, downloadPath, fileName, streamingUrl, uri } = this.props;
|
||||
const {
|
||||
mediaType,
|
||||
currentTheme,
|
||||
claim,
|
||||
contentType,
|
||||
downloadPath,
|
||||
fileName,
|
||||
streamingUrl,
|
||||
embedUrl,
|
||||
uri,
|
||||
} = this.props;
|
||||
const fileType = fileName && path.extname(fileName).substring(1);
|
||||
const streamUrl = embedUrl || streamingUrl;
|
||||
|
||||
// Ideally the lbrytv api server would just replace the streaming_url returned by the sdk so we don't need this check
|
||||
// https://github.com/lbryio/lbrytv/issues/51
|
||||
const source = IS_WEB ? generateStreamUrl(claim.name, claim.claim_id) : streamingUrl;
|
||||
const source = IS_WEB ? generateStreamUrl(claim.name, claim.claim_id) : streamUrl;
|
||||
|
||||
// Human-readable files (scripts and plain-text files)
|
||||
const readableFiles = ['text', 'document', 'script'];
|
||||
|
@ -208,7 +220,6 @@ class FileRender extends React.PureComponent<Props, State> {
|
|||
// Return viewer
|
||||
return viewer || unsupported;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { isText, uri, currentlyFloating } = this.props;
|
||||
const { showAutoplayCountdown } = this.state;
|
||||
|
|
|
@ -28,6 +28,7 @@ import FourOhFourPage from 'page/fourOhFour';
|
|||
import SignInPage from 'page/signIn';
|
||||
import SignInVerifyPage from 'page/signInVerify';
|
||||
import ChannelsPage from 'page/channels';
|
||||
import EmbedWrapperPage from 'page/embedWrapper';
|
||||
|
||||
// Tell the browser we are handling scroll restoration
|
||||
if ('scrollRestoration' in history) {
|
||||
|
@ -105,6 +106,9 @@ function AppRouter(props: Props) {
|
|||
<PrivateRoute {...props} path={`/$/${PAGES.WALLET}`} exact component={WalletPage} />
|
||||
<PrivateRoute {...props} path={`/$/${PAGES.CHANNELS}`} component={ChannelsPage} />
|
||||
|
||||
<Route path={`/$/${PAGES.EMBED}/:claimName`} exact component={EmbedWrapperPage} />
|
||||
<Route path={`/$/${PAGES.EMBED}/:claimName/:claimId`} exact component={EmbedWrapperPage} />
|
||||
|
||||
{/* Below need to go at the end to make sure we don't match any of our pages first */}
|
||||
<Route path="/:claimName" exact component={ShowPage} />
|
||||
<Route path="/:claimName/:streamName" exact component={ShowPage} />
|
||||
|
|
|
@ -3,7 +3,7 @@ import * as ICONS from 'constants/icons';
|
|||
import React from 'react';
|
||||
import Button from 'component/button';
|
||||
import CopyableText from 'component/copyableText';
|
||||
import EmbedArea from 'component/embedArea';
|
||||
import EmbedTextArea from 'component/embedTextArea';
|
||||
|
||||
type Props = {
|
||||
claim: Claim,
|
||||
|
@ -58,7 +58,7 @@ class SocialShare extends React.PureComponent<Props> {
|
|||
href={`https://twitter.com/intent/tweet?text=${encodedLbryURL}`}
|
||||
/>
|
||||
</div>
|
||||
{webShareable && !isChannel && <EmbedArea label={__('Embedded')} claim={claim} noSnackbar />}
|
||||
{webShareable && !isChannel && <EmbedTextArea label={__('Embedded')} claim={claim} noSnackbar />}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -27,3 +27,4 @@ exports.CHANNELS_FOLLOWING_MANAGE = 'following/channels/manage';
|
|||
exports.WALLET = 'wallet';
|
||||
exports.BLOCKED = 'blocked';
|
||||
exports.CHANNELS = 'channels';
|
||||
exports.EMBED = 'embed';
|
||||
|
|
|
@ -3,7 +3,13 @@ import { useState, useEffect } from 'react';
|
|||
export default function usePersistedState(key, firstTimeDefault) {
|
||||
// If no key is passed in, act as a normal `useState`
|
||||
let defaultValue;
|
||||
if (key) {
|
||||
let localStorageAvailable;
|
||||
try {
|
||||
localStorageAvailable = Boolean(window.localStorage);
|
||||
} catch (e) {
|
||||
localStorageAvailable = false;
|
||||
}
|
||||
if (key && localStorageAvailable) {
|
||||
let item = localStorage.getItem(key);
|
||||
|
||||
if (item) {
|
||||
|
@ -27,7 +33,7 @@ export default function usePersistedState(key, firstTimeDefault) {
|
|||
const [value, setValue] = useState(defaultValue);
|
||||
|
||||
useEffect(() => {
|
||||
if (key) {
|
||||
if (key && localStorageAvailable) {
|
||||
localStorage.setItem(key, typeof value === 'object' ? JSON.stringify(value) : value);
|
||||
}
|
||||
}, [key, value]);
|
||||
|
|
10
ui/i18n.js
10
ui/i18n.js
|
@ -4,6 +4,12 @@ let fs = require('fs');
|
|||
|
||||
const isProduction = process.env.NODE_ENV === 'production';
|
||||
let knownMessages = null;
|
||||
let localStorageAvailable;
|
||||
try {
|
||||
localStorageAvailable = Boolean(window.localStorage);
|
||||
} catch (e) {
|
||||
localStorageAvailable = false;
|
||||
}
|
||||
|
||||
window.i18n_messages = window.i18n_messages || {};
|
||||
|
||||
|
@ -44,7 +50,9 @@ function saveMessage(message) {
|
|||
// @endif
|
||||
|
||||
export function __(message, tokens) {
|
||||
const language = window.localStorage.getItem('language') || 'en';
|
||||
const language = localStorageAvailable
|
||||
? window.localStorage.getItem('language') || 'en'
|
||||
: window.navigator.language.slice(0, 2) || 'en';
|
||||
|
||||
if (!isProduction) {
|
||||
saveMessage(message);
|
||||
|
|
26
ui/page/embedWrapper/index.js
Normal file
26
ui/page/embedWrapper/index.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
import { connect } from 'react-redux';
|
||||
import EmbedWrapperPage from './view';
|
||||
import { doResolveUri, makeSelectClaimForUri } from 'lbry-redux';
|
||||
import { generateStreamUrl } from 'util/lbrytv';
|
||||
|
||||
const select = (state, props) => {
|
||||
const PROTOCOL = 'lbry://';
|
||||
const { match } = props;
|
||||
const { params } = match;
|
||||
const { claimName, claimId } = params;
|
||||
const uri = PROTOCOL + claimName + (claimId ? `#${claimId}` : '');
|
||||
return {
|
||||
uri,
|
||||
claim: makeSelectClaimForUri(uri)(state),
|
||||
streamUrl: generateStreamUrl(claimName, claimId),
|
||||
};
|
||||
};
|
||||
|
||||
const perform = dispatch => ({
|
||||
resolveUri: uri => dispatch(doResolveUri(uri)),
|
||||
});
|
||||
|
||||
export default connect(
|
||||
select,
|
||||
perform
|
||||
)(EmbedWrapperPage);
|
31
ui/page/embedWrapper/view.jsx
Normal file
31
ui/page/embedWrapper/view.jsx
Normal file
|
@ -0,0 +1,31 @@
|
|||
// @flow
|
||||
import React, { useEffect } from 'react';
|
||||
import FileRender from 'component/fileRender';
|
||||
import Spinner from 'component/spinner';
|
||||
|
||||
type Props = {
|
||||
uri: string,
|
||||
resolveUri: string => void,
|
||||
claim: Claim,
|
||||
streamUrl: string,
|
||||
};
|
||||
const EmbedWrapperPage = (props: Props) => {
|
||||
const { resolveUri, claim, uri, streamUrl } = props;
|
||||
useEffect(() => {
|
||||
if (resolveUri && uri) {
|
||||
resolveUri(uri);
|
||||
}
|
||||
}, []);
|
||||
|
||||
if (uri && claim) {
|
||||
return (
|
||||
<div className={'embed__wrapper'}>
|
||||
<FileRender uri={uri} embedUrl={streamUrl} />
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return <Spinner />;
|
||||
}
|
||||
};
|
||||
|
||||
export default EmbedWrapperPage;
|
|
@ -45,12 +45,14 @@ const defaultState: AppState = {
|
|||
modal: null,
|
||||
modalProps: {},
|
||||
platform: process.platform,
|
||||
upgradeSkipped: sessionStorage.getItem('upgradeSkipped') === 'true',
|
||||
daemonVersionMatched: null,
|
||||
daemonReady: false,
|
||||
hasSignature: false,
|
||||
badgeNumber: 0,
|
||||
// @if TARGET='app'
|
||||
upgradeSkipped: sessionStorage.getItem('upgradeSkipped') === 'true',
|
||||
volume: Number(sessionStorage.getItem('volume')) || 1,
|
||||
// @endif
|
||||
muted: false,
|
||||
autoUpdateDownloaded: false,
|
||||
autoUpdateDeclined: false,
|
||||
|
|
|
@ -5,6 +5,14 @@ import SUPPORTED_LANGUAGES from 'constants/supported_languages';
|
|||
import { ACTIONS as LBRY_REDUX_ACTIONS, SHARED_PREFERENCES } from 'lbry-redux';
|
||||
|
||||
const reducers = {};
|
||||
let settingLanguage = [];
|
||||
try {
|
||||
let appLanguage = window.localStorage.getItem(SETTINGS.LANGUAGE);
|
||||
settingLanguage.push(appLanguage);
|
||||
} catch (e) {}
|
||||
settingLanguage.push(window.navigator.language.slice(0, 2));
|
||||
settingLanguage.push('en');
|
||||
|
||||
const defaultState = {
|
||||
isNight: false,
|
||||
loadedLanguages: [...Object.keys(window.i18n_messages), 'en'] || ['en'],
|
||||
|
@ -21,11 +29,7 @@ const defaultState = {
|
|||
[SETTINGS.ENABLE_SYNC]: true,
|
||||
|
||||
// UI
|
||||
[SETTINGS.LANGUAGE]: [
|
||||
window.localStorage.getItem(SETTINGS.LANGUAGE),
|
||||
window.navigator.language.slice(0, 2),
|
||||
'en',
|
||||
].find(language => SUPPORTED_LANGUAGES[language]),
|
||||
[SETTINGS.LANGUAGE]: settingLanguage.find(language => SUPPORTED_LANGUAGES[language]),
|
||||
[SETTINGS.THEME]: __('light'),
|
||||
[SETTINGS.THEMES]: [__('light'), __('dark')],
|
||||
[SETTINGS.SUPPORT_OPTION]: false,
|
||||
|
@ -111,7 +115,7 @@ reducers[LBRY_REDUX_ACTIONS.SHARED_PREFERENCE_SET] = (state, action) => {
|
|||
return Object.assign({}, state, {
|
||||
sharedPreferences,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
reducers[ACTIONS.CLIENT_SETTING_CHANGED] = (state, action) => {
|
||||
const { key, value } = action.data;
|
||||
|
@ -124,10 +128,7 @@ reducers[ACTIONS.CLIENT_SETTING_CHANGED] = (state, action) => {
|
|||
});
|
||||
};
|
||||
|
||||
reducers[LBRY_REDUX_ACTIONS.USER_STATE_POPULATE] = (
|
||||
state,
|
||||
action,
|
||||
) => {
|
||||
reducers[LBRY_REDUX_ACTIONS.USER_STATE_POPULATE] = (state, action) => {
|
||||
const { settings: sharedPreferences } = action.data;
|
||||
|
||||
// process clientSettings and daemonSettings
|
||||
|
@ -135,8 +136,8 @@ reducers[LBRY_REDUX_ACTIONS.USER_STATE_POPULATE] = (
|
|||
};
|
||||
|
||||
reducers[LBRY_REDUX_ACTIONS.SAVE_CUSTOM_WALLET_SERVERS] = (state, action) => {
|
||||
return Object.assign({}, state, {customWalletServers: action.data});
|
||||
}
|
||||
return Object.assign({}, state, { customWalletServers: action.data });
|
||||
};
|
||||
|
||||
export default function reducer(state = defaultState, action) {
|
||||
const handler = reducers[action.type];
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
@import 'component/comments';
|
||||
@import 'component/content';
|
||||
@import 'component/dat-gui';
|
||||
@import 'component/embed-player';
|
||||
@import 'component/expandable';
|
||||
@import 'component/file-properties';
|
||||
@import 'component/file-render';
|
||||
|
|
9
ui/scss/component/_embed-player.scss
Normal file
9
ui/scss/component/_embed-player.scss
Normal file
|
@ -0,0 +1,9 @@
|
|||
.embed__wrapper {
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
|
@ -154,6 +154,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
.video-overlay__wrapper {
|
||||
position: absolute;
|
||||
left: auto;
|
||||
|
@ -218,3 +219,27 @@
|
|||
margin-top: var(--spacing-small);
|
||||
}
|
||||
}
|
||||
=======
|
||||
.file-render__embed {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
.video-js {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.vjs-big-play-button {
|
||||
@extend .button--icon;
|
||||
@extend .button--play;
|
||||
border: none;
|
||||
position: static;
|
||||
z-index: 2;
|
||||
|
||||
.vjs-icon-placeholder {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
>>>>>>> app plays embed in iframe
|
||||
|
|
Loading…
Add table
Reference in a new issue