Pārlūkot izejas kodu

Got more work done on the station pages. Converted previous things mostly to use Redux and added more functionality to volume slider and added more event listeners.

KrisVos130 7 gadi atpakaļ
vecāks
revīzija
a019484030

+ 3 - 1
backend/logic/actions/stations.js

@@ -134,7 +134,9 @@ cache.sub('privatePlaylist.selected', data => {
 });
 
 cache.sub('station.pause', stationId => {
-	utils.emitToRoom(`station.${stationId}`, "event:stations.pause");
+	stations.getStation(stationId, (err, station) => {
+		utils.emitToRoom(`station.${stationId}`, "event:stations.pause", station.pausedAt);
+	});
 });
 
 cache.sub('station.resume', stationId => {

+ 23 - 0
frontend/app/js/actions/songPlayer.js

@@ -0,0 +1,23 @@
+export const CHANGE_SONG = "CHANGE_SONG";
+export const SET_TIME_ELAPSED = "SET_TIME_ELAPSED";
+export const UPDATE_TIME_PAUSED = "UPDATE_TIME_PAUSED";
+
+export function changeSong(song) {
+	return {
+		type: CHANGE_SONG,
+		song,
+	};
+}
+export function setTimeElapsed(paused, pausedAt) {
+	return {
+		type: SET_TIME_ELAPSED,
+		paused,
+		pausedAt,
+	};
+}
+export function updateTimePaused(timePaused) {
+	return {
+		type: UPDATE_TIME_PAUSED,
+		timePaused,
+	};
+}

+ 27 - 0
frontend/app/js/actions/station.js

@@ -0,0 +1,27 @@
+export const INITIALIZE_STATION = "INITIALIZE_STATION";
+export const PAUSE_STATION = "PAUSE_STATION";
+export const RESUME_STATION = "RESUME_STATION";
+export const LEAVE_STATION = "LEAVE_STATION";
+
+export function initializeStation(station) {
+	return {
+		type: INITIALIZE_STATION,
+		station,
+	};
+}
+export function pauseStation(pausedAt) {
+	return {
+		type: PAUSE_STATION,
+		pausedAt,
+	};
+}
+export function resumeStation() {
+	return {
+		type: RESUME_STATION,
+	};
+}
+export function leaveStation() {
+	return {
+		type: LEAVE_STATION,
+	};
+}

+ 0 - 1
frontend/app/js/app.jsx

@@ -50,7 +50,6 @@ class App extends Component { // eslint-disable-line react/no-multi-comp
 
 		let volume = parseFloat(localStorage.getItem("volume"));
 		volume = (typeof volume === "number" && !isNaN(volume)) ? volume : 20;
-		console.log("VOLUME", volume);
 		localStorage.setItem("volume", volume);
 		dispatch(initializeVolume(volume));
 	}

+ 31 - 12
frontend/app/js/components/AuthRoute.jsx

@@ -3,6 +3,7 @@ import { connect } from "react-redux";
 import PropTypes from "prop-types";
 import { Redirect, Route } from "react-router-dom";
 import { translate } from "react-i18next";
+import { initializeStation } from "actions/station";
 
 import io from "io";
 
@@ -30,6 +31,10 @@ function clone(obj) {
 	loggedIn: state.user.get("loggedIn"),
 	role: state.user.get("role"),
 	authProcessed: state.user.get("authProcessed"),
+	station: {
+		stationId: state.station.get("id"),
+		name: state.station.get("name"),
+	},
 }))
 
 @translate(["general"], { wait: true })
@@ -88,30 +93,44 @@ export default class AuthRoute extends Component {
 	getStationData = () => {
 		io.getSocket(socket => {
 			socket.emit("stations.findByName", this.state.stationName, res => {
-				this.setState({
-					receivedStationData: true,
-					stationData: res.data,
-				});
+				if (res.status === "success") {
+					this.props.dispatch(initializeStation({
+						//TODO Refactor this to be better optimized
+						stationId: res.data._id,
+						name: res.data.name,
+						displayName: res.data.displayName,
+						description: res.data.description,
+						privacy: res.data.privacy,
+						locked: res.data.locked,
+						partyMode: res.data.partyMode,
+						owner: res.data.owner,
+						privatePlaylist: res.data.privatePlaylist,
+						type: res.data.type,
+						paused: res.data.paused,
+						pausedAt: res.data.pausedAt,
+					}));
+				} else {
+					this.setState({
+						noStation: true,
+					});
+				}
 			});
 		});
 	};
 
 	render() {
 		const { auth, role, loggedIn, authProcessed, t } = this.props;
-		const { stationName, waitingFor, receivedStationData, stationData } = this.state;
+		const { waitingFor, receivedStationData } = this.state;
 
 		if (this.state.continue) {
 			return <PropsRoute props={ this.props } component={ this.props.component }/>
-		} else if (waitingFor === "station" && receivedStationData) {
-			if (stationData) {
-				const props = clone(this.props);
+		} else if (waitingFor === "station") {
+			if (this.props.station.stationId) {
 				// TODO Replace the above hack with a proper Object.clone
-				props.stationName = stationName;
-				props.stationData = stationData;
-				window.props = props; //TODO Replace
 				return <Route component={ this.props.component } />;
+			} else if (this.state.noStation) {
+				return <Redirect to={ "/" } />;
 			}
-			return <Redirect to={ "/" } />;
 		} else if (waitingFor === "auth" && authProcessed) {
 			if (auth === "required") {
 				if (loggedIn) return <Route props={ this.props } component={ this.props.component } />;

+ 4 - 0
frontend/app/js/reducers/index.js

@@ -1,8 +1,12 @@
 import { combineReducers } from "redux";
 import user from "reducers/user";
 import volume from "reducers/volume";
+import songPlayer from "reducers/songPlayer";
+import station from "reducers/station";
 
 export default combineReducers({
 	user,
 	volume,
+	songPlayer,
+	station,
 });

+ 64 - 0
frontend/app/js/reducers/songPlayer.js

@@ -0,0 +1,64 @@
+import { Map } from "immutable";
+
+import {
+	CHANGE_SONG,
+	SET_TIME_ELAPSED,
+	UPDATE_TIME_PAUSED,
+} from "actions/songPlayer";
+
+const initialState = Map({
+	simple: true,
+	exists: false,
+	title: "",
+	artists: [],
+	duration: 0,
+	skipDuration: 0,
+	songId: "",
+	dislikes: 0,
+	likes: 0,
+	startedAt: 0,
+	timePaused: 0,
+	timeElapsed: 0,
+});
+
+const actionsMap = {
+	[CHANGE_SONG]: (state, action) => {
+		let obj = {};
+		let exists = !!action.song;
+		obj.simple = (exists) ? (action.song.likes === -1 && action.song.dislikes === -1) : true;
+		obj.exists = exists;
+		if (exists) {
+			obj.title = action.song.title;
+			obj.artists = action.song.artists;
+			obj.duration = action.song.duration;
+			obj.skipDuration = action.song.skipDuration;
+			obj.songId = action.song.songId;
+			obj.dislikes = action.song.dislikes;
+			obj.likes = action.song.likes;
+			obj.startedAt = action.song.startedAt;
+			obj.timePaused = action.song.timePaused;
+			obj.timeElapsed = 0;
+		} else {
+			obj = initialState;
+		}
+
+		return state.merge(obj);
+	},
+	[SET_TIME_ELAPSED]: (state, action) => {
+		let timePausedNow = 0;
+		if (action.paused) timePausedNow = Date.now() - action.pausedAt;
+		return state.merge({
+			timeElapsed: (Date.now() - state.get("startedAt") - state.get("timePaused") - timePausedNow) / 1000,
+		});
+	},
+	[UPDATE_TIME_PAUSED]: (state, action) => {
+		return state.merge({
+			timePaused: action.timePaused,
+		});
+	},
+};
+
+export default function reducer(state = initialState, action = {}) {
+	const fn = actionsMap[action.type];
+	return fn ? fn(state, action) : state;
+}

+ 59 - 0
frontend/app/js/reducers/station.js

@@ -0,0 +1,59 @@
+import { Map } from "immutable";
+
+import {
+	INITIALIZE_STATION,
+	PAUSE_STATION,
+	RESUME_STATION,
+	LEAVE_STATION,
+} from "actions/station";
+
+const initialState = Map({
+	id: "",
+	name: "",
+	displayName: "",
+	description: "",
+	paused: true,
+	pausedAt: 0,
+	privacy: "public",
+	type: "official",
+	locked: false,
+	partyMode: false,
+	privatePlaylist: "",
+});
+
+const actionsMap = {
+	[INITIALIZE_STATION]: (state, action) => {
+		return state.merge({
+			id: action.station.stationId,
+			name: action.station.name,
+			displayName: action.station.displayName,
+			description: action.station.description,
+			paused: action.station.paused,
+			pausedAt: action.station.pausedAt,
+			privacy: action.station.privacy,
+			type: action.station.type,
+			locked: action.station.locked,
+			partyMode: action.station.partyMode,
+			privatePlaylist: action.station.privatePlaylist,
+		});
+	},
+	[PAUSE_STATION]: (state, action) => {
+		return state.merge({
+			paused: true,
+			pausedAt: action.pausedAt,
+		});
+	},
+	[RESUME_STATION]: (state, action) => {
+		return state.merge({
+			paused: false,
+		});
+	},
+	[LEAVE_STATION]: (state, action) => {
+		return initialState;
+	},
+};
+
+export default function reducer(state = initialState, action = {}) {
+	const fn = actionsMap[action.type];
+	return fn ? fn(state, action) : state;
+}

+ 54 - 37
frontend/app/js/views/Station/Player.jsx

@@ -4,11 +4,21 @@ const i18next = require("i18next");
 
 import { connect } from "react-redux";
 
+import { pauseStation, unpauseStation } from "actions/station";
+
 const t = i18next.t;
 let getPlayerCallbacks = [];
 
 @connect(state => ({
 	volume: state.volume.get("volume"),
+	muted: state.volume.get("muted"),
+	songId: state.songPlayer.get("songId"),
+	startedAt: state.songPlayer.get("startedAt"),
+	timePaused: state.songPlayer.get("timePaused"),
+	skipDuration: state.songPlayer.get("skipDuration"),
+	pausedAt: state.songPlayer.get("pausedAt"),
+	exists: state.songPlayer.get("exists"),
+	paused: state.station.get("paused"),
 }))
 export default class Player extends Component {
 	static propTypes = {
@@ -27,10 +37,10 @@ export default class Player extends Component {
 				initializing: false,
 				ready: false,
 				loading: false,
-				paused: true,
-				pausedAt: null, // Find better spot for this one
 			},
 		};
+
+		if (props.paused) this.pause();
 	}
 
 	componentDidMount() {
@@ -50,70 +60,58 @@ export default class Player extends Component {
 		});
 	}
 
-	playSong(songId, skipDuration, timePaused, startedAt, cb) {
+	playSong() {
 		this.getPlayer((player) => {
-			let pausedAt = (this.state.player.paused) ? Date.now() : null;
 			this.setState({
-				song: {
-					songId,
-					skipDuration,
-					timePaused,
-					startedAt,
-				},
 				player: {
 					...this.state.player,
-					pausedAt,
 					loading: true,
 				},
 			});
 
-			player.loadVideoById(songId, this.getProperVideoTime());
-			cb();
+			player.loadVideoById(this.props.songId, this.getProperVideoTime());
 		});
 	}
 
 	getProperVideoTime = () => {
-		if (this.state.song) {
-			return this.getTimeElapsed() / 1000 + this.state.song.skipDuration;
+		if (this.props.exists) {
+			return this.getTimeElapsed() / 1000 + this.props.skipDuration;
 		} else return 0;
 	};
 
 	getTimeElapsed = () => {
-		if (this.state.song) {
+		if (this.props.exists) {
 			// TODO Replace with Date.currently
 			let timePausedNow = 0;
-			if (this.state.player.paused) timePausedNow = Date.now() - this.state.player.pausedAt;
-			return Date.now() - this.state.song.startedAt - this.state.song.timePaused - timePausedNow;
+			if (this.props.paused) timePausedNow = Date.now() - this.props.pausedAt;
+			return Date.now() - this.props.startedAt - this.props.timePaused - timePausedNow;
 		} else return 0;
 	};
 
 	pause() {
 		this.getPlayer((player) => {
-			if (this.state.player.paused) return;
-			this.setState({
-				player: {
-					...this.state.player,
-					paused: true,
-					pausedAt: Date.now(),
-				},
-			});
 			player.pauseVideo();
 		});
 	}
 
 	resume() {
 		this.getPlayer((player) => {
-			if (!this.state.player.paused) return;
-			this.setState({
-				player: {
-					...this.state.player,
-					paused: false,
-				},
-			});
 			player.playVideo();
 		});
 	}
 
+	mute() {
+		this.getPlayer((player) => {
+			player.mute();
+		});
+	}
+
+	unmute() {
+		this.getPlayer((player) => {
+			player.unMute();
+		});
+	}
+
 	initializePlayer = () => {
 		// TODO Ensure YT.Player exists
 		if (this.state.player.ready || this.state.player.initializing) return;
@@ -135,7 +133,6 @@ export default class Player extends Component {
 							...this.state.player,
 							initializing: false,
 							ready: true,
-							test: 1,
 						},
 					});
 
@@ -144,6 +141,8 @@ export default class Player extends Component {
 					});
 
 					this.player.setVolume(this.props.volume);
+					if (this.props.muted) this.mute();
+					else this.unmute();
 				},
 				"onError": function(err) {
 					console.log("iframe error", err);
@@ -158,12 +157,12 @@ export default class Player extends Component {
 									loading: false,
 								},
 							});
-							if (this.state.player.paused) player.pauseVideo();
-							if (this.state.player.paused || this.state.player.loading) player.seekTo(this.getProperVideoTime(), true);
+							if (this.props.paused) player.pauseVideo();
+							if (this.props.paused || this.state.player.loading) player.seekTo(this.getProperVideoTime(), true);
 						}
 
 						if (event.data === YT.PlayerState.PAUSED) {
-							if (!this.state.player.paused) {
+							if (!this.props.paused) {
 								player.seekTo(this.getProperVideoTime(), true);
 								player.playVideo();
 							}
@@ -187,6 +186,24 @@ export default class Player extends Component {
 		}
 	}
 
+	componentDidUpdate(prevProps, prevState) {
+		if (this.props.songId !== prevProps.songId && this.props.startedAt !== prevProps.startedAt) { //Add unique token instead of comparing startedAt
+			if (this.props.exists) {
+				this.playSong();
+			} else this.clearSong();
+		}
+
+		if (this.props.paused !== prevProps.paused) { //Add unique token instead of comparing startedAt
+			if (this.props.paused) this.pause();
+			else this.resume();
+		}
+
+		if (this.props.muted !== prevProps.muted) {
+			if (this.props.muted) this.mute();
+			else this.unmute();
+		}
+	}
+
 	render() {
 		return (
 			<div id="player"/>

+ 23 - 32
frontend/app/js/views/Station/Seekerbar.jsx

@@ -1,6 +1,13 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 
+import { connect } from "react-redux";
+
+@connect(state => ({
+	timeElapsed: state.songPlayer.get("timeElapsed") * 1000,
+	timeTotal: state.songPlayer.get("duration") * 1000,
+	paused: state.station.get("paused"),
+}))
 export default class Seekerbar extends Component {
 	static propTypes = {
 		onRef: PropTypes.func,
@@ -14,47 +21,31 @@ export default class Seekerbar extends Component {
 		super(props);
 
 		this.state = {
-			timeTotal: 0,
-			timeElapsed: 0,
 			timeElapsedGuess: 0,
 			percentage: 0,
 		};
 
 		setInterval(() => {
-			let timeElapsedGuess = this.state.timeElapsedGuess;
-			timeElapsedGuess += 15;
-
-			if (timeElapsedGuess <= this.state.timeElapsed) {
-				timeElapsedGuess = this.state.timeElapsed;
+			if (!this.props.paused) {
+				let timeElapsedGuess = this.state.timeElapsedGuess;
+				timeElapsedGuess += 15;
+
+				if (timeElapsedGuess <= this.props.timeElapsed) {
+					timeElapsedGuess = this.props.timeElapsed;
+				}
+
+				this.setState({
+					percentage: (timeElapsedGuess / this.props.timeTotal) * 100,
+					timeElapsedGuess,
+				});
+			} else {
+				this.setState({
+					percentage: (this.props.timeElapsed / this.props.timeTotal) * 100,
+				});
 			}
-
-			this.setState({
-				percentage: (timeElapsedGuess / this.state.timeTotal) * 100,
-				timeElapsedGuess,
-			});
 		}, 50);
 	}
 
-	componentDidMount() {
-		this.props.onRef(this);
-	}
-	componentWillUnmount() {
-		this.props.onRef(null);
-	}
-
-	setTime = (timeTotal) => {
-		this.setState({
-			timeTotal: timeTotal * 1000,
-			timeElapsed: 0,
-		});
-	};
-
-	setTimeElapsed = (time) => {
-		this.setState({
-			timeElapsed: time * 1000,
-		});
-	};
-
 	render() {
 		return (
 			<span style={{"width": this.state.percentage + "%", "background-color": "blue", "height": "100%", "display": "inline-block"}}/>

+ 0 - 48
frontend/app/js/views/Station/Time.jsx

@@ -1,48 +0,0 @@
-import React, { Component } from "react";
-import PropTypes from "prop-types";
-
-const formatTime = (duration) => {
-	let d = moment.duration(duration, "seconds");
-	if (duration < 0) return "0:00";
-	return ((d.hours() > 0) ? (d.hours() < 10 ? ("0" + d.hours() + ":") : (d.hours() + ":")) : "") + (d.minutes() + ":") + (d.seconds() < 10 ? ("0" + d.seconds()) : d.seconds());
-};
-
-export default class Time extends Component {
-	static propTypes = {
-		onRef: PropTypes.func,
-	};
-
-	static defaultProps = {
-		onRef: () => {},
-	};
-
-	constructor(props) {
-		super(props);
-
-		this.state = {
-			time: 0,
-		};
-	}
-
-	componentDidMount() {
-		this.props.onRef(this);
-	}
-	componentWillUnmount() {
-		this.props.onRef(null);
-	}
-
-	formatTime = formatTime;
-	static formatTime = formatTime;
-
-	setTime = (time) => {
-		this.setState({
-			time,
-		});
-	};
-
-	render() {
-		return (
-			<span>{ this.formatTime(this.state.time) }</span>
-		);
-	}
-}

+ 6 - 5
frontend/app/js/views/Station/VolumeSlider.jsx

@@ -14,8 +14,9 @@ export default class VolumeSlider extends Component {
 		super(props);
 	}
 
-	changeVolumeHandler = (e) => {
-		let volume = e.target.value / 100;
+	changeVolumeHandler = (volume) => {
+		volume = volume / 100;
+		localStorage.setItem("volume", volume);
 		this.props.dispatch(changeVolume(volume));
 	};
 
@@ -33,11 +34,11 @@ export default class VolumeSlider extends Component {
 				<h2>{ this.props.volume }. Muted: { (this.props.muted) ? "true" : "false" }</h2>
 				{
 					(this.props.muted) ? ([
-						<span key="unmuteButton" onClick={ this.unmuteVolume }>UNMUTE</span>,
+						<i className="material-icons" key="unmuteButton" onClick={ this.unmuteVolume }>volume_off</i>,
 						<input key="disabledVolumeInput" type="range" min="0" max="10000" value="0" disabled/>,
 					]) : ([
-						<span key="muteButton" onClick={ this.muteVolume }>MUTE</span>,
-						<input key="volumeInput" type="range" min="0" max="10000" onChange={ this.changeVolumeHandler }/>, //Add default value
+						<i className="material-icons" key="muteButton" onClick={ this.muteVolume }>volume_up</i>,
+						<input key="volumeInput" type="range" min="0" max="10000" value={ this.props.volume * 100 } onChange={ (e) => { this.changeVolumeHandler(e.target.value) } }/>, //Add default value
 					])
 				}
 			</div>

+ 78 - 94
frontend/app/js/views/Station/index.jsx

@@ -5,28 +5,48 @@ import PropTypes from "prop-types";
 import { translate, Trans } from "react-i18next";
 
 import Player from "./Player";
-import Time from "./Time";
 import Seekerbar from "./Seekerbar";
 import VolumeSlider from "./VolumeSlider";
 
 import { changeVolume } from "actions/volume";
+import { changeSong, setTimeElapsed, timePaused } from "actions/songPlayer";
+import { pauseStation, resumeStation } from "actions/station";
 
 import { connect } from "react-redux";
 
 import io from "io";
 import config from "config";
+import {updateTimePaused} from "../../actions/songPlayer";
 
 const Aux = (props) => {
 	return props.children;
 };
 
+const formatTime = (duration) => {
+	let d = moment.duration(duration, "seconds");
+	if (duration < 0) return "0:00";
+	return ((d.hours() > 0) ? (d.hours() < 10 ? ("0" + d.hours() + ":") : (d.hours() + ":")) : "") + (d.minutes() + ":") + (d.seconds() < 10 ? ("0" + d.seconds()) : d.seconds());
+};
+
 @connect(state => ({
 	user: {
 		userId: state.user.get("userId"),
 		role: state.user.get("role"),
 	},
 	loggedIn: state.user.get("loggedIn"),
-	volume: state.volume.get("volume"),
+	songTitle: state.songPlayer.get("title"),
+	songDuration: state.songPlayer.get("duration"),
+	songTimeElapsed: state.songPlayer.get("timeElapsed"),
+	songArtists: state.songPlayer.get("artists"),
+	simpleSong: state.songPlayer.get("simple"),
+	songExists: state.songPlayer.get("exists"),
+	station: {
+		stationId: state.station.get("id"),
+		name: state.station.get("name"),
+		displayName: state.station.get("displayName"),
+		paused: state.station.get("paused"),
+		pausedAt: state.station.get("pausedAt"),
+	},
 }))
 
 @translate(["station"], { wait: true })
@@ -39,88 +59,46 @@ export default class Station extends Component {
 		t: () => {},
 	};
 
-	constructor() {
+	constructor(props) {
 		super();
 
-		let temp = window.props;
-		let stationName = temp.stationName;
-
-		this.state = {
-			station: temp.stationData,
-			currentSongExists: false,
-		};
-
 		io.getSocket(socket => {
-			socket.emit("stations.join", stationName, res => {
+			socket.emit("stations.join", props.station.name, res => {
 				console.log(res);
 				if (res.status === 'success') {
-					this.setState({
-						station: { //TODO Refactor this to be better optimized
-							_id: res.data._id,
-							name: stationName,
-							displayName: res.data.displayName,
-							description: res.data.description,
-							privacy: res.data.privacy,
-							locked: res.data.locked,
-							partyMode: res.data.partyMode,
-							owner: res.data.owner,
-							privatePlaylist: res.data.privatePlaylist,
-							type: res.data.type,
-							paused: res.data.paused,
-						},
-						currentSong: (res.data.currentSong) ? res.data.currentSong : {},
-						currentSongExists: !!res.data.currentSong,
-					});
-
-					if (res.data.paused) this.player.pause(); //TODO Add async getPlayer here
-					else this.player.resume();
-
 					if (res.data.currentSong) {
 						res.data.currentSong.startedAt = res.data.startedAt;
 						res.data.currentSong.timePaused = res.data.timePaused;
 					}
-					this.changeSong(res.data.currentSong);
+					this.props.dispatch(changeSong(res.data.currentSong));
 				}
+
+				socket.on('event:songs.next', data => {
+					if (data.currentSong) {
+						data.currentSong.startedAt = res.data.startedAt;
+						data.currentSong.timePaused = res.data.timePaused;
+					}
+					this.props.dispatch(changeSong(data.currentSong));
+				});
+
+				socket.on('event:stations.pause', pausedAt => {
+					this.props.dispatch(pauseStation(pausedAt));
+				});
+
+				socket.on('event:stations.resume', data => {
+					this.props.dispatch(updateTimePaused(data.timePaused));
+					this.props.dispatch(resumeStation());
+				});
 			});
 		});
 
 		setInterval(() => {
-			if (this.state.currentSongExists) {
-				this.time.setTime(this.player.getTimeElapsed() / 1000);
-				this.seekerbar.setTimeElapsed(this.player.getTimeElapsed() / 1000);
+			if (this.props.songExists) {
+				this.props.dispatch(setTimeElapsed(this.props.station.paused, this.props.station.pausedAt)); // TODO Fix
 			}
 		}, 1000);
 	}
 
-	changeSong = (newSongObject) => {
-		let currentSongExists = !!newSongObject;
-		let state = {
-			currentSongExists,
-			currentSong: newSongObject,
-		};
-
-		if (currentSongExists) {
-			state.timeTotal = Time.formatTime(newSongObject.duration);
-			state.simpleSong = (newSongObject.likes === -1 && newSongObject.dislikes === -1);
-			if (state.simpleSong) {
-				state.currentSong.skipDuration = 0;
-				newSongObject.skipDuration = 0;// Do this better
-			}
-
-			this.seekerbar.setTime(newSongObject.duration);
-
-			this.player.playSong(newSongObject.songId, newSongObject.skipDuration, newSongObject.timePaused, newSongObject.startedAt, () => {
-				this.seekerbar.setTimeElapsed(this.player.getTimeElapsed() / 1000);
-			});
-		} else {
-			this.player.clearSong();
-		}
-
-		this.setState(state, () => {
-			this.getOwnRatings();
-		});
-	};
-
 	getOwnRatings = () => {
 		io.getSocket((socket) => {
 			if (!this.state.currentSongExists) return;
@@ -147,20 +125,28 @@ export default class Station extends Component {
 		return false;
 	};
 
-	changeId = () => {
-		this.player.playSong("jbZXYhjh3ms", 0, 0, Date.now());
-	};
-
 	addSongTemp = () => {
 		io.getSocket(socket => {
-			socket.emit('stations.addToQueue', this.state.station._id, '60ItHLz5WEA', data => {
+			socket.emit('stations.addToQueue', this.props.station.stationId, '60ItHLz5WEA', data => {
 				console.log("ATQ Res", data);
 			});
 		});
 	};
 
-	changeVolume = () => {
-		this.props.dispatch(changeVolume(32))
+	resumeStation = () => {
+		io.getSocket(socket => {
+			socket.emit('stations.resume', this.props.station.stationId, data => {
+
+			});
+		});
+	};
+
+	pauseStation = () => {
+		io.getSocket(socket => {
+			socket.emit('stations.pause', this.props.station.stationId, data => {
+
+			});
+		});
 	};
 
 	render() {
@@ -170,38 +156,36 @@ export default class Station extends Component {
 
 		return (
 			<main id="station">
-				<h1>{ this.state.station.displayName }</h1>
-
+				<h1>{ this.props.station.displayName }</h1>
 
-				<button onClick={ this.changeVolume }>Change volume</button>
+				{ (this.props.station.paused) ? <button onClick={ this.resumeStation }>Resume</button> : <button onClick={ this.pauseStation }>Pause</button>}
 
-				<button onClick={ this.changeId }>Change ID</button>
-				<button onClick={ () => { this.player.pause() } }>Pause</button>
-				<button onClick={ () => { this.player.resume() } }>Resume</button>
+				<button onClick={ this.addSongTemp }>Add song to queue TEMP</button>
 
-				<div className={(!this.state.currentSongExists) ? "hidden" : ""}>
+				<hr/>
+				<div className={(!this.props.songExists) ? "hidden" : ""}>
 					<Player onRef={ ref => (this.player = ref) }/>
 				</div>
 
-				{ (this.state.currentSongExists) ? (
+				{ (this.props.songExists) ? (
 				[
-					<span key="title">{ this.state.currentSong.title }</span>,
-					<br key="br1"/>,
-					<span key="artists">{ this.state.currentSong.artists.join(", ") }</span>,
-					<span key="time">
-						<Time onRef={ ref => (this.time = ref) }/> - { Time.formatTime(this.state.currentSong.duration) }
-					</span>,
-					<div key="seekerbar" className="seekerbar-container" style={{"width": "100%", "background-color": "yellow", "height": "20px", "display": "block"}}>
-						<Seekerbar onRef={ ref => (this.seekerbar = ref) }/>
+					<div key="content">
+						<h1>Title: { this.props.songTitle }</h1>
+						<br/>
+						Paused: { (this.props.station.paused) ? "true" : "false" }
+						<br/>
+						<span>Artists: { this.props.songArtists.join(", ") }</span>
+						<span key="time">
+							{ formatTime(this.props.songTimeElapsed) } - { formatTime(this.props.songDuration) }
+						</span>
+						<div key="seekerbar" className="seekerbar-container" style={{"width": "100%", "background-color": "yellow", "height": "20px", "display": "block"}}>
+							<Seekerbar/>
+						</div>
+						<VolumeSlider key="volumeSlider"/>
 					</div>,
 				]) : (
 					<h1>No song playing</h1>
 				) }
-
-
-				<VolumeSlider key="volumeSlider"/>,
-
-				<button onClick={ this.addSongTemp }>Add song to queue TEMP</button>
 			</main>
 		);
 	}