Parallax disabling for low-powered devices

This commit is contained in:
James Barnsley
2018-09-17 08:18:07 +12:00
parent cbdd2c4ad3
commit b5111b1840
17 changed files with 204 additions and 123 deletions

View File

@ -6,61 +6,69 @@ export default class Parallax extends React.Component{
constructor(props){
super(props);
this._loading = false
this._loaded = false
if (!this.props.disabled){
this.state = {
scrollTop: 0,
windowWidth: 0,
windowHeight: 0,
canvas: {
width: 0,
height: 0
},
image: {},
loading: false,
url: false
this._loading = false
this._loaded = false
this.state = {
scrollTop: 0,
windowWidth: 0,
windowHeight: 0,
canvas: {
width: 0,
height: 0
},
image: {},
loading: false,
url: false
}
// we need to manually bind this as eventListener doesn't work with anonymous functions
this.handleResize = this.handleResize.bind(this);
this.handleScroll = this.handleScroll.bind(this);
}
// we need to manually bind this as eventListener doesn't work with anonymous functions
this.handleResize = this.handleResize.bind(this);
this.handleScroll = this.handleScroll.bind(this);
}
componentDidMount(){
this._mounted = true;
window.addEventListener("resize", this.handleResize);
window.addEventListener("scroll", this.handleScroll);
if (!this.props.disabled){
if (this.props.image){
this._loading = true;
this.setState({url: this.props.image, image: false, loading: true});
this.loadImage(this.props.image)
.then(
response => {
if (this._mounted){
this._loading = false;
this._loaded = true;
this.setState({url: this.props.image, image: response, loading: false});
this.updateCanvas(response);
this._mounted = true;
window.addEventListener("resize", this.handleResize);
window.addEventListener("scroll", this.handleScroll);
if (this.props.image){
this._loading = true;
this.setState({url: this.props.image, image: false, loading: true});
this.loadImage(this.props.image)
.then(
response => {
if (this._mounted){
this._loading = false;
this._loaded = true;
this.setState({url: this.props.image, image: response, loading: false});
this.updateCanvas(response);
}
}
}
)
} else {
this._loaded = true;
this.state.image = false;
this.updateCanvas();
)
} else {
this._loaded = true;
this.state.image = false;
this.updateCanvas();
}
}
}
componentWillUnmount(){
this._mounted = false;
window.removeEventListener("resize", this.handleResize);
window.removeEventListener("scroll", this.handleScroll);
}
if (!this.props.disabled){
this._mounted = false;
window.removeEventListener("resize", this.handleResize);
window.removeEventListener("scroll", this.handleScroll);
}
}
componentWillReceiveProps(nextProps){
if ((!this.state.url || nextProps.image != this.state.url ) && !this._loading && nextProps.image){
if (!nextProps.disabled && (!this.state.url || nextProps.image != this.state.url ) && !this._loading && nextProps.image){
this._loading = true;
this.setState({ url: nextProps.image, image: false, loading: true });
this.loadImage(nextProps.image)
@ -204,6 +212,9 @@ export default class Parallax extends React.Component{
}
render(){
if (this.props.disabled){
return null;
}
return (
<div className={this.props.blur ? "parallax blur" : "parallax"}>

View File

@ -313,11 +313,13 @@ export default class Track extends React.Component{
{track.duration ? <Dater type="length" data={track.duration} /> : '-'}
</span>
)
track_columns.push(
<span className="col popularity" key="popularity">
<Popularity popularity={track.popularity} />
</span>
)
if (track.popularity !== undefined){
track_columns.push(
<span className="col popularity" key="popularity">
<Popularity popularity={track.popularity} />
</span>
)
}
}
track_actions.push(

View File

@ -586,6 +586,7 @@ export let formatTrack = function(data){
'track_number',
'duration',
'followers',
'popularity',
'userloved',
'is_explicit',
'is_local',

View File

@ -158,6 +158,7 @@ export default function reducer(core = {}, action){
**/
case 'PLAYLIST_TRACKS':
console.log(action)
var playlists = Object.assign({}, core.playlists)
var playlist = Object.assign({}, playlists[action.key], { tracks_uris: action.tracks_uris })

View File

@ -181,7 +181,7 @@ export function getTrack(uri){
var track = getState().core.tracks[uri];
if (!track.artists){
dispatch(coreActions.handleException(
"Could not get track",
"Could not get LastFM track",
{},
"Track has no artists"
));
@ -189,7 +189,7 @@ export function getTrack(uri){
}
} else {
dispatch(coreActions.handleException(
"Could not get track",
"Could not get LastFM track",
{},
"Could not find track in index"
));
@ -347,7 +347,7 @@ export function loveTrack(uri){
var track = getState().core.tracks[uri];
if (!track.artists){
dispatch(coreActions.handleException(
"Could not love track",
"Could not love LastFM track",
track,
"Track has no artists"
));
@ -355,7 +355,7 @@ export function loveTrack(uri){
}
} else {
dispatch(coreActions.handleException(
"Could not love track",
"Could not love LastFM track",
track,
"Could not find track in index"
));
@ -389,7 +389,7 @@ export function unloveTrack(uri){
var track = getState().core.tracks[uri];
if (!track.artists){
dispatch(coreActions.handleException(
"Could not unlove track",
"Could not unlove LastFM track",
track,
"Track has no artists"
));
@ -397,7 +397,7 @@ export function unloveTrack(uri){
}
} else {
dispatch(coreActions.handleException(
"Could not unlove track",
"Could not unlove LastFM track",
track,
"Could not find track in index"
));
@ -450,7 +450,7 @@ export function scrobble(track){
},
error => {
dispatch(coreActions.handleException(
'Could not scrobble track',
'Could not scrobble LastFM track',
error,
(error.description ? error.description : null)
));

View File

@ -1497,6 +1497,7 @@ const MopidyMiddleware = (function(){
request(socket, store, 'library.lookup', { uris: uris })
.then(response => {
console.log(response)
for(var uri in response){
if (response.hasOwnProperty(uri)){

View File

@ -114,9 +114,12 @@ const PusherMiddleware = (function(){
window.location.reload(true);
break;
case 'upgrading':
case 'upgrade_started':
store.dispatch(mopidyActions.upgrading());
store.dispatch(uiActions.createNotification({content: 'Upgrading...', type: 'info'}));
break;
case 'restarting':
store.dispatch(mopidyActions.restarting());
store.dispatch(uiActions.createNotification({content: 'Restarting...', type: 'info'}));
break;
}

View File

@ -294,7 +294,7 @@ class Artist extends React.Component{
<div className="view artist-view">
<div className="intro">
<Parallax image={image} theme={this.props.theme} />
<Parallax image={image} theme={this.props.theme} disabled={this.props.disable_parallax} />
<div className="liner">
<h1>{this.props.artist ? this.props.artist.name : null}</h1>
@ -324,6 +324,7 @@ class Artist extends React.Component{
const mapStateToProps = (state, ownProps) => {
var uri = ownProps.params.uri;
return {
disable_parallax: state.ui.disable_parallax,
theme: state.ui.theme,
slim_mode: state.ui.slim_mode,
load_queue: state.ui.load_queue,

View File

@ -165,7 +165,7 @@ class Queue extends React.Component{
<Icon name="play_arrow" type="material" />
Now playing
</Header>
<Parallax blur image={current_track_image} theme={this.props.theme} />
<Parallax blur image={current_track_image} theme={this.props.theme} disabled={this.props.disable_parallax} />
<div className="content-wrapper">
<div className="current-track">
@ -204,6 +204,7 @@ class Queue extends React.Component{
const mapStateToProps = (state, ownProps) => {
return {
disable_parallax: state.ui.disable_parallax,
theme: state.ui.theme,
spotify_enabled: state.spotify.enabled,
radio: state.core.radio,

View File

@ -320,6 +320,17 @@ class Settings extends React.Component {
Enable shortkeys
</span>
</label>
<label>
<input
type="checkbox"
name="shortkeys_enabled"
checked={ this.props.ui.disable_parallax }
onChange={ e => this.props.uiActions.set({ disable_parallax: !this.props.ui.disable_parallax })} />
<span className="label has-tooltip">
Disable parallax
<span className="tooltip">Improves scroll performance on low-powered devices</span>
</span>
</label>
</div>
</div>

View File

@ -90,7 +90,7 @@ class User extends React.Component{
return (
<div className="view user-view">
<div className="intro">
<Parallax image={image} theme={this.props.theme} />
<Parallax image={image} theme={this.props.theme} disabled={this.props.disable_parallax} />
<div className="liner">
<h1>{user.name}</h1>
<h2>
@ -127,6 +127,7 @@ const mapStateToProps = (state, ownProps) => {
return {
me: state.spotify.me,
theme: state.ui.theme,
disable_parallax: state.ui.disable_parallax,
load_queue: state.ui.load_queue,
spotify_authorized: state.spotify.authorization,
playlists: state.core.playlists,

View File

@ -47,7 +47,7 @@ class DiscoverFeatured extends React.Component{
if (playlist){
return (
<div className="intro">
<Parallax image={playlist.images ? playlist.images.large : null} blur theme={this.props.theme} />
<Parallax image={playlist.images ? playlist.images.large : null} blur theme={this.props.theme} disabled={this.props.disable_parallax} />
<div className="content cf">
<Link
to={global.baseURL+'playlist/'+playlist.uri}
@ -67,7 +67,7 @@ class DiscoverFeatured extends React.Component{
} else {
return (
<div className="intro">
<Parallax />
<Parallax disabled={this.props.disable_parallax} />
</div>
)
}
@ -134,6 +134,7 @@ class DiscoverFeatured extends React.Component{
const mapStateToProps = (state, ownProps) => {
return {
disable_parallax: state.ui.disable_parallax,
theme: state.ui.theme,
load_queue: state.ui.load_queue,
featured_playlists: state.spotify.featured_playlists,

View File

@ -60,7 +60,7 @@ class DiscoverNewReleases extends React.Component{
if (album){
return (
<div className="intro">
<Parallax image={album.images ? album.images.large : null} blur theme={this.props.theme} />
<Parallax image={album.images ? album.images.large : null} blur theme={this.props.theme} disabled={this.props.disable_parallax} />
<div className="content cf">
<Link
to={global.baseURL+'album/'+album.uri}
@ -84,7 +84,7 @@ class DiscoverNewReleases extends React.Component{
} else {
return (
<div className="intro">
<Parallax />
<Parallax disabled={this.props.disable_parallax} />
</div>
)
}
@ -155,6 +155,7 @@ class DiscoverNewReleases extends React.Component{
const mapStateToProps = (state, ownProps) => {
return {
disable_parallax: state.ui.disable_parallax,
theme: state.ui.theme,
load_queue: state.ui.load_queue,
artists: state.core.artists,

View File

@ -503,7 +503,7 @@ class Discover extends React.Component{
<div className="view discover-view">
<div className="intro">
<Parallax image="assets/backgrounds/discover.jpg" theme={this.props.theme} />
<Parallax image="assets/backgrounds/discover.jpg" theme={this.props.theme} disabled={this.props.disable_parallax} />
<div className="liner">
<h1>Explore new music</h1>
@ -547,6 +547,7 @@ class Discover extends React.Component{
const mapStateToProps = (state, ownProps) => {
return {
disable_parallax: state.ui.disable_parallax,
theme: state.ui.theme,
albums: state.core.albums,
artists: state.core.artists,