Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
converse.js
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
converse.js
Commits
91bdb56b
Commit
91bdb56b
authored
May 31, 2013
by
JC Brand
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed race condition bug. More intelligent fetching of vcards
parent
7a94f73d
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
98 additions
and
57 deletions
+98
-57
CHANGES.rst
CHANGES.rst
+5
-0
converse.js
converse.js
+92
-56
converse.min.js
converse.min.js
+1
-1
No files found.
CHANGES.rst
View file @
91bdb56b
...
@@ -12,6 +12,11 @@ Changelog
...
@@ -12,6 +12,11 @@ Changelog
[jcbrand]
[jcbrand]
- Fixed alignment of chat messages in Firefox.
- Fixed alignment of chat messages in Firefox.
[jcbrand]
[jcbrand]
- More intelligent fetching of vCards.
[jcbrand]
- Fixed a race condition bug. Make sure that the roster is populated before
sending initial presence.
[jcbrand]
0.3 (2013-05-21)
0.3 (2013-05-21)
----------------
----------------
...
...
converse.js
View file @
91bdb56b
...
@@ -217,7 +217,7 @@
...
@@ -217,7 +217,7 @@
'
fullname
'
:
this
.
get
(
'
fullname
'
),
'
fullname
'
:
this
.
get
(
'
fullname
'
),
'
url
'
:
this
.
get
(
'
url
'
),
'
url
'
:
this
.
get
(
'
url
'
),
'
image_type
'
:
this
.
get
(
'
image_type
'
),
'
image_type
'
:
this
.
get
(
'
image_type
'
),
'
image
_src
'
:
this
.
get
(
'
image_src
'
)
'
image
'
:
this
.
get
(
'
image
'
)
});
});
}
}
},
},
...
@@ -420,10 +420,7 @@
...
@@ -420,10 +420,7 @@
keyPressed
:
function
(
ev
)
{
keyPressed
:
function
(
ev
)
{
var
$textarea
=
$
(
ev
.
target
),
var
$textarea
=
$
(
ev
.
target
),
message
,
message
,
notify
,
composing
;
notify
,
composing
;
if
(
ev
.
keyCode
==
13
)
{
if
(
ev
.
keyCode
==
13
)
{
ev
.
preventDefault
();
ev
.
preventDefault
();
message
=
$textarea
.
val
();
message
=
$textarea
.
val
();
...
@@ -436,7 +433,6 @@
...
@@ -436,7 +433,6 @@
}
}
}
}
this
.
$el
.
data
(
'
composing
'
,
false
);
this
.
$el
.
data
(
'
composing
'
,
false
);
}
else
if
(
!
this
.
model
.
get
(
'
chatroom
'
))
{
}
else
if
(
!
this
.
model
.
get
(
'
chatroom
'
))
{
// composing data is only for single user chat
// composing data is only for single user chat
composing
=
this
.
$el
.
data
(
'
composing
'
);
composing
=
this
.
$el
.
data
(
'
composing
'
);
...
@@ -470,7 +466,10 @@
...
@@ -470,7 +466,10 @@
}
}
}
if
(
_
.
has
(
item
.
changed
,
'
status
'
))
{
}
if
(
_
.
has
(
item
.
changed
,
'
status
'
))
{
this
.
showStatusMessage
(
item
.
get
(
'
status
'
));
this
.
showStatusMessage
(
item
.
get
(
'
status
'
));
}
if
(
_
.
has
(
item
.
changed
,
'
image
'
))
{
this
.
renderAvatar
();
}
}
// TODO check for changed fullname as well
},
},
showStatusMessage
:
function
(
msg
)
{
showStatusMessage
:
function
(
msg
)
{
...
@@ -485,12 +484,34 @@
...
@@ -485,12 +484,34 @@
}
}
},
},
updateVCard
:
function
()
{
var
jid
=
this
.
model
.
get
(
'
jid
'
),
rosteritem
=
converse
.
roster
.
get
(
jid
);
if
((
rosteritem
)
&&
(
!
rosteritem
.
get
(
'
vcard_updated
'
)))
{
converse
.
getVCard
(
jid
,
$
.
proxy
(
function
(
jid
,
fullname
,
image
,
image_type
,
url
)
{
this
.
model
.
save
({
'
fullname
'
:
fullname
,
'
url
'
:
url
,
'
image_type
'
:
image_type
,
'
image
'
:
image
,
'
vcard_updated
'
:
converse
.
toISOString
(
new
Date
())
});
},
this
),
$
.
proxy
(
function
(
stanza
)
{
console
.
log
(
"
ChatBoxView.initialize: An error occured while fetching vcard
"
);
},
this
)
);
}
},
initialize
:
function
(){
initialize
:
function
(){
this
.
model
.
messages
.
on
(
'
add
'
,
this
.
showMessage
,
this
);
this
.
model
.
messages
.
on
(
'
add
'
,
this
.
showMessage
,
this
);
this
.
model
.
on
(
'
show
'
,
this
.
show
,
this
);
this
.
model
.
on
(
'
show
'
,
this
.
show
,
this
);
this
.
model
.
on
(
'
destroy
'
,
this
.
hide
,
this
);
this
.
model
.
on
(
'
destroy
'
,
this
.
hide
,
this
);
this
.
model
.
on
(
'
change
'
,
this
.
onChange
,
this
);
this
.
model
.
on
(
'
change
'
,
this
.
onChange
,
this
);
this
.
updateVCard
();
this
.
$el
.
appendTo
(
converse
.
chatboxesview
.
$el
);
this
.
$el
.
appendTo
(
converse
.
chatboxesview
.
$el
);
this
.
render
().
show
().
model
.
messages
.
fetch
({
add
:
true
});
this
.
render
().
show
().
model
.
messages
.
fetch
({
add
:
true
});
if
(
this
.
model
.
get
(
'
status
'
))
{
if
(
this
.
model
.
get
(
'
status
'
))
{
...
@@ -514,21 +535,26 @@
...
@@ -514,21 +535,26 @@
'
placeholder="Personal message"/>
'
+
'
placeholder="Personal message"/>
'
+
'
</form>
'
),
'
</form>
'
),
renderAvatar
:
function
()
{
if
(
!
this
.
model
.
get
(
'
image
'
))
{
return
;
}
var
img_src
=
'
data:
'
+
this
.
model
.
get
(
'
image_type
'
)
+
'
;base64,
'
+
this
.
model
.
get
(
'
image
'
),
canvas
=
$
(
'
<canvas height="35px" width="35px" class="avatar"></canvas>
'
),
ctx
=
canvas
.
get
(
0
).
getContext
(
'
2d
'
),
img
=
new
Image
();
// Create new Image object
img
.
onload
=
function
()
{
var
ratio
=
img
.
width
/
img
.
height
;
ctx
.
drawImage
(
img
,
0
,
0
,
35
*
ratio
,
35
);
};
img
.
src
=
img_src
;
this
.
$el
.
find
(
'
.chat-title
'
).
before
(
canvas
);
},
render
:
function
()
{
render
:
function
()
{
this
.
$el
.
attr
(
'
id
'
,
this
.
model
.
get
(
'
box_id
'
))
this
.
$el
.
attr
(
'
id
'
,
this
.
model
.
get
(
'
box_id
'
))
.
html
(
this
.
template
(
this
.
model
.
toJSON
()));
.
html
(
this
.
template
(
this
.
model
.
toJSON
()));
if
(
this
.
model
.
get
(
'
image
'
))
{
this
.
renderAvatar
();
var
img_src
=
'
data:
'
+
this
.
model
.
get
(
'
image_type
'
)
+
'
;base64,
'
+
this
.
model
.
get
(
'
image
'
),
canvas
=
$
(
'
<canvas height="35px" width="35px" class="avatar"></canvas>
'
),
ctx
=
canvas
.
get
(
0
).
getContext
(
'
2d
'
),
img
=
new
Image
();
// Create new Image object
img
.
onload
=
function
()
{
var
ratio
=
img
.
width
/
img
.
height
;
ctx
.
drawImage
(
img
,
0
,
0
,
35
*
ratio
,
35
);
};
img
.
src
=
img_src
;
this
.
$el
.
find
(
'
.chat-title
'
).
before
(
canvas
);
}
return
this
;
return
this
;
},
},
...
@@ -584,7 +610,7 @@
...
@@ -584,7 +610,7 @@
template
:
_
.
template
(
template
:
_
.
template
(
'
<form class="set-xmpp-status" action="" method="post">
'
+
'
<form class="set-xmpp-status" action="" method="post">
'
+
'
<span id="xmpp-status-holder">
'
+
'
<span id="xmpp-status-holder">
'
+
'
<select id="select-xmpp-status">
'
+
'
<select id="select-xmpp-status"
style="display:none"
>
'
+
'
<option value="online">Online</option>
'
+
'
<option value="online">Online</option>
'
+
'
<option value="dnd">Busy</option>
'
+
'
<option value="dnd">Busy</option>
'
+
'
<option value="away">Away</option>
'
+
'
<option value="away">Away</option>
'
+
...
@@ -628,6 +654,7 @@
...
@@ -628,6 +654,7 @@
markup
=
this
.
add_contact_template
();
markup
=
this
.
add_contact_template
();
}
}
this
.
$el
.
find
(
'
.search-xmpp ul
'
).
append
(
markup
);
this
.
$el
.
find
(
'
.search-xmpp ul
'
).
append
(
markup
);
this
.
$el
.
append
(
converse
.
rosterview
.
$el
);
return
this
;
return
this
;
},
},
...
@@ -1021,6 +1048,22 @@
...
@@ -1021,6 +1048,22 @@
this
.
contactspanel
=
new
converse
.
ContactsPanel
();
this
.
contactspanel
=
new
converse
.
ContactsPanel
();
this
.
contactspanel
.
$parent
=
this
.
$el
;
this
.
contactspanel
.
$parent
=
this
.
$el
;
this
.
contactspanel
.
render
();
this
.
contactspanel
.
render
();
converse
.
xmppstatus
=
new
converse
.
XMPPStatus
();
converse
.
xmppstatus
.
localStorage
=
new
Backbone
.
LocalStorage
(
hex_sha1
(
'
converse.xmppstatus-
'
+
converse
.
bare_jid
));
converse
.
xmppstatus
.
fetch
({
success
:
function
(
xmppstatus
,
resp
)
{
if
(
!
xmppstatus
.
get
(
'
fullname
'
))
{
converse
.
getVCard
(
null
,
// No 'to' attr when getting one's own vCard
function
(
jid
,
fullname
,
image
,
image_type
,
url
)
{
converse
.
xmppstatus
.
save
({
'
fullname
'
:
fullname
});
}
);
}
}
});
converse
.
xmppstatusview
=
new
converse
.
XMPPStatusView
({
'
model
'
:
converse
.
xmppstatus
});
this
.
roomspanel
=
new
converse
.
RoomsPanel
();
this
.
roomspanel
=
new
converse
.
RoomsPanel
();
this
.
roomspanel
.
$parent
=
this
.
$el
;
this
.
roomspanel
.
$parent
=
this
.
$el
;
this
.
roomspanel
.
render
();
this
.
roomspanel
.
render
();
...
@@ -1114,7 +1157,7 @@
...
@@ -1114,7 +1157,7 @@
},
},
renderChatArea
:
function
()
{
renderChatArea
:
function
()
{
if
(
!
this
.
$el
.
find
(
'
.chat-area
'
).
length
)
{
if
(
!
this
.
$el
.
find
(
'
.chat-area
'
).
length
)
{
this
.
$el
.
find
(
'
.chat-body
'
).
empty
().
append
(
this
.
chatarea_template
());
this
.
$el
.
find
(
'
.chat-body
'
).
empty
().
append
(
this
.
chatarea_template
());
}
}
return
this
;
return
this
;
...
@@ -1387,7 +1430,7 @@
...
@@ -1387,7 +1430,7 @@
}
}
this
.
model
.
set
(
'
connected
'
,
false
)
this
.
model
.
set
(
'
connected
'
,
false
)
return
;
return
;
}
}
this
.
renderChatArea
();
this
.
renderChatArea
();
for
(
i
=
0
;
i
<
info_msgs
.
length
;
i
++
)
{
for
(
i
=
0
;
i
<
info_msgs
.
length
;
i
++
)
{
$chat_content
.
append
(
this
.
info_template
({
message
:
info_msgs
[
i
]}));
$chat_content
.
append
(
this
.
info_template
({
message
:
info_msgs
[
i
]}));
...
@@ -1463,7 +1506,7 @@
...
@@ -1463,7 +1506,7 @@
// check if server changed our nick
// check if server changed our nick
this
.
model
.
set
({
'
nick
'
:
Strophe
.
getResourceFromJid
(
from
)});
this
.
model
.
set
({
'
nick
'
:
Strophe
.
getResourceFromJid
(
from
)});
}
}
}
}
}
}
return
true
;
return
true
;
},
},
...
@@ -1654,6 +1697,7 @@
...
@@ -1654,6 +1697,7 @@
}
}
this
.
views
[
item
.
get
(
'
id
'
)]
=
view
;
this
.
views
[
item
.
get
(
'
id
'
)]
=
view
;
}
else
{
}
else
{
delete
view
.
model
;
// Remove ref to old model to help garbage collection
view
.
model
=
item
;
view
.
model
=
item
;
view
.
initialize
();
view
.
initialize
();
if
(
item
.
get
(
'
id
'
)
!==
'
controlbox
'
)
{
if
(
item
.
get
(
'
id
'
)
!==
'
controlbox
'
)
{
...
@@ -1784,6 +1828,16 @@
...
@@ -1784,6 +1828,16 @@
img
=
$vcard
.
find
(
'
BINVAL
'
).
text
(),
img
=
$vcard
.
find
(
'
BINVAL
'
).
text
(),
img_type
=
$vcard
.
find
(
'
TYPE
'
).
text
(),
img_type
=
$vcard
.
find
(
'
TYPE
'
).
text
(),
url
=
$vcard
.
find
(
'
URL
'
).
text
();
url
=
$vcard
.
find
(
'
URL
'
).
text
();
var
rosteritem
=
converse
.
roster
.
get
(
jid
);
if
(
rosteritem
)
{
rosteritem
.
save
({
'
fullname
'
:
fullname
,
'
image_type
'
:
img_type
,
'
image
'
:
img
,
'
url
'
:
url
,
'
vcard_updated
'
:
converse
.
toISOString
(
new
Date
())
});
}
callback
(
jid
,
fullname
,
img
,
img_type
,
url
);
callback
(
jid
,
fullname
,
img
,
img_type
,
url
);
},
this
),
jid
,
errback
);
},
this
),
jid
,
errback
);
}
}
...
@@ -2072,8 +2126,7 @@
...
@@ -2072,8 +2126,7 @@
this
.
$el
.
hide
().
html
(
this
.
template
());
this
.
$el
.
hide
().
html
(
this
.
template
());
this
.
model
.
fetch
({
add
:
true
});
// Get the cached roster items from localstorage
this
.
model
.
fetch
({
add
:
true
});
// Get the cached roster items from localstorage
this
.
initialSort
();
// XXX: is this necessary? this.initialSort();
this
.
$el
.
appendTo
(
converse
.
chatboxesview
.
views
.
controlbox
.
contactspanel
.
$el
);
},
},
updateChatBox
:
function
(
item
,
changed
)
{
updateChatBox
:
function
(
item
,
changed
)
{
...
@@ -2140,7 +2193,9 @@
...
@@ -2140,7 +2193,9 @@
// options where all of the items are offline and now we can show the rosterView
// options where all of the items are offline and now we can show the rosterView
item
.
set
(
'
sorted
'
,
true
);
item
.
set
(
'
sorted
'
,
true
);
this
.
initialSort
();
this
.
initialSort
();
this
.
$el
.
show
();
this
.
$el
.
show
(
function
()
{
converse
.
xmppstatusview
.
render
();
});
}
}
}
}
// Hide the headings if there are no contacts under them
// Hide the headings if there are no contacts under them
...
@@ -2180,10 +2235,10 @@
...
@@ -2180,10 +2235,10 @@
initStatus
:
function
()
{
initStatus
:
function
()
{
var
stat
=
this
.
get
(
'
status
'
);
var
stat
=
this
.
get
(
'
status
'
);
if
(
stat
===
undefined
)
{
if
(
stat
===
undefined
)
{
this
.
save
({
status
:
'
online
'
});
stat
=
'
online
'
;
}
else
{
this
.
save
({
status
:
stat
});
this
.
sendPresence
(
stat
);
}
}
this
.
sendPresence
(
stat
);
},
},
sendPresence
:
function
(
type
)
{
sendPresence
:
function
(
type
)
{
...
@@ -2340,6 +2395,7 @@
...
@@ -2340,6 +2395,7 @@
$options_target
=
this
.
$el
.
find
(
"
#target dd ul
"
).
hide
();
$options_target
=
this
.
$el
.
find
(
"
#target dd ul
"
).
hide
();
$options_target
.
append
(
options_list
.
join
(
''
));
$options_target
.
append
(
options_list
.
join
(
''
));
$select
.
remove
();
$select
.
remove
();
this
.
model
.
initStatus
();
return
this
;
return
this
;
}
}
});
});
...
@@ -2537,53 +2593,33 @@
...
@@ -2537,53 +2593,33 @@
this
.
domain
=
Strophe
.
getDomainFromJid
(
this
.
connection
.
jid
);
this
.
domain
=
Strophe
.
getDomainFromJid
(
this
.
connection
.
jid
);
this
.
features
=
new
this
.
Features
();
this
.
features
=
new
this
.
Features
();
// Set up the roster
// Set up the roster
this
.
roster
=
new
this
.
RosterItems
();
this
.
roster
=
new
this
.
RosterItems
();
this
.
roster
.
localStorage
=
new
Backbone
.
LocalStorage
(
this
.
roster
.
localStorage
=
new
Backbone
.
LocalStorage
(
hex_sha1
(
'
converse.rosteritems-
'
+
this
.
bare_jid
));
hex_sha1
(
'
converse.rosteritems-
'
+
this
.
bare_jid
));
this
.
connection
.
roster
.
registerCallback
(
this
.
xmppstatus
=
new
this
.
XMPPStatus
({
id
:
1
});
$
.
proxy
(
this
.
roster
.
rosterHandler
,
this
.
roster
),
this
.
xmppstatus
.
localStorage
=
new
Backbone
.
LocalStorage
(
null
,
'
presence
'
,
null
);
hex_sha1
(
'
converse.xmppstatus-
'
+
this
.
bare_jid
));
this
.
chatboxes
.
onConnected
();
this
.
rosterview
=
new
this
.
RosterView
({
'
model
'
:
this
.
roster
});
this
.
rosterview
=
new
this
.
RosterView
({
'
model
'
:
this
.
roster
});
this
.
xmppstatusview
=
new
this
.
XMPPStatusView
({
'
model
'
:
this
.
xmppstatus
}).
render
();
this
.
chatboxes
.
onConnected
();
this
.
xmppstatus
.
fetch
({
success
:
$
.
proxy
(
function
(
xmppstatus
,
resp
)
{
if
(
!
xmppstatus
.
get
(
'
fullname
'
))
{
this
.
getVCard
(
null
,
// No 'to' attr when getting one's own vCard
$
.
proxy
(
function
(
jid
,
fullname
,
image
,
image_type
,
url
)
{
this
.
xmppstatus
.
save
({
'
fullname
'
:
fullname
});
},
this
));
}
},
this
)
});
this
.
connection
.
addHandler
(
this
.
connection
.
addHandler
(
$
.
proxy
(
this
.
roster
.
subscribeToSuggestedItems
,
this
.
roster
),
$
.
proxy
(
this
.
roster
.
subscribeToSuggestedItems
,
this
.
roster
),
'
http://jabber.org/protocol/rosterx
'
,
'
message
'
,
null
);
'
http://jabber.org/protocol/rosterx
'
,
'
message
'
,
null
);
this
.
connection
.
roster
.
registerCallback
(
this
.
connection
.
roster
.
get
(
$
.
proxy
(
function
(
a
)
{
$
.
proxy
(
this
.
roster
.
rosterHandler
,
this
.
roster
),
null
,
'
presence
'
,
null
);
this
.
connection
.
roster
.
get
(
$
.
proxy
(
function
()
{
this
.
connection
.
addHandler
(
this
.
connection
.
addHandler
(
$
.
proxy
(
function
(
presence
)
{
$
.
proxy
(
function
(
presence
)
{
this
.
presenceHandler
(
presence
);
this
.
presenceHandler
(
presence
);
return
true
;
return
true
;
},
this
.
roster
),
null
,
'
presence
'
,
null
);
},
this
.
roster
),
null
,
'
presence
'
,
null
);
this
.
connection
.
addHandler
(
this
.
connection
.
addHandler
(
$
.
proxy
(
function
(
message
)
{
$
.
proxy
(
function
(
message
)
{
this
.
chatboxes
.
messageReceived
(
message
);
this
.
chatboxes
.
messageReceived
(
message
);
return
true
;
return
true
;
},
this
),
null
,
'
message
'
,
'
chat
'
);
},
this
),
null
,
'
message
'
,
'
chat
'
);
this
.
xmppstatus
.
initStatus
();
},
this
));
},
this
));
$
(
window
).
on
(
"
blur focus
"
,
$
.
proxy
(
function
(
e
)
{
$
(
window
).
on
(
"
blur focus
"
,
$
.
proxy
(
function
(
e
)
{
...
...
converse.min.js
View file @
91bdb56b
This source diff could not be displayed because it is too large. You can
view the blob
instead.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment