comparison browser_side/panels.py @ 19:e8e3704eb97f

Added basic chat panel - the chat panel show history, timestamp, and nickname (pretty similar to primitivus and wix chat window) - JID has be rewritten to work with pyjamas, and is now in browser_side directory - a widget can now be selected: the message send in uniBox will be sent to it if there is no explicit target prefix ("@something") - a basic status panel is added under the uniBox, but not used yet
author Goffi <goffi@goffi.org>
date Sat, 16 Apr 2011 01:46:01 +0200
parents 795d144fc1d2
children 8f4b1a8914c3
comparison
equal deleted inserted replaced
18:795d144fc1d2 19:e8e3704eb97f
28 from pyjamas.ui.Grid import Grid 28 from pyjamas.ui.Grid import Grid
29 from pyjamas.ui.MenuBar import MenuBar 29 from pyjamas.ui.MenuBar import MenuBar
30 from pyjamas.ui.MenuItem import MenuItem 30 from pyjamas.ui.MenuItem import MenuItem
31 from pyjamas.ui.Label import Label 31 from pyjamas.ui.Label import Label
32 from pyjamas.ui.DropWidget import DropWidget 32 from pyjamas.ui.DropWidget import DropWidget
33 from pyjamas.ui.ClickListener import ClickHandler
33 from pyjamas.ui import HasAlignment 34 from pyjamas.ui import HasAlignment
34 from pyjamas import Window 35 from pyjamas import Window
35 from pyjamas import DOM 36 from pyjamas import DOM
36 37
37 from pyjamas.dnd import makeDraggable 38 from pyjamas.dnd import makeDraggable
38 from pyjamas.ui.DragWidget import DragWidget, DragContainer 39 from pyjamas.ui.DragWidget import DragWidget, DragContainer
39 from tools.jid import JID 40 from jid import JID
40 from datetime import datetime 41 from datetime import datetime
42 from time import time
41 43
42 class MenuCmd: 44 class MenuCmd:
43 45
44 def __init__(self, object, handler): 46 def __init__(self, object, handler):
45 self._object = object 47 self._object = object
113 print "no message found" 115 print "no message found"
114 item='&nbsp;' 116 item='&nbsp;'
115 item_type = None 117 item_type = None
116 DOM.eventPreventDefault(event) 118 DOM.eventPreventDefault(event)
117 if item_type=="GROUP": 119 if item_type=="GROUP":
118 _mblog = MicroblogPanel(self.host, item) 120 _new_panel = MicroblogPanel(self.host, item)
119 _mblog.setAcceptedGroup(item) 121 _new_panel.setAcceptedGroup(item)
120 elif item_type=="CONTACT": 122 elif item_type=="CONTACT":
121 _mblog = MicroblogPanel(self.host, accept_all=True) 123 _contact = JID(item)
124 _new_panel = ChatPanel(self.host, _contact)
125 _new_panel.historyPrint()
126 elif item_type=="CONTACT_TITLE":
127 _new_panel = MicroblogPanel(self.host, accept_all=True)
122 self.host.mpanels.remove(self) 128 self.host.mpanels.remove(self)
123 self.host.mpanels.append(_mblog) 129 self.host.mpanels.append(_new_panel)
124 print "DEBUG" 130 print "DEBUG"
125 grid = self.getParent() 131 grid = self.getParent()
126 row_idx, cell_idx = self._getCellAndRow(grid, event) 132 row_idx, cell_idx = self._getCellAndRow(grid, event)
127 self.removeFromParent() 133 self.removeFromParent()
128 grid.setWidget(row_idx, cell_idx, _mblog) 134 if self.host.selected == self:
129 print "index:", row_idx, cell_idx 135 self.host.select(None)
136 grid.setWidget(row_idx, cell_idx, _new_panel)
130 #FIXME: delete object ? Check the right way with pyjamas 137 #FIXME: delete object ? Check the right way with pyjamas
131 #self.host.middle_panel.changePanel(self.data,self.host.mpanels[0])
132
133 138
134 class EmptyPanel(DropCell, SimplePanel): 139 class EmptyPanel(DropCell, SimplePanel):
135 """Empty dropable panel""" 140 """Empty dropable panel"""
136 141
137 def __init__(self, host): 142 def __init__(self, host):
154 "timestamp": _datetime, 159 "timestamp": _datetime,
155 "body": body} 160 "body": body}
156 ) 161 )
157 panel.setStyleName('microblogEntry') 162 panel.setStyleName('microblogEntry')
158 self.add(panel) 163 self.add(panel)
159
160 164
161 class MicroblogPanel(DropCell, ScrollPanel): 165 class MicroblogPanel(DropCell, ScrollPanel):
162 166
163 def __init__(self,host, title='&nbsp;', accept_all=False): 167 def __init__(self,host, title='&nbsp;', accept_all=False):
164 """Panel used to show microblog 168 """Panel used to show microblog
205 return True 209 return True
206 for group in self.accepted_groups: 210 for group in self.accepted_groups:
207 if self.host.contactPanel.isContactInGroup(group, jid): 211 if self.host.contactPanel.isContactInGroup(group, jid):
208 return True 212 return True
209 return False 213 return False
210 214
211 215 class StatusPanel(HTMLPanel):
216 def __init__(self, status=''):
217 self.status = status
218 HTMLPanel.__init__(self, self.__getContent())
219
220 def __getContent(self):
221 return "<span class='status'>%(status)s</span>" % {'status':self.status}
222
223 def changeStatus(self, new_status):
224 self.status = new_status
225 self.setHTML(self.__getContent())
226
227 class ChatText(HTMLPanel):
228
229 def __init__(self, timestamp, nick, mymess, msg):
230 _date = datetime.fromtimestamp(float(timestamp or time()))
231 print "DEBUG"
232 print timestamp
233 print time()
234 print _date
235 _msg_class = ["chat_text_msg"]
236 if mymess:
237 _msg_class.append("chat_text_mymess")
238 HTMLPanel.__init__(self, "<span class='chat_text_timestamp'>%(timestamp)s</span> <span class='chat_text_nick'>%(nick)s</span> <span class='%(msg_class)s'>%(msg)s</span>" %
239 {"timestamp": _date.strftime("%H:%M"),
240 "nick": "[%s]" % nick,
241 "msg_class": ' '.join(_msg_class),
242 "msg": msg}
243 )
244 self.setStyleName('chatText')
245
246 class ChatPanel(DropCell, ClickHandler, ScrollPanel):
247
248 def __init__(self, host, target, type='one2one'):
249 """Panel used for conversation (one 2 one or group chat)
250 @param host: SatWebFrontend instance
251 @param target: entity (JID) with who we have a conversation (contact's jid for one 2 one chat, or MUC room)
252 @param type: one2one for simple conversation, group for MUC"""
253 self.host = host
254 if not target:
255 print "ERROR: Empty target !"
256 return
257 self.target = target
258 title="%s" % target.bare
259 title.replace('<','&lt;').replace('>','&gt;')
260 _class = ['mb_panel_header']
261 ScrollPanel.__init__(self)
262 self.content = VerticalPanel()
263 self.content.add(HTMLPanel("<div class='%s'>%s</div>" % (','.join(_class),title)))
264 self.content.setWidth('100%')
265 self.setHeight('100%')
266 self.setStyleName('chatPanel')
267 self.add(self.content)
268 DropCell.__init__(self)
269 ClickHandler.__init__(self)
270 self.addClickListener(self)
271
272 def onClick(self, sender, event):
273 self.host.select(self)
274
275 def setUserNick(self, nick):
276 """Set the nick of the user, usefull for e.g. change the color of the user"""
277 self.nick = nick
278
279 def historyPrint(self, size=20):
280 """Print the initial history"""
281 def getHistoryCB(history):
282 stamps=history.keys()
283 stamps.sort()
284 for stamp in stamps:
285 self.printMessage(history[stamp][0], history[stamp][1], stamp)
286 self.host.bridge.call('getHistory', getHistoryCB, self.host.whoami.bare, str(self.target), 20)
287
288 def printMessage(self, from_jid, msg, timestamp=None):
289 """Print message in chat window. Must be implemented by child class"""
290 _jid=JID(from_jid)
291 nick = _jid.node
292 mymess = _jid.bare == self.host.whoami.bare #mymess = True if message comes from local user
293 """if msg.startswith('/me '):
294 self.printInfo('* %s %s' % (nick, msg[4:]),type='me')
295 return"""
296 self.content.add(ChatText(timestamp, nick, mymess, msg))
212 297
213 class MiddlePannel(HorizontalPanel): 298 class MiddlePannel(HorizontalPanel):
214 299
215 def __init__(self, host): 300 def __init__(self, host):
216 self.host=host 301 self.host=host
239 self.setHorizontalAlignment(HasAlignment.ALIGN_LEFT) 324 self.setHorizontalAlignment(HasAlignment.ALIGN_LEFT)
240 self.setVerticalAlignment(HasAlignment.ALIGN_TOP) 325 self.setVerticalAlignment(HasAlignment.ALIGN_TOP)
241 326
242 menu = Menu() 327 menu = Menu()
243 uni_box = host.uniBox 328 uni_box = host.uniBox
329 status = host.statusPanel
244 self.middle_panel = MiddlePannel(self.host) 330 self.middle_panel = MiddlePannel(self.host)
245 self.middle_panel.setWidth('100%') 331 self.middle_panel.setWidth('100%')
246 332
247 self.add(menu) 333 self.add(menu)
248 self.add(uni_box) 334 self.add(uni_box)
335 self.add(status)
249 self.add(self.middle_panel) 336 self.add(self.middle_panel)
250 337
251 self.setCellHeight(menu, "5%") 338 self.setCellHeight(menu, "5%")
252 self.setCellHeight(uni_box, "5%") 339 self.setCellHeight(uni_box, "5%")
253 self.setCellVerticalAlignment(uni_box, HasAlignment.ALIGN_CENTER) 340 self.setCellVerticalAlignment(uni_box, HasAlignment.ALIGN_CENTER)