Added site locales

This commit is contained in:
magnolia-fan 2011-06-30 09:12:52 +04:00
parent 124e9e481e
commit 13a233ac72
26 changed files with 406 additions and 112 deletions

View File

@ -29,13 +29,13 @@ class Ajax
loadSearchPage: -> loadSearchPage: ->
$.get '/templates/search.html', (data) -> $.get '/templates/search.html', (data) ->
_ajax.setArchor '/search/' _ajax.setArchor '/search/'
_pages.renderSearch data _pages.renderSearch _beathaven.localizeHTML $(data)
false false
loadSettingsPage: -> loadSettingsPage: ->
$.get '/templates/settings.html', (data) -> $.get '/templates/settings.html', (data) ->
_ajax.setArchor '/settings/' _ajax.setArchor '/settings/'
_pages.renderSettings data _pages.renderSettings _beathaven.localizeHTML $(data)
false false
load404Page: -> load404Page: ->

View File

@ -18,13 +18,16 @@ $ ->
$(window).resize -> $(window).resize ->
_beathaven.adjustSizes() _beathaven.adjustSizes()
false
window.setTimeout -> window.setTimeout ->
_beathaven.checkRedrawScrollbar() _beathaven.checkRedrawScrollbar()
false
, 500 , 500
class BeatHaven class BeatHaven
last_height: false last_height: false
lang: 'ru'
init: -> init: ->
this.adjustSizes() this.adjustSizes()
@ -45,6 +48,8 @@ class BeatHaven
_settings = new Settings() _settings = new Settings()
false
adjustSizes: -> adjustSizes: ->
$('.data-container').height $(window).height() - $('.header-container').height() $('.data-container').height $(window).height() - $('.header-container').height()
$('.data-container').width $(window).width() - $('.player').width() $('.data-container').width $(window).width() - $('.player').width()
@ -53,6 +58,7 @@ class BeatHaven
$('.data-container').scrollbar() $('.data-container').scrollbar()
$('.playlist').scrollbar() $('.playlist').scrollbar()
false
checkRedrawScrollbar: -> checkRedrawScrollbar: ->
focused_id = false focused_id = false
@ -67,11 +73,33 @@ class BeatHaven
focused_id = false focused_id = false
window.setTimeout -> window.setTimeout ->
_beathaven.checkRedrawScrollbar() _beathaven.checkRedrawScrollbar()
false
, 500 , 500
false
redrawScrollbar: -> redrawScrollbar: ->
$('.data-container').html $('.data-container').find('.inner').first() $('.data-container').html $('.data-container').find('.inner').first()
$('.data-container').scrollbar() $('.data-container').scrollbar()
false
localizeHTML: (obj) ->
unless obj?
obj = $('body')
$(obj).find('[data-ls]').each ->
if _locale[$(this).attr 'data-ls']? and _locale[$(this).attr 'data-ls'][_beathaven.lang]?
if this.nodeName is 'INPUT'
$(this).val _locale[$(this).attr 'data-ls'][_beathaven.lang]
else
$(this).text _locale[$(this).attr 'data-ls'][_beathaven.lang]
return obj
ls: (id, lang) ->
unless lang?
lang = _beathaven.lang
if _locale[id]? and _locale[id][lang]?
_locale[id][lang]
else
id
String::htmlsafe = -> String::htmlsafe = ->

View File

@ -0,0 +1,80 @@
_locale =
# Global
SEARCH:
en: "Search"
ru: "Поиск"
NEWS:
en: "News"
ru: "Новости"
ABOUT:
en: "About"
ru: "О проекте"
LOGIN:
en: "Log in"
ru: "Войти"
LOGOUT:
en: "Log out"
ru: "Выйти"
ADD_SOME_MUSIC:
en: "Add some music to playlist"
ru: "Добавьте музыку в плей-лист"
LOGIN_PLEASE:
en: "Don't forget to log in, please. It's simple."
ru: "Авторизуйтесь, пожалуйста. Это действительно просто."
REPEAT:
en: "Repeat"
ru: "Повторять"
SHUFFLE:
en: "Shuffle"
ru: "Перемешать"
EMPTY_PLAYLIST:
en: "Empty playlist"
ru: "Очистить"
HELLO:
en: "Hi there"
ru: "Привет"
# Search
ARTIST_LOADING_FAILED:
en: "Something very bad happened while we tried out to load some info about this artist. How about some other one?"
ru: "Что-то ужасное произошло пока мы собирали информацию об этом исполнителе. Может пока поищем другого?"
ARTIST_LOADING_IN_PROCESS:
en: "Artist info is loading for the first time now. Usually it takes less than a minute, please wait a bit."
ru: "Прямо сейчас мы собираем всю возможною информацию об этом исполнителе в первый раз. Обычно это занимает меньше минуты."
MISSPELLED:
en: "Misspelled?"
ru: "Опечатались?"
# Settings
SETTINGS_ACCOUNT:
en: "Account"
ru: "Аккаунт"
SETTINGS_LASTFM:
en: "Last.fm"
ru: "Last.fm"
USERNAME:
en: "Username"
ru: "Имя"
EMAIL:
en: "Email"
ru: "Почта"
LANG:
en: "Language"
ru: "Язык"
USELESS_BUTTON:
en: "Hello, my name is Useless Button"
ru: "Привет, меня зовут Бесполезная Кнопка"
NOT_CONNECTED:
en: "Not connected"
ru: "Не подключен"
CONNECT:
en: "Connect"
ru: "Подключить"
WINDOW_LANG_RELOAD:
en: "To change application language it is needed to reload page. Your current playlist will be emptied and music will stop. Do you really wish to continue?"
ru: "Чтобы изменить язык приложения, необходимо перезагрузить страницу. Ваш текущий плей-лист будет очищен и музыка остановится. Вы действительно хотите продолжить?"
# Player
ADD_TO_NOW_PLAYING:
en: "Add to Now Playing"
ru: "Добавить в плей-лист"

View File

@ -21,7 +21,7 @@ class Pages
<div class="pic"> <div class="pic">
<img src="' +(if album.pic then album.pic else '/images/kitteh.png')+ '" alt="' +album.name+ ' by ' +data.artist.name+ '" width="250" height="250"/> <img src="' +(if album.pic then album.pic else '/images/kitteh.png')+ '" alt="' +album.name+ ' by ' +data.artist.name+ '" width="250" height="250"/>
<div class="add-album-button-container"> <div class="add-album-button-container">
<div class="add-album button gray">Add to Now Playing</div> <div class="add-album button gray">'+_beathaven.ls('ADD_TO_NOW_PLAYING')+'</div>
</div> </div>
</div> </div>
<div class="tracklist"><ul></ul></div> <div class="tracklist"><ul></ul></div>

View File

@ -13,6 +13,8 @@ class Session
setUser: (user) -> setUser: (user) ->
@user = user @user = user
_beathaven.lang = @user.lang
_beathaven.localizeHTML()
false false
getUser: -> getUser: ->

View File

@ -12,6 +12,7 @@ class Settings
if form == 'account' if form == 'account'
$('.settings-container .form input[name$="username"]').val _session.getUser().name $('.settings-container .form input[name$="username"]').val _session.getUser().name
$('.settings-container .form input[name$="email"]').val _session.getUser().email $('.settings-container .form input[name$="email"]').val _session.getUser().email
$('.settings-container .form select').val _session.getUser().lang
else if form == 'lastfm' else if form == 'lastfm'
if _session.getUser().lastfm_username if _session.getUser().lastfm_username
$('.form-container input[name$="username"]').first().val _session.getUser().lastfm_username $('.form-container input[name$="username"]').first().val _session.getUser().lastfm_username
@ -44,13 +45,20 @@ $('.lastfm-connect') .live 'click', ->
setTimeout _settings.updateLastfmLogin, 100 setTimeout _settings.updateLastfmLogin, 100
false false
$('.settings-container .form input').live 'blur', -> $('.settings-container .form input, .settings-container .form select').live 'blur', ->
active_tab = $('.settings-container .tabs .tab.active').attr 'data-fieldset' active_tab = $('.settings-container .tabs .tab.active').attr 'data-fieldset'
if active_tab == 'account' if active_tab == 'account'
params = params =
username: $('.settings-container .form input[name$="username"]').first().val() username: $('.settings-container .form input[name$="username"]').first().val()
email: $('.settings-container .form input[name$="email"]').first().val() email: $('.settings-container .form input[name$="email"]').first().val()
lang: $('.settings-container .form select').first().val()
lang_changed = params.lang != _session.getUser().lang
if lang_changed
if not confirm _beathaven.ls 'WINDOW_LANG_RELOAD', params.lang
$('.settings-container .form select').val _session.getUser().lang
_settings.saveAccountInfo params, -> _settings.saveAccountInfo params, ->
if lang_changed
window.location.reload()
$('.header-container .hello .greating span').text (if params.username.length > 0 then params.username else '%username%') $('.header-container .hello .greating span').text (if params.username.length > 0 then params.username else '%username%')
false false
false false

View File

@ -18,14 +18,14 @@ class Vkontakte
setTimeout -> setTimeout ->
$('#vk_api_transport').append('<script async="async" src="http://vkontakte.ru/js/api/openapi.js"></script>') $('#vk_api_transport').append('<script async="async" type="text/javascript" src="http://vkontakte.ru/js/api/openapi.js"></script>')
, 0 , 0
authInfo: (response) -> authInfo: (response) ->
if typeof response isnt 'undefined' and response.session if typeof response isnt 'undefined' and response.session
_session = new Session(response.session) _session = new Session(response.session)
$('#vk_login, .auth_notice').hide() $('#vk_login, .auth-notice').hide()
$('#vk_logout').css display: 'block' $('#vk_logout').css display: 'block'
$('#search_field').focus() if $('#search_field').length > 0 $('#search_field').focus() if $('#search_field').length > 0
@ -36,7 +36,7 @@ class Vkontakte
_session.query '/user/update', name: r.response, (ar2) -> _session.query '/user/update', name: r.response, (ar2) ->
_session.setUser ar2.user _session.setUser ar2.user
$('.header-container .hello .greating') $('.header-container .hello .greating')
.html 'Tēnā koe, <span class="settings">' +(if _session.getUser().name then _session.getUser().name else '%username%')+ '</span>!' .html _beathaven.ls('HELLO')+', <span class="settings">' +(if _session.getUser().name then _session.getUser().name else '%username%')+ '</span>!'
window._session = _session window._session = _session
_ajax.detectPage() _ajax.detectPage()
$('.fullscreen').hide(); $('.fullscreen').hide();
@ -45,7 +45,7 @@ class Vkontakte
$('.header-container .hello').show() $('.header-container .hello').show()
$('.header-container .hello .greating') $('.header-container .hello .greating')
.html 'Tēnā koe, <span class="settings">' +(if _session.getUser().name then _session.getUser().name else '%username%')+ '</span>!' .html _beathaven.ls('HELLO')+', <span class="settings">' +(if _session.getUser().name then _session.getUser().name else '%username%')+ '</span>!'
window._session = _session window._session = _session
_ajax.detectPage() _ajax.detectPage()
$('.fullscreen').hide(); $('.fullscreen').hide();
@ -58,7 +58,8 @@ class Vkontakte
else else
_session = new Session({}) _session = new Session({})
_session.setUser {} _session.setUser {}
$('#vk_login, .auth_notice').css display: 'block' $('#vk_login').css display: 'block'
$('.auth-notice').css('left', $('#vk_login').offset().left).show()
$('.header-container .hello').hide() $('.header-container .hello').hide()
window._session = _session window._session = _session
_ajax.detectPage() _ajax.detectPage()
@ -128,7 +129,7 @@ class Vkontakte
@qr[query] @qr[query]
false false
$('#vk_login').live 'click', -> $('#vk_login, .auth-notice').live 'click', ->
VK.Auth.login (response) -> VK.Auth.login (response) ->
_vkontakte.authInfo(response) _vkontakte.authInfo(response)
false false

View File

@ -8,6 +8,7 @@ class UserController < ApplicationController
if user.nil? if user.nil?
user = User.new user = User.new
user.vkid = params[:mid] user.vkid = params[:mid]
user.lang = 'ru'
user.save user.save
@res[:newbie] = true @res[:newbie] = true
end end
@ -20,10 +21,13 @@ class UserController < ApplicationController
:name => user.name, :name => user.name,
:email => user.email, :email => user.email,
:vkid => user.vkid, :vkid => user.vkid,
:lastfm_username => user.lastfm_username, :lang => user.lang,
:lastfm_login_url => 'http://www.last.fm/api/auth?api_key='+ LastFmController.api_key + :lastfm_username => user.lastfm_username
'&cb=http://'+ request.host << '/lastfm/connect/?sid='+ user.session.key
} }
unless user.lastfm_username
@res[:lastfm_login_url] = 'http://www.last.fm/api/auth?api_key='+ LastFmController.api_key +
'&cb=http://'+ request.host << '/lastfm/connect/?sid='+ user.session.key
end
render :json => @res render :json => @res
end end
@ -36,6 +40,7 @@ class UserController < ApplicationController
unless params[:username].nil? or params[:email].nil? unless params[:username].nil? or params[:email].nil?
user.name = params[:username] user.name = params[:username]
user.email = params[:email] user.email = params[:email]
user.lang = params[:lang] if ['ru', 'en'].include? params[:lang]
user.save user.save
end end
@res[:user] = { @res[:user] = {
@ -43,10 +48,13 @@ class UserController < ApplicationController
:name => user.name, :name => user.name,
:email => user.email, :email => user.email,
:vkid => user.vkid, :vkid => user.vkid,
:lastfm_username => user.lastfm_username, :lang => user.lang,
:lastfm_login_url => 'http://www.last.fm/api/auth?api_key='+ LastFmController.api_key + :lastfm_username => user.lastfm_username
'&cb=http://'+ request.host << '/lastfm/connect/?sid='+ user.session.key
} }
unless user.lastfm_username
@res[:lastfm_login_url] = 'http://www.last.fm/api/auth?api_key='+ LastFmController.api_key +
'&cb=http://'+ request.host << '/lastfm/connect/?sid='+ user.session.key
end
render :json => @res render :json => @res
end end

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>BetaHaven</title> <title>BeatHaven</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel="shortcut icon" href="/favicon.ico" /> <link rel="shortcut icon" href="/favicon.ico" />
<link rel="stylesheet" type="text/css" media="screen" href="/stylesheets/beathaven.css" /> <link rel="stylesheet" type="text/css" media="screen" href="/stylesheets/beathaven.css" />
@ -12,6 +12,7 @@
<%= javascript_include_tag "jquery/jquery.jplayer.js", :type => "text/javascript", :charset => "utf-8" %> <%= javascript_include_tag "jquery/jquery.jplayer.js", :type => "text/javascript", :charset => "utf-8" %>
<%= javascript_include_tag "jquery/jquery.scroll.js", :type => "text/javascript", :charset => "utf-8" %> <%= javascript_include_tag "jquery/jquery.scroll.js", :type => "text/javascript", :charset => "utf-8" %>
<%= javascript_include_tag "coffee/beathaven.js", :type => "text/javascript", :charset => "utf-8" %> <%= javascript_include_tag "coffee/beathaven.js", :type => "text/javascript", :charset => "utf-8" %>
<%= javascript_include_tag "coffee/locale.js", :type => "text/javascript", :charset => "utf-8" %>
<%= javascript_include_tag "coffee/vkontakte.js", :type => "text/javascript", :charset => "utf-8" %> <%= javascript_include_tag "coffee/vkontakte.js", :type => "text/javascript", :charset => "utf-8" %>
<%= javascript_include_tag "coffee/session.js", :type => "text/javascript", :charset => "utf-8" %> <%= javascript_include_tag "coffee/session.js", :type => "text/javascript", :charset => "utf-8" %>
<%= javascript_include_tag "coffee/ajax.js", :type => "text/javascript", :charset => "utf-8" %> <%= javascript_include_tag "coffee/ajax.js", :type => "text/javascript", :charset => "utf-8" %>
@ -27,7 +28,7 @@
<div class="player-container"> <div class="player-container">
<div class="player"> <div class="player">
<div id="jplayer"></div> <div id="jplayer"></div>
<div class="now-playing">Add some music to playlist</div> <div class="now-playing" data-ls="ADD_SOME_MUSIC"></div>
<div class="progress"> <div class="progress">
<div class="loaded"> <div class="loaded">
<div class="played"></div> <div class="played"></div>
@ -45,13 +46,13 @@
</div> </div>
<div class="additional-controls"> <div class="additional-controls">
<div class="item active" id="repeat"> <div class="item active" id="repeat">
<img src="/images/icns/repeat.png" alt=""/><div class="annotation">Repeat</div> <img src="/images/icns/repeat.png" alt=""/><div class="annotation" data-ls="REPEAT"></div>
</div> </div>
<div class="item" id="shuffle"> <div class="item" id="shuffle">
<img src="/images/icns/shuffle.png" alt=""/><div class="annotation">Shuffle</div> <img src="/images/icns/shuffle.png" alt=""/><div class="annotation" data-ls="SHUFFLE"></div>
</div> </div>
<div class="item" id="empty-playlist"> <div class="item" id="empty-playlist">
<img src="/images/icns/empty.png" alt=""/><div class="annotation">Empty Playlist</div> <img src="/images/icns/empty.png" alt=""/><div class="annotation" data-ls="EMPTY_PLAYLIST"></div>
</div> </div>
</div> </div>
</div> </div>
@ -62,10 +63,10 @@
</div> </div>
<ul class="navigation"> <ul class="navigation">
<li class="logo search">BeatHaven<div class="version">0.4b</div></li> <li class="logo search">BeatHaven<div class="version">0.4b</div></li>
<li class="search">Search</li> <li class="search" data-ls="SEARCH"></li>
<li><a href="https://twitter.com/#!/beat_haven" target="_blank">News</a></li> <li><a href="http://blog.beathaven.org/" target="_blank" data-ls="NEWS"></a></li>
<li class="about">About</li> <li class="about" data-ls="ABOUT"></li>
<li class="vk_auth" id="vk_login">Login</li> <li class="vk_auth" id="vk_login" data-ls="LOGIN"></li>
</ul> </ul>
</div> </div>
<div class="data-container" class="css-scrollbar"> <div class="data-container" class="css-scrollbar">
@ -73,7 +74,10 @@
</div> </div>
<div id="vk_api_transport"></div> <div id="vk_api_transport"></div>
<div class="auth_notice"><div class="arrow">&uarr;</div>Don't forget to log in, please. It's simple.</div> <div class="auth-notice">
<div class="arrow">&uarr;</div>
<span data-ls="LOGIN_PLEASE"></span>
</div>
<div class="fullscreen"> <div class="fullscreen">
<div class="inner"> <div class="inner">
<img src="/images/loader.gif" alt=""/> <img src="/images/loader.gif" alt=""/>

View File

@ -0,0 +1,9 @@
class AddLangToUser < ActiveRecord::Migration
def self.up
add_column :users, :lang, :string
end
def self.down
remove_column :users, :lang
end
end

View File

@ -10,7 +10,7 @@
# #
# It's strongly recommended to check this file into your version control system. # It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20110624073136) do ActiveRecord::Schema.define(:version => 20110630035132) do
create_table "albums", :force => true do |t| create_table "albums", :force => true do |t|
t.string "name" t.string "name"
@ -101,6 +101,7 @@ ActiveRecord::Schema.define(:version => 20110624073136) do
t.datetime "updated_at" t.datetime "updated_at"
t.string "lastfm_key" t.string "lastfm_key"
t.string "lastfm_username" t.string "lastfm_username"
t.string "lang"
end end
end end

View File

@ -32,14 +32,14 @@ Ajax = (function() {
Ajax.prototype.loadSearchPage = function() { Ajax.prototype.loadSearchPage = function() {
$.get('/templates/search.html', function(data) { $.get('/templates/search.html', function(data) {
_ajax.setArchor('/search/'); _ajax.setArchor('/search/');
return _pages.renderSearch(data); return _pages.renderSearch(_beathaven.localizeHTML($(data)));
}); });
return false; return false;
}; };
Ajax.prototype.loadSettingsPage = function() { Ajax.prototype.loadSettingsPage = function() {
$.get('/templates/settings.html', function(data) { $.get('/templates/settings.html', function(data) {
_ajax.setArchor('/settings/'); _ajax.setArchor('/settings/');
return _pages.renderSettings(data); return _pages.renderSettings(_beathaven.localizeHTML($(data)));
}); });
return false; return false;
}; };

View File

@ -16,15 +16,18 @@ $(function() {
_beathaven = new BeatHaven(); _beathaven = new BeatHaven();
_beathaven.init(); _beathaven.init();
$(window).resize(function() { $(window).resize(function() {
return _beathaven.adjustSizes(); _beathaven.adjustSizes();
return false;
}); });
return window.setTimeout(function() { return window.setTimeout(function() {
return _beathaven.checkRedrawScrollbar(); _beathaven.checkRedrawScrollbar();
return false;
}, 500); }, 500);
}); });
BeatHaven = (function() { BeatHaven = (function() {
function BeatHaven() {} function BeatHaven() {}
BeatHaven.prototype.last_height = false; BeatHaven.prototype.last_height = false;
BeatHaven.prototype.lang = 'ru';
BeatHaven.prototype.init = function() { BeatHaven.prototype.init = function() {
this.adjustSizes(); this.adjustSizes();
this.checkRedrawScrollbar(); this.checkRedrawScrollbar();
@ -35,7 +38,8 @@ BeatHaven = (function() {
_player.initJplayer(); _player.initJplayer();
_search = new Search(); _search = new Search();
_pages = new Pages(); _pages = new Pages();
return _settings = new Settings(); _settings = new Settings();
return false;
}; };
BeatHaven.prototype.adjustSizes = function() { BeatHaven.prototype.adjustSizes = function() {
$('.data-container').height($(window).height() - $('.header-container').height()); $('.data-container').height($(window).height() - $('.header-container').height());
@ -43,7 +47,8 @@ BeatHaven = (function() {
$('.player-container').height($(window).height()); $('.player-container').height($(window).height());
$('.playlist').height($(window).height() - $('.player').height() - $('.player-container .additional-controls').height()); $('.playlist').height($(window).height() - $('.player').height() - $('.player-container .additional-controls').height());
$('.data-container').scrollbar(); $('.data-container').scrollbar();
return $('.playlist').scrollbar(); $('.playlist').scrollbar();
return false;
}; };
BeatHaven.prototype.checkRedrawScrollbar = function() { BeatHaven.prototype.checkRedrawScrollbar = function() {
var focused_id, outer_height; var focused_id, outer_height;
@ -60,13 +65,41 @@ BeatHaven = (function() {
document.getElementById(focused_id).focus(); document.getElementById(focused_id).focus();
focused_id = false; focused_id = false;
} }
return window.setTimeout(function() { window.setTimeout(function() {
return _beathaven.checkRedrawScrollbar(); _beathaven.checkRedrawScrollbar();
return false;
}, 500); }, 500);
return false;
}; };
BeatHaven.prototype.redrawScrollbar = function() { BeatHaven.prototype.redrawScrollbar = function() {
$('.data-container').html($('.data-container').find('.inner').first()); $('.data-container').html($('.data-container').find('.inner').first());
return $('.data-container').scrollbar(); $('.data-container').scrollbar();
return false;
};
BeatHaven.prototype.localizeHTML = function(obj) {
if (obj == null) {
obj = $('body');
}
$(obj).find('[data-ls]').each(function() {
if ((_locale[$(this).attr('data-ls')] != null) && (_locale[$(this).attr('data-ls')][_beathaven.lang] != null)) {
if (this.nodeName === 'INPUT') {
return $(this).val(_locale[$(this).attr('data-ls')][_beathaven.lang]);
} else {
return $(this).text(_locale[$(this).attr('data-ls')][_beathaven.lang]);
}
}
});
return obj;
};
BeatHaven.prototype.ls = function(id, lang) {
if (lang == null) {
lang = _beathaven.lang;
}
if ((_locale[id] != null) && (_locale[id][lang] != null)) {
return _locale[id][lang];
} else {
return id;
}
}; };
return BeatHaven; return BeatHaven;
})(); })();

View File

@ -0,0 +1,99 @@
var _locale;
_locale = {
SEARCH: {
en: "Search",
ru: "Поиск"
},
NEWS: {
en: "News",
ru: "Новости"
},
ABOUT: {
en: "About",
ru: "О проекте"
},
LOGIN: {
en: "Log in",
ru: "Войти"
},
LOGOUT: {
en: "Log out",
ru: "Выйти"
},
ADD_SOME_MUSIC: {
en: "Add some music to playlist",
ru: "Добавьте музыку в плей-лист"
},
LOGIN_PLEASE: {
en: "Don't forget to log in, please. It's simple.",
ru: "Авторизуйтесь, пожалуйста. Это действительно просто."
},
REPEAT: {
en: "Repeat",
ru: "Повторять"
},
SHUFFLE: {
en: "Shuffle",
ru: "Перемешать"
},
EMPTY_PLAYLIST: {
en: "Empty playlist",
ru: "Очистить"
},
HELLO: {
en: "Hi there",
ru: "Привет"
},
ARTIST_LOADING_FAILED: {
en: "Something very bad happened while we tried out to load some info about this artist. How about some other one?",
ru: "Что-то ужасное произошло пока мы собирали информацию об этом исполнителе. Может пока поищем другого?"
},
ARTIST_LOADING_IN_PROCESS: {
en: "Artist info is loading for the first time now. Usually it takes less than a minute, please wait a bit.",
ru: "Прямо сейчас мы собираем всю возможною информацию об этом исполнителе в первый раз. Обычно это занимает меньше минуты."
},
MISSPELLED: {
en: "Misspelled?",
ru: "Опечатались?"
},
SETTINGS_ACCOUNT: {
en: "Account",
ru: "Аккаунт"
},
SETTINGS_LASTFM: {
en: "Last.fm",
ru: "Last.fm"
},
USERNAME: {
en: "Username",
ru: "Имя"
},
EMAIL: {
en: "Email",
ru: "Почта"
},
LANG: {
en: "Language",
ru: "Язык"
},
USELESS_BUTTON: {
en: "Hello, my name is Useless Button",
ru: "Привет, меня зовут Бесполезная Кнопка"
},
NOT_CONNECTED: {
en: "Not connected",
ru: "Не подключен"
},
CONNECT: {
en: "Connect",
ru: "Подключить"
},
WINDOW_LANG_RELOAD: {
en: "To change application language it is needed to reload page. Your current playlist will be emptied and music will stop. Do you really wish to continue?",
ru: "Чтобы изменить язык приложения, необходимо перезагрузить страницу. Ваш текущий плей-лист будет очищен и музыка остановится. Вы действительно хотите продолжить?"
},
ADD_TO_NOW_PLAYING: {
en: "Add to Now Playing",
ru: "Добавить в плей-лист"
}
};

View File

@ -23,7 +23,7 @@ Pages = (function() {
<div class="pic">\ <div class="pic">\
<img src="' + (album.pic ? album.pic : '/images/kitteh.png') + '" alt="' + album.name + ' by ' + data.artist.name + '" width="250" height="250"/>\ <img src="' + (album.pic ? album.pic : '/images/kitteh.png') + '" alt="' + album.name + ' by ' + data.artist.name + '" width="250" height="250"/>\
<div class="add-album-button-container">\ <div class="add-album-button-container">\
<div class="add-album button gray">Add to Now Playing</div>\ <div class="add-album button gray">' + _beathaven.ls('ADD_TO_NOW_PLAYING') + '</div>\
</div>\ </div>\
</div>\ </div>\
<div class="tracklist"><ul></ul></div>\ <div class="tracklist"><ul></ul></div>\

View File

@ -16,6 +16,8 @@ Session = (function() {
} }
Session.prototype.setUser = function(user) { Session.prototype.setUser = function(user) {
this.user = user; this.user = user;
_beathaven.lang = this.user.lang;
_beathaven.localizeHTML();
return false; return false;
}; };
Session.prototype.getUser = function() { Session.prototype.getUser = function() {

View File

@ -13,6 +13,7 @@ Settings = (function() {
if (form === 'account') { if (form === 'account') {
$('.settings-container .form input[name$="username"]').val(_session.getUser().name); $('.settings-container .form input[name$="username"]').val(_session.getUser().name);
$('.settings-container .form input[name$="email"]').val(_session.getUser().email); $('.settings-container .form input[name$="email"]').val(_session.getUser().email);
$('.settings-container .form select').val(_session.getUser().lang);
} else if (form === 'lastfm') { } else if (form === 'lastfm') {
if (_session.getUser().lastfm_username) { if (_session.getUser().lastfm_username) {
$('.form-container input[name$="username"]').first().val(_session.getUser().lastfm_username); $('.form-container input[name$="username"]').first().val(_session.getUser().lastfm_username);
@ -51,15 +52,25 @@ $('.lastfm-connect').live('click', function() {
setTimeout(_settings.updateLastfmLogin, 100); setTimeout(_settings.updateLastfmLogin, 100);
return false; return false;
}); });
$('.settings-container .form input').live('blur', function() { $('.settings-container .form input, .settings-container .form select').live('blur', function() {
var active_tab, params; var active_tab, lang_changed, params;
active_tab = $('.settings-container .tabs .tab.active').attr('data-fieldset'); active_tab = $('.settings-container .tabs .tab.active').attr('data-fieldset');
if (active_tab === 'account') { if (active_tab === 'account') {
params = { params = {
username: $('.settings-container .form input[name$="username"]').first().val(), username: $('.settings-container .form input[name$="username"]').first().val(),
email: $('.settings-container .form input[name$="email"]').first().val() email: $('.settings-container .form input[name$="email"]').first().val(),
lang: $('.settings-container .form select').first().val()
}; };
lang_changed = params.lang !== _session.getUser().lang;
if (lang_changed) {
if (!confirm(_beathaven.ls('WINDOW_LANG_RELOAD', params.lang))) {
$('.settings-container .form select').val(_session.getUser().lang);
}
}
_settings.saveAccountInfo(params, function() { _settings.saveAccountInfo(params, function() {
if (lang_changed) {
window.location.reload();
}
$('.header-container .hello .greating span').text((params.username.length > 0 ? params.username : '%username%')); $('.header-container .hello .greating span').text((params.username.length > 0 ? params.username : '%username%'));
return false; return false;
}); });

View File

@ -19,14 +19,14 @@ Vkontakte = (function() {
}); });
}; };
return setTimeout(function() { return setTimeout(function() {
return $('#vk_api_transport').append('<script async="async" src="http://vkontakte.ru/js/api/openapi.js"></script>'); return $('#vk_api_transport').append('<script async="async" type="text/javascript" src="http://vkontakte.ru/js/api/openapi.js"></script>');
}, 0); }, 0);
}; };
Vkontakte.prototype.authInfo = function(response) { Vkontakte.prototype.authInfo = function(response) {
var _session; var _session;
if (typeof response !== 'undefined' && response.session) { if (typeof response !== 'undefined' && response.session) {
_session = new Session(response.session); _session = new Session(response.session);
$('#vk_login, .auth_notice').hide(); $('#vk_login, .auth-notice').hide();
$('#vk_logout').css({ $('#vk_logout').css({
display: 'block' display: 'block'
}); });
@ -42,7 +42,7 @@ Vkontakte = (function() {
name: r.response name: r.response
}, function(ar2) { }, function(ar2) {
_session.setUser(ar2.user); _session.setUser(ar2.user);
$('.header-container .hello .greating').html('Tēnā koe, <span class="settings">' + (_session.getUser().name ? _session.getUser().name : '%username%') + '</span>!'); $('.header-container .hello .greating').html(_beathaven.ls('HELLO') + ', <span class="settings">' + (_session.getUser().name ? _session.getUser().name : '%username%') + '</span>!');
window._session = _session; window._session = _session;
_ajax.detectPage(); _ajax.detectPage();
return $('.fullscreen').hide(); return $('.fullscreen').hide();
@ -52,7 +52,7 @@ Vkontakte = (function() {
_session.setUser(ar.user); _session.setUser(ar.user);
} }
$('.header-container .hello').show(); $('.header-container .hello').show();
$('.header-container .hello .greating').html('Tēnā koe, <span class="settings">' + (_session.getUser().name ? _session.getUser().name : '%username%') + '</span>!'); $('.header-container .hello .greating').html(_beathaven.ls('HELLO') + ', <span class="settings">' + (_session.getUser().name ? _session.getUser().name : '%username%') + '</span>!');
window._session = _session; window._session = _session;
_ajax.detectPage(); _ajax.detectPage();
return $('.fullscreen').hide(); return $('.fullscreen').hide();
@ -66,9 +66,10 @@ Vkontakte = (function() {
} else { } else {
_session = new Session({}); _session = new Session({});
_session.setUser({}); _session.setUser({});
$('#vk_login, .auth_notice').css({ $('#vk_login').css({
display: 'block' display: 'block'
}); });
$('.auth-notice').css('left', $('#vk_login').offset().left).show();
$('.header-container .hello').hide(); $('.header-container .hello').hide();
window._session = _session; window._session = _session;
_ajax.detectPage(); _ajax.detectPage();
@ -152,7 +153,7 @@ Vkontakte = (function() {
}; };
return Vkontakte; return Vkontakte;
})(); })();
$('#vk_login').live('click', function() { $('#vk_login, .auth-notice').live('click', function() {
VK.Auth.login(function(response) { VK.Auth.login(function(response) {
_vkontakte.authInfo(response); _vkontakte.authInfo(response);
return false; return false;

View File

@ -45,6 +45,10 @@
border-color: #eaa0a0; border-color: #eaa0a0;
box-shadow: #da9090 1px 1px 0px; box-shadow: #da9090 1px 1px 0px;
} }
&.big {
font-size: 22px;
}
} }
/* Scrollbars */ /* Scrollbars */
@ -129,20 +133,22 @@
clear: both; clear: both;
} }
.auth_notice { .auth-notice {
display: none; display: none;
position: absolute; position: absolute;
background-color: #07F; background-color: #60a0ff;
color: #FFF; color: #ffffff;
top: 32px; top: 32px;
left: 280px; left: 290px;
padding: 8px; line-height: 35px;
border: #05D 1px solid; padding-right: 10px;
border: #4080dd 1px solid;
@include rounded(3); @include rounded(3);
cursor: pointer;
.arrow { .arrow {
float: left; float: left;
margin: -8px 15px 0 8px; margin: -5px 10px 0 10px;
font-size: 25px; font-size: 25px;
font-weight: bold; font-weight: bold;
} }

View File

@ -12,15 +12,6 @@
border: #CCC 1px solid; border: #CCC 1px solid;
@include rounded(3); @include rounded(3);
} }
#search_button {
width: 100px;
font-size: 24px;
padding: 4px;
background-color: #DDD;
border: #CCC 1px solid;
@include rounded(3);
}
} }
.spinner { .spinner {

View File

@ -80,22 +80,26 @@
input[type="text"]{ input[type="text"]{
font-size: 24px; font-size: 24px;
padding: 4px; padding: 4px;
background-color: #ffffff;
color: #202020;
border: #CCC 1px solid; border: #CCC 1px solid;
@include rounded(3); @include rounded(3);
width: 300px; width: 300px;
} }
select {
font-size: 24px;
background-color: #ffffff;
color: #202020;
border: #CCC 1px solid;
width: 310px;
height: 38px;
}
} }
.action-button { .action-button {
input[type="button"]{ float: left;
width: 120px; margin: 6px 0 0 5px;
font-size: 24px;
padding: 4px;
background-color: #DDD;
border: #CCC 1px solid;
@include rounded(3);
margin-left: 5px;
}
} }
.saved { .saved {

View File

@ -37,6 +37,8 @@
text-shadow: #c08080 0px 1px 1px; text-shadow: #c08080 0px 1px 1px;
border-color: #eaa0a0; border-color: #eaa0a0;
box-shadow: #da9090 1px 1px 0px; } box-shadow: #da9090 1px 1px 0px; }
.button.big {
font-size: 22px; }
/* Scrollbars */ /* Scrollbars */
.data-container .scrollbar-pane { .data-container .scrollbar-pane {
@ -86,20 +88,22 @@
height: 30px; height: 30px;
clear: both; } clear: both; }
.auth_notice { .auth-notice {
display: none; display: none;
position: absolute; position: absolute;
background-color: #07F; background-color: #60a0ff;
color: #FFF; color: #ffffff;
top: 32px; top: 32px;
left: 280px; left: 290px;
padding: 8px; line-height: 35px;
border: #05D 1px solid; padding-right: 10px;
border: #4080dd 1px solid;
border-radius: 3px; border-radius: 3px;
-moz-border-radius: 3px; -moz-border-radius: 3px;
-webkit-border-radius: 3px; } -webkit-border-radius: 3px;
.auth_notice .arrow { cursor: pointer; }
.auth-notice .arrow {
float: left; float: left;
margin: -8px 15px 0 8px; margin: -5px 10px 0 10px;
font-size: 25px; font-size: 25px;
font-weight: bold; } font-weight: bold; }

View File

@ -9,15 +9,6 @@
border-radius: 3px; border-radius: 3px;
-moz-border-radius: 3px; -moz-border-radius: 3px;
-webkit-border-radius: 3px; } -webkit-border-radius: 3px; }
.search-container #search_form #search_button {
width: 100px;
font-size: 24px;
padding: 4px;
background-color: #DDD;
border: #CCC 1px solid;
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px; }
.search-container .spinner { .search-container .spinner {
display: none; display: none;
margin: 20px 0 0 175px; } margin: 20px 0 0 175px; }

View File

@ -63,21 +63,23 @@
.settings-container .form-container .form .field .value input[type="text"] { .settings-container .form-container .form .field .value input[type="text"] {
font-size: 24px; font-size: 24px;
padding: 4px; padding: 4px;
background-color: #ffffff;
color: #202020;
border: #CCC 1px solid; border: #CCC 1px solid;
border-radius: 3px; border-radius: 3px;
-moz-border-radius: 3px; -moz-border-radius: 3px;
-webkit-border-radius: 3px; -webkit-border-radius: 3px;
width: 300px; } width: 300px; }
.settings-container .form-container .form .field .action-button input[type="button"] { .settings-container .form-container .form .field .value select {
width: 120px;
font-size: 24px; font-size: 24px;
padding: 4px; background-color: #ffffff;
background-color: #DDD; color: #202020;
border: #CCC 1px solid; border: #CCC 1px solid;
border-radius: 3px; width: 310px;
-moz-border-radius: 3px; height: 38px; }
-webkit-border-radius: 3px; .settings-container .form-container .form .field .action-button {
margin-left: 5px; } float: left;
margin: 6px 0 0 5px; }
.settings-container .form-container .form .field .saved { .settings-container .form-container .form .field .saved {
float: left; } float: left; }
.settings-container .form-container .logout { .settings-container .form-container .logout {

View File

@ -1,14 +1,14 @@
<div class="search-container"> <div class="search-container">
<form action="" method="post" id="search_form"> <form action="" method="post" id="search_form">
<input type="text" id="search_field"/> <input type="text" id="search_field"/>
<input type="submit" value="Search" id="search_button"/> <input type="submit" value="" id="search_button" class="button gray big" data-ls="SEARCH"/>
</form> </form>
<img class="spinner" src="/images/loader.gif" alt=""/> <img class="spinner" src="/images/loader.gif" alt=""/>
<div class="artist_loading failed">Something very bad happened while we tried out to load some info about this artist. How about some other one?</div> <div class="artist_loading failed" data-ls="ARTIST_LOADING_FAILED"></div>
<div class="artist_loading ok">Artist info is loading for the first time now. Usually it takes less than a minute, please wait a bit.</div> <div class="artist_loading ok" data-ls="ARTIST_LOADING_IN_PROCESS"></div>
<div class="artist_pics"></div> <div class="artist_pics"></div>
<div class="suggestions"> <div class="suggestions">
<div>Misspelled?</div> <div data-ls="MISSPELLED"></div>
<ul></ul> <ul></ul>
</div> </div>
</div> </div>

View File

@ -1,37 +1,46 @@
<div class="settings-container"> <div class="settings-container">
<div class="tabs"> <div class="tabs">
<div class="left-space"></div> <div class="left-space"></div>
<div class="tab" data-fieldset="account">Account</div> <div class="tab" data-fieldset="account" data-ls="SETTINGS_ACCOUNT"></div>
<div class="middle-space"></div> <div class="middle-space"></div>
<div class="tab" data-fieldset="lastfm">Last.fm</div> <div class="tab" data-fieldset="lastfm" data-ls="SETTINGS_LASTFM"></div>
</div> </div>
<div class="form-container"></div> <div class="form-container"></div>
<div class="forms"> <div class="forms">
<div class="account"> <div class="account">
<div class="form"> <div class="form">
<div class="field"> <div class="field">
<div class="label">Username:</div> <div class="label" data-ls="USERNAME"></div>
<div class="value"><input name="username" type="text"/></div> <div class="value"><input name="username" type="text"/></div>
</div> </div>
<div class="field"> <div class="field">
<div class="label">Email:</div> <div class="label" data-ls="EMAIL"></div>
<div class="value"><input name="email" type="text"/></div> <div class="value"><input name="email" type="text"/></div>
</div> </div>
<div class="field">
<div class="label" data-ls="LANG"></div>
<div class="value">
<select name="lang">
<option value="ru">Русский</option>
<option value="en">English</option>
</select>
</div>
</div>
<div class="save"> <div class="save">
<div class="button gray">Hello, my name is Useless Button</div> <div class="button gray" data-ls="USELESS_BUTTON"></div>
</div> </div>
</div> </div>
<div class="logout"> <div class="logout">
<div class="button red" id="vk_logout">Log out</div> <div class="button red" id="vk_logout" data-ls="LOGOUT"></div>
</div> </div>
</div> </div>
<div class="lastfm"> <div class="lastfm">
<div class="form"> <div class="form">
<div class="field"> <div class="field">
<div class="label">Username:</div> <div class="label" data-ls="USERNAME"></div>
<div class="value"><input name="username" type="text" disabled="disabled" readonly="readonly" value="Not connected" /></div> <div class="value"><input name="username" type="text" disabled="disabled" readonly="readonly" value="" data-ls="NOT_CONNECTED" /></div>
<div class="action-button"><input type="button" class="lastfm-connect" value="Connect"/></div> <div class="action-button"><div class="lastfm-connect button gray big" data-ls="CONNECT"></div></div>
</div> </div>
</div> </div>
</div> </div>