Autoplay: start playing/downloading video/audio/image in video component. Adds on/off checkbox on settings and file pages. Adds CHECK_SIMPLE icon (w/o circle).
add changelog entry
This commit is contained in:
parent
cce1bdebcd
commit
bf8518d04c
12 changed files with 118 additions and 10 deletions
|
@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
|
||||||
* New dark mode ([#1269](https://github.com/lbryio/lbry-app/pull/1269))
|
* New dark mode ([#1269](https://github.com/lbryio/lbry-app/pull/1269))
|
||||||
* Pre-fill publish URL after clicking "Put something here" link ([#1303](https://github.com/lbryio/lbry-app/pull/1303))
|
* Pre-fill publish URL after clicking "Put something here" link ([#1303](https://github.com/lbryio/lbry-app/pull/1303))
|
||||||
* Add Danger JS to automate code reviews ([#1289](https://github.com/lbryio/lbry-app/pull/1289))
|
* Add Danger JS to automate code reviews ([#1289](https://github.com/lbryio/lbry-app/pull/1289))
|
||||||
|
* Autoplay downloaded and free media ([#584](https://github.com/lbryio/lbry-app/pull/1453))
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
* Add flair to snackbar ([#1313](https://github.com/lbryio/lbry-app/pull/1313))
|
* Add flair to snackbar ([#1313](https://github.com/lbryio/lbry-app/pull/1313))
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import * as settings from 'constants/settings';
|
||||||
import { doChangeVolume } from 'redux/actions/app';
|
import { doChangeVolume } from 'redux/actions/app';
|
||||||
import { selectVolume } from 'redux/selectors/app';
|
import { selectVolume } from 'redux/selectors/app';
|
||||||
import { doPlayUri, doSetPlayingUri } from 'redux/actions/content';
|
import { doPlayUri, doSetPlayingUri, doLoadVideo } from 'redux/actions/content';
|
||||||
import { doPlay, doPause, savePosition } from 'redux/actions/media';
|
import { doPlay, doPause, savePosition } from 'redux/actions/media';
|
||||||
import {
|
import {
|
||||||
makeSelectMetadataForUri,
|
makeSelectMetadataForUri,
|
||||||
|
@ -12,7 +13,10 @@ import {
|
||||||
makeSelectLoadingForUri,
|
makeSelectLoadingForUri,
|
||||||
makeSelectDownloadingForUri,
|
makeSelectDownloadingForUri,
|
||||||
} from 'lbry-redux';
|
} from 'lbry-redux';
|
||||||
import { selectShowNsfw } from 'redux/selectors/settings';
|
import {
|
||||||
|
makeSelectClientSetting,
|
||||||
|
selectShowNsfw
|
||||||
|
} from 'redux/selectors/settings';
|
||||||
import { selectMediaPaused, makeSelectMediaPositionForUri } from 'redux/selectors/media';
|
import { selectMediaPaused, makeSelectMediaPositionForUri } from 'redux/selectors/media';
|
||||||
import { selectPlayingUri } from 'redux/selectors/content';
|
import { selectPlayingUri } from 'redux/selectors/content';
|
||||||
import Video from './view';
|
import Video from './view';
|
||||||
|
@ -30,10 +34,12 @@ const select = (state, props) => ({
|
||||||
volume: selectVolume(state),
|
volume: selectVolume(state),
|
||||||
mediaPaused: selectMediaPaused(state),
|
mediaPaused: selectMediaPaused(state),
|
||||||
mediaPosition: makeSelectMediaPositionForUri(props.uri)(state),
|
mediaPosition: makeSelectMediaPositionForUri(props.uri)(state),
|
||||||
|
autoplay: makeSelectClientSetting(settings.AUTOPLAY)(state)
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
play: uri => dispatch(doPlayUri(uri)),
|
play: uri => dispatch(doPlayUri(uri)),
|
||||||
|
load: uri => dispatch(doLoadVideo(uri)),
|
||||||
cancelPlay: () => dispatch(doSetPlayingUri(null)),
|
cancelPlay: () => dispatch(doSetPlayingUri(null)),
|
||||||
changeVolume: volume => dispatch(doChangeVolume(volume)),
|
changeVolume: volume => dispatch(doChangeVolume(volume)),
|
||||||
doPlay: () => dispatch(doPlay()),
|
doPlay: () => dispatch(doPlay()),
|
||||||
|
|
|
@ -34,7 +34,7 @@ type Props = {
|
||||||
mediaPosition: ?number,
|
mediaPosition: ?number,
|
||||||
className: ?string,
|
className: ?string,
|
||||||
obscureNsfw: boolean,
|
obscureNsfw: boolean,
|
||||||
play: string => void,
|
play: string => void
|
||||||
};
|
};
|
||||||
|
|
||||||
class Video extends React.PureComponent<Props> {
|
class Video extends React.PureComponent<Props> {
|
||||||
|
@ -42,6 +42,52 @@ class Video extends React.PureComponent<Props> {
|
||||||
this.props.cancelPlay();
|
this.props.cancelPlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.handleAutoplay(this.props);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(nextProps: Props) {
|
||||||
|
this.handleAutoplay(nextProps);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleAutoplay(props: Props) {
|
||||||
|
const {
|
||||||
|
autoplay,
|
||||||
|
obscureNsfw,
|
||||||
|
playingUri,
|
||||||
|
fileInfo,
|
||||||
|
costInfo,
|
||||||
|
isDownloading,
|
||||||
|
uri,
|
||||||
|
load,
|
||||||
|
play
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
const playable = (
|
||||||
|
autoplay &&
|
||||||
|
obscureNsfw === false &&
|
||||||
|
playingUri !== uri
|
||||||
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
playable &&
|
||||||
|
costInfo &&
|
||||||
|
costInfo.cost === 0 &&
|
||||||
|
!fileInfo &&
|
||||||
|
!isDownloading
|
||||||
|
) {
|
||||||
|
load(uri);
|
||||||
|
play(uri);
|
||||||
|
}
|
||||||
|
else if (
|
||||||
|
playable &&
|
||||||
|
fileInfo &&
|
||||||
|
fileInfo.blobs_completed > 0
|
||||||
|
) {
|
||||||
|
play(uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
isMediaSame(nextProps: Props) {
|
isMediaSame(nextProps: Props) {
|
||||||
return (
|
return (
|
||||||
this.props.fileInfo &&
|
this.props.fileInfo &&
|
||||||
|
@ -90,14 +136,18 @@ class Video extends React.PureComponent<Props> {
|
||||||
}
|
}
|
||||||
|
|
||||||
const poster = metadata && metadata.thumbnail;
|
const poster = metadata && metadata.thumbnail;
|
||||||
|
const layoverClass = classnames('content__cover', { 'card__media--nsfw': shouldObscureNsfw });
|
||||||
|
const layoverStyle = !shouldObscureNsfw && poster ? { backgroundImage: `url("${poster}")` } : {};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classnames('video', {}, className)}>
|
<div className={classnames('video', {}, className)}>
|
||||||
{isPlaying && (
|
{isPlaying && (
|
||||||
<div className="content__view">
|
<div className="content__view">
|
||||||
{!isReadyToPlay ? (
|
{!isReadyToPlay ? (
|
||||||
<LoadingScreen status={loadStatusMessage} />
|
<div className={layoverClass} style={layoverStyle}>
|
||||||
) : (
|
<LoadingScreen status={loadStatusMessage} />
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
<VideoPlayer
|
<VideoPlayer
|
||||||
filename={fileInfo.file_name}
|
filename={fileInfo.file_name}
|
||||||
poster={poster}
|
poster={poster}
|
||||||
|
@ -119,10 +169,7 @@ class Video extends React.PureComponent<Props> {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{!isPlaying && (
|
{!isPlaying && (
|
||||||
<div
|
<div className={layoverClass} style={layoverStyle}>
|
||||||
className={classnames('content__cover', { 'card__media--nsfw': shouldObscureNsfw })}
|
|
||||||
style={!shouldObscureNsfw && poster ? { backgroundImage: `url("${poster}")` } : {}}
|
|
||||||
>
|
|
||||||
<VideoPlayButton
|
<VideoPlayButton
|
||||||
play={play}
|
play={play}
|
||||||
fileInfo={fileInfo}
|
fileInfo={fileInfo}
|
||||||
|
|
|
@ -24,3 +24,4 @@ export const PHONE = 'Phone';
|
||||||
export const CHECK = 'CheckCircle';
|
export const CHECK = 'CheckCircle';
|
||||||
export const HEART = 'Heart';
|
export const HEART = 'Heart';
|
||||||
export const UNLOCK = 'Unlock';
|
export const UNLOCK = 'Unlock';
|
||||||
|
export const CHECK_SIMPLE = 'Check';
|
||||||
|
|
|
@ -12,3 +12,4 @@ export const INSTANT_PURCHASE_MAX = 'instantPurchaseMax';
|
||||||
export const THEME = 'theme';
|
export const THEME = 'theme';
|
||||||
export const THEMES = 'themes';
|
export const THEMES = 'themes';
|
||||||
export const AUTOMATIC_DARK_MODE_ENABLED = 'automaticDarkModeEnabled';
|
export const AUTOMATIC_DARK_MODE_ENABLED = 'automaticDarkModeEnabled';
|
||||||
|
export const AUTOPLAY = 'autoplay';
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import * as settings from 'constants/settings';
|
||||||
import { doNavigate } from 'redux/actions/navigation';
|
import { doNavigate } from 'redux/actions/navigation';
|
||||||
import { selectRewardContentClaimIds, selectPlayingUri } from 'redux/selectors/content';
|
import { selectRewardContentClaimIds, selectPlayingUri } from 'redux/selectors/content';
|
||||||
import { doCheckSubscription } from 'redux/actions/subscriptions';
|
import { doCheckSubscription } from 'redux/actions/subscriptions';
|
||||||
|
import { doSetClientSetting } from 'redux/actions/settings';
|
||||||
import {
|
import {
|
||||||
doFetchFileInfo,
|
doFetchFileInfo,
|
||||||
doFetchCostInfoForUri,
|
doFetchCostInfoForUri,
|
||||||
|
@ -13,7 +15,7 @@ import {
|
||||||
makeSelectMetadataForUri,
|
makeSelectMetadataForUri,
|
||||||
doNotify,
|
doNotify,
|
||||||
} from 'lbry-redux';
|
} from 'lbry-redux';
|
||||||
import { selectShowNsfw } from 'redux/selectors/settings';
|
import { selectShowNsfw, makeSelectClientSetting } from 'redux/selectors/settings';
|
||||||
import { selectSubscriptions } from 'redux/selectors/subscriptions';
|
import { selectSubscriptions } from 'redux/selectors/subscriptions';
|
||||||
import { selectMediaPaused } from 'redux/selectors/media';
|
import { selectMediaPaused } from 'redux/selectors/media';
|
||||||
import { doPrepareEdit } from 'redux/actions/publish';
|
import { doPrepareEdit } from 'redux/actions/publish';
|
||||||
|
@ -31,6 +33,7 @@ const select = (state, props) => ({
|
||||||
playingUri: selectPlayingUri(state),
|
playingUri: selectPlayingUri(state),
|
||||||
isPaused: selectMediaPaused(state),
|
isPaused: selectMediaPaused(state),
|
||||||
claimIsMine: makeSelectClaimIsMine(props.uri)(state),
|
claimIsMine: makeSelectClaimIsMine(props.uri)(state),
|
||||||
|
autoplay: makeSelectClientSetting(settings.AUTOPLAY)(state)
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
|
@ -40,6 +43,7 @@ const perform = dispatch => ({
|
||||||
checkSubscription: subscription => dispatch(doCheckSubscription(subscription)),
|
checkSubscription: subscription => dispatch(doCheckSubscription(subscription)),
|
||||||
openModal: (modal, props) => dispatch(doNotify(modal, props)),
|
openModal: (modal, props) => dispatch(doNotify(modal, props)),
|
||||||
prepareEdit: (publishData, uri) => dispatch(doPrepareEdit(publishData, uri)),
|
prepareEdit: (publishData, uri) => dispatch(doPrepareEdit(publishData, uri)),
|
||||||
|
setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(FilePage);
|
export default connect(select, perform)(FilePage);
|
||||||
|
|
|
@ -7,6 +7,7 @@ import FilePrice from 'component/filePrice';
|
||||||
import FileDetails from 'component/fileDetails';
|
import FileDetails from 'component/fileDetails';
|
||||||
import FileActions from 'component/fileActions';
|
import FileActions from 'component/fileActions';
|
||||||
import UriIndicator from 'component/uriIndicator';
|
import UriIndicator from 'component/uriIndicator';
|
||||||
|
import { FormField } from 'component/common/form';
|
||||||
import Icon from 'component/common/icon';
|
import Icon from 'component/common/icon';
|
||||||
import DateTime from 'component/dateTime';
|
import DateTime from 'component/dateTime';
|
||||||
import * as icons from 'constants/icons';
|
import * as icons from 'constants/icons';
|
||||||
|
@ -14,6 +15,7 @@ import Button from 'component/button';
|
||||||
import SubscribeButton from 'component/subscribeButton';
|
import SubscribeButton from 'component/subscribeButton';
|
||||||
import Page from 'component/page';
|
import Page from 'component/page';
|
||||||
import player from 'render-media';
|
import player from 'render-media';
|
||||||
|
import * as settings from 'constants/settings';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
claim: {
|
claim: {
|
||||||
|
@ -45,9 +47,16 @@ type Props = {
|
||||||
fetchFileInfo: string => void,
|
fetchFileInfo: string => void,
|
||||||
fetchCostInfo: string => void,
|
fetchCostInfo: string => void,
|
||||||
prepareEdit: ({}) => void,
|
prepareEdit: ({}) => void,
|
||||||
|
setClientSetting: (string, boolean | string | Price) => void,
|
||||||
};
|
};
|
||||||
|
|
||||||
class FilePage extends React.Component<Props> {
|
class FilePage extends React.Component<Props> {
|
||||||
|
constructor(props: Props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
(this: any).onAutoplayChange = this.onAutoplayChange.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { uri, fileInfo, fetchFileInfo, costInfo, fetchCostInfo } = this.props;
|
const { uri, fileInfo, fetchFileInfo, costInfo, fetchCostInfo } = this.props;
|
||||||
|
|
||||||
|
@ -88,6 +97,10 @@ class FilePage extends React.Component<Props> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onAutoplayChange(event: SyntheticInputEvent<*>) {
|
||||||
|
this.props.setClientSetting(settings.AUTOPLAY, event.target.checked);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
claim,
|
claim,
|
||||||
|
@ -102,6 +115,8 @@ class FilePage extends React.Component<Props> {
|
||||||
claimIsMine,
|
claimIsMine,
|
||||||
prepareEdit,
|
prepareEdit,
|
||||||
navigate,
|
navigate,
|
||||||
|
autoplay,
|
||||||
|
setClientSetting
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
// File info
|
// File info
|
||||||
|
@ -144,6 +159,14 @@ class FilePage extends React.Component<Props> {
|
||||||
<div className="card__title-identity-icons">
|
<div className="card__title-identity-icons">
|
||||||
<FilePrice uri={normalizeURI(uri)} />
|
<FilePrice uri={normalizeURI(uri)} />
|
||||||
{isRewardContent && <Icon icon={icons.FEATURED} />}
|
{isRewardContent && <Icon icon={icons.FEATURED} />}
|
||||||
|
<FormField
|
||||||
|
type="checkbox"
|
||||||
|
name="autoplay"
|
||||||
|
className="autoplay"
|
||||||
|
onChange={this.onAutoplayChange}
|
||||||
|
checked={autoplay}
|
||||||
|
postfix={__('Autoplay')}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span className="card__subtitle card__subtitle--file">
|
<span className="card__subtitle card__subtitle--file">
|
||||||
|
|
|
@ -26,6 +26,7 @@ const select = state => ({
|
||||||
language: selectCurrentLanguage(state),
|
language: selectCurrentLanguage(state),
|
||||||
languages: selectLanguages(state),
|
languages: selectLanguages(state),
|
||||||
automaticDarkModeEnabled: makeSelectClientSetting(settings.AUTOMATIC_DARK_MODE_ENABLED)(state),
|
automaticDarkModeEnabled: makeSelectClientSetting(settings.AUTOMATIC_DARK_MODE_ENABLED)(state),
|
||||||
|
autoplay: makeSelectClientSetting(settings.AUTOPLAY)(state)
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
|
|
|
@ -31,6 +31,7 @@ type Props = {
|
||||||
currentTheme: string,
|
currentTheme: string,
|
||||||
themes: Array<string>,
|
themes: Array<string>,
|
||||||
automaticDarkModeEnabled: boolean,
|
automaticDarkModeEnabled: boolean,
|
||||||
|
autoplay: boolean
|
||||||
};
|
};
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
|
@ -53,6 +54,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
||||||
(this: any).onShareDataChange = this.onShareDataChange.bind(this);
|
(this: any).onShareDataChange = this.onShareDataChange.bind(this);
|
||||||
(this: any).onThemeChange = this.onThemeChange.bind(this);
|
(this: any).onThemeChange = this.onThemeChange.bind(this);
|
||||||
(this: any).onAutomaticDarkModeChange = this.onAutomaticDarkModeChange.bind(this);
|
(this: any).onAutomaticDarkModeChange = this.onAutomaticDarkModeChange.bind(this);
|
||||||
|
(this: any).onAutoplayChange = this.onAutoplayChange.bind(this);
|
||||||
(this: any).clearCache = this.clearCache.bind(this);
|
(this: any).clearCache = this.clearCache.bind(this);
|
||||||
// (this: any).onLanguageChange = this.onLanguageChange.bind(this)
|
// (this: any).onLanguageChange = this.onLanguageChange.bind(this)
|
||||||
}
|
}
|
||||||
|
@ -95,6 +97,10 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
||||||
this.props.setClientSetting(settings.AUTOMATIC_DARK_MODE_ENABLED, value);
|
this.props.setClientSetting(settings.AUTOMATIC_DARK_MODE_ENABLED, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onAutoplayChange(event: SyntheticInputEvent<*>) {
|
||||||
|
this.props.setClientSetting(settings.AUTOPLAY, event.target.checked);
|
||||||
|
}
|
||||||
|
|
||||||
onInstantPurchaseEnabledChange(enabled: boolean) {
|
onInstantPurchaseEnabledChange(enabled: boolean) {
|
||||||
this.props.setClientSetting(settings.INSTANT_PURCHASE_ENABLED, enabled);
|
this.props.setClientSetting(settings.INSTANT_PURCHASE_ENABLED, enabled);
|
||||||
}
|
}
|
||||||
|
@ -138,6 +144,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
||||||
currentTheme,
|
currentTheme,
|
||||||
themes,
|
themes,
|
||||||
automaticDarkModeEnabled,
|
automaticDarkModeEnabled,
|
||||||
|
autoplay
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const noDaemonSettings = !daemonSettings || Object.keys(daemonSettings).length === 0;
|
const noDaemonSettings = !daemonSettings || Object.keys(daemonSettings).length === 0;
|
||||||
|
@ -239,6 +246,13 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
||||||
</section>
|
</section>
|
||||||
<section className="card card--section">
|
<section className="card card--section">
|
||||||
<div className="card__title">{__('Content Settings')}</div>
|
<div className="card__title">{__('Content Settings')}</div>
|
||||||
|
<FormField
|
||||||
|
type="checkbox"
|
||||||
|
name="autoplay"
|
||||||
|
onChange={this.onAutoplayChange}
|
||||||
|
checked={autoplay}
|
||||||
|
postfix={__('Autoplay media files')}
|
||||||
|
/>
|
||||||
<FormField
|
<FormField
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
name="show_unavailable"
|
name="show_unavailable"
|
||||||
|
|
|
@ -24,6 +24,7 @@ const defaultState = {
|
||||||
theme: getLocalStorageSetting(SETTINGS.THEME, 'light'),
|
theme: getLocalStorageSetting(SETTINGS.THEME, 'light'),
|
||||||
themes: getLocalStorageSetting(SETTINGS.THEMES, []),
|
themes: getLocalStorageSetting(SETTINGS.THEMES, []),
|
||||||
automaticDarkModeEnabled: getLocalStorageSetting(SETTINGS.AUTOMATIC_DARK_MODE_ENABLED, false),
|
automaticDarkModeEnabled: getLocalStorageSetting(SETTINGS.AUTOMATIC_DARK_MODE_ENABLED, false),
|
||||||
|
autoplay: getLocalStorageSetting(SETTINGS.AUTOPLAY, false)
|
||||||
},
|
},
|
||||||
isNight: false,
|
isNight: false,
|
||||||
languages: {},
|
languages: {},
|
||||||
|
|
|
@ -86,10 +86,15 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
.credit-amount,
|
.credit-amount,
|
||||||
|
.autoplay,
|
||||||
.icon {
|
.icon {
|
||||||
margin-top: $spacing-vertical * 1/3;
|
margin-top: $spacing-vertical * 1/3;
|
||||||
margin-left: $spacing-vertical * 2/3;
|
margin-left: $spacing-vertical * 2/3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.autoplay .icon {
|
||||||
|
margin: 0 0 0 5px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.card__title-identity-icons {
|
.card__title-identity-icons {
|
||||||
|
|
|
@ -59,7 +59,11 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content__loading-text {
|
.content__loading-text {
|
||||||
|
|
Loading…
Reference in a new issue