浏览代码

Very large change, hopefully the last big refactor. Got vue-loader integration in. The old UI is completely gone as of now, and will need reimplemented using vue components. Checkout frontend/README.md and backend/README.md for more info. Make sure to run 'vagrant up --provision' to get the latest bootstrap.sh changes on your vagrant machine.

Cameron Kline 8 年之前
父节点
当前提交
17eea5f2cb

+ 11 - 0
.editorconfig

@@ -0,0 +1,11 @@
+root = true
+
+[*]
+charset = utf-8
+indent_style = tab
+indent_size = 4
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+continuation_indent_size = 4

+ 2 - 89
.gitignore

@@ -1,92 +1,5 @@
-### Node template
-# Logs
-logs
-*.log
-npm-debug.log*
-
-# Runtime data
-pids
-*.pid
-*.seed
-
-# Directory for instrumented libs generated by jscoverage/JSCover
-lib-cov
-
-# Coverage directory used by tools like istanbul
-coverage
-
-# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
-.grunt
-
-# node-waf configuration
-.lock-wscript
-
-# Compiled binary addons (http://nodejs.org/api/addons.html)
-build/Release
-
-# Dependency directories
-node_modules
-jspm_packages
-
-# Optional npm cache directory
-.npm
-
-# Optional REPL history
-.node_repl_history
-
-# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
-# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
-
-.idea/
-
-# User-specific stuff:
-.idea/workspace.xml
-.idea/tasks.xml
-.idea/dictionaries
-.idea/vcs.xml
-.idea/jsLibraryMappings.xml
-
-# Sensitive or high-churn files:
-.idea/dataSources.ids
-.idea/dataSources.xml
-.idea/dataSources.local.xml
-.idea/sqlDataSources.xml
-.idea/dynamic.xml
-.idea/uiDesigner.xml
-
-# Gradle:
-.idea/gradle.xml
-.idea/libraries
-
-# Mongo Explorer plugin:
-.idea/mongoSettings.xml
-
-## File-based project format:
-*.iws
-
-## Plugin-specific files:
-
-# IntelliJ
-/out/
-
-# mpeltonen/sbt-idea plugin
-.idea_modules/
-
-# JIRA plugin
-atlassian-ide-plugin.xml
-
-# Crashlytics plugin (for Android Studio and IntelliJ)
-com_crashlytics_export_strings.xml
-crashlytics.properties
-crashlytics-build.properties
-fabric.properties
-
-*.iml
-
-# Created by .ignore support plugin (hsz.mobi)
-
 Thumbs.db
 .DS_Store
-
+*.swp
+.idea/
 .vagrant/
-config/default.json

+ 3 - 7
README.md

@@ -13,7 +13,7 @@ Once you've installed the required tools:
 
 1. `git clone https://github.com/MusareNode/MusareNode.git`
 2. `cd MusareNode`
-3. `cp config/template.json config/default.json` 
+3. `cp backend/config/template.json backend/config/default.json` 
  
   > The `secret` key can be whatever. It's used by express's session module. The `apis.youtube.key` value can be obtained by setting up a [YouTube API Key](https://developers.google.com/youtube/v3/getting-started).
 
@@ -34,7 +34,7 @@ Or if you have [mosh](https://mosh.org/) installed (and have ran `vagrant plugin
 
 You can run `vagrant` to view more options.
 
-### Logs
+### Production Logs
 
 You can view logs at the following locations:
 
@@ -43,11 +43,7 @@ You can view logs at the following locations:
 
 ### Development
 
-Ideally we'd have the app running using [nodemon](http://nodemon.io/). But for whatever reason, it doesn't restart when server code is changed on Ubuntu 14.04. If you find a solution for this let us know! Or make a pull request :)
-
-Because of this, you'll need to manually restart the nodejs app. You can do this by calling `sudo service musare restart` on the machine (make sure to ssh into the machine before calling this by running `vagrant ssh`).
-
-You'll probably want to have two terminal windows open, one that you can restart Musare with. And another that you can run `sudo tail -F /var/log/upstart/musare.log` in. This will output everything that running `node app.js` would typically output.
+Please refer to `frontend/README.md` and `backend/README.md`.
 
 ### FAQ
 

+ 1 - 0
Vagrantfile

@@ -23,3 +23,4 @@ Vagrant.configure(2) do |config|
 	config.vm.provision "shell", path: "bootstrap.sh"
 
 end
+

+ 3 - 0
backend/.gitignore

@@ -0,0 +1,3 @@
+node_modules/
+config/default.json
+

+ 8 - 0
backend/README.md

@@ -0,0 +1,8 @@
+# Musare Backend
+
+Make sure to run `vagrant ssh` into your vagrant machine first, and `cd /musare/backend` before calling any of these commands.
+
+``` bash
+sudo node app.js
+```
+

+ 108 - 0
backend/app.js

@@ -0,0 +1,108 @@
+'use strict';
+
+// nodejs modules
+const path = require('path'),
+      fs   = require('fs'),
+      os   = require('os');
+
+// npm modules
+const express          = require('express'),
+      session          = require('express-session'),
+      mongoose         = require('mongoose'),
+      mongoStore       = require('connect-mongo')(session),
+      bodyParser       = require('body-parser'),
+      config           = require('config'),
+      request          = require('request'),
+      passport         = require('passport'),
+      LocalStrategy    = require('passport-local').Strategy,
+      passportSocketIo = require("passport.socketio");
+
+// custom modules
+const global         = require('./logic/global'),
+      coreHandler    = require('./logic/coreHandler'),
+      socketHandler  = require('./logic/socketHandler'),
+      expressHandler = require('./logic/expressHandler');
+
+
+// database
+const MongoDB = mongoose.connect('mongodb://localhost:27017/musare').connection;
+
+MongoDB.on('error', function(err) {
+	console.log('Database error: ' + err.message);
+});
+
+MongoDB.once('open', function() {
+	console.log('Connected to database');
+});
+
+global.db = {
+	user: require('./schemas/user')(mongoose)
+};
+
+// setup express and socket.io
+const app = express(MongoDB);
+const server = app.listen(80);
+global.io = require('socket.io')(server);
+
+app.use(passport.initialize());
+app.use(passport.session());
+
+app.use(session({
+	secret: config.get('secret'),
+	store: new mongoStore({ mongooseConnection: MongoDB }),
+	resave: true,
+	saveUninitialized: true
+}));
+
+global.io.use(passportSocketIo.authorize({
+	secret: config.get('secret'),
+	store: new mongoStore({ mongooseConnection: MongoDB })
+}));
+
+passport.serializeUser(function(user, done) {
+	done(null, user);
+});
+
+passport.deserializeUser(function(user, done) {
+	done(null, user);
+});
+
+passport.use('local-signup', new LocalStrategy(function(username, password, cb) {
+	process.nextTick(function() {
+		db.user.findOne({'username' : username }, function(err, user) {
+			if (err) return cb(err);
+			if (user) return cb(null, false);
+			else {
+				var newUser = new db.user({
+					username: username
+				});
+				newUser.save(function(err) {
+					if (err) throw err;
+					return cb(null, newUser);
+				});
+			}
+		});
+	});
+}));
+
+passport.use('local-login', new LocalStrategy(function(username, password, cb) {
+	process.nextTick(function() {
+		db.user.findOne({'username' : username }, function(err, user) {
+			if (err) return cb(err);
+			if (!user) return cb(null, false);
+			if (!user.services.token.password == password) return done(null, false);
+			return done(null, user);
+		});
+	});
+}));
+
+
+app.use(bodyParser.json());
+app.use(bodyParser.urlencoded({
+	extended: true
+}));
+
+app.use(express.static(__dirname + '/../frontend/build/'));
+
+socketHandler(coreHandler, global.io);
+expressHandler(coreHandler, app);

+ 0 - 0
config/template.json → backend/config/template.json


+ 0 - 0
gulpfile.js → backend/gulpfile.js


+ 0 - 0
src/logic/coreHandler.js → backend/logic/coreHandler.js


+ 0 - 0
src/logic/expressHandler.js → backend/logic/expressHandler.js


+ 0 - 0
src/logic/global.js → backend/logic/global.js


+ 0 - 0
src/logic/socketHandler.js → backend/logic/socketHandler.js


+ 0 - 0
src/logic/stations.js → backend/logic/stations.js


+ 28 - 0
backend/package.json

@@ -0,0 +1,28 @@
+{
+	"name": "musare-backend",
+	"version": "0.0.1",
+	"description": "A modern, open-source, collaborative music app https://musare.com",
+	"main": "app.js",
+	"author": "Musare Team",
+	"repository": "https://github.com/Musare/MusareNode",
+	"dependencies": {
+		"async": "2.0.1",
+		"body-parser": "^1.15.2",
+		"config": "^1.21.0",
+		"connect-mongo": "^1.3.2",
+		"cookie-parser": "^1.4.3",
+		"express": "^4.14.0",
+		"express-session": "^1.14.0",
+		"mongoose": "^4.6.0",
+		"passport": "^0.3.2",
+		"passport-local": "^1.0.0",
+		"passport.socketio": "^3.6.2",
+		"request": "^2.74.0",
+		"socket.io": "^1.4.8"
+	},
+	"devDependencies": {
+		"gulp": "^3.9.1",
+		"gulp-nodemon": "^2.1.0",
+		"gulp-sass": "^2.3.2"
+	}
+}

+ 0 - 0
schema.json → backend/schema.json


+ 0 - 0
src/schemas/user.js → backend/schemas/user.js


+ 12 - 0
bootstrap.sh

@@ -89,5 +89,17 @@ fi
 
 # automatically install all of our dependencies
 cd /musare
+
+cd backend
+rm -rf node_modules/
 npm install --no-bin-links
+cd ../
+
+cd frontend
+rm -rf node_modules/
+npm install
+cd ../
+
 sudo npm install -g gulp-cli
+
+sudo mkdir -p /data/db

+ 3 - 0
frontend/.gitignore

@@ -0,0 +1,3 @@
+node_modules/
+build/
+

+ 15 - 0
frontend/README.md

@@ -0,0 +1,15 @@
+# Musare Backend
+
+Make sure to run `vagrant ssh` into your vagrant machine first, and `cd /musare/frontend` before calling any of these commands.
+
+``` bash
+# Generate development build
+npm run development
+
+# Generate production build
+npm run production
+
+# Automatically rebuild the project when files change
+npm run development-watch
+```
+

+ 11 - 0
frontend/build/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+	<meta charset="UTF-8">
+	<title></title>
+</head>
+<body>
+	<app></app>
+	<script src="build.js"></script>
+</body>
+</html>

+ 29 - 0
frontend/components/App.vue

@@ -0,0 +1,29 @@
+<template>
+	<div class="app">
+		Hello world! :)
+	</div>
+</template>
+
+<script>
+	// TODO: Implement these files
+	//import Header from './components/Header.vue'
+	//import Body from './components/Body.vue'
+	//import Footer from './components/Header.vue'
+
+	export default {
+		data() {
+			return {
+				msg: 'hello vue'
+			}
+		},
+		components: { /*Header, Body, Footer*/ }
+	}
+</script>
+
+<!-- TODO: Get sass setup in webpack config -->
+<style scoped>
+	body {
+		background-color: #ff0000;
+	}
+</style>
+

+ 10 - 0
frontend/main.js

@@ -0,0 +1,10 @@
+import Vue from 'vue'
+import App from './components/App.vue'
+
+new Vue({
+	el: 'body',
+	components: {
+		app: App
+	}
+});
+

+ 30 - 0
frontend/package.json

@@ -0,0 +1,30 @@
+{
+	"name": "musare-frontend",
+	"version": "0.0.0",
+	"description": "A modern, open-source, collaborative music app https://musare.com",
+	"main": "main.js",
+	"author": "Musare Team",
+	"repository": "https://github.com/Musare/MusareNode",
+	"scripts": {
+		"development": "webpack",
+		"development-watch": "webpack --watch --watch-poll",
+		"production": "webpack -p"
+	},
+	"devDependencies": {
+		"babel-core": "^6.14.0",
+		"babel-loader": "^6.2.5",
+		"babel-plugin-transform-runtime": "^6.15.0",
+		"babel-preset-es2015": "^6.14.0",
+		"babel-runtime": "^6.11.6",
+		"css-loader": "^0.25.0",
+		"vue-hot-reload-api": "^2.0.6",
+		"vue-html-loader": "^1.2.3",
+		"vue-loader": "^8.5.2",
+		"vue-style-loader": "^1.0.0",
+		"webpack": "^1.13.2",
+		"webpack-dev-server": "^1.15.1"
+	},
+	"dependencies": {
+		"vue": "^1.0.26"
+	}
+}

+ 29 - 0
frontend/webpack.config.js

@@ -0,0 +1,29 @@
+// webpack.config.js
+module.exports = {
+	// entry point of our application
+	entry: './main.js',
+	// where to place the compiled bundle
+	output: {
+		path: __dirname + '/build/',
+		filename: 'build.js'
+	},
+	module: {
+		// `loaders` is an array of loaders to use.
+		// here we are only configuring vue-loader
+		loaders: [
+			{
+				test: /\.vue$/, // a regex for matching all files that end in `.vue`
+				loader: 'vue'   // loader to use for matched files,
+			},
+			{
+				test: /\.js$/,
+				loader: 'babel',
+				exclude: /node_modules/
+			}
+		]
+	},
+	babel: {
+		presets: ['es2015'],
+		plugins: ['transform-runtime']
+	}
+};

+ 0 - 27
package.json

@@ -1,27 +0,0 @@
-{
-  "name": "musare",
-  "version": "0.0.0",
-  "description": "",
-  "main": "src/app.js",
-  "repository": "",
-  "dependencies": {
-    "async": "2.0.1",
-    "body-parser": "^1.15.2",
-    "config": "^1.21.0",
-    "connect-mongo": "^1.3.2",
-    "cookie-parser": "^1.4.3",
-    "express": "^4.14.0",
-    "express-session": "^1.14.0",
-    "mongoose": "^4.6.0",
-    "passport": "^0.3.2",
-    "passport-local": "^1.0.0",
-    "passport.socketio": "^3.6.2",
-    "request": "^2.74.0",
-    "socket.io": "^1.4.8"
-  },
-  "devDependencies": {
-    "gulp": "^3.9.1",
-    "gulp-nodemon": "^2.1.0",
-    "gulp-sass": "^2.3.2"
-  }
-}

文件差异内容过多而无法显示
+ 0 - 0
public/css/main.css


二进制
public/images/loading.gif


+ 0 - 123
public/index.html

@@ -1,123 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1">
-		<title>Musare with NodeJS + Express + SocketIO + VueJS</title>
-		<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.8/socket.io.min.js"></script>
-		<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/fetch/1.0.0/fetch.min.js"></script>
-		<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js"></script>
-		<script src='https://www.google.com/recaptcha/api.js'></script>
-		<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" type="text/css">
-		<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet" type="text/css">
-		<link type="text/css" rel="stylesheet" href="css/main.css" />
-		<script src="js/main.js"></script>
-	</head>
-	<body>
-		<div id="app">
-			<div class="loading" style="display: block;" v-show="!(home.visible || room.visible)"></div>
-			<header style="display: none;" v-show="home.visible || room.visible">
-				<div id="header-home" v-show="home.visible">
-					<div class="title">Musare</div>
-					<div class="link" v-on:click="showModal('account')">Account&nbsp;&nbsp;&nbsp;&nbsp;<i class="fa fa-caret-down" aria-hidden="true"></i></div>
-					<div class="link" v-on:click="showModal('donate')">Donate</div>
-					<div class="link" v-on:click="showModal('project')">The Project</div>
-				</div>
-				<div id="header-room" v-show="room.visible">
-					<div class="left-link" v-on:click="leaveRoom"><i class="fa fa-home" aria-hidden="true"></i></div>
-					<div class="left-link"><i class="fa fa-plus" aria-hidden="true"></i></div>
-					<div class="left-link"><i class="fa fa-flag" aria-hidden="true"></i></div>
-					<div class="left-link"><i class="fa fa-step-forward" aria-hidden="true"></i></div>
-					<div class="center-link">{{ room.name }}</div>
-					<div class="right-link"><i class="fa fa-users" aria-hidden="true"></i></div>
-					<div class="right-link"><i class="fa fa-comment" aria-hidden="true"></i></div>
-					<div class="right-link"><i class="fa fa-list" aria-hidden="true"></i></div>
-				</div>
-			</header>
-			<main style="display: none;" v-show="home.visible || room.visible">
-				<div id="home" v-show="home.visible">
-					<div class="group" v-for="group in home.groups">
-						<div class="group-title">{{ group.name }}</div>
-						<div class="group-nav"><i class="fa fa-chevron-left" aria-hidden="true"></i></div>
-						<div class="group-rooms">
-							<div class="rooms-room" v-for="room in group.rooms" v-on:click="enterRoom(room)">
-								<img class="room-image" :src="room.thumbnail" />
-								<div class="room-info">
-									<div class="room-grid-left">
-										<h3>{{ room.name }}</h3>
-										<p>{{ room.description }}</p>
-									</div>
-									<div class="room-grid-right">
-										<div>{{ room.users }}&nbsp;&nbsp;<i class="fa fa-user" aria-hidden="true"></i></div>
-									</div>
-								</div>
-							</div>
-						</div>
-						<div class="group-nav"><i class="fa fa-chevron-right" aria-hidden="true"></i></div>
-					</div>
-				</div>
-				<div id="room" v-show="room.visible">
-					<div class="room-player">
-						<!-- Youtube stuff goes here -->
-					</div>
-					<div class="room-playlist">
-						<div class="playlist-song" v-for="song in room.playlist.songs"></div>
-					</div>
-					<div class="room-chat">
-						<div class="chat-message" v-for="message in room.chat.messages"></div>
-					</div>
-					<div class="body-room-users"></div>
-				</div>
-				<div id="overlay" v-show="modalVisible()" v-on:click="showModal()"></div>
-				<div class="modal" v-bind:style="modalPositionStyle('register', 350, 400)">
-					<div class="modal-title">Register</div>
-					<div class="modal-exit" v-on:click="showModal()"><i class="fa fa-times" aria-hidden="true"></i></div>
-					<input class="modal-input" type="text" placeholder="Email..." v-model="modals.register.email"/>
-					<input class="modal-input" type="text" placeholder="Username..." v-model="modals.register.username"/>
-					<input class="modal-input" type="password" placeholder="Password..." v-model="modals.register.password"/>
-					<div class="g-recaptcha modal-recaptcha" data-sitekey="6Ld5jygTAAAAAEi0E1IwovUuVFhZKctMvKnY553W"></div>
-					<div class="modal-submit" v-on:click="register()">Submit</div>
-				</div>
-				<div class="modal" v-bind:style="modalPositionStyle('account', 360, 200)">
-					<div class="modal-account-btn" v-on:click="showModal('register')">Register</div>
-					<div class="modal-account-btn" v-on:click="showModal('login')">Login</div>
-				</div>
-				<div class="modal" v-bind:style="modalPositionStyle('donate', 360, 200)">
-					<p>Donations! Woo! :)</p>
-				</div>
-				<div class="modal" style="padding: 24px;" v-bind:style="modalPositionStyle('project', 600, 468)">
-					<h2 style="margin: 0 0 8px 0;">What is Musare?</h2>
-					<p style="margin: 0 0 16px 0;">Musare is an open-source music website where you can listen to real-time genre specific music stations with your friends, or just alone.</p>
-					<h2 style="margin: 0 0 8px 0;">How can I help?</h2>
-					<p style="margin: 0;">There are essentially 3 main ways in which you can help us:</p>
-					<ol>
-						<li style="margin-bottom: 16px; text-align: justify;">If you are a JavaScript developer, then we can use your help! Our project is open source and all the source code can be found on GitHub. We would love for you to create new features, add exciting content or just improve what already is on Musare. Also, if you see a bug or glitch on Musare, then create a new "issue" on GitHub and we will fix it as soon as possible. You can also have a try at fixing a bug that you may find!</li>
-						<li style="margin-bottom: 16px; text-align: justify;">If you are not a developer but want some way of supporting us - you can donate to Musare. Any amount of donation is highly appreciated, and will help us maintain server costs.</li>
-						<li style="margin-bottom: 16px; text-align: justify;">Send us feedback! Your comments and/or suggestion are extremely valuable to us. In order to improve we need to know what you like, don't like or what you might want on the app.</li>
-					</ol>
-				</div>
-			</main>
-			<footer style="display: none;" v-show="home.visible || room.visible">
-				<div class="footer-left">
-					<div class="left-title">Stay Connected</div>
-					<div class="left-message">Follow us on social media or send us an email!</div>
-					<div class="left-icons">
-						<div class="icon"><i class="fa fa-twitter" aria-hidden="true"></i></div>
-						<div class="icon"><i class="fa fa-facebook" aria-hidden="true"></i></div>
-						<div class="icon"><i class="fa fa-twitch" aria-hidden="true"></i></div>
-					</div>
-				</div>
-				<div class="footer-right">
-					<div class="right-links">
-						<div class="links-title">Links</div>
-						<a class="link">Github</a>
-						<a class="link">Feedback</a>
-						<a class="link">FAQ</a>
-						<a class="link">Terms</a>
-						<a class="link">Privacy</a>
-					</div>
-				</div>
-				<div class="footer-message">© Copyright Musare: 2015 - {{ new Date().getFullYear() }}</div>
-			</footer>
-		</div>
-	</body>
-</html>

+ 0 - 154
public/js/main.js

@@ -1,154 +0,0 @@
-window.onload = function () {
-
-	var socket = io();
-
-	socket.on('disconnect', function () {
-		console.log('Disconnected from server');
-	});
-
-	socket.on('search', function (res) {
-		console.log(res);
-	});
-
-	var data = {
-		user: {
-			id: null
-		},
-		modals: {
-			register: {
-				visible: false,
-				email: "",
-				username: "",
-				password: ""
-			},
-			account: {
-				visible: false
-			},
-			donate: {
-				visible: false
-			},
-			project: {
-				visible: false
-			}
-		},
-		home: {
-			visible: false,
-			groups: [
-				{
-					id: "lu08gw56571r4497wrk9",
-					name: "Official Rooms",
-					rooms: [
-						{ id: "73qvw65746acvo8yqfr", thumbnail: "https://lh6.googleusercontent.com/-ghASz3s6yL4/AAAAAAAAAAI/AAAAAAAAALc/tFblPp2myu0/s0-c-k-no-ns/photo.jpg", name: "Country", description: "Johnny Cash - I Walk The Line", users: 10 },
-						{ id: "enxcysmhn1k7ld56ogvi", thumbnail: "http://66.media.tumblr.com/1734069af425e491fae7deae0a19869f/tumblr_o0i0xmIYrF1v421f2o1_1280.jpg", name: "Pop", description: "Sia - Cheap Thrills", users: 14 },
-						{ id: "kqa99gbva7lij05dn29", thumbnail: "http://www.youredm.com/wp-content/uploads/2014/09/taking-you-higher.jpg", name: "Chill", description: "MrSuicideSheep - Taking you higher", users: 13 },
-						{ id: "w19hu791iiub6wmjf9a4i", thumbnail: "http://edmsauce.wpengine.netdna-cdn.com/wp-content/uploads/2012/12/Deadmau5-album-title-goes-here.jpg", name: "EDM", description: "Deadmau5 - There Might Be Coffee", users: 13 }
-					]
-				},
-				{
-					id: "g2b8v03xaedj8ht1emi",
-					name: "Trending Rooms",
-					rooms: [
-						{ id: "73qvw65746acvo8yqfr", thumbnail: "https://lh6.googleusercontent.com/-ghASz3s6yL4/AAAAAAAAAAI/AAAAAAAAALc/tFblPp2myu0/s0-c-k-no-ns/photo.jpg", name: "Country", description: "Johnny Cash - I Walk The Line", users: 10 },
-						{ id: "enxcysmhn1k7ld56ogvi", thumbnail: "http://66.media.tumblr.com/1734069af425e491fae7deae0a19869f/tumblr_o0i0xmIYrF1v421f2o1_1280.jpg", name: "Pop", description: "Sia - Cheap Thrills", users: 14 },
-						{ id: "kqa99gbva7lij05dn29", thumbnail: "http://www.youredm.com/wp-content/uploads/2014/09/taking-you-higher.jpg", name: "Chill", description: "MrSuicideSheep - Taking you higher", users: 13 },
-						{ id: "w19hu791iiub6wmjf9a4i", thumbnail: "http://edmsauce.wpengine.netdna-cdn.com/wp-content/uploads/2012/12/Deadmau5-album-title-goes-here.jpg", name: "EDM", description: "Deadmau5 - There Might Be Coffee", users: 13 }
-					]
-				}
-			]
-		},
-		room: {
-			visible: false,
-			id: "",
-			name: "",
-			description: "",
-			player: {
-
-			},
-			chat: {
-				visible: false,
-				messages: []
-			},
-			users: {
-				list: {}
-			},
-			playlist: {
-				visible: false,
-				messages: []
-			}
-		}
-	};
-
-	var methods = {
-		leaveRoom: function () {
-			data.room.visible = false;
-			window.setTimeout(function () { data.home.visible = true; }, 500);
-			socket.leave("/" + data.room.id);
-		},
-		enterRoom: function (room) {
-			data.home.visible = false;
-			window.setTimeout(function () { data.room.visible = true; }, 500);
-			data.room.id = room.id;
-			data.room.displayName = room.displayName;
-			data.room.description = room.description;
-			socket.join("/" + room.id);
-			socket.emit("/stations/join/:id", room.id, function(result) {
-				console.log(result);
-			});
-		},
-		modalVisibilityChange: function (name) {
-			var modal = data.modals[name];
-			if (modal) {
-				switch (name) {
-					case 'register': {
-						data.modals.register.email = "";
-						data.modals.register.username = "";
-						data.modals.register.password = "";
-						grecaptcha.reset();
-					} break;
-				}
-			}
-		},
-		showModal: function (name) {
-			Object.keys(data.modals).forEach(function (key) {
-				var visibility = data.modals[key].visible;
-				data.modals[key].visible = (key == name);
-				if (visibility != data.modals[key].visible) {
-					methods.modalVisibilityChange(key);
-				}
-			});
-		},
-		modalVisible: function (name) {
-			var visible = false;
-			// check if the specific modal is visible
-			if (name) {
-				Object.keys(data.modals).forEach(function (key) { if (key == name) visible = data.modals[key].visible; });
-			}
-			// check if any of them are visible
-			else {
-				Object.keys(data.modals).forEach(function (key) { if (visible == false) visible = data.modals[key].visible; });
-			}
-			return visible;
-		},
-		modalPositionStyle: function (name, width, height) {
-			return {
-				width: width + 'px',
-				height: height + 'px',
-				left: 'calc(50% - ' + (width / 2) + 'px)',
-				top: (data.modals[name].visible ? 'calc(50% - ' + (height / 2) + 'px)' : '-' + (height + 32) + 'px')
-			}
-		},
-		register: function () {
-			socket.emit('/users/register', {
-				email: data.modals.register.email,
-				username: data.modals.register.username,
-				password: data.modals.register.password,
-				recaptcha: grecaptcha.getResponse()
-			});
-		}
-	};
-
-	var app = new Vue({ el: '#app', data: data, methods: methods, ready: function () { window.setTimeout(function () { data.home.visible = true; }, 250); } });
-
-	window.socket = socket;
-	window.data = data;
-};

+ 0 - 111
src/app.js

@@ -1,111 +0,0 @@
-'use strict';
-
-// nodejs modules
-const path = require('path'),
-      fs   = require('fs'),
-      os   = require('os');
-
-// npm modules
-const express          = require('express'),
-    session          = require('express-session'),
-    mongoose         = require('mongoose'),
-    mongoStore       = require('connect-mongo')(session),
-    bodyParser       = require('body-parser'),
-    config           = require('config'),
-    request          = require('request'),
-    passport         = require('passport'),
-    localStrategy    = require('passport-local').Strategy,
-    passportSocketIo = require("passport.socketio");
-
-// custom modules
-const global         = require('./logic/global'),
-      coreHandler    = require('./logic/coreHandler'),
-      socketHandler  = require('./logic/socketHandler'),
-      expressHandler = require('./logic/expressHandler');
-
-// database
-const MongoDB = mongoose.connect('mongodb://localhost:27017/musare').connection;
-
-MongoDB.on('error', function(err) {
-    console.log('Database error: ' + err.message);
-});
-
-MongoDB.once('open', function() {
-    console.log('Connected to database');
-});
-
-const db = {
-    user: require('./schemas/user')(mongoose)
-};
-
-// setup express and socket.io
-const app = express(MongoDB);
-const server = app.listen(80);
-const io = require('socket.io')(server);
-
-global.io = io;
-global.db = db;
-
-app.use(passport.initialize());
-app.use(passport.session());
-
-app.use(session({
-    secret: config.get('secret'),
-    store: new mongoStore({ mongooseConnection: MongoDB }),
-    resave: true,
-    saveUninitialized: true
-}));
-
-io.use(passportSocketIo.authorize({
-  secret: config.get('secret'),
-  store: new mongoStore({ mongooseConnection: MongoDB })
-}));
-
-passport.serializeUser(function(user, done) {
-    done(null, user);
-});
-
-passport.deserializeUser(function(user, done) {
-    done(null, user);
-});
-
-passport.use('local-signup', new localStrategy (function(username, password, cb) {
-    process.nextTick(function() {
-        db.user.findOne({'username' : username }, function(err, user) {
-            if (err) return cb(err);
-            if (user) return cb(null, false);
-            else {
-                var newUser = new db.user({
-                    username: username
-                });
-                newUser.save(function(err) {
-                    if (err) throw err;
-                    return cb(null, newUser);
-                });
-            }
-        });
-    });
-}));
-
-passport.use('local-login', new localStrategy (function(username, password, cb) {
-    process.nextTick(function() {
-        db.user.findOne({'username' : username }, function(err, user) {
-            if (err) return cb(err);
-            if (!user) return cb(null, false);
-            if (!user.services.token.password == password) return done(null, false);
-
-            return done(null, user);
-        });
-    });
-}));
-
-
-app.use(bodyParser.json());
-app.use(bodyParser.urlencoded({
-    extended: true
-}));
-
-app.use(express.static(__dirname + '/../public'));
-
-socketHandler(coreHandler, io);
-expressHandler(coreHandler, app);

+ 0 - 127
src/sass/main.scss

@@ -1,127 +0,0 @@
-* { box-sizing: border-box; font-family: Roboto, sans-serif; }
-html, body { margin: 0; padding: 0; width: 100%; height: 100%; }
-
-#app {
-	background-color: white;
-	width: 100%;
-	height: 100%;
-}
-
-.loading {
-	background-color: white;
-	width: 100%;
-	height: 100%;
-	background-image: url("../images/loading.gif");
-	background-position: center;
-	background-size: 128px 128px;
-	background-repeat: no-repeat;
-}
-
-@import 'partials/header';
-@import 'partials/footer';
-@import 'partials/modal';
-
-main {
-
-	#home {
-		width: 100%;
-		height: auto;
-
-		.group {
-			width: 100%;
-			height: 448px;
-			margin: 64px 0 64px 0;
-
-			.group-title {
-				float: left;
-				clear: none;
-				width: 100%;
-				height: 64px;
-				line-height: 48px;
-				text-align: center;
-				font-size: 48px;
-			}
-
-			.group-nav {
-				background-color: transparent;
-				color: rgba(0, 0, 0, 0.75);
-				float: left; clear: none;
-				width: 64px;
-				height: 384px;
-				line-height: 384px;
-				text-align: center;
-				font-size: 64px;
-				cursor: pointer;
-
-				&:hover {
-					color: #222222;
-				}
-			}
-
-			.group-rooms {
-				white-space: nowrap;
-				text-align: center;
-				overflow: hidden;
-				float: left;
-				clear: none;
-				width: calc(100% - 128px);
-				height: 384px;
-
-				.rooms-room {
-					position: relative;
-					top: 16px;
-					display: inline-block;
-					clear: none;
-					width: 256px;
-					height: 345px;
-					margin: 0 16px 0 16px;
-					box-shadow: 0 1px 6px 2px rgba(0, 0, 0, 0.25);
-					cursor: pointer;
-
-					.room-info {
-						display: flex;
-						flex-direction: row;
-						align-items: center;
-						padding: 5px;
-					}
-
-					.room-image {
-						width: 100%;
-						height: 256px;
-					}
-
-					.room-grid-left {
-						display: flex;
-						flex-direction: column;
-						width: 75%;
-						text-align: left;
-						padding-left: 10px;
-
-						h3, p {
-							margin: 0;
-							white-space: normal;
-						}
-					}
-
-					.room-grid-right {
-						display: flex;
-						flex-direction: column;
-						width: 25%;
-					}
-				}
-			}
-		}
-	}
-
-	#overlay {
-		position: fixed;
-		top: 0;
-		left: 0;
-		width: 100%;
-		height: 100%;
-		background-color: rgba(0, 0, 0, 0.5);
-		z-index: 90000;
-		cursor: pointer;
-	}
-
-}

+ 0 - 83
src/sass/partials/footer.scss

@@ -1,83 +0,0 @@
-footer {
-  width: 100%;
-  height: 200px;
-  background-color: #e0e0e0;
-  padding-top: 26px;
-
-  .footer-left {
-    float: left;
-    width: 50%;
-    height: 150px;
-    padding-left: 64px;
-
-    .left-title {
-      font-size: 25px;
-      color: #616161;
-      margin-bottom: 16px;
-    }
-
-    .left-message {
-      font-size: 15px;
-      color: #757575;
-      margin-bottom: 16px;
-    }
-
-    .left-icons {
-      .icon {
-        float: left;
-        font-size: 32px;
-        padding-right: 16px;
-        color: #757575;
-
-        &:hover {
-          cursor: pointer;
-          color: #222222;
-        }
-      }
-    }
-  }
-
-  .footer-right {
-    float: right;
-    width: 50%;
-    height: 150px;
-    padding-left: 64px;
-
-    .right-links {
-      float: right;
-      width: 200px;
-    }
-
-    .links-title {
-      float: right;
-      width: 200px;
-      font-size: 25px;
-      color: #616161;
-      margin-bottom: 8px;
-    }
-
-    .link {
-      float: right;
-      width: 200px;
-      clear: both;
-      font-size: 15px;
-      color: #757575;
-      margin-bottom: 2px;
-
-      &:hover {
-        cursor: pointer;
-        color: #222222;
-      }
-    }
-  }
-
-  .footer-message {
-    float: left;
-    width: 100%;
-    height: 50px;
-    line-height: 50px;
-    padding-left: 128px;
-    background-color: #d3d3d3;
-    color: #757575;
-  }
-}

+ 0 - 67
src/sass/partials/header.scss

@@ -1,67 +0,0 @@
-header {
-  width: 100%;
-  height: 64px;
-  line-height: 64px;
-  text-align: center;
-  box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
-}
-
-#header-home {
-  width: 100%;
-  height: 100%;
-  background-color: #424242;
-
-  .title {
-    float: left;
-    height: 100%;
-    color: white;
-    padding: 0 16px 0 16px;
-    font-weight: 300;
-    font-size: 32px;
-    cursor: pointer;
-  }
-
-  .link {
-    z-index: 101;
-    position: relative;
-    float: right;
-    height: 100%;
-    color: white;
-    padding: 0 16px 0 16px;
-    cursor: pointer;
-  }
-
-  .title:hover, .link:hover {
-    cursor: pointer;
-    background-color: #393939;
-  }
-}
-
-#header-room {
-  width: 100%;
-  height: 100%;
-  background-color: #0091ea;
-
-  .left-link, .right-link {
-    float: left;
-    width: 64px;
-    color: white;
-    text-decoration: none;
-    font-weight: 300;
-    font-size: 28px;
-
-    &:hover {
-      cursor: pointer;
-      background-color: #0083d3;
-    }
-  }
-
-  .center-link {
-    display: inline-block;
-    margin: 0 auto;
-    color: white;
-    text-decoration: none;
-    font-weight: 300;
-    font-size: 32px;
-  }
-}

+ 0 - 87
src/sass/partials/modal.scss

@@ -1,87 +0,0 @@
-main {
-  .modal {
-    position: fixed;
-    display: block;
-    box-shadow: 0 1px 6px 2px rgba(0, 0, 0, 0.25);
-    background-color: white;
-    z-index: 90001;
-    padding: 12px;
-    transition: top 0.5s ease;
-    overflow: hidden;
-
-    .modal-title {
-      text-align: center;
-      font-size: 32px;
-      margin: 0 12px;
-      height: 42px;
-      line-height: 42px;
-      display: inline-block;
-      width: calc(100% - 24px);
-    }
-
-    .modal-exit {
-      cursor: pointer;
-      position: absolute;
-      right: 8px;
-      top: 8px;
-      font-size: 24px;
-    }
-
-    .modal-input {
-      outline: none;
-      border: 1px solid #d3d3d3;
-      padding-left: 8px;
-      font-size: 16px;
-      height: 42px;
-      line-height: 42px;
-      margin: 8px 12px;
-      display: inline-block;
-      width: calc(100% - 24px);
-    }
-
-    .modal-recaptcha {
-      display: block;
-      height: 76px;
-      overflow: hidden;
-      margin: 8px 12px;
-      display: inline-block;
-      width: calc(100% - 24px);
-    }
-
-    .modal-submit {
-      cursor: pointer;
-      color: white;
-      background-color: #1976d2;
-      font-size: 24px;
-      text-align: center;
-      box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.1);
-      display: inline-block;
-      width: calc(100% - 24px);
-      height: 42px;
-      line-height: 42px;
-      margin: 8px 12px;
-
-      &:hover {
-        box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.25);
-      }
-    }
-
-    .modal-account-btn {
-      float: left;
-      width: 144px;
-      height: 144px;
-      line-height: 144px;
-      text-align: center;
-      background-color: #e9e9e9;
-      border: 1px solid #d3d3d3;
-      border-radius: 5px;
-      margin: 12px;
-      color: #3a3a3a;
-      cursor: pointer;
-
-      &:hover {
-        background-color: #dfdfdf;
-      }
-    }
-  }
-}

部分文件因为文件数量过多而无法显示