mirror of
https://github.com/captbaritone/webamp.git
synced 2026-01-24 02:36:00 +00:00
In anticipation of supporting the ability to drag the marquee contents, we're moving to offsetting by pixels rather than actually modifying the text.
120 lines
3.1 KiB
JavaScript
120 lines
3.1 KiB
JavaScript
// Single line text display that can animate and hold multiple registers
|
|
import React from 'react';
|
|
import {connect} from 'react-redux';
|
|
|
|
import {getTimeStr} from './utils';
|
|
|
|
const getBalanceText = (balance) => {
|
|
if (balance === 0) {
|
|
return 'Balance: Center';
|
|
}
|
|
const direction = balance > 0 ? 'Right' : 'Left';
|
|
return `Balance: ${Math.abs(balance)}% ${direction}`;
|
|
};
|
|
|
|
const getVolumeText = (volume) => `Volume: ${volume}%`;
|
|
|
|
const getPositionText = (duration, seekToPercent) => {
|
|
const newElapsedStr = getTimeStr(duration * seekToPercent / 100);
|
|
const durationStr = getTimeStr(duration);
|
|
return `Seek to: ${newElapsedStr}/${durationStr} (${seekToPercent}%)`;
|
|
};
|
|
|
|
const getMediaText = (name, duration) => {
|
|
return `${name} (${getTimeStr(duration)}) *** `;
|
|
};
|
|
|
|
const getDoubleSizeModeText = (enabled) => {
|
|
return `${enabled ? 'Disable' : 'Enable'} doublesize mode`;
|
|
};
|
|
|
|
const isLong = (text) => text.length > 30;
|
|
|
|
// Given text and step, how many pixels should it be shifted?
|
|
const stepOffset = (text, step) => {
|
|
if (!isLong(text)) {
|
|
return 0;
|
|
}
|
|
return (step % text.length) * 5;
|
|
};
|
|
|
|
// Format an int as negative pixels
|
|
const negativePixels = (pixels) => `-${pixels}px`;
|
|
|
|
// If text is wider than the marquee, it needs to loop
|
|
const loopText = (text) => isLong(text) ? text + text : text;
|
|
|
|
import CharacterString from './CharacterString.jsx';
|
|
|
|
class Marquee extends React.Component {
|
|
constructor(props) {
|
|
super(props);
|
|
this.state = {stepping: true};
|
|
this.handleMouseDown = this.handleMouseDown.bind(this);
|
|
this.getText = this.getText.bind(this);
|
|
}
|
|
|
|
componentDidMount() {
|
|
const step = () => {
|
|
setTimeout(() => {
|
|
if (this.state.stepping) {
|
|
this.props.dispatch({type: 'STEP_MARQUEE'});
|
|
}
|
|
step();
|
|
}, 220);
|
|
};
|
|
step();
|
|
}
|
|
|
|
getText() {
|
|
switch (this.props.userInput.focus) {
|
|
case 'balance':
|
|
return getBalanceText(this.props.media.balance);
|
|
case 'volume':
|
|
return getVolumeText(this.props.media.volume);
|
|
case 'position':
|
|
return getPositionText(this.props.media.length, this.props.userInput.scrubPosition);
|
|
case 'double':
|
|
return getDoubleSizeModeText(this.props.display.doubled);
|
|
default:
|
|
break;
|
|
}
|
|
if (this.props.media.name) {
|
|
return getMediaText(this.props.media.name, this.props.media.length);
|
|
}
|
|
return 'Winamp 2.91';
|
|
}
|
|
|
|
handleMouseDown() {
|
|
this.setState({stepping: false});
|
|
document.addEventListener('mouseup', () => {
|
|
// TODO: Remove this listener
|
|
setTimeout(() => {
|
|
this.setState({stepping: true});
|
|
}, 1000);
|
|
});
|
|
}
|
|
|
|
render() {
|
|
const text = this.getText();
|
|
const offset = stepOffset(text, this.props.display.marqueeStep);
|
|
return <div id='marquee' className='text' onMouseDown={this.handleMouseDown}>
|
|
<CharacterString style={{marginLeft: negativePixels(offset)}} >
|
|
{loopText(text)}
|
|
</CharacterString>
|
|
</div>;
|
|
}
|
|
}
|
|
|
|
export {
|
|
getBalanceText,
|
|
getVolumeText,
|
|
getPositionText,
|
|
getMediaText,
|
|
getDoubleSizeModeText,
|
|
negativePixels,
|
|
stepOffset,
|
|
loopText,
|
|
Marquee
|
|
};
|
|
export default connect(state => state)(Marquee);
|