primitivus: chat state implementation
for now chat states are displayed in primitivus surrended text (after the contact's name)
This commit is contained in:
parent
9cb7071e89
commit
41375e7bde
2 changed files with 126 additions and 63 deletions
|
|
@ -145,7 +145,22 @@ class Chat(urwid.WidgetWrap, QuickChat):
|
|||
self.__appendPresentPanel()
|
||||
|
||||
def __getDecoration(self, widget):
|
||||
return sat_widgets.LabelLine(widget, sat_widgets.SurroundedText(unicode(unescapePrivate(self.target))))
|
||||
return sat_widgets.LabelLine(widget, self.__getSurrendedText())
|
||||
|
||||
def __getSurrendedText(self):
|
||||
"""Get the text to be displayed as the dialog title."""
|
||||
if not hasattr(self, "surrended_text"):
|
||||
self.__setSurrendedText()
|
||||
return self.surrended_text
|
||||
|
||||
def __setSurrendedText(self, state=None):
|
||||
"""Set the text to be displayed as the dialog title
|
||||
@param stat: chat state of the contact
|
||||
"""
|
||||
text = unicode(unescapePrivate(self.target))
|
||||
if state:
|
||||
text += " (" + state + ")"
|
||||
self.surrended_text = sat_widgets.SurroundedText(text)
|
||||
|
||||
def showDecoration(self, show=True):
|
||||
"""Show/Hide the decoration around the chat window"""
|
||||
|
|
@ -155,6 +170,18 @@ class Chat(urwid.WidgetWrap, QuickChat):
|
|||
main_widget = self.pile
|
||||
self._w = main_widget
|
||||
|
||||
def updateChatState(self, state):
|
||||
"""Update the chat state of the contact.
|
||||
@param state: new state to set
|
||||
"""
|
||||
if (self.type == 'one2one'):
|
||||
self.__setSurrendedText(state)
|
||||
self.showDecoration()
|
||||
self.host.redraw()
|
||||
elif (self.type == 'group'):
|
||||
# TODO: chat state for groupchat
|
||||
pass
|
||||
|
||||
def _presentClicked(self, list_wid, clicked_wid):
|
||||
assert(self.type == 'group')
|
||||
nick = clicked_wid.getValue()
|
||||
|
|
|
|||
|
|
@ -49,6 +49,85 @@ class ChatList(QuickChatList):
|
|||
def createChat(self, target):
|
||||
return Chat(target, self.host)
|
||||
|
||||
|
||||
class EditBar(sat_widgets.ModalEdit):
|
||||
"""
|
||||
The modal edit bar where you would enter messages and commands.
|
||||
"""
|
||||
|
||||
def __init__(self, app):
|
||||
modes = {None: ('NORMAL', u''),
|
||||
'i': ('INSERTION', u'> '),
|
||||
':': ('COMMAND', u':')} #XXX: captions *MUST* be unicode
|
||||
super(EditBar, self).__init__(modes)
|
||||
self.app = app
|
||||
self.setCompletionMethod(self._text_completion)
|
||||
urwid.connect_signal(self, 'click', self.onTextEntered)
|
||||
|
||||
def _text_completion(self, text, completion_data, mode):
|
||||
if mode == 'INSERTION':
|
||||
return self._nick_completion(text, completion_data)
|
||||
else:
|
||||
return text
|
||||
|
||||
def _nick_completion(self, text, completion_data):
|
||||
"""Completion method which complete pseudo in group chat
|
||||
for params, see AdvancedEdit"""
|
||||
contact = self.app.contact_list.getContact() ###Based on the fact that there is currently only one contact selectable at once
|
||||
if contact:
|
||||
chat = self.app.chat_wins[contact]
|
||||
if chat.type != "group":
|
||||
return text
|
||||
space = text.rfind(" ")
|
||||
start = text[space+1:]
|
||||
nicks = list(chat.occupants)
|
||||
nicks.sort()
|
||||
try:
|
||||
start_idx=nicks.index(completion_data['last_nick'])+1
|
||||
if start_idx == len(nicks):
|
||||
start_idx = 0
|
||||
except (KeyError,ValueError):
|
||||
start_idx = 0
|
||||
for idx in range(start_idx,len(nicks)) + range(0,start_idx):
|
||||
if nicks[idx].lower().startswith(start.lower()):
|
||||
completion_data['last_nick'] = nicks[idx]
|
||||
return text[:space+1] + nicks[idx] + (': ' if space < 0 else '')
|
||||
return text
|
||||
|
||||
def onTextEntered(self, editBar):
|
||||
"""Called when text is entered in the main edit bar"""
|
||||
if self.mode == 'INSERTION':
|
||||
contact = self.app.contact_list.getContact() ###Based on the fact that there is currently only one contact selectableat once
|
||||
if contact:
|
||||
chat = self.app.chat_wins[contact]
|
||||
try:
|
||||
self.app.sendMessage(contact,
|
||||
editBar.get_edit_text(),
|
||||
mess_type = "groupchat" if chat.type == 'group' else "chat",
|
||||
profile_key=self.app.profile)
|
||||
except:
|
||||
self.app.notify(_("Error while sending message"))
|
||||
editBar.set_edit_text('')
|
||||
elif self.mode == 'COMMAND':
|
||||
self.commandHandler()
|
||||
|
||||
def commandHandler(self):
|
||||
#TODO: separate class with auto documentation (with introspection)
|
||||
# and completion method
|
||||
command = self.get_edit_text()
|
||||
if command == 'quit':
|
||||
self.app.onExit()
|
||||
raise urwid.ExitMainLoop()
|
||||
|
||||
def keypress(self, size, key):
|
||||
"""Callback when a key is pressed. Send "composing" states."""
|
||||
if key != "enter":
|
||||
contact = self.app.contact_list.getContact()
|
||||
if contact:
|
||||
self.app.bridge.chatStateComposing(contact, self.app.profile)
|
||||
return super(EditBar, self).keypress(size, key)
|
||||
|
||||
|
||||
class PrimitivusApp(QuickApp):
|
||||
|
||||
def __init__(self):
|
||||
|
|
@ -172,13 +251,6 @@ class PrimitivusApp(QuickApp):
|
|||
except AttributeError:
|
||||
return input
|
||||
|
||||
def commandHandler(self, editBar):
|
||||
#TODO: separate class with auto documentation (with introspection)
|
||||
# and completion method
|
||||
command = editBar.get_edit_text()
|
||||
if command == 'quit':
|
||||
self.onExit()
|
||||
raise urwid.ExitMainLoop()
|
||||
|
||||
def __buildMenuRoller(self):
|
||||
menu = sat_widgets.Menu(self.loop)
|
||||
|
|
@ -215,48 +287,11 @@ class PrimitivusApp(QuickApp):
|
|||
#self.center_part = urwid.Columns([('weight',2,self.contact_list),('weight',8,Chat('',self))])
|
||||
self.center_part = urwid.Columns([('weight',2,self.contact_list), ('weight',8,urwid.Filler(urwid.Text('')))])
|
||||
|
||||
modes = {None: ('NORMAL', u''),
|
||||
'i': ('INSERTION', u'> '),
|
||||
':': ('COMMAND', u':')} #XXX: captions *MUST* be unicode
|
||||
self.editBar = sat_widgets.ModalEdit(modes)
|
||||
self.editBar.setCompletionMethod(self._text_completion)
|
||||
urwid.connect_signal(self.editBar,'click',self.onTextEntered)
|
||||
self.editBar = EditBar(self)
|
||||
self.menu_roller = self.__buildMenuRoller()
|
||||
self.main_widget = sat_widgets.FocusFrame(self.center_part, header=self.menu_roller, footer=self.editBar, focus_part='footer')
|
||||
return self.main_widget
|
||||
|
||||
def _text_completion(self, text, completion_data, mode):
|
||||
if mode == 'INSERTION':
|
||||
return self._nick_completion(text, completion_data)
|
||||
else:
|
||||
return text
|
||||
|
||||
def _nick_completion(self, text, completion_data):
|
||||
"""Completion method which complete pseudo in group chat
|
||||
for params, see AdvancedEdit"""
|
||||
contact = self.contact_list.getContact() ###Based on the fact that there is currently only one contact selectable at once
|
||||
if contact:
|
||||
chat = self.chat_wins[contact]
|
||||
if chat.type != "group":
|
||||
return text
|
||||
space = text.rfind(" ")
|
||||
start = text[space+1:]
|
||||
nicks = list(chat.occupants)
|
||||
nicks.sort()
|
||||
try:
|
||||
start_idx=nicks.index(completion_data['last_nick'])+1
|
||||
if start_idx == len(nicks):
|
||||
start_idx = 0
|
||||
except (KeyError,ValueError):
|
||||
start_idx = 0
|
||||
for idx in range(start_idx,len(nicks)) + range(0,start_idx):
|
||||
if nicks[idx].lower().startswith(start.lower()):
|
||||
completion_data['last_nick'] = nicks[idx]
|
||||
return text[:space+1] + nicks[idx] + (': ' if space < 0 else '')
|
||||
return text
|
||||
|
||||
|
||||
|
||||
def plug_profile(self, profile_key='@DEFAULT@'):
|
||||
self.loop.widget = self.__buildMainWidget()
|
||||
self.redraw()
|
||||
|
|
@ -320,23 +355,6 @@ class PrimitivusApp(QuickApp):
|
|||
self.center_part.widget_list[1] = self.chat_wins[contact]
|
||||
self.menu_roller.addMenu(_('Chat menu'), self.chat_wins[contact].getMenu())
|
||||
|
||||
def onTextEntered(self, editBar):
|
||||
"""Called when text is entered in the main edit bar"""
|
||||
if self.mode == 'INSERTION':
|
||||
contact = self.contact_list.getContact() ###Based on the fact that there is currently only one contact selectableat once
|
||||
if contact:
|
||||
chat = self.chat_wins[contact]
|
||||
try:
|
||||
self.sendMessage(contact,
|
||||
editBar.get_edit_text(),
|
||||
mess_type = "groupchat" if chat.type == 'group' else "chat",
|
||||
profile_key=self.profile)
|
||||
except:
|
||||
self.notify(_("Error while sending message"))
|
||||
editBar.set_edit_text('')
|
||||
elif self.mode == 'COMMAND':
|
||||
self.commandHandler(editBar)
|
||||
|
||||
def newMessage(self, from_jid, to_jid, msg, _type, extra, profile):
|
||||
QuickApp.newMessage(self, from_jid, to_jid, msg, _type, extra, profile)
|
||||
|
||||
|
|
@ -576,6 +594,24 @@ class PrimitivusApp(QuickApp):
|
|||
self.showPopUp(sat_widgets.Alert(_("Error"), _("Can't get search UI"), ok_cb=self.removePopUp))
|
||||
self.bridge.searchRequest(search_jid, dict(data), self.profile, callback=success, errback=failure)
|
||||
|
||||
def chatStateReceived(self, from_jid_s, state, profile):
|
||||
"""Signal observer to display a contact chat state
|
||||
@param from_jid_s: contact who sent his new state
|
||||
@state: state
|
||||
@profile: current profile
|
||||
"""
|
||||
if not self.check_profile(profile):
|
||||
return
|
||||
|
||||
if from_jid_s == "@ALL@":
|
||||
for win in self.chat_wins:
|
||||
self.chat_wins[win].updateChatState(state)
|
||||
return
|
||||
|
||||
from_bare = JID(from_jid_s).short
|
||||
if from_bare in self.chat_wins:
|
||||
self.chat_wins[from_bare].updateChatState(state)
|
||||
|
||||
sat = PrimitivusApp()
|
||||
sat.start()
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue