The player is playing!
This commit is contained in:
@@ -1,18 +1,8 @@
|
||||
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
||||
// listed below.
|
||||
//
|
||||
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
||||
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
||||
//
|
||||
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
||||
// the compiled file.
|
||||
//
|
||||
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
||||
// GO AFTER THE REQUIRES BELOW.
|
||||
//
|
||||
//= require jquery
|
||||
//= require jquery_ujs
|
||||
//= require jquery.autocomplete
|
||||
//= require soundmanager
|
||||
//= require vk_music
|
||||
//= require mustache
|
||||
//= require hogan
|
||||
//= require underscore
|
||||
@@ -20,5 +10,6 @@
|
||||
//= require backbone_rails_sync
|
||||
//= require backbone_datalink
|
||||
//= require backbone/beat_haven
|
||||
//= require bootstrap-dropdown
|
||||
//= require_tree .
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
$ ->
|
||||
$(".navbar-search input").focus ->
|
||||
$(this).animate(width: 249)
|
||||
$(".player").animate(width: 408)
|
||||
$(".player").animate(width: 368)
|
||||
$(".navbar-search input").blur ->
|
||||
$(this).animate(width: 99)
|
||||
$(".player").animate(width: 558)
|
||||
$(".player").animate(width: 518)
|
||||
|
||||
window.desired = $(".navbar-search input").autocomplete
|
||||
serviceUrl: "/api/search/complete"
|
||||
|
||||
@@ -9,24 +9,32 @@ window.BeatHaven =
|
||||
Collections: {}
|
||||
Routers: {}
|
||||
Views: {}
|
||||
player: null
|
||||
|
||||
Player: null
|
||||
User: null
|
||||
|
||||
init: ->
|
||||
new BeatHaven.Routers.Artist()
|
||||
new BeatHaven.Routers.Album()
|
||||
new BeatHaven.Routers.Search()
|
||||
@player = new BeatHaven.Models.Player()
|
||||
@Player = new BeatHaven.Models.Player()
|
||||
@User = new BeatHaven.Models.User()
|
||||
@VK = new BeatHaven.Models.VK()
|
||||
|
||||
@VK.init()
|
||||
|
||||
Backbone.history.start(pushState: true);
|
||||
$("a").live "click", (e) ->
|
||||
if $(this).attr("href").substr(0, 1) == "/"
|
||||
e.preventDefault()
|
||||
Backbone.history.navigate($(this).attr("href"), true)
|
||||
return false
|
||||
else
|
||||
alert "Window close attempt!"
|
||||
return false
|
||||
true
|
||||
false
|
||||
|
||||
log: (data) ->
|
||||
console.log data
|
||||
|
||||
$ ->
|
||||
BeatHaven.init()
|
||||
|
||||
# Setup shortcut
|
||||
window.BH = window.BeatHaven
|
||||
|
||||
@@ -2,10 +2,63 @@ class BeatHaven.Models.Player extends Backbone.Model
|
||||
playlist_on: false
|
||||
playlist: null
|
||||
tracks: null
|
||||
current_track: null
|
||||
|
||||
initialize: ->
|
||||
@playlist = new BeatHaven.Collections.Tracklist()
|
||||
@tracks = new BeatHaven.Collections.Tracklist()
|
||||
|
||||
play: (track) ->
|
||||
unless track?
|
||||
if @current_track?
|
||||
@current_track.get("sm_obj").resume()
|
||||
else
|
||||
this.play_something()
|
||||
else
|
||||
if @current_track?
|
||||
@current_track.get("sm_obj").stop()
|
||||
$(".player .progress-bar .bar").css(width: 0)
|
||||
@current_track = track
|
||||
@current_track.get("sm_obj").play()
|
||||
$(".player .controls .play").css(display: "none")
|
||||
$(".player .controls .pause").css(display: "inline-block")
|
||||
|
||||
pause: ->
|
||||
return false unless @current_track?
|
||||
@current_track.get("sm_obj").pause()
|
||||
$(".player .controls .play").css(display: "inline-block")
|
||||
$(".player .controls .pause").css(display: "none")
|
||||
|
||||
next: ->
|
||||
return false unless @current_track?
|
||||
if @playlist_on
|
||||
# not implemented
|
||||
else
|
||||
nodes = @current_track.node().next()
|
||||
return false unless nodes.length == 1
|
||||
@tracks.get(parseInt($(nodes[0]).data("id"), 10)).play()
|
||||
|
||||
prev: ->
|
||||
return false unless @current_track?
|
||||
if @playlist_on
|
||||
# not implemented
|
||||
else
|
||||
nodes = @current_track.node().prev()
|
||||
return false unless nodes.length == 1
|
||||
@tracks.get(parseInt($(nodes[0]).data("id"), 10)).play()
|
||||
|
||||
play_something: ->
|
||||
nodes = $(".artist-page .tracks li[data-id]")
|
||||
return false unless nodes.length > 0
|
||||
@tracks.get(parseInt($(nodes[0]).data("id"), 10)).play()
|
||||
|
||||
update_title: (params) ->
|
||||
$(".player .progress-bar .title").html("#{params.artists.join(', ')} — #{params.track}")
|
||||
|
||||
update_buffer_bar: (event) ->
|
||||
false
|
||||
|
||||
update_progress_bar: (obj) ->
|
||||
percent = obj.position / obj.duration * 100
|
||||
$(".player .progress-bar .bar").css(width: "#{percent}%")
|
||||
|
||||
|
||||
@@ -1,7 +1,43 @@
|
||||
class BeatHaven.Models.Track extends Backbone.Model
|
||||
|
||||
play: ->
|
||||
BeatHaven.player.update_title(
|
||||
if @.get("sm_obj")?
|
||||
this.start()
|
||||
else
|
||||
this.find_and_start()
|
||||
|
||||
start: ->
|
||||
BH.Player.update_title(
|
||||
artists: @.get("artists")
|
||||
track: @.get("title")
|
||||
)
|
||||
unless @.get("sm_obj")?
|
||||
this.add_to_library(autoload: true, autoplay: false)
|
||||
BH.Player.play(this)
|
||||
$(".artist-page .tracks li[data-id]").removeClass("now-playing")
|
||||
this.node().addClass("now-playing")
|
||||
|
||||
find_and_start: ->
|
||||
self = this
|
||||
BH.VK.Music.search @.get("artists")[0], @.get("title"), @.get("length"), (url) ->
|
||||
self.set(url: url)
|
||||
self.start()
|
||||
|
||||
add_to_library: (params) ->
|
||||
obj = soundManager.createSound
|
||||
id: @.get("id")
|
||||
url: @.get("url")
|
||||
autoLoad: params.autoload
|
||||
autoPlay: params.autoplay
|
||||
whileloading: ->
|
||||
BH.Player.update_buffer_bar(this)
|
||||
whileplaying: ->
|
||||
BH.Player.update_progress_bar(this)
|
||||
onfinish: ->
|
||||
BH.Player.next()
|
||||
ondataerror: ->
|
||||
BH.Player.next()
|
||||
@.set("sm_obj", obj)
|
||||
|
||||
node: ->
|
||||
$(".artist-page .tracks li[data-id='#{@.get("id")}']")
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
class BeatHaven.Models.User extends Backbone.Model
|
||||
|
||||
auth: ->
|
||||
BH.log "Authenticating user ..."
|
||||
this.query "/api/session/auth", {}, (response) ->
|
||||
if response.error?
|
||||
# report error
|
||||
else
|
||||
BH.User.set(JSON.parse(response.user))
|
||||
if response.is_newbie
|
||||
BH.log "Requesting user tracks from Vkontakte ..."
|
||||
# BH.VK.set_favorites()
|
||||
|
||||
query: (path, params, callback) ->
|
||||
query_params = $.extend {}, @.get("vk_session"), params
|
||||
query_params.authenticity_token = $('meta[name="csrf-token"]').attr("content")
|
||||
$.post path, query_params, callback
|
||||
false
|
||||
|
||||
set_favorites: (tracks) ->
|
||||
BH.log tracks
|
||||
BH.log "Sending your Vkontakte media collection to BeatHaven ..."
|
||||
this.query "/user/set_first_favorites", tracks: tracks, (response) ->
|
||||
if response.error?
|
||||
BH.log "Got error: #{response.error}"
|
||||
else
|
||||
BH.log "We believe your favorite artists are #{response.join(', ')}"
|
||||
@@ -0,0 +1,43 @@
|
||||
class BeatHaven.Models.VK extends Backbone.Model
|
||||
|
||||
session_length: 3600 # seconds
|
||||
Music: null
|
||||
|
||||
popup: ->
|
||||
alert(1)
|
||||
|
||||
init: ->
|
||||
@Music = new VkMusic()
|
||||
BH.log "Initializing Vkontakte API ..."
|
||||
window.VK.init(apiId: VK_APP_ID)
|
||||
BH.VK.auth()
|
||||
# VK.Widgets.Like("vk-like", {type: "mini", height: 20, pageUrl: "http://beathaven.org/", text: "Like"})
|
||||
|
||||
auth: ->
|
||||
BH.log "Requesting new Vkontakte session ..."
|
||||
window.VK.Auth.getLoginStatus (response) ->
|
||||
BH.VK.auth_info(response)
|
||||
false
|
||||
, 8
|
||||
false
|
||||
|
||||
auth_info: (response) ->
|
||||
if typeof response isnt "undefined" and response.session?
|
||||
BH.User.set(vk_session: response.session)
|
||||
BH.User.auth()
|
||||
|
||||
if response.session.expire?
|
||||
expire_in = response.session.expire * 1000 - new Date().getTime()
|
||||
# time is an illusion...
|
||||
expire_in = @session_length * 1000
|
||||
BH.log "Session will expire in #{Math.round(expire_in / 1000)} seconds"
|
||||
setTimeout ->
|
||||
BH.log "Session expired"
|
||||
BH.VK.auth()
|
||||
, expire_in + 1000
|
||||
else
|
||||
BH.log "Not authorized"
|
||||
|
||||
set_favorites: ->
|
||||
window.VK.Api.call "audio.get", uid: BH.User.vk_id(), (response) ->
|
||||
BH.User.set_favorites(response.response)
|
||||
@@ -10,6 +10,7 @@
|
||||
{{#album_tracks}}
|
||||
<li data-id="{{track_id}}">
|
||||
<a href="" class="btn btn-round track-play"><i class="icon-play"></i></a>
|
||||
<a href="" class="btn btn-round track-pause"><i class="icon-pause"></i></a>
|
||||
<div class="title">
|
||||
<div class="inner">
|
||||
<a href="{{track_url}}" class="track-link">{{track_title}}</a>
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
{{#album_tracks}}
|
||||
<li data-id="{{track_id}}">
|
||||
<a href="" class="btn btn-round track-play"><i class="icon-play"></i></a>
|
||||
<a href="" class="btn btn-round track-pause"><i class="icon-pause"></i></a>
|
||||
<div class="title">
|
||||
<div class="inner">
|
||||
<a href="{{track_url}}" class="track-link">{{track_title}}</a>
|
||||
|
||||
@@ -8,6 +8,6 @@ class BeatHaven.Views.AlbumShow extends Backbone.View
|
||||
if typeof @model.get("album_tracks") != "undefined"
|
||||
for track_info in @model.get("album_tracks")
|
||||
track = new BeatHaven.Models.Track(track_info.meta)
|
||||
BeatHaven.player.tracks.push(track)
|
||||
BeatHaven.Player.tracks.push(track)
|
||||
$(@el).html(@template.render(@model.toJSON()))
|
||||
this
|
||||
|
||||
@@ -9,6 +9,6 @@ class BeatHaven.Views.ArtistShow extends Backbone.View
|
||||
for album_info in @model.get("artist_albums")
|
||||
for track_info in album_info.album_tracks
|
||||
track = new BeatHaven.Models.Track(track_info.meta)
|
||||
BeatHaven.player.tracks.push(track)
|
||||
BeatHaven.Player.tracks.push(track)
|
||||
$(@el).html(@template.render(@model.toJSON()))
|
||||
this
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
$ ->
|
||||
$(".auth a").bind "mouseup", (e) ->
|
||||
e.preventDefault()
|
||||
if BeatHaven.authenticated
|
||||
alert("auth ok!!!!!")
|
||||
else
|
||||
BeatHaven.VK.popup()
|
||||
@@ -0,0 +1,9 @@
|
||||
$ ->
|
||||
$(".player .controls .prev").live "click", (e) ->
|
||||
BH.Player.prev()
|
||||
$(".player .controls .play").live "click", (e) ->
|
||||
BH.Player.play()
|
||||
$(".player .controls .pause").live "click", (e) ->
|
||||
BH.Player.pause()
|
||||
$(".player .controls .next").live "click", (e) ->
|
||||
BH.Player.next()
|
||||
@@ -0,0 +1,5 @@
|
||||
$ ->
|
||||
$(".track-play").live "click", (e) ->
|
||||
e.preventDefault()
|
||||
id = parseInt($(this).parent().data("id"), 10)
|
||||
BH.Player.tracks.get(id).play()
|
||||
@@ -24,6 +24,23 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.now-playing {
|
||||
a {
|
||||
color: #126be8 !important;
|
||||
text-shadow: 0 0 1px rgba(255, 255, 255, .2);
|
||||
}
|
||||
.track-play {
|
||||
display: none;
|
||||
}
|
||||
.track-pause {
|
||||
display: block;
|
||||
|
||||
i {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-round {
|
||||
width: 10px;
|
||||
height: 22px;
|
||||
@@ -34,7 +51,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.track-play {
|
||||
.track-play, .track-pause {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left: 5px;
|
||||
@@ -43,6 +60,9 @@
|
||||
opacity: .3;
|
||||
}
|
||||
}
|
||||
.track-pause {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// Track title
|
||||
.title {
|
||||
@@ -112,7 +132,7 @@
|
||||
}
|
||||
background-color: rgba(200, 200, 200, .3);
|
||||
|
||||
.track-play i {
|
||||
.track-play i, .track-pause i {
|
||||
opacity: 1;
|
||||
}
|
||||
.track-add {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
@import "artist";
|
||||
@import "album-track";
|
||||
@import "player";
|
||||
@import "auth";
|
||||
|
||||
@import url(http://fonts.googleapis.com/css?family=Lobster+Two:400,400italic,700);
|
||||
@import url(http://fonts.googleapis.com/css?family=Source+Sans+Pro);
|
||||
@@ -25,6 +26,10 @@ body {
|
||||
.navbar-inner {
|
||||
background: none;
|
||||
@include background-image(linear-gradient(rgba(0, 0, 0, .05) 0, rgba(0, 0, 0, .4) 100%));
|
||||
|
||||
.container {
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
a.brand {
|
||||
margin-top: 1px;
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
.navbar .auth {
|
||||
margin: 14px 10px 0 15px;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
.player {
|
||||
width: 558px;
|
||||
width: 518px;
|
||||
|
||||
.controls {
|
||||
float: left;
|
||||
@@ -8,6 +8,10 @@
|
||||
a {
|
||||
margin: 5px 6px 0 -9px;
|
||||
}
|
||||
|
||||
.pause {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.progress-bar {
|
||||
position: relative;
|
||||
@@ -25,6 +29,7 @@
|
||||
|
||||
.bar {
|
||||
position: absolute;
|
||||
width: 0%;
|
||||
height: 26px;
|
||||
background-color: rgba(255, 255, 255, .1);
|
||||
@include box-shadow(inset 0 0 2px rgba(255, 255, 255, .2));
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
module Api
|
||||
class SessionController < ApplicationController
|
||||
|
||||
def auth
|
||||
render json: { error: "Signature verification failed!" } unless request_valid?
|
||||
|
||||
user_name = "#{params[:user][:first_name]} #{params[:user][:last_name]}"
|
||||
|
||||
user = User.find_by_vk_id(params[:mid].to_i)
|
||||
is_newbie = false
|
||||
if user.nil?
|
||||
user = User.create(name: user_name, vk_id: params[:mid].to_i)
|
||||
is_newbie = true
|
||||
elsif user.name != user_name
|
||||
user.update_attributes(name: user_name)
|
||||
end
|
||||
|
||||
render json: { user: user.dump_json, is_newbie: is_newbie }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def request_valid?
|
||||
%w[ expire mid secret sid sig ].map(&:to_sym).each do |key|
|
||||
raise "Parameter not set: #{key}" if params[key].nil?
|
||||
end
|
||||
|
||||
validation_string = %w[ expire mid secret sid ].map{ |key|
|
||||
"#{key}=#{params[key.to_sym]}"
|
||||
}.join() << BeatHaven::Application.config.api_accounts["vk"]["api_secret"]
|
||||
|
||||
params[:sig] == Digest::MD5.hexdigest(validation_string)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,12 @@
|
||||
class User < ActiveRecord::Base
|
||||
attr_accessible :lang, :name, :vk_id
|
||||
|
||||
def dump_json
|
||||
Jbuilder.encode do |j|
|
||||
j.id id
|
||||
j.name name
|
||||
j.lang lang
|
||||
j.vk_id vk_id
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,13 @@
|
||||
<div class="player pull-right">
|
||||
<div class="controls">
|
||||
<a href="" class="btn btn-bh-dark prev"><i class="icon-backward icon-white"></i></a>
|
||||
<a href="" class="btn btn-bh-dark play"><i class="icon-play icon-white"></i></a>
|
||||
<a href="" class="btn btn-bh-dark pause"><i class="icon-pause icon-white"></i></a>
|
||||
<a href="" class="btn btn-bh-dark next"><i class="icon-forward icon-white"></i></a>
|
||||
</div>
|
||||
<div class="progress-bar">
|
||||
<div class="bar"></div>
|
||||
<div class="title">Waiting...</div>
|
||||
<div class="move-it"></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -4,7 +4,11 @@
|
||||
<title>BeatHaven</title>
|
||||
<%= stylesheet_link_tag "application", media: "all" %>
|
||||
<%= javascript_include_tag "application" %>
|
||||
<%= javascript_include_tag "http://vkontakte.ru/js/api/openapi.js" %>
|
||||
<%= csrf_meta_tags %>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
window.VK_APP_ID = 2335068;
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -15,18 +19,10 @@
|
||||
<form class="navbar-search pull-left">
|
||||
<input type="search" placeholder="Search" class="search-query">
|
||||
</form>
|
||||
<div class="player pull-right">
|
||||
<div class="controls">
|
||||
<a href="" class="btn btn-bh-dark prev"><i class="icon-backward icon-white"></i></a>
|
||||
<a href="" class="btn btn-bh-dark pause"><i class="icon-pause icon-white"></i></a>
|
||||
<a href="" class="btn btn-bh-dark next"><i class="icon-forward icon-white"></i></a>
|
||||
</div>
|
||||
<div class="progress-bar">
|
||||
<div class="bar" style="width: 42%"></div>
|
||||
<div class="title">Foo Fighters — Alone + Easy Target</div>
|
||||
<div class="move-it"></div>
|
||||
</div>
|
||||
<div class="auth pull-right">
|
||||
<a href=""><i class="icon-user icon-white"></i></a>
|
||||
</div>
|
||||
<%= render partial: "player" %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user