social_stream-presence 0.7.5 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/app/assets/images/status/chat.png +0 -0
- data/app/assets/javascripts/chat_interface_manager.js.erb +42 -45
- data/app/assets/javascripts/chat_parser.js +5 -5
- data/app/assets/javascripts/chat_utilities.js +15 -11
- data/app/assets/javascripts/chat_window_manager.js +129 -26
- data/app/assets/javascripts/jquery.ui.chatbox.sstreampresence.js +22 -3
- data/app/assets/javascripts/social_stream-presence.js +1 -0
- data/app/assets/javascripts/videochat.js.erb +459 -0
- data/app/assets/javascripts/xmpp_client_management.js.erb +303 -65
- data/app/assets/stylesheets/chat.css.scss +42 -1
- data/app/controllers/xmpp_controller.rb +17 -0
- data/app/views/chat/_index.html.erb +7 -2
- data/app/views/xmpp/getOpenTokSessionIDAndToken.xml.builder +6 -0
- data/config/locales/en.yml +22 -1
- data/config/locales/es.yml +23 -2
- data/config/routes.rb +2 -0
- data/lib/OpenTok/Exceptions.rb +11 -0
- data/lib/OpenTok/OpenTokSDK.rb +184 -0
- data/lib/OpenTok/Session.rb +27 -0
- data/lib/generators/social_stream/presence/templates/initializer.rb +7 -1
- data/lib/open_tok.rb +31 -0
- data/lib/opentok.rb +29 -0
- data/lib/social_stream-presence.rb +4 -0
- data/lib/social_stream/presence/version.rb +1 -1
- data/vendor/assets/javascripts/TB.min.js +4329 -0
- metadata +100 -64
@@ -80,12 +80,48 @@
|
|
80
80
|
div.ui-videobox{
|
81
81
|
height: 0px;
|
82
82
|
border-bottom: 1px solid $separation-color;
|
83
|
+
max-width: 230px;
|
83
84
|
}
|
84
85
|
|
85
86
|
div.ui-videobox-icon{
|
86
87
|
|
87
88
|
}
|
88
89
|
|
90
|
+
div.ui-videobox-icon-change{
|
91
|
+
width: 100px;
|
92
|
+
height: 100px;
|
93
|
+
}
|
94
|
+
|
95
|
+
|
96
|
+
p.video-info{
|
97
|
+
padding-top: 25%;
|
98
|
+
text-align: center;
|
99
|
+
}
|
100
|
+
|
101
|
+
p.video-request{
|
102
|
+
padding-top: 20%;
|
103
|
+
text-align: center;
|
104
|
+
font-size: 130%;
|
105
|
+
font-weight: bolder;
|
106
|
+
color: $main-color;
|
107
|
+
}
|
108
|
+
|
109
|
+
.videoChatButton {
|
110
|
+
cursor: pointer;
|
111
|
+
font-size: 100%;
|
112
|
+
}
|
113
|
+
|
114
|
+
.stream_publish_videochat {
|
115
|
+
z-index: -1;
|
116
|
+
position: absolute;
|
117
|
+
top: 177px;
|
118
|
+
}
|
119
|
+
|
120
|
+
.stream_videochat{
|
121
|
+
width: 60%;
|
122
|
+
height: 60%;
|
123
|
+
}
|
124
|
+
|
89
125
|
/* notifications style sheet */
|
90
126
|
|
91
127
|
div.ui-chatbox-notify{
|
@@ -135,9 +171,14 @@ p.ui-chatbox-notify-text{
|
|
135
171
|
}
|
136
172
|
|
137
173
|
.chat-videothick{
|
138
|
-
display: none;
|
174
|
+
/* display: none; */
|
175
|
+
padding: 1px;
|
139
176
|
}
|
140
177
|
|
178
|
+
.chat-videoPublisherthick{
|
179
|
+
display: none;
|
180
|
+
padding: 0px 9px 0px 9px;
|
181
|
+
}
|
141
182
|
|
142
183
|
/* Presence Partial */
|
143
184
|
|
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'opentok'
|
2
|
+
|
3
|
+
|
1
4
|
class XmppController < ApplicationController
|
2
5
|
|
3
6
|
before_filter :authorization, :only => [:setConnection, :unsetConecction, :setPresence, :unsetPresence, :resetConnection, :synchronizePresence ]
|
@@ -157,6 +160,20 @@ class XmppController < ApplicationController
|
|
157
160
|
end
|
158
161
|
|
159
162
|
|
163
|
+
def getOpenTokSessionIDAndToken
|
164
|
+
if current_user
|
165
|
+
opentok = OpenTok::OpenTokSDK.new SocialStream::Presence.opentok_api_key, SocialStream::Presence.opentok_api_secret
|
166
|
+
@session = opentok.create_session request.remote_addr
|
167
|
+
@user_token = opentok.generate_token :session_id => @session
|
168
|
+
@guest_token = opentok.generate_token :session_id => @session
|
169
|
+
|
170
|
+
respond_to do |format|
|
171
|
+
format.xml
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
|
160
177
|
private
|
161
178
|
|
162
179
|
def setStatus(user,status)
|
@@ -68,6 +68,10 @@
|
|
68
68
|
</div>
|
69
69
|
</div>
|
70
70
|
|
71
|
+
<div>
|
72
|
+
<div id="publisherID"></div>
|
73
|
+
</div>
|
74
|
+
|
71
75
|
</div>
|
72
76
|
|
73
77
|
|
@@ -94,13 +98,14 @@
|
|
94
98
|
connectToChat(user_jid,null,null);
|
95
99
|
}
|
96
100
|
|
97
|
-
initialTimer = setTimeout("updateChatWindow()",
|
101
|
+
initialTimer = setTimeout("updateChatWindow()", 10000);
|
98
102
|
} else {
|
99
|
-
|
103
|
+
updateChatWindow();
|
100
104
|
}
|
101
105
|
|
102
106
|
initAudio();
|
103
107
|
initFocusListeners();
|
108
|
+
checkVideocallFeature();
|
104
109
|
});
|
105
110
|
|
106
111
|
</script>
|
data/config/locales/en.yml
CHANGED
@@ -21,4 +21,25 @@ en:
|
|
21
21
|
update: "Update Settings"
|
22
22
|
notify:
|
23
23
|
offline: "You are offline"
|
24
|
-
guestOffline: "is offline"
|
24
|
+
guestOffline: "{{name}} is offline"
|
25
|
+
videochat:
|
26
|
+
disconnected: Videochat disconnected
|
27
|
+
disconnecting: Videochat disconnecting...
|
28
|
+
negotiating: Negotiating...
|
29
|
+
connectingWait: Connecting...
|
30
|
+
connecting: Connecting to the server...
|
31
|
+
waiting: Waiting for response...
|
32
|
+
establishing: Establishing...
|
33
|
+
connnected: Videochat connected.
|
34
|
+
unable: Unable to init videochat.
|
35
|
+
serverIssue: "Server Error: Invalid response"
|
36
|
+
call: "{{name}} wants to start a video call"
|
37
|
+
rejected: "{{name}} has rejected your call"
|
38
|
+
rejectedBusy: "{{name}} is busy"
|
39
|
+
accept: Accept
|
40
|
+
deny: Deny
|
41
|
+
clientIssue: "{{name}}'s client not support videochat"
|
42
|
+
guestOffline: "Unable to connect. {{name}} is offline"
|
43
|
+
offline: "Unable to connect. You are offline"
|
44
|
+
cancel: "{{name}} cancel the videocall"
|
45
|
+
requirements: You don't have the minimum requirements to run videocall application. Please upgrade to the latest version of Flash.
|
data/config/locales/es.yml
CHANGED
@@ -20,5 +20,26 @@ es:
|
|
20
20
|
checkbox: "Activar o desactivar chat"
|
21
21
|
update: "Guardar configuración"
|
22
22
|
notify:
|
23
|
-
offline: "
|
24
|
-
guestOffline: "está desconectado"
|
23
|
+
offline: "Estás desconectado"
|
24
|
+
guestOffline: "{{name}} está desconectado"
|
25
|
+
videochat:
|
26
|
+
disconnected: Videochat desconectado
|
27
|
+
disconnecting: Videochat desconectando...
|
28
|
+
negotiating: Negociando...
|
29
|
+
connectingWait: Conectando...
|
30
|
+
connecting: Conectando con el servidor...
|
31
|
+
waiting: Esperando respuesta...
|
32
|
+
establishing: Estableciendo conexión...
|
33
|
+
connnected: Videochat conectado
|
34
|
+
unable: Imposible iniciar videochat
|
35
|
+
serverIssue: "Error del servidor: Respuesta inválida"
|
36
|
+
call: "{{name}} quiere iniciar una videollamada"
|
37
|
+
rejected: "{{name}} ha rechazado tu llamada"
|
38
|
+
rejectedBusy: "{{name}} está ocupado"
|
39
|
+
accept: Aceptar
|
40
|
+
deny: Rechazar
|
41
|
+
clientIssue: "El cliente de {{name}} no soporta videochat"
|
42
|
+
guestOffline: "Imposible conectar. {{name}} está desconectado"
|
43
|
+
offline: "Imposible conectar. Estás desconectado"
|
44
|
+
cancel: "{{name}} canceló la videollamada"
|
45
|
+
requirements: No tienes los requisitos minimos para iniciar la aplicación de videoconferencia. Por favor, actualiza a la última versión de Flash.
|
data/config/routes.rb
CHANGED
@@ -7,7 +7,9 @@ Rails.application.routes.draw do
|
|
7
7
|
match '/xmpp/unsetPresence' => "Xmpp#unsetPresence"
|
8
8
|
match '/xmpp/resetConnection' => "Xmpp#resetConnection"
|
9
9
|
match '/xmpp/synchronizePresence' => "Xmpp#synchronizePresence"
|
10
|
+
|
10
11
|
match '/xmpp/updateSettings'=> "Xmpp#updateSettings"
|
11
12
|
match '/chatWindow'=> "Xmpp#chatWindow"
|
13
|
+
match '/requestVideoChat'=> "Xmpp#getOpenTokSessionIDAndToken"
|
12
14
|
|
13
15
|
end
|
@@ -0,0 +1,184 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
|
4
|
+
=begin
|
5
|
+
OpenTok Ruby Library
|
6
|
+
http://www.tokbox.com/
|
7
|
+
|
8
|
+
Copyright 2010, TokBox, Inc.
|
9
|
+
|
10
|
+
=end
|
11
|
+
|
12
|
+
require 'cgi'
|
13
|
+
require 'openssl'
|
14
|
+
require 'base64'
|
15
|
+
require 'uri'
|
16
|
+
require 'net/https'
|
17
|
+
require 'rexml/document'
|
18
|
+
|
19
|
+
DIGEST = OpenSSL::Digest::Digest.new('sha1')
|
20
|
+
|
21
|
+
class Hash
|
22
|
+
def urlencode
|
23
|
+
to_a.map do |name_value|
|
24
|
+
if name_value[1].is_a? Array
|
25
|
+
name_value[0] = CGI.escape name_value[0].to_s
|
26
|
+
name_value[1].map { |e| CGI.escape e.to_s }
|
27
|
+
name_value[1] = name_value[1].join "&" + name_value[0] + "="
|
28
|
+
name_value.join '='
|
29
|
+
else
|
30
|
+
name_value.map { |e| CGI.escape e.to_s }.join '='
|
31
|
+
end
|
32
|
+
end.join '&'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
module OpenTok
|
37
|
+
|
38
|
+
class SessionPropertyConstants
|
39
|
+
ECHOSUPPRESSION_ENABLED = "echoSuppression.enabled"; #Boolean
|
40
|
+
MULTIPLEXER_NUMOUTPUTSTREAMS = "multiplexer.numOutputStreams"; #Integer
|
41
|
+
MULTIPLEXER_SWITCHTYPE = "multiplexer.switchType"; #Integer
|
42
|
+
MULTIPLEXER_SWITCHTIMEOUT = "multiplexer.switchTimeout"; #Integer
|
43
|
+
P2P_PREFERENCE = "p2p.preference"; #String
|
44
|
+
end
|
45
|
+
|
46
|
+
class RoleConstants
|
47
|
+
SUBSCRIBER = "subscriber" #Can only subscribe
|
48
|
+
PUBLISHER = "publisher" #Can publish, subscribe, and signal
|
49
|
+
MODERATOR = "moderator" #Can do the above along with forceDisconnect and forceUnpublish
|
50
|
+
end
|
51
|
+
|
52
|
+
class Net::HTTP
|
53
|
+
alias_method :old_initialize, :initialize
|
54
|
+
def initialize(*args)
|
55
|
+
old_initialize(*args)
|
56
|
+
@ssl_context = OpenSSL::SSL::SSLContext.new
|
57
|
+
@ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.included(base)
|
62
|
+
# Initialize module.
|
63
|
+
end
|
64
|
+
|
65
|
+
class OpenTokSession
|
66
|
+
attr_accessor :session_id
|
67
|
+
|
68
|
+
def initialize(session_id)
|
69
|
+
@session_id = session_id
|
70
|
+
end
|
71
|
+
|
72
|
+
def to_s
|
73
|
+
session_id
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class OpenTokSDK
|
78
|
+
attr_writer :api_url
|
79
|
+
@@TOKEN_SENTINEL = "T1=="
|
80
|
+
@@SDK_VERSION = "tbruby-%s" % [ VERSION ]
|
81
|
+
|
82
|
+
# @@API_URL = API_URL
|
83
|
+
|
84
|
+
def initialize(partner_id, partner_secret)
|
85
|
+
@api_url = API_URL
|
86
|
+
@partner_id = partner_id
|
87
|
+
@partner_secret = partner_secret.strip
|
88
|
+
end
|
89
|
+
|
90
|
+
def generate_token(opts = {})
|
91
|
+
{:session_id=>nil, :create_time=>nil, :expire_time=>nil, :role=>nil, :connection_data=>nil}.merge!(opts)
|
92
|
+
|
93
|
+
create_time = opts[:create_time].nil? ? Time.now : opts[:create_time]
|
94
|
+
session_id = opts[:session_id].nil? ? '' : opts[:session_id]
|
95
|
+
role = opts[:role].nil? ? RoleConstants::PUBLISHER : opts[:role]
|
96
|
+
|
97
|
+
if role != RoleConstants::SUBSCRIBER and \
|
98
|
+
role != RoleConstants::PUBLISHER and \
|
99
|
+
role != RoleConstants::MODERATOR
|
100
|
+
raise OpenTokException.new "'#{role}' is not a recognized role"
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
data_params = {
|
105
|
+
:role => role,
|
106
|
+
:session_id => session_id,
|
107
|
+
:create_time => create_time.to_i,
|
108
|
+
:nonce => rand
|
109
|
+
}
|
110
|
+
|
111
|
+
if not opts[:expire_time].nil?
|
112
|
+
raise OpenTokException.new 'Expire time must be a number' if not opts[:expire_time].is_a?(Numeric)
|
113
|
+
raise OpenTokException.new 'Expire time must be in the future' if opts[:expire_time] < Time.now.to_i
|
114
|
+
raise OpenTokException.new 'Expire time must be in the next 7 days' if opts[:expire_time] > (Time.now.to_i + 604800)
|
115
|
+
data_params[:expire_time] = opts[:expire_time].to_i
|
116
|
+
end
|
117
|
+
|
118
|
+
if not opts[:connection_data].nil?
|
119
|
+
raise OpenTokException.new 'Connection data must be less than 1000 characters' if opts[:connection_data].length > 1000
|
120
|
+
data_params[:connection_data] = opts[:connection_data]
|
121
|
+
end
|
122
|
+
|
123
|
+
data_string = data_params.urlencode
|
124
|
+
|
125
|
+
sig = sign_string(data_string, @partner_secret)
|
126
|
+
meta_string = {
|
127
|
+
:partner_id => @partner_id,
|
128
|
+
:sdk_version => @@SDK_VERSION,
|
129
|
+
:sig => sig
|
130
|
+
}.urlencode
|
131
|
+
|
132
|
+
@@TOKEN_SENTINEL + Base64.encode64(meta_string + ":" + data_string).gsub("\n","")
|
133
|
+
end
|
134
|
+
|
135
|
+
def create_session(location='', opts={})
|
136
|
+
opts.merge!({:partner_id => @partner_id, :location=>location})
|
137
|
+
doc = do_request("/session/create", opts)
|
138
|
+
if not doc.get_elements('Errors').empty?
|
139
|
+
raise OpenTokException.new doc.get_elements('Errors')[0].get_elements('error')[0].children.to_s
|
140
|
+
end
|
141
|
+
OpenTokSession.new(doc.root.get_elements('Session')[0].get_elements('session_id')[0].children[0].to_s)
|
142
|
+
end
|
143
|
+
|
144
|
+
protected
|
145
|
+
|
146
|
+
def sign_string(data, secret)
|
147
|
+
OpenSSL::HMAC.hexdigest(DIGEST, secret, data)
|
148
|
+
end
|
149
|
+
|
150
|
+
def do_request(api_url, params, token=nil)
|
151
|
+
|
152
|
+
url = URI.parse(@api_url + api_url)
|
153
|
+
if not params.empty?
|
154
|
+
req = Net::HTTP::Post.new(url.path)
|
155
|
+
req.set_form_data(params)
|
156
|
+
else
|
157
|
+
req = Net::HTTP::Get.new(url.path)
|
158
|
+
end
|
159
|
+
|
160
|
+
if not token.nil?
|
161
|
+
req.add_field 'X-TB-TOKEN-AUTH', token
|
162
|
+
else
|
163
|
+
req.add_field 'X-TB-PARTNER-AUTH', "#{@partner_id}:#{@partner_secret}"
|
164
|
+
end
|
165
|
+
http = Net::HTTP.new(url.host, url.port)
|
166
|
+
http.use_ssl = true if @api_url.start_with?("https")
|
167
|
+
res = http.start {|http| http.request(req)}
|
168
|
+
case res
|
169
|
+
when Net::HTTPSuccess, Net::HTTPRedirection
|
170
|
+
# OK
|
171
|
+
doc = REXML::Document.new(res.read_body)
|
172
|
+
return doc
|
173
|
+
else
|
174
|
+
res.error!
|
175
|
+
end
|
176
|
+
rescue Net::HTTPExceptions
|
177
|
+
raise
|
178
|
+
raise OpenTokException.new 'Unable to create fufill request: ' + $!
|
179
|
+
rescue NoMethodError
|
180
|
+
raise
|
181
|
+
raise OpenTokException.new 'Unable to create a fufill request at this time: ' + $1
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
=begin
|
3
|
+
OpenTok Ruby Library v0.90.0
|
4
|
+
http://www.tokbox.com/
|
5
|
+
|
6
|
+
Copyright 2010, TokBox, Inc.
|
7
|
+
|
8
|
+
Date: November 05 14:50:00 2010
|
9
|
+
=end
|
10
|
+
|
11
|
+
module OpenTok
|
12
|
+
|
13
|
+
class Session
|
14
|
+
|
15
|
+
attr_reader :sessionId
|
16
|
+
|
17
|
+
def initialize(sessionId)
|
18
|
+
@sessionId = sessionId
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
sessionId
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -29,6 +29,12 @@ SocialStream::Presence.setup do |config|
|
|
29
29
|
#Username of the the Social Stream Admin sid
|
30
30
|
config.social_stream_presence_username = "social_stream-presence"
|
31
31
|
#Configures Social Stream Rails App Password
|
32
|
-
config.password = <%= SecureRandom.hex(32).inspect %>
|
32
|
+
config.password = <%= SecureRandom.hex(32).inspect %>
|
33
|
+
|
34
|
+
#OpenTok settings (Only for videochat)
|
35
|
+
#Replace with your OpenTok API key.
|
36
|
+
#config.opentok_api_key = ""
|
37
|
+
#Replace with your OpenTok API secret.
|
38
|
+
#config.opentok_api_secret = ""
|
33
39
|
|
34
40
|
end
|
data/lib/open_tok.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
+
|
4
|
+
=begin
|
5
|
+
OpenTok Ruby Library
|
6
|
+
http://www.tokbox.com/
|
7
|
+
|
8
|
+
Copyright 2010, TokBox, Inc.
|
9
|
+
|
10
|
+
Last modified: 2011-10-12
|
11
|
+
=end
|
12
|
+
|
13
|
+
|
14
|
+
require 'rubygems'
|
15
|
+
require 'net/http'
|
16
|
+
require 'uri'
|
17
|
+
require 'digest/md5'
|
18
|
+
require 'cgi'
|
19
|
+
#require 'pp' # just for debugging purposes
|
20
|
+
|
21
|
+
Net::HTTP.version_1_2 # to make sure version 1.2 is used
|
22
|
+
|
23
|
+
module OpenTok
|
24
|
+
VERSION = "tbrb-v0.91.2011-10-12"
|
25
|
+
#API_URL = "https://staging.tokbox.com/hl"
|
26
|
+
#Uncomment this line when you launch your app
|
27
|
+
API_URL = "https://api.opentok.com/hl";
|
28
|
+
end
|
29
|
+
|
30
|
+
require 'OpenTok/Exceptions'
|
31
|
+
require 'OpenTok/OpenTokSDK'
|