social_stream 0.9.2 → 0.9.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/base/app/assets/images/arrow-end.png +0 -0
- data/base/app/assets/images/arrow-start.png +0 -0
- data/base/app/assets/images/arrow.png +0 -0
- data/base/app/assets/javascripts/layouts.js +0 -1
- data/base/app/assets/stylesheets/frontpage.css +2 -2
- data/base/app/assets/stylesheets/location.css +36 -0
- data/base/app/helpers/location_helper.rb +3 -5
- data/base/app/helpers/toolbar_helper.rb +5 -6
- data/base/app/views/avatars/index.html.erb +2 -2
- data/base/app/views/contacts/edit.html.erb +2 -2
- data/base/app/views/conversations/_show.html.erb +2 -2
- data/base/app/views/conversations/index.html.erb +1 -3
- data/base/app/views/devise/registrations/edit.html.erb +1 -1
- data/base/app/views/frontpage/_header.html.erb +1 -1
- data/base/app/views/home/index.html.erb +1 -2
- data/base/app/views/invitation_mailer/send_invitation.html.erb +1 -1
- data/base/app/views/invitation_mailer/send_invitation.text.erb +2 -2
- data/base/app/views/invitations/new.html.erb +1 -1
- data/base/app/views/layouts/_footer.html.erb +1 -1
- data/base/app/views/layouts/_header.erb +1 -1
- data/base/app/views/layouts/application.html.erb +1 -1
- data/base/app/views/layouts/frontpage.html.erb +1 -1
- data/base/app/views/location/_location_body.html.erb +18 -0
- data/base/app/views/message_mailer/new_message_email.html.erb +2 -2
- data/base/app/views/message_mailer/new_message_email.text.erb +1 -1
- data/base/app/views/message_mailer/reply_message_email.html.erb +2 -2
- data/base/app/views/message_mailer/reply_message_email.text.erb +1 -1
- data/base/app/views/messages/new.html.erb +2 -2
- data/base/app/views/profiles/edit.html.erb +6 -6
- data/base/app/views/profiles/show.html.erb +1 -2
- data/base/app/views/users/index.html.erb +1 -1
- data/base/app/views/users/show.html.erb +1 -2
- data/base/config/locales/en.yml +7 -6
- data/base/lib/social_stream-base.rb +4 -1
- data/base/lib/social_stream/base.rb +6 -0
- data/base/lib/social_stream/base/version.rb +1 -1
- data/base/lib/social_stream/toolbar_config/base.rb +87 -0
- data/base/lib/tasks/workers.rake +163 -0
- data/documents/app/assets/stylesheets/documents.css +5 -0
- data/documents/app/models/audio.rb +2 -7
- data/documents/app/models/video.rb +2 -7
- data/documents/app/views/audios/_audio.html.erb +7 -42
- data/documents/app/views/audios/_audio_processed.html.erb +47 -0
- data/documents/app/views/audios/_audio_processing.html.erb +7 -0
- data/documents/app/views/common-documents/_index.html.erb +3 -3
- data/documents/app/views/videos/_video.html.erb +5 -46
- data/documents/app/views/videos/_video_processed.html.erb +49 -0
- data/documents/app/views/videos/_video_processing.html.erb +7 -0
- data/documents/config/locales/en.yml +2 -0
- data/documents/db/migrate/20110922173707_add_file_processing_to_document.rb +9 -0
- data/documents/lib/social_stream-documents.rb +5 -0
- data/documents/lib/social_stream/documents/engine.rb +5 -0
- data/documents/lib/social_stream/toolbar_config/documents.rb +40 -0
- data/documents/social_stream-documents.gemspec +2 -0
- data/events/lib/social_stream-events.rb +6 -1
- data/events/lib/social_stream/events/engine.rb +5 -2
- data/events/lib/social_stream/toolbar_config/events.rb +40 -0
- data/lib/social_stream/version.rb +1 -1
- data/social_stream.gemspec +1 -1
- data/social_stream.thor +110 -0
- metadata +22 -33
- data/base/lib/social_stream/toolbar_config.rb +0 -99
- data/events/app/views/users/index.html.erb +0 -46
- data/spec/dummy/documents/pictures/000/000/009/original.png +0 -0
- data/spec/dummy/documents/pictures/000/000/009/thumb.png +0 -0
- data/spec/dummy/documents/pictures/000/000/009/thumb0.png +0 -0
- data/spec/dummy/documents/pictures/000/000/010/original.png +0 -0
- data/spec/dummy/documents/pictures/000/000/010/thumb.png +0 -0
- data/spec/dummy/documents/pictures/000/000/010/thumb0.png +0 -0
- data/spec/dummy/documents/pictures/000/000/011/original.png +0 -0
- data/spec/dummy/documents/pictures/000/000/011/thumb.png +0 -0
- data/spec/dummy/documents/pictures/000/000/011/thumb0.png +0 -0
- data/spec/dummy/documents/pictures/000/000/012/original.png +0 -0
- data/spec/dummy/documents/pictures/000/000/012/thumb.png +0 -0
- data/spec/dummy/documents/pictures/000/000/012/thumb0.png +0 -0
- data/spec/dummy/documents/pictures/000/000/013/original.png +0 -0
- data/spec/dummy/documents/pictures/000/000/013/thumb.png +0 -0
- data/spec/dummy/documents/pictures/000/000/013/thumb0.png +0 -0
- data/spec/dummy/documents/pictures/000/000/014/original.png +0 -0
- data/spec/dummy/documents/pictures/000/000/014/thumb.png +0 -0
- data/spec/dummy/documents/pictures/000/000/014/thumb0.png +0 -0
- data/spec/dummy/documents/pictures/000/000/015/original.png +0 -0
- data/spec/dummy/documents/pictures/000/000/015/thumb.png +0 -0
- data/spec/dummy/documents/pictures/000/000/015/thumb0.png +0 -0
- data/spec/dummy/documents/pictures/000/000/016/original.png +0 -0
- data/spec/dummy/documents/pictures/000/000/016/thumb.png +0 -0
- data/spec/dummy/documents/pictures/000/000/016/thumb0.png +0 -0
@@ -45,7 +45,6 @@ module SocialStream
|
|
45
45
|
autoload :Populate, 'social_stream/populate'
|
46
46
|
autoload :Relations, 'social_stream/relations'
|
47
47
|
autoload :TestHelpers, 'social_stream/test_helpers'
|
48
|
-
autoload :ToolbarConfig, 'social_stream/toolbar_config'
|
49
48
|
|
50
49
|
module Controllers
|
51
50
|
autoload :Helpers, 'social_stream/controllers/helpers'
|
@@ -61,6 +60,10 @@ module SocialStream
|
|
61
60
|
autoload :Controllers, 'social_stream/test_helpers/controllers'
|
62
61
|
end
|
63
62
|
|
63
|
+
module ToolbarConfig
|
64
|
+
autoload :Base, 'social_stream/toolbar_config/base'
|
65
|
+
end
|
66
|
+
|
64
67
|
mattr_accessor :subjects
|
65
68
|
@@subjects = [ :user, :group ]
|
66
69
|
|
@@ -24,6 +24,12 @@ module SocialStream
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
initializer "social_stream-base.toolbar_config" do
|
28
|
+
SocialStream::ToolbarConfig.module_eval do
|
29
|
+
include SocialStream::ToolbarConfig::Base
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
27
33
|
initializer "social_stream-base.avatars_for_rails" do
|
28
34
|
AvatarsForRails.setup do |config|
|
29
35
|
config.avatarable_model = :actor
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module SocialStream
|
2
|
+
module ToolbarConfig
|
3
|
+
module Base
|
4
|
+
# Base toolbar items
|
5
|
+
def home_toolbar_items
|
6
|
+
Array.new.tap do |items|
|
7
|
+
# Messages
|
8
|
+
items << {
|
9
|
+
:key => :messages,
|
10
|
+
:name => image_tag("btn/new.png")+t('message.other')+' (' + current_subject.mailbox.inbox(:unread => true).count.to_s + ')',
|
11
|
+
:url => "#",
|
12
|
+
:options => {:link => {:id => "messages_menu"}},
|
13
|
+
:items => [
|
14
|
+
{ :key => :message_new,
|
15
|
+
:name => image_tag("btn/message_new.png")+ t('message.new'),
|
16
|
+
:url => new_message_path,
|
17
|
+
:options => {:link =>{:remote=> false}}},
|
18
|
+
{ :key => :message_inbox,
|
19
|
+
:name => image_tag("btn/message_inbox.png")+t('message.inbox')+' (' + current_subject.mailbox.inbox(:unread => true).count.to_s + ')',
|
20
|
+
:url => conversations_path,
|
21
|
+
:options => {:link =>{:remote=> false}}},
|
22
|
+
{ :key => :message_sentbox,
|
23
|
+
:name => image_tag("btn/message_sentbox.png")+t('message.sentbox'),
|
24
|
+
:url => conversations_path(:box => :sentbox),
|
25
|
+
:options => {:link =>{:remote=> false}}},
|
26
|
+
{ :key => :message_trash,
|
27
|
+
:name => image_tag("btn/message_trash.png")+t('message.trash'),
|
28
|
+
:url => conversations_path(:box => :trash)}
|
29
|
+
]
|
30
|
+
}
|
31
|
+
|
32
|
+
#Contacts
|
33
|
+
items << {
|
34
|
+
:key => :contacts,
|
35
|
+
:name => image_tag("btn/btn_friend.png")+t('contact.other'),
|
36
|
+
:url => "#",
|
37
|
+
:options => {:link => {:id => "contacts_menu"}},
|
38
|
+
:items => [
|
39
|
+
{:key => :invitations, :name => image_tag("btn/btn_friend.png")+t('contact.current'), :url => contacts_path},
|
40
|
+
{:key => :contacts_graph, :name => image_tag("btn/btn_friend.png")+t('contact.graph.one'), :url => ties_path},
|
41
|
+
{:key => :invitations, :name => image_tag("btn/btn_friend.png")+t('contact.pending.other'), :url => contacts_path(:pending=>true)},
|
42
|
+
{:key => :invitations, :name => image_tag("btn/btn_invitation.png")+t('invitation.toolbar'), :url => new_invitation_path}
|
43
|
+
]
|
44
|
+
}
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Builds the default profile toolbar items
|
49
|
+
def profile_toolbar_items(subject = current_subject)
|
50
|
+
Array.new.tap do |items|
|
51
|
+
#Information button
|
52
|
+
items << {
|
53
|
+
:key => :subject_info,
|
54
|
+
:name => image_tag("btn/btn_edit.png")+t('menu.information'),
|
55
|
+
:url => [subject, :profile]
|
56
|
+
}
|
57
|
+
|
58
|
+
if subject != current_subject
|
59
|
+
#Like button
|
60
|
+
items << {
|
61
|
+
:key => :like_button,
|
62
|
+
:name => link_like_params(subject)[0],
|
63
|
+
:url => link_like_params(subject)[1],
|
64
|
+
:options => {:link => link_like_params(subject)[2]}
|
65
|
+
}
|
66
|
+
|
67
|
+
if user_signed_in?
|
68
|
+
#Relation button
|
69
|
+
items << {
|
70
|
+
:key => :subject_relation,
|
71
|
+
:name => image_tag("btn/btn_friend.png") + current_subject.contact_to!(subject).status,
|
72
|
+
:url => edit_contact_path(current_subject.contact_to!(subject))
|
73
|
+
}
|
74
|
+
|
75
|
+
#Send message button
|
76
|
+
items << {:key => :send_message,
|
77
|
+
:name => image_tag("btn/btn_send.png")+t('message.send'),
|
78
|
+
:url => new_message_path(:receiver => subject.slug)
|
79
|
+
}
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
@@ -0,0 +1,163 @@
|
|
1
|
+
# Rake task to launch multiple Resque workers in development/production with simple management included
|
2
|
+
|
3
|
+
require 'resque/tasks' # Require Resque tasks
|
4
|
+
|
5
|
+
namespace :workers do
|
6
|
+
|
7
|
+
# = $ rake workers:start
|
8
|
+
#
|
9
|
+
# Launch multiple Resque workers with the Rails environment loaded,
|
10
|
+
# so they have access to your models, etc.
|
11
|
+
#
|
12
|
+
# Each worker is being run in their own separate process (_not_ thread).
|
13
|
+
#
|
14
|
+
# On clean shutdown (SIGINT / Ctrl-C, SIGQUIT, SIGTERM), the task will clean
|
15
|
+
# after itself: kill its workers and delete PID files, when appropriate. It
|
16
|
+
# will deal fine with already dead workers.
|
17
|
+
#
|
18
|
+
#
|
19
|
+
# Default options like COUNT can and should be over-ridden when invoking, of course:
|
20
|
+
#
|
21
|
+
# $ rake workers:start COUNT=10 QUEUE=my_queue
|
22
|
+
#
|
23
|
+
#
|
24
|
+
# To daemonize, simply run with nohup:
|
25
|
+
#
|
26
|
+
# $ nohup rake workers:start > log/workers.log 2>&1 &
|
27
|
+
#
|
28
|
+
#
|
29
|
+
# You can and should set up your monitoring tool to watch for process with PID
|
30
|
+
# from `cat tmp/pids/resque/master.pid`.
|
31
|
+
#
|
32
|
+
# For proper monitoring of _individual_ workers, use provided examples for God or Monit:
|
33
|
+
# http://github.com/defunkt/resque/blob/master/examples/.
|
34
|
+
#
|
35
|
+
#
|
36
|
+
# A task for killing all workers on the machine (`rake workers:killall`) is also provided,
|
37
|
+
# for pruning orphaned workers etc.
|
38
|
+
#
|
39
|
+
desc "Run and manage group of Resque workers with some default options"
|
40
|
+
task :start => :environment do
|
41
|
+
|
42
|
+
# - CONFIGURATION ----
|
43
|
+
ENV['QUEUE'] ||= '*'
|
44
|
+
ENV['COUNT'] ||= '3'
|
45
|
+
# --------------------
|
46
|
+
|
47
|
+
def queue
|
48
|
+
ENV['QUEUE']
|
49
|
+
end
|
50
|
+
|
51
|
+
def count
|
52
|
+
ENV['COUNT']
|
53
|
+
end
|
54
|
+
|
55
|
+
def Process.exists?(pid)
|
56
|
+
kill(0, pid.to_i) rescue false
|
57
|
+
end
|
58
|
+
|
59
|
+
def pid_directory
|
60
|
+
@pid_directory ||= Rails.root.join('tmp', 'pids', "resque")
|
61
|
+
end
|
62
|
+
|
63
|
+
def pid_directory_for_group
|
64
|
+
@pid_directory_for_group ||= Rails.root.join('tmp', 'pids', "resque", queue)
|
65
|
+
end
|
66
|
+
|
67
|
+
def group_master_pid
|
68
|
+
File.read pid_directory.join("#{queue}.pid").to_s rescue nil
|
69
|
+
end
|
70
|
+
|
71
|
+
def group?
|
72
|
+
!group_master_pid || group_master_pid.to_s == Process.pid.to_s
|
73
|
+
end
|
74
|
+
|
75
|
+
def group_running?
|
76
|
+
Process.exists?(group_master_pid)
|
77
|
+
end
|
78
|
+
|
79
|
+
def kill_worker(pid)
|
80
|
+
Process.kill("QUIT", pid)
|
81
|
+
puts "Killed worker with PID #{pid}"
|
82
|
+
rescue Errno::ESRCH => e
|
83
|
+
puts " STALE worker with PID #{pid}"
|
84
|
+
end
|
85
|
+
|
86
|
+
def kill_workers
|
87
|
+
@pids.each { |pid| kill_worker(pid) }
|
88
|
+
end
|
89
|
+
|
90
|
+
def kill_workers_and_remove_pids_for_group
|
91
|
+
Dir.glob(pid_directory_for_group.join('worker_*.pid').to_s) do |pidfile|
|
92
|
+
begin
|
93
|
+
pid = pidfile[/(\d+)\.pid/, 1].to_i
|
94
|
+
kill_worker(pid)
|
95
|
+
ensure
|
96
|
+
FileUtils.rm pidfile, :force => true
|
97
|
+
end
|
98
|
+
end
|
99
|
+
if group_master_pid
|
100
|
+
FileUtils.rm pid_directory.join("#{queue}.pid").to_s
|
101
|
+
FileUtils.rm_rf pid_directory_for_group.to_s
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def shutdown
|
106
|
+
puts "\n*** Exiting"
|
107
|
+
if group?
|
108
|
+
kill_workers_and_remove_pids_for_group
|
109
|
+
else
|
110
|
+
kill_workers
|
111
|
+
end
|
112
|
+
exit(0)
|
113
|
+
end
|
114
|
+
|
115
|
+
# Clean up after dead group from before -- and become one
|
116
|
+
unless group_running?
|
117
|
+
puts "--- Cleaning up after previous group (PID: #{group_master_pid})"
|
118
|
+
kill_workers_and_remove_pids_for_group
|
119
|
+
end
|
120
|
+
|
121
|
+
# Handle exit
|
122
|
+
trap('INT') { shutdown }
|
123
|
+
trap('QUIT') { shutdown }
|
124
|
+
trap('TERM') { shutdown }
|
125
|
+
trap('KILL') { shutdown }
|
126
|
+
trap('SIGKILL') { shutdown }
|
127
|
+
|
128
|
+
puts "=== Launching #{ENV['COUNT']} worker(s) on '#{ENV['QUEUE']}' queue(s) with PID #{Process.pid}"
|
129
|
+
|
130
|
+
# Launch workers in separate processes, saving their PIDs
|
131
|
+
@pids = []
|
132
|
+
ENV['COUNT'].to_i.times do
|
133
|
+
@pids << Process.fork { Rake::Task['resque:work'].invoke }
|
134
|
+
end
|
135
|
+
|
136
|
+
if group?
|
137
|
+
# Make sure we have directory for pids
|
138
|
+
FileUtils.mkdir_p pid_directory.to_s
|
139
|
+
FileUtils.mkdir_p pid_directory_for_group.to_s
|
140
|
+
# Create PID files for workers
|
141
|
+
File.open( pid_directory.join("#{queue}.pid").to_s, 'w' ) do |f| f.write Process.pid end
|
142
|
+
@pids.each do |pid|
|
143
|
+
File.open( pid_directory_for_group.join("worker_#{pid}.pid").to_s, 'w' ) { |f| f.write pid }
|
144
|
+
end
|
145
|
+
# Stay in foreground, if any of our workers dies, we'll get killed so Monit/God etc can come to the resq^Hcue
|
146
|
+
Process.wait
|
147
|
+
else
|
148
|
+
# Stay in foreground, if any of our workers dies, continue running
|
149
|
+
Process.waitall
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
desc "Kill ALL workers on this machine"
|
154
|
+
task :kilall do
|
155
|
+
require 'resque'
|
156
|
+
Resque::Worker.all.each do |worker|
|
157
|
+
puts "Shutting down worker #{worker}"
|
158
|
+
host, pid, queues = worker.id.split(':')
|
159
|
+
Process.kill("QUIT", pid.to_i)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
@@ -1,16 +1,11 @@
|
|
1
|
-
class Audio < Document
|
2
|
-
after_save :audioprocess
|
3
|
-
|
1
|
+
class Audio < Document
|
4
2
|
has_attached_file :file,
|
5
3
|
:url => '/:class/:id.:extension',
|
6
4
|
:path => ':rails_root/documents/:class/:id_partition/:style.:extension',
|
7
5
|
:styles => {:webma => {:format => 'webm'}
|
8
6
|
},:processors => [:ffmpeg]
|
9
7
|
|
10
|
-
|
11
|
-
Resque.enqueue(Audioencoder, self.id)
|
12
|
-
end
|
13
|
-
|
8
|
+
process_in_background :file
|
14
9
|
|
15
10
|
# Thumbnail file
|
16
11
|
def thumb(size, helper)
|
@@ -1,6 +1,4 @@
|
|
1
|
-
class Video < Document
|
2
|
-
after_save :videoprocess
|
3
|
-
|
1
|
+
class Video < Document
|
4
2
|
has_attached_file :file,
|
5
3
|
:url => '/:class/:id.:extension',
|
6
4
|
:path => ':rails_root/documents/:class/:id_partition/:style.:extension',
|
@@ -10,10 +8,7 @@ class Video < Document
|
|
10
8
|
:thumb0 => {:geometry => "130x80", :format => 'png', :time => 5}
|
11
9
|
},:processors => [:ffmpeg]
|
12
10
|
|
13
|
-
|
14
|
-
Resque.enqueue(Videoencoder, self.id)
|
15
|
-
end
|
16
|
-
|
11
|
+
process_in_background :file
|
17
12
|
|
18
13
|
# Thumbnail file
|
19
14
|
def thumb(size, helper)
|
@@ -16,47 +16,12 @@
|
|
16
16
|
|
17
17
|
<%= div_for audio, :class => 'content_size' do %>
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
<div class="attachment_text">
|
27
|
-
<%= t('audio.msg') %><%= link_to "\""+audio.file_file_name+"\"",
|
28
|
-
{:controller => "documents", :action => "download", :id => audio},
|
29
|
-
:class => "attachment_text_link" %>
|
30
|
-
</div>
|
31
|
-
<div id="jpId<%=audio.id%>" class="jpId_size0"></div>
|
32
|
-
|
33
|
-
<div class="jp-audio">
|
34
|
-
<div class="jp-type-single">
|
35
|
-
<div id="jp_interface_<%=audio.id%>" class="jp-interface">
|
36
|
-
<ul class="jp-controls">
|
37
|
-
<li><a href="#" class="jp-play" tabindex="1">play</a></li>
|
38
|
-
<li><a href="#" class="jp-pause" tabindex="1">pause</a></li>
|
39
|
-
<li><a href="#" class="jp-stop" tabindex="1">stop</a></li>
|
40
|
-
<li><a href="#" class="jp-mute" tabindex="1">mute</a></li>
|
41
|
-
<li><a href="#" class="jp-unmute" tabindex="1">unmute</a></li>
|
42
|
-
</ul>
|
43
|
-
<div class="jp-progress">
|
44
|
-
<div class="jp-seek-bar">
|
45
|
-
<div class="jp-play-bar"></div>
|
46
|
-
</div>
|
47
|
-
</div>
|
48
|
-
<div class="jp-volume-bar">
|
49
|
-
<div class="jp-volume-bar-value"></div>
|
50
|
-
</div>
|
51
|
-
<div class="jp-current-time"></div>
|
52
|
-
<div class="jp-duration"></div>
|
53
|
-
</div>
|
54
|
-
<div id="jp_playlist_<%=audio.id%>" class="jp-playlist">
|
55
|
-
|
56
|
-
</div>
|
57
|
-
</div>
|
58
|
-
</div>
|
59
|
-
|
60
|
-
</div>
|
19
|
+
|
20
|
+
<% if audio.file_processing %>
|
21
|
+
<%= render :partial => 'audios/audio_processing', :locals => {:audio => audio}%>
|
22
|
+
<% else %>
|
23
|
+
<%= render :partial => 'audios/audio_processed', :locals => {:audio => audio}%>
|
24
|
+
<% end %>
|
25
|
+
|
61
26
|
|
62
27
|
<% end %>
|
@@ -0,0 +1,47 @@
|
|
1
|
+
<div class="attachment_thumb">
|
2
|
+
<%= link_to thumb_for(audio, 16),
|
3
|
+
{:controller => "documents", :action => "download", :id => audio},
|
4
|
+
:class => "" %>
|
5
|
+
</div>
|
6
|
+
<div class="attachment_content">
|
7
|
+
<div class="attachment_text">
|
8
|
+
<%= t('audio.msg') %><%= link_to "\""+audio.file_file_name+"\"",
|
9
|
+
{:controller => "documents", :action => "download", :id => audio},
|
10
|
+
:class => "attachment_text_link" %>
|
11
|
+
</div>
|
12
|
+
<div id="jpId<%= audio.id%>" class="jpId_size0"></div>
|
13
|
+
<div class="jp-audio">
|
14
|
+
<div class="jp-type-single">
|
15
|
+
<div id="jp_interface_<%= audio.id%>" class="jp-interface">
|
16
|
+
<ul class="jp-controls">
|
17
|
+
<li>
|
18
|
+
<a href="#" class="jp-play" tabindex="1">play</a>
|
19
|
+
</li>
|
20
|
+
<li>
|
21
|
+
<a href="#" class="jp-pause" tabindex="1">pause</a>
|
22
|
+
</li>
|
23
|
+
<li>
|
24
|
+
<a href="#" class="jp-stop" tabindex="1">stop</a>
|
25
|
+
</li>
|
26
|
+
<li>
|
27
|
+
<a href="#" class="jp-mute" tabindex="1">mute</a>
|
28
|
+
</li>
|
29
|
+
<li>
|
30
|
+
<a href="#" class="jp-unmute" tabindex="1">unmute</a>
|
31
|
+
</li>
|
32
|
+
</ul>
|
33
|
+
<div class="jp-progress">
|
34
|
+
<div class="jp-seek-bar">
|
35
|
+
<div class="jp-play-bar"></div>
|
36
|
+
</div>
|
37
|
+
</div>
|
38
|
+
<div class="jp-volume-bar">
|
39
|
+
<div class="jp-volume-bar-value"></div>
|
40
|
+
</div>
|
41
|
+
<div class="jp-current-time"></div>
|
42
|
+
<div class="jp-duration"></div>
|
43
|
+
</div>
|
44
|
+
<div id="jp_playlist_<%= audio.id%>" class="jp-playlist"></div>
|
45
|
+
</div>
|
46
|
+
</div>
|
47
|
+
</div>
|