sonice 2.0.0 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.jshintrc +3 -0
- data/.rubocop.yml +105 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +42 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +44 -23
- data/README.md +4 -4
- data/Rakefile +2 -1
- data/bin/rake +29 -0
- data/bin/sonice +2 -0
- data/config.ru +2 -1
- data/lib/sonice.rb +3 -2
- data/lib/sonice/app.rb +24 -21
- data/lib/sonice/command_line.rb +4 -2
- data/lib/sonice/noplayer.rb +40 -0
- data/lib/sonice/public/favicon.ico +0 -0
- data/lib/sonice/public/script.js +8 -63
- data/lib/sonice/public/stylesheet.css +44 -44
- data/lib/sonice/version.rb +4 -1
- data/lib/sonice/views/index.erb +81 -0
- data/sonice.gemspec +22 -18
- metadata +33 -42
- data/lib/sonice/views/index.haml +0 -31
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 3663e23a3502f84a181a07d3a65323993980b9b0c97860b138b36e1fbd983f84
|
|
4
|
+
data.tar.gz: 121da492eac569ac3dced778d5e47212445fb35d0f38f265862e34ac4bd47c3d
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: f034dd6cae0e045236effdfb114f6ab75718d6fb3ec9d2d5e5f005c55caabb1f7f9aee664de70693ea5415eefb7a88fe04e27c21da6a98f70a8b585f2aa378ac
|
|
7
|
+
data.tar.gz: f70229248edc86a3ef54fc4b74ebac8dd5225bd9735d36c17618229dc3ca588f2249de18b34dd8a9bd99dd2030305054f3e204e8adf07aa7255ce97068164235
|
data/.jshintrc
ADDED
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
Style/StringLiterals:
|
|
2
|
+
Enabled: false
|
|
3
|
+
|
|
4
|
+
Layout/BeginEndAlignment: # (new in 0.91)
|
|
5
|
+
Enabled: true
|
|
6
|
+
Layout/EmptyLinesAroundAttributeAccessor: # (new in 0.83)
|
|
7
|
+
Enabled: true
|
|
8
|
+
Layout/SpaceAroundMethodCallOperator: # (new in 0.82)
|
|
9
|
+
Enabled: true
|
|
10
|
+
Lint/BinaryOperatorWithIdenticalOperands: # (new in 0.89)
|
|
11
|
+
Enabled: true
|
|
12
|
+
Lint/ConstantDefinitionInBlock: # (new in 0.91)
|
|
13
|
+
Enabled: true
|
|
14
|
+
Lint/DeprecatedOpenSSLConstant: # (new in 0.84)
|
|
15
|
+
Enabled: true
|
|
16
|
+
Lint/DuplicateElsifCondition: # (new in 0.88)
|
|
17
|
+
Enabled: true
|
|
18
|
+
Lint/DuplicateRequire: # (new in 0.90)
|
|
19
|
+
Enabled: true
|
|
20
|
+
Lint/DuplicateRescueException: # (new in 0.89)
|
|
21
|
+
Enabled: true
|
|
22
|
+
Lint/EmptyConditionalBody: # (new in 0.89)
|
|
23
|
+
Enabled: true
|
|
24
|
+
Lint/EmptyFile: # (new in 0.90)
|
|
25
|
+
Enabled: true
|
|
26
|
+
Lint/FloatComparison: # (new in 0.89)
|
|
27
|
+
Enabled: true
|
|
28
|
+
Lint/HashCompareByIdentity: # (new in 0.93)
|
|
29
|
+
Enabled: true
|
|
30
|
+
Lint/IdentityComparison: # (new in 0.91)
|
|
31
|
+
Enabled: true
|
|
32
|
+
Lint/MissingSuper: # (new in 0.89)
|
|
33
|
+
Enabled: true
|
|
34
|
+
Lint/MixedRegexpCaptureTypes: # (new in 0.85)
|
|
35
|
+
Enabled: true
|
|
36
|
+
Lint/OutOfRangeRegexpRef: # (new in 0.89)
|
|
37
|
+
Enabled: true
|
|
38
|
+
Lint/RaiseException: # (new in 0.81)
|
|
39
|
+
Enabled: true
|
|
40
|
+
Lint/RedundantSafeNavigation: # (new in 0.93)
|
|
41
|
+
Enabled: true
|
|
42
|
+
Lint/SelfAssignment: # (new in 0.89)
|
|
43
|
+
Enabled: true
|
|
44
|
+
Lint/StructNewOverride: # (new in 0.81)
|
|
45
|
+
Enabled: true
|
|
46
|
+
Lint/TopLevelReturnWithArgument: # (new in 0.89)
|
|
47
|
+
Enabled: true
|
|
48
|
+
Lint/TrailingCommaInAttributeDeclaration: # (new in 0.90)
|
|
49
|
+
Enabled: true
|
|
50
|
+
Lint/UnreachableLoop: # (new in 0.89)
|
|
51
|
+
Enabled: true
|
|
52
|
+
Lint/UselessMethodDefinition: # (new in 0.90)
|
|
53
|
+
Enabled: true
|
|
54
|
+
Lint/UselessTimes: # (new in 0.91)
|
|
55
|
+
Enabled: true
|
|
56
|
+
Style/AccessorGrouping: # (new in 0.87)
|
|
57
|
+
Enabled: true
|
|
58
|
+
Style/BisectedAttrAccessor: # (new in 0.87)
|
|
59
|
+
Enabled: true
|
|
60
|
+
Style/CaseLikeIf: # (new in 0.88)
|
|
61
|
+
Enabled: true
|
|
62
|
+
Style/ClassEqualityComparison: # (new in 0.93)
|
|
63
|
+
Enabled: true
|
|
64
|
+
Style/CombinableLoops: # (new in 0.90)
|
|
65
|
+
Enabled: true
|
|
66
|
+
Style/ExplicitBlockArgument: # (new in 0.89)
|
|
67
|
+
Enabled: true
|
|
68
|
+
Style/ExponentialNotation: # (new in 0.82)
|
|
69
|
+
Enabled: true
|
|
70
|
+
Style/GlobalStdStream: # (new in 0.89)
|
|
71
|
+
Enabled: true
|
|
72
|
+
Style/HashAsLastArrayItem: # (new in 0.88)
|
|
73
|
+
Enabled: true
|
|
74
|
+
Style/HashEachMethods: # (new in 0.80)
|
|
75
|
+
Enabled: true
|
|
76
|
+
Style/HashLikeCase: # (new in 0.88)
|
|
77
|
+
Enabled: true
|
|
78
|
+
Style/HashTransformKeys: # (new in 0.80)
|
|
79
|
+
Enabled: true
|
|
80
|
+
Style/HashTransformValues: # (new in 0.80)
|
|
81
|
+
Enabled: true
|
|
82
|
+
Style/KeywordParametersOrder: # (new in 0.90)
|
|
83
|
+
Enabled: true
|
|
84
|
+
Style/OptionalBooleanParameter: # (new in 0.89)
|
|
85
|
+
Enabled: true
|
|
86
|
+
Style/RedundantAssignment: # (new in 0.87)
|
|
87
|
+
Enabled: true
|
|
88
|
+
Style/RedundantFetchBlock: # (new in 0.86)
|
|
89
|
+
Enabled: true
|
|
90
|
+
Style/RedundantFileExtensionInRequire: # (new in 0.88)
|
|
91
|
+
Enabled: true
|
|
92
|
+
Style/RedundantRegexpCharacterClass: # (new in 0.85)
|
|
93
|
+
Enabled: true
|
|
94
|
+
Style/RedundantRegexpEscape: # (new in 0.85)
|
|
95
|
+
Enabled: true
|
|
96
|
+
Style/RedundantSelfAssignment: # (new in 0.90)
|
|
97
|
+
Enabled: true
|
|
98
|
+
Style/SingleArgumentDig: # (new in 0.89)
|
|
99
|
+
Enabled: true
|
|
100
|
+
Style/SlicingWithRange: # (new in 0.83)
|
|
101
|
+
Enabled: true
|
|
102
|
+
Style/SoleNestedConditional: # (new in 0.89)
|
|
103
|
+
Enabled: true
|
|
104
|
+
Style/StringConcatenation: # (new in 0.89)
|
|
105
|
+
Enabled: true
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.7.1
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
Changelog
|
|
2
|
+
=========
|
|
3
|
+
|
|
4
|
+
So Nice tries its best to follow Semantic Versioning.
|
|
5
|
+
|
|
6
|
+
## Unreleased
|
|
7
|
+
|
|
8
|
+
## v2.2.1
|
|
9
|
+
|
|
10
|
+
- Remove rake executable in gemspec.
|
|
11
|
+
- Bump anyplayer dependency
|
|
12
|
+
|
|
13
|
+
## v2.2.0
|
|
14
|
+
|
|
15
|
+
Fixes:
|
|
16
|
+
|
|
17
|
+
- Remove background image since LastFM API doesn’t contain images
|
|
18
|
+
|
|
19
|
+
Dependencies:
|
|
20
|
+
|
|
21
|
+
- Bump anyplayer dependency
|
|
22
|
+
- Remove Haml dependency
|
|
23
|
+
- Bump Sinatra dependency
|
|
24
|
+
- Replace Thin by Webrick
|
|
25
|
+
|
|
26
|
+
## v2.1.2
|
|
27
|
+
|
|
28
|
+
Dependencies:
|
|
29
|
+
|
|
30
|
+
- Fix Sinatra upgrade (#22)
|
|
31
|
+
- Fix Thin dependency so as not to break with thin versions > 2
|
|
32
|
+
|
|
33
|
+
## v2.1.1
|
|
34
|
+
|
|
35
|
+
Fixes:
|
|
36
|
+
|
|
37
|
+
- Fix LastFM JavaScript (thanks @datagutt)
|
|
38
|
+
- Fix Thin dependency with Sinatra
|
|
39
|
+
|
|
40
|
+
## v2.1.0 (2013-12-18)
|
|
41
|
+
|
|
42
|
+
First Gem version.
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,40 +1,61 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
sonice (
|
|
5
|
-
anyplayer (
|
|
6
|
-
haml
|
|
4
|
+
sonice (2.2.1)
|
|
5
|
+
anyplayer (>= 1.2.1)
|
|
7
6
|
sinatra
|
|
8
|
-
|
|
7
|
+
webrick
|
|
9
8
|
xml-simple
|
|
10
9
|
|
|
11
10
|
GEM
|
|
12
11
|
remote: http://rubygems.org/
|
|
13
12
|
specs:
|
|
14
|
-
anyplayer (1.1
|
|
13
|
+
anyplayer (1.2.1)
|
|
15
14
|
ruby-mpd (~> 0.3.0)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
ast (2.4.1)
|
|
16
|
+
mustermann (1.1.1)
|
|
17
|
+
ruby2_keywords (~> 0.0.1)
|
|
18
|
+
parallel (1.19.2)
|
|
19
|
+
parser (2.7.2.0)
|
|
20
|
+
ast (~> 2.4.1)
|
|
21
|
+
rack (2.2.3)
|
|
22
|
+
rack-protection (2.1.0)
|
|
22
23
|
rack
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
rainbow (3.0.0)
|
|
25
|
+
rake (13.0.1)
|
|
26
|
+
regexp_parser (1.8.1)
|
|
27
|
+
rexml (3.2.4)
|
|
28
|
+
rubocop (0.93.0)
|
|
29
|
+
parallel (~> 1.10)
|
|
30
|
+
parser (>= 2.7.1.5)
|
|
31
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
32
|
+
regexp_parser (>= 1.8)
|
|
33
|
+
rexml
|
|
34
|
+
rubocop-ast (>= 0.6.0)
|
|
35
|
+
ruby-progressbar (~> 1.7)
|
|
36
|
+
unicode-display_width (>= 1.4.0, < 2.0)
|
|
37
|
+
rubocop-ast (0.7.1)
|
|
38
|
+
parser (>= 2.7.1.5)
|
|
39
|
+
ruby-mpd (0.3.3)
|
|
40
|
+
ruby-progressbar (1.10.1)
|
|
41
|
+
ruby2_keywords (0.0.2)
|
|
42
|
+
sinatra (2.1.0)
|
|
43
|
+
mustermann (~> 1.0)
|
|
44
|
+
rack (~> 2.2)
|
|
45
|
+
rack-protection (= 2.1.0)
|
|
46
|
+
tilt (~> 2.0)
|
|
47
|
+
tilt (2.0.10)
|
|
48
|
+
unicode-display_width (1.7.0)
|
|
49
|
+
webrick (1.7.0)
|
|
50
|
+
xml-simple (1.1.7)
|
|
34
51
|
|
|
35
52
|
PLATFORMS
|
|
36
53
|
ruby
|
|
37
54
|
|
|
38
55
|
DEPENDENCIES
|
|
39
|
-
|
|
56
|
+
rake
|
|
57
|
+
rubocop
|
|
40
58
|
sonice!
|
|
59
|
+
|
|
60
|
+
BUNDLED WITH
|
|
61
|
+
2.1.4
|
data/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
So Nice ♫
|
|
2
2
|
=======
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
>
|
|
4
|
+
[](http://badge.fury.io/rb/sonice)
|
|
5
|
+
|
|
6
|
+
> “Everynight with my star friends, we eat caviar and drink champage”
|
|
7
7
|
|
|
8
8
|
A small Web interface to play, pause, change volume or skip the currently
|
|
9
9
|
playing song in iTunes Mac, iTunes Windows, Spotify Mac, MPD, Rhythmbox, Amarok and XMMS2.
|
|
@@ -14,7 +14,7 @@ playing song in iTunes Mac, iTunes Windows, Spotify Mac, MPD, Rhythmbox, Amarok
|
|
|
14
14
|
Install
|
|
15
15
|
-------
|
|
16
16
|
|
|
17
|
-
Make sure you have Ruby and Rubygems installed. You can then type in a terminal:
|
|
17
|
+
Make sure you have Ruby > 1.9 and Rubygems installed. You can then type in a terminal:
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
20
|
$ gem install sonice
|
data/Rakefile
CHANGED
data/bin/rake
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
#
|
|
5
|
+
# This file was generated by Bundler.
|
|
6
|
+
#
|
|
7
|
+
# The application 'rake' is installed as part of a gem, and
|
|
8
|
+
# this file is here to facilitate running it.
|
|
9
|
+
#
|
|
10
|
+
|
|
11
|
+
require "pathname"
|
|
12
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
|
13
|
+
Pathname.new(__FILE__).realpath)
|
|
14
|
+
|
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
|
16
|
+
|
|
17
|
+
if File.file?(bundle_binstub)
|
|
18
|
+
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
|
19
|
+
load(bundle_binstub)
|
|
20
|
+
else
|
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
require "rubygems"
|
|
27
|
+
require "bundler/setup"
|
|
28
|
+
|
|
29
|
+
load Gem.bin_path("rake", "rake")
|
data/bin/sonice
CHANGED
data/config.ru
CHANGED
data/lib/sonice.rb
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# Standard library
|
|
2
4
|
require 'open-uri'
|
|
3
5
|
|
|
4
6
|
# Gems
|
|
5
7
|
require 'anyplayer'
|
|
6
8
|
require 'sinatra'
|
|
7
|
-
require 'haml'
|
|
8
9
|
require 'xmlsimple' # xml-simple gem
|
|
9
10
|
require 'json'
|
|
10
|
-
require 'thin'
|
|
11
11
|
|
|
12
12
|
# So Nice
|
|
13
|
+
require 'sonice/noplayer'
|
|
13
14
|
require 'sonice/app'
|
data/lib/sonice/app.rb
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Sonice
|
|
4
|
+
# Sinatra application
|
|
2
5
|
class App < Sinatra::Base
|
|
3
6
|
set :port, ENV['SONICE_PORT'] || 3000
|
|
4
7
|
set :controls, ENV['SONICE_CONTROLS'] != '0'
|
|
@@ -7,47 +10,47 @@ module Sonice
|
|
|
7
10
|
|
|
8
11
|
set :logging, true
|
|
9
12
|
set :static, true
|
|
10
|
-
set :public_dir, File.expand_path('
|
|
11
|
-
set :views, File.expand_path('
|
|
12
|
-
set :haml, format: :html5
|
|
13
|
+
set :public_dir, File.expand_path('public', __dir__)
|
|
14
|
+
set :views, File.expand_path('views', __dir__)
|
|
13
15
|
set :protection, except: :frame_options
|
|
16
|
+
set :server, :webrick
|
|
14
17
|
|
|
15
|
-
def
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
abort "Error: no music player launched!" if !player
|
|
20
|
-
puts "Connected to #{player.name}"
|
|
21
|
-
player
|
|
22
|
-
end
|
|
18
|
+
def player_instance
|
|
19
|
+
return @player if @player&.launched?
|
|
20
|
+
|
|
21
|
+
@player = Anyplayer::Selector.new.player || Noplayer.new
|
|
23
22
|
end
|
|
24
23
|
|
|
25
24
|
put '/player' do
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
player = player_instance
|
|
26
|
+
|
|
27
|
+
player.vote if settings.voting && params['vote']
|
|
29
28
|
|
|
30
29
|
if settings.controls
|
|
31
|
-
methods = %w
|
|
30
|
+
methods = %w[playpause prev next voldown volup] & params.keys
|
|
32
31
|
methods.each { |method| player.send(method) }
|
|
33
32
|
end
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
redirect '/'
|
|
37
|
-
end
|
|
34
|
+
redirect "/" unless request.xhr?
|
|
38
35
|
end
|
|
39
36
|
|
|
40
37
|
get '/' do
|
|
38
|
+
player = player_instance
|
|
39
|
+
|
|
41
40
|
@title = player.track
|
|
42
41
|
@artist = player.artist
|
|
43
42
|
@album = player.album
|
|
43
|
+
@connected = player.launched?
|
|
44
|
+
|
|
44
45
|
if request.xhr?
|
|
45
46
|
content_type :json
|
|
46
|
-
{ :
|
|
47
|
+
{ title: @title,
|
|
48
|
+
artist: @artist,
|
|
49
|
+
album: @album,
|
|
50
|
+
connected: @connected }.to_json
|
|
47
51
|
else
|
|
48
|
-
|
|
52
|
+
erb :index
|
|
49
53
|
end
|
|
50
54
|
end
|
|
51
|
-
|
|
52
55
|
end
|
|
53
56
|
end
|
data/lib/sonice/command_line.rb
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "sonice"
|
|
2
4
|
require 'sonice/version'
|
|
3
5
|
|
|
4
6
|
module Sonice
|
|
7
|
+
# Module CommandLine
|
|
5
8
|
module CommandLine
|
|
6
|
-
|
|
9
|
+
module_function
|
|
7
10
|
|
|
8
11
|
def parse(argv)
|
|
9
12
|
case argv
|
|
@@ -19,7 +22,6 @@ module Sonice
|
|
|
19
22
|
puts "Usage: sonice [--version]"
|
|
20
23
|
exit(1)
|
|
21
24
|
end
|
|
22
|
-
|
|
23
25
|
end
|
|
24
26
|
end
|
|
25
27
|
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sonice
|
|
4
|
+
# A null-object that represents a player when none was found.
|
|
5
|
+
class Noplayer < Anyplayer::Player
|
|
6
|
+
def playing?
|
|
7
|
+
false
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def play; end
|
|
11
|
+
|
|
12
|
+
def pause; end
|
|
13
|
+
|
|
14
|
+
def voldown; end
|
|
15
|
+
|
|
16
|
+
def volup; end
|
|
17
|
+
|
|
18
|
+
def volume; end
|
|
19
|
+
|
|
20
|
+
def track
|
|
21
|
+
nil
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def artist
|
|
25
|
+
nil
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def album
|
|
29
|
+
nil
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def launched?
|
|
33
|
+
false
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def name
|
|
37
|
+
"no player"
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
Binary file
|
data/lib/sonice/public/script.js
CHANGED
|
@@ -8,11 +8,6 @@ Array.prototype.random = function() {
|
|
|
8
8
|
|
|
9
9
|
/* jQuery helpers */
|
|
10
10
|
|
|
11
|
-
// Change CSS background image
|
|
12
|
-
$.fn.background = function(bg) {
|
|
13
|
-
return $(this).css('backgroundImage', bg ? 'url('+bg+')' : 'none')
|
|
14
|
-
}
|
|
15
|
-
|
|
16
11
|
// Assigns keyboard keys to elements and adds them to the title attributes
|
|
17
12
|
// Needs the data-keyboard-key attribute on elements and optionally accepts
|
|
18
13
|
// the data-keyboard-name attribute
|
|
@@ -29,47 +24,6 @@ $.fn.keyboardShortcut = function() {
|
|
|
29
24
|
})
|
|
30
25
|
}
|
|
31
26
|
|
|
32
|
-
|
|
33
|
-
/* So nice helpers */
|
|
34
|
-
|
|
35
|
-
// Get a new artist image from Last.fm via jsonp
|
|
36
|
-
// When found calls the `callback` with the image url as the first argument
|
|
37
|
-
function artistImage(artist, callback) {
|
|
38
|
-
// Commented out because Last.fm does not support this URL anymore.
|
|
39
|
-
|
|
40
|
-
// if (!artist)
|
|
41
|
-
// return callback()
|
|
42
|
-
// var cb = function() { callback(cache[artist].random()) },
|
|
43
|
-
// cache = artistImage.cache
|
|
44
|
-
// artist = encodeURI(artist)
|
|
45
|
-
|
|
46
|
-
// // Deliver from cache
|
|
47
|
-
// if (cache.hasOwnProperty(artist)) {
|
|
48
|
-
// // execute the callback asynchronously to minimize codepaths
|
|
49
|
-
// setTimeout(cb, 10)
|
|
50
|
-
// return
|
|
51
|
-
// }
|
|
52
|
-
|
|
53
|
-
// // Load
|
|
54
|
-
// var last_fm_uri = "http://ws.audioscrobbler.com/2.0/?format=json&method=artist.getimages&artist=%s&api_key=5636ca9fea36d0323a76638385aab1f3"
|
|
55
|
-
// $.ajax({
|
|
56
|
-
// url: last_fm_uri.replace('%s', artist),
|
|
57
|
-
// dataType: 'jsonp',
|
|
58
|
-
// success: function(obj) {
|
|
59
|
-
// if (obj.images.image) {
|
|
60
|
-
// cache[artist] = $.map(obj.images.image, function(img) {
|
|
61
|
-
// return img.sizes.size[0]['#text']
|
|
62
|
-
// })
|
|
63
|
-
// cb()
|
|
64
|
-
// } else {
|
|
65
|
-
// callback()
|
|
66
|
-
// }
|
|
67
|
-
// }
|
|
68
|
-
// })
|
|
69
|
-
}
|
|
70
|
-
artistImage.cache = {}
|
|
71
|
-
|
|
72
|
-
|
|
73
27
|
$(function() {
|
|
74
28
|
// Object that contains all the song info
|
|
75
29
|
var currentSong = {}
|
|
@@ -81,12 +35,15 @@ $(function() {
|
|
|
81
35
|
currentSong = obj = obj || {}
|
|
82
36
|
|
|
83
37
|
var artist = obj.artist || '',
|
|
84
|
-
|
|
85
|
-
|
|
38
|
+
album = obj.album || '',
|
|
39
|
+
title = obj.title || '',
|
|
40
|
+
connected = !!obj.connected
|
|
86
41
|
|
|
87
42
|
$('#title' ).text(title)
|
|
88
43
|
$('#artist').text(artist)
|
|
89
44
|
$('#album' ).text(album)
|
|
45
|
+
$('[data-sonice-show-if-connected]')[connected ? 'show' : 'hide']()
|
|
46
|
+
$('[data-sonice-hide-if-connected]')[connected ? 'hide' : 'show']()
|
|
90
47
|
|
|
91
48
|
if (!title)
|
|
92
49
|
$('title').text('So nice')
|
|
@@ -95,16 +52,6 @@ $(function() {
|
|
|
95
52
|
|
|
96
53
|
if (artistChange || songChange)
|
|
97
54
|
$('#vote').removeAttr('disabled').show()
|
|
98
|
-
|
|
99
|
-
if (artistChange)
|
|
100
|
-
changeBackground()
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Change background on the body regularly
|
|
104
|
-
var changeBackground = function(){
|
|
105
|
-
artistImage(currentSong.artist, function(url) {
|
|
106
|
-
$('body').background(url)
|
|
107
|
-
})
|
|
108
55
|
}
|
|
109
56
|
|
|
110
57
|
// XHR updating the text regularly
|
|
@@ -118,7 +65,7 @@ $(function() {
|
|
|
118
65
|
|
|
119
66
|
// XHR overriding the buttons
|
|
120
67
|
$(document).on('click', 'input', function(e) {
|
|
121
|
-
e.preventDefault()
|
|
68
|
+
e.preventDefault()
|
|
122
69
|
|
|
123
70
|
$.ajax({
|
|
124
71
|
type: 'put',
|
|
@@ -133,12 +80,10 @@ $(function() {
|
|
|
133
80
|
$(this).attr('disabled', true).fadeOut(500)
|
|
134
81
|
})
|
|
135
82
|
|
|
136
|
-
update()
|
|
83
|
+
update()
|
|
137
84
|
setInterval(update, 500)
|
|
138
|
-
setInterval(changeBackground, 10000)
|
|
139
85
|
|
|
140
86
|
// Keyboard shortcuts
|
|
141
|
-
$('
|
|
87
|
+
$('[data-key]').keyboardShortcut()
|
|
142
88
|
|
|
143
89
|
})
|
|
144
|
-
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
body {
|
|
2
2
|
padding: 2em;
|
|
3
3
|
margin: 0;
|
|
4
|
-
background-color:
|
|
4
|
+
background-color: #555;
|
|
5
|
+
color: white;
|
|
6
|
+
font: 1.5em Helvetica, sans-serif;
|
|
7
|
+
|
|
8
|
+
/* Prepare for having a background-image */
|
|
5
9
|
background-position: center center fixed no-repeat;
|
|
6
|
-
background-repeat:
|
|
10
|
+
background-repeat: no-repeat;
|
|
7
11
|
background-attachment: fixed;
|
|
8
12
|
background-size: cover;
|
|
9
|
-
color: white;
|
|
10
|
-
font: 1.5em Helvetica, sans-serif;
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
/* Overlay image */
|
|
@@ -31,19 +33,19 @@ h1, h2, h3 {
|
|
|
31
33
|
text-shadow: black 0 0 7px;
|
|
32
34
|
}
|
|
33
35
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
h1 {
|
|
37
|
+
font-size: 230%;
|
|
38
|
+
}
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
h2 {
|
|
41
|
+
font-size: 150%;
|
|
42
|
+
}
|
|
41
43
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
h3 {
|
|
45
|
+
font-size: 100%;
|
|
46
|
+
margin-top: 1ex;
|
|
47
|
+
font-weight: normal;
|
|
48
|
+
}
|
|
47
49
|
|
|
48
50
|
form {
|
|
49
51
|
opacity: .5;
|
|
@@ -52,35 +54,33 @@ form {
|
|
|
52
54
|
left: 42px;
|
|
53
55
|
}
|
|
54
56
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
input {
|
|
60
|
-
font-size: 1em;
|
|
61
|
-
color: inherit;
|
|
62
|
-
text-decoration: none;
|
|
63
|
-
padding: .2em .3em;
|
|
64
|
-
background: #222;
|
|
65
|
-
color: #aaa;
|
|
66
|
-
-webkit-border-radius: .4em;
|
|
67
|
-
-moz-border-radius: .4em;
|
|
68
|
-
-o-border-radius: .4em;
|
|
69
|
-
border-radius: .4em;
|
|
70
|
-
border: .1em solid #222;
|
|
71
|
-
cursor: pointer;
|
|
72
|
-
width: 2em;
|
|
73
|
-
height: 2em;
|
|
74
|
-
|
|
75
|
-
}
|
|
57
|
+
form:hover {
|
|
58
|
+
opacity: 1;
|
|
59
|
+
}
|
|
76
60
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
61
|
+
input {
|
|
62
|
+
font-size: 1em;
|
|
63
|
+
color: inherit;
|
|
64
|
+
text-decoration: none;
|
|
65
|
+
padding: .2em .3em;
|
|
66
|
+
background: #222;
|
|
67
|
+
color: #aaa;
|
|
68
|
+
-webkit-border-radius: .4em;
|
|
69
|
+
-moz-border-radius: .4em;
|
|
70
|
+
-o-border-radius: .4em;
|
|
71
|
+
border-radius: .4em;
|
|
72
|
+
border: .1em solid #222;
|
|
73
|
+
cursor: pointer;
|
|
74
|
+
width: 2em;
|
|
75
|
+
height: 2em;
|
|
76
|
+
}
|
|
80
77
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
}
|
|
78
|
+
input:hover {
|
|
79
|
+
border-color: inherit;
|
|
80
|
+
}
|
|
86
81
|
|
|
82
|
+
@media (max-width:800px) {
|
|
83
|
+
input {
|
|
84
|
+
font-size: 2em;
|
|
85
|
+
}
|
|
86
|
+
}
|
data/lib/sonice/version.rb
CHANGED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>
|
|
5
|
+
<% if !@artist && !@title %>
|
|
6
|
+
So Nice ♫
|
|
7
|
+
<% else %>
|
|
8
|
+
<%= [@artist, @title].compact.join(" — ") %>
|
|
9
|
+
<% end %>
|
|
10
|
+
</title>
|
|
11
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
12
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
13
|
+
<link rel="stylesheet" href="/stylesheet.css" />
|
|
14
|
+
</head>
|
|
15
|
+
<body>
|
|
16
|
+
<h1 id="title"><%= @title %></h1>
|
|
17
|
+
<h2 id="artist"><%= @artist %></h2>
|
|
18
|
+
<h3 id="album"><%= @album %></h3>
|
|
19
|
+
|
|
20
|
+
<h1 style="display:none" data-sonice-hide-if-connected>Connecting…</h1>
|
|
21
|
+
|
|
22
|
+
<form method="post" action="player" data-sonice-show-if-connected>
|
|
23
|
+
<input name="_method" type="hidden" value="put">
|
|
24
|
+
<% if settings.controls %>
|
|
25
|
+
<input
|
|
26
|
+
type="button"
|
|
27
|
+
value="▶"
|
|
28
|
+
id="playpause"
|
|
29
|
+
name="playpause"
|
|
30
|
+
title="Play/Pause"
|
|
31
|
+
data-key-name="space"
|
|
32
|
+
data-key=" "
|
|
33
|
+
/>
|
|
34
|
+
<input
|
|
35
|
+
type="button"
|
|
36
|
+
value="←"
|
|
37
|
+
id="prev"
|
|
38
|
+
name="prev"
|
|
39
|
+
title="Previous"
|
|
40
|
+
data-key="p"
|
|
41
|
+
/>
|
|
42
|
+
<input
|
|
43
|
+
type="button"
|
|
44
|
+
value="→"
|
|
45
|
+
id="next"
|
|
46
|
+
name="next"
|
|
47
|
+
title="Next"
|
|
48
|
+
data-key="n"
|
|
49
|
+
/>
|
|
50
|
+
<input
|
|
51
|
+
type="button"
|
|
52
|
+
value="♪"
|
|
53
|
+
id="voldown"
|
|
54
|
+
name="voldown"
|
|
55
|
+
title="Quieter"
|
|
56
|
+
data-key="-"
|
|
57
|
+
/>
|
|
58
|
+
<input
|
|
59
|
+
type="button"
|
|
60
|
+
value="♫"
|
|
61
|
+
id="volup"
|
|
62
|
+
name="volup"
|
|
63
|
+
title="Louder"
|
|
64
|
+
data-key="+"
|
|
65
|
+
/>
|
|
66
|
+
<% end %>
|
|
67
|
+
<% if settings.voting %>
|
|
68
|
+
<input
|
|
69
|
+
type="button"
|
|
70
|
+
value="↡"
|
|
71
|
+
id="vote"
|
|
72
|
+
name="vote"
|
|
73
|
+
title="Vote to Skip"
|
|
74
|
+
data-key="s"
|
|
75
|
+
/>
|
|
76
|
+
<% end %>
|
|
77
|
+
</form>
|
|
78
|
+
<script src="/jquery.min.js"></script>
|
|
79
|
+
<script src="/script.js"></script>
|
|
80
|
+
</body>
|
|
81
|
+
</html>
|
data/sonice.gemspec
CHANGED
|
@@ -1,27 +1,31 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
$LOAD_PATH.push File.expand_path('lib', __dir__)
|
|
3
4
|
require "sonice/version"
|
|
4
5
|
|
|
5
6
|
Gem::Specification.new do |s|
|
|
6
|
-
s.name
|
|
7
|
-
s.version
|
|
8
|
-
s.platform
|
|
9
|
-
s.authors
|
|
10
|
-
s.email
|
|
11
|
-
s.homepage
|
|
12
|
-
s.summary
|
|
13
|
-
s.description =
|
|
14
|
-
|
|
7
|
+
s.name = "sonice"
|
|
8
|
+
s.version = Sonice::VERSION
|
|
9
|
+
s.platform = Gem::Platform::RUBY
|
|
10
|
+
s.authors = ["Sunny Ripert"]
|
|
11
|
+
s.email = ["sunny@sunfox.org"]
|
|
12
|
+
s.homepage = "http://github.com/sunny/so-nice"
|
|
13
|
+
s.summary = "Web interface to control your current music player"
|
|
14
|
+
s.description =
|
|
15
|
+
"Small Web interface to control iTunes, Spotify, Rdio, MPD, Rhythmbox, " \
|
|
16
|
+
"Amarok and XMMS2. ♫"
|
|
17
|
+
s.license = "WTFPL"
|
|
15
18
|
|
|
16
|
-
s.files = `git ls-files`.split("\n")
|
|
17
|
-
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
18
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
19
19
|
s.require_paths = ["lib"]
|
|
20
|
+
s.files = `git ls-files`.split("\n")
|
|
21
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
22
|
+
s.executables = ["sonice"]
|
|
20
23
|
|
|
21
|
-
s.add_runtime_dependency 'anyplayer', '
|
|
24
|
+
s.add_runtime_dependency 'anyplayer', '>= 1.2.1'
|
|
22
25
|
s.add_runtime_dependency 'sinatra'
|
|
23
|
-
s.add_runtime_dependency '
|
|
26
|
+
s.add_runtime_dependency 'webrick'
|
|
24
27
|
s.add_runtime_dependency 'xml-simple'
|
|
25
|
-
|
|
26
|
-
s.add_development_dependency '
|
|
28
|
+
|
|
29
|
+
s.add_development_dependency 'rake'
|
|
30
|
+
s.add_development_dependency 'rubocop'
|
|
27
31
|
end
|
metadata
CHANGED
|
@@ -1,110 +1,97 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sonice
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
5
|
-
prerelease:
|
|
4
|
+
version: 2.2.1
|
|
6
5
|
platform: ruby
|
|
7
6
|
authors:
|
|
8
7
|
- Sunny Ripert
|
|
9
8
|
autorequire:
|
|
10
9
|
bindir: bin
|
|
11
10
|
cert_chain: []
|
|
12
|
-
date:
|
|
11
|
+
date: 2020-12-19 00:00:00.000000000 Z
|
|
13
12
|
dependencies:
|
|
14
13
|
- !ruby/object:Gem::Dependency
|
|
15
14
|
name: anyplayer
|
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
|
17
|
-
none: false
|
|
18
16
|
requirements:
|
|
19
|
-
- -
|
|
17
|
+
- - ">="
|
|
20
18
|
- !ruby/object:Gem::Version
|
|
21
|
-
version: 1.
|
|
19
|
+
version: 1.2.1
|
|
22
20
|
type: :runtime
|
|
23
21
|
prerelease: false
|
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
-
none: false
|
|
26
23
|
requirements:
|
|
27
|
-
- -
|
|
24
|
+
- - ">="
|
|
28
25
|
- !ruby/object:Gem::Version
|
|
29
|
-
version: 1.
|
|
26
|
+
version: 1.2.1
|
|
30
27
|
- !ruby/object:Gem::Dependency
|
|
31
28
|
name: sinatra
|
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
|
33
|
-
none: false
|
|
34
30
|
requirements:
|
|
35
|
-
- -
|
|
31
|
+
- - ">="
|
|
36
32
|
- !ruby/object:Gem::Version
|
|
37
33
|
version: '0'
|
|
38
34
|
type: :runtime
|
|
39
35
|
prerelease: false
|
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
-
none: false
|
|
42
37
|
requirements:
|
|
43
|
-
- -
|
|
38
|
+
- - ">="
|
|
44
39
|
- !ruby/object:Gem::Version
|
|
45
40
|
version: '0'
|
|
46
41
|
- !ruby/object:Gem::Dependency
|
|
47
|
-
name:
|
|
42
|
+
name: webrick
|
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
|
49
|
-
none: false
|
|
50
44
|
requirements:
|
|
51
|
-
- -
|
|
45
|
+
- - ">="
|
|
52
46
|
- !ruby/object:Gem::Version
|
|
53
47
|
version: '0'
|
|
54
48
|
type: :runtime
|
|
55
49
|
prerelease: false
|
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
-
none: false
|
|
58
51
|
requirements:
|
|
59
|
-
- -
|
|
52
|
+
- - ">="
|
|
60
53
|
- !ruby/object:Gem::Version
|
|
61
54
|
version: '0'
|
|
62
55
|
- !ruby/object:Gem::Dependency
|
|
63
56
|
name: xml-simple
|
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
|
65
|
-
none: false
|
|
66
58
|
requirements:
|
|
67
|
-
- -
|
|
59
|
+
- - ">="
|
|
68
60
|
- !ruby/object:Gem::Version
|
|
69
61
|
version: '0'
|
|
70
62
|
type: :runtime
|
|
71
63
|
prerelease: false
|
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
73
|
-
none: false
|
|
74
65
|
requirements:
|
|
75
|
-
- -
|
|
66
|
+
- - ">="
|
|
76
67
|
- !ruby/object:Gem::Version
|
|
77
68
|
version: '0'
|
|
78
69
|
- !ruby/object:Gem::Dependency
|
|
79
|
-
name:
|
|
70
|
+
name: rake
|
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
|
81
|
-
none: false
|
|
82
72
|
requirements:
|
|
83
|
-
- -
|
|
73
|
+
- - ">="
|
|
84
74
|
- !ruby/object:Gem::Version
|
|
85
75
|
version: '0'
|
|
86
|
-
type: :
|
|
76
|
+
type: :development
|
|
87
77
|
prerelease: false
|
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
89
|
-
none: false
|
|
90
79
|
requirements:
|
|
91
|
-
- -
|
|
80
|
+
- - ">="
|
|
92
81
|
- !ruby/object:Gem::Version
|
|
93
82
|
version: '0'
|
|
94
83
|
- !ruby/object:Gem::Dependency
|
|
95
|
-
name:
|
|
84
|
+
name: rubocop
|
|
96
85
|
requirement: !ruby/object:Gem::Requirement
|
|
97
|
-
none: false
|
|
98
86
|
requirements:
|
|
99
|
-
- -
|
|
87
|
+
- - ">="
|
|
100
88
|
- !ruby/object:Gem::Version
|
|
101
89
|
version: '0'
|
|
102
90
|
type: :development
|
|
103
91
|
prerelease: false
|
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
105
|
-
none: false
|
|
106
93
|
requirements:
|
|
107
|
-
- -
|
|
94
|
+
- - ">="
|
|
108
95
|
- !ruby/object:Gem::Version
|
|
109
96
|
version: '0'
|
|
110
97
|
description: Small Web interface to control iTunes, Spotify, Rdio, MPD, Rhythmbox,
|
|
@@ -116,46 +103,50 @@ executables:
|
|
|
116
103
|
extensions: []
|
|
117
104
|
extra_rdoc_files: []
|
|
118
105
|
files:
|
|
119
|
-
- .gitignore
|
|
106
|
+
- ".gitignore"
|
|
107
|
+
- ".jshintrc"
|
|
108
|
+
- ".rubocop.yml"
|
|
109
|
+
- ".ruby-version"
|
|
110
|
+
- CHANGELOG.md
|
|
120
111
|
- Gemfile
|
|
121
112
|
- Gemfile.lock
|
|
122
113
|
- README.md
|
|
123
114
|
- Rakefile
|
|
115
|
+
- bin/rake
|
|
124
116
|
- bin/sonice
|
|
125
117
|
- config.ru
|
|
126
118
|
- lib/sonice.rb
|
|
127
119
|
- lib/sonice/app.rb
|
|
128
120
|
- lib/sonice/command_line.rb
|
|
121
|
+
- lib/sonice/noplayer.rb
|
|
129
122
|
- lib/sonice/public/favicon.ico
|
|
130
123
|
- lib/sonice/public/jquery.min.js
|
|
131
124
|
- lib/sonice/public/script.js
|
|
132
125
|
- lib/sonice/public/stylesheet.css
|
|
133
126
|
- lib/sonice/version.rb
|
|
134
|
-
- lib/sonice/views/index.
|
|
127
|
+
- lib/sonice/views/index.erb
|
|
135
128
|
- sonice.gemspec
|
|
136
129
|
homepage: http://github.com/sunny/so-nice
|
|
137
130
|
licenses:
|
|
138
131
|
- WTFPL
|
|
132
|
+
metadata: {}
|
|
139
133
|
post_install_message:
|
|
140
134
|
rdoc_options: []
|
|
141
135
|
require_paths:
|
|
142
136
|
- lib
|
|
143
137
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
144
|
-
none: false
|
|
145
138
|
requirements:
|
|
146
|
-
- -
|
|
139
|
+
- - ">="
|
|
147
140
|
- !ruby/object:Gem::Version
|
|
148
141
|
version: '0'
|
|
149
142
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
150
|
-
none: false
|
|
151
143
|
requirements:
|
|
152
|
-
- -
|
|
144
|
+
- - ">="
|
|
153
145
|
- !ruby/object:Gem::Version
|
|
154
146
|
version: '0'
|
|
155
147
|
requirements: []
|
|
156
|
-
|
|
157
|
-
rubygems_version: 1.8.23
|
|
148
|
+
rubygems_version: 3.1.2
|
|
158
149
|
signing_key:
|
|
159
|
-
specification_version:
|
|
150
|
+
specification_version: 4
|
|
160
151
|
summary: Web interface to control your current music player
|
|
161
152
|
test_files: []
|
data/lib/sonice/views/index.haml
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
!!! 5
|
|
2
|
-
%html
|
|
3
|
-
%head
|
|
4
|
-
%title
|
|
5
|
-
- if !@artist && !@title
|
|
6
|
-
So nice
|
|
7
|
-
- else
|
|
8
|
-
= [@artist, @title].compact.join(" — ")
|
|
9
|
-
%meta{'http-equiv' => 'Content-Type', :content => 'text/html; charset=utf-8'}
|
|
10
|
-
%meta{:name => 'viewport', :content => 'width=device-width, initial-scale=1.0' }
|
|
11
|
-
%link{:rel => 'stylesheet', :href => '/stylesheet.css'}
|
|
12
|
-
|
|
13
|
-
%body{:style => @image_uri ? "background-image:url(#{@image_uri})" : nil }
|
|
14
|
-
%h1#title= @title
|
|
15
|
-
%h2#artist= @artist
|
|
16
|
-
%h3#album= @album
|
|
17
|
-
|
|
18
|
-
%form{:method => 'post', :action => 'player'}
|
|
19
|
-
%input{:type => "hidden", :name => "_method", :value => "put"}
|
|
20
|
-
- if settings.controls
|
|
21
|
-
%input#playpause{:type=>'button', :value=>'▸', :name=>'playpause', :title=>"Play/Pause", :'data-key'=>" ", :'data-key-name'=>"space"}
|
|
22
|
-
%input#prev{ :type=>'button', :value=>'←', :name=>'prev', :title=>"Previous", :'data-key'=>"p"}
|
|
23
|
-
%input#next{ :type=>'button', :value=>'→', :name=>'next', :title=>"Next", :'data-key'=>"n"}
|
|
24
|
-
%input#voldown{ :type=>'button', :value=>'♪', :name=>'voldown', :title=>"Quieter", :'data-key'=>"-"}
|
|
25
|
-
%input#volup{ :type=>'button', :value=>'♫', :name=>'volup', :title=>"Louder", :'data-key'=>"+"}
|
|
26
|
-
- if settings.voting
|
|
27
|
-
%input#vote{ :type=>'button', :value=>'↡', :name=>'vote', :title=>"Vote to Skip", :'data-key' => "s" }
|
|
28
|
-
|
|
29
|
-
%script{:src => '/jquery.min.js'}
|
|
30
|
-
%script{:src => '/script.js'}
|
|
31
|
-
|