# HG changeset patch # User souliane # Date 1384707434 -3600 # Node ID 79970bf6af9330c802f583084cbbb036df3f7c9e # Parent a76243c0207446122fc9c63f293d8eeab0a46009 browser_side: added class RoomAndContactsChooser: - unified UI for all the MUC menu items callbacks to join a room, invite people and start a game diff -r a76243c02074 -r 79970bf6af93 browser_side/dialog.py --- a/browser_side/dialog.py Sun Nov 17 17:53:37 2013 +0100 +++ b/browser_side/dialog.py Sun Nov 17 17:57:14 2013 +0100 @@ -20,6 +20,7 @@ """ from pyjamas.ui.VerticalPanel import VerticalPanel +from pyjamas.ui.Grid import Grid from pyjamas.ui.HorizontalPanel import HorizontalPanel from pyjamas.ui.PopupPanel import PopupPanel from pyjamas.ui.DialogBox import DialogBox @@ -28,30 +29,79 @@ from pyjamas.ui.TextBox import TextBox from pyjamas.ui.Label import Label from pyjamas.ui.HTML import HTML -from pyjamas.ui.Frame import Frame +from pyjamas.ui.RadioButton import RadioButton from pyjamas.ui import HasAlignment from pyjamas.ui.KeyboardListener import KEY_ESCAPE, KEY_ENTER from pyjamas.ui.MouseListener import MouseWheelHandler -from pyjamas import DOM from pyjamas import Window +from browser_side import panels +from sat.tools.frontends.misc import DEFAULT_MUC # List here the patterns that are not allowed in contact group names FORBIDDEN_PATTERNS_IN_GROUP = () -class ContactsChooser(DialogBox): +class RoomChooser(Grid): + """Select a room from the rooms you already joined, or create a new one""" + + GENERATE_MUC = "" + + def __init__(self, host, default_room=DEFAULT_MUC): + Grid.__init__(self, 2, 2, Width='100%') + self.host = host + + self.exist_radio = RadioButton("room", "Select discussion room:") + self.rooms_list = ListBox(Width='100%') + self.setRooms() + self.add(self.exist_radio, 0, 0) + self.add(self.rooms_list, 0, 1) + + self.new_radio = RadioButton("room", "New discussion room:") + self.new_radio.setChecked(True) + self.box = TextBox(Width='100%') + self.box.setText(self.GENERATE_MUC if default_room == "" else default_room) + self.add(self.new_radio, 1, 0) + self.add(self.box, 1, 1) + + self.rooms_list.addFocusListener(self) + self.box.addFocusListener(self) - def __init__(self, host, callback, nb_contact=None, text='Please select contacts'): + def onFocus(self, sender): + if sender == self.rooms_list: + self.exist_radio.setChecked(True) + elif sender == self.box: + if self.box.getText() == self.GENERATE_MUC: + self.box.setText("") + self.new_radio.setChecked(True) + + def onLostFocus(self, sender): + if sender == self.box: + if self.box.getText() == "": + self.box.setText(self.GENERATE_MUC) + + def setRooms(self, room_data): + for room in self.host.room_list: + self.rooms_list.addItem(room.bare) + + def getRoom(self): + if self.exist_radio.getChecked(): + values = self.rooms_list.getSelectedValues() + return "" if values == [] else values[0] + value = self.box.getText() + return "" if value == self.GENERATE_MUC else value + + +class ContactsChooser(VerticalPanel): + """Select one or several connected contacts""" + + def __init__(self, host, nb_contact=None, ok_button=None): """ - ContactsChooser allow to select one or several connected contacts @param host: SatWebFrontend instance - @param callback: method to call when contacts have been choosed @param nb_contact: number of contacts that have to be selected, None for no limit If a tuple is given instead of an integer, nb_contact[0] is the minimal and nb_contact[1] is the maximal number of contacts to be chosen. """ self.host = host - self.callback = callback if isinstance(nb_contact, tuple): if len(nb_contact) == 0: nb_contact = None @@ -64,48 +114,108 @@ else: print "Need to select between %d and %d contacts" % nb_contact self.nb_contact = nb_contact - DialogBox.__init__(self, centered=True) - content = VerticalPanel() - content.setWidth('100%') + self.ok_button = ok_button + VerticalPanel.__init__(self, Width='100%') self.contacts_list = ListBox() - self.contacts_list.setVisibleItemCount(10) self.contacts_list.setMultipleSelect(True) - self.contacts_list.setWidth("100%") - self.contacts_list.setStyleName('contactsChooser') + self.contacts_list.setWidth("95%") + self.contacts_list.addStyleName('contactsChooser') self.contacts_list.addChangeListener(self.onChange) - content.add(self.contacts_list) + self.add(self.contacts_list) + self.setContacts() + self.onChange() + + def onChange(self, sender=None): + if self.ok_button is None: + return + if self.nb_contact: + selected = len(self.contacts_list.getSelectedValues(True)) + if selected >= self.nb_contact[0] and selected <= self.nb_contact[1]: + self.ok_button.setEnabled(True) + else: + self.ok_button.setEnabled(False) + + def setContacts(self, selected=[]): + """Fill the list with the connected contacts + @param select: list of the contacts to select by default + """ + self.contacts_list.clear() + contacts = self.host.contact_panel.getConnected() + self.contacts_list.setVisibleItemCount(10 if len(contacts) > 5 else 5) + self.contacts_list.addItem("") + for contact in contacts: + if contact not in [room.bare for room in self.host.room_list]: + self.contacts_list.addItem(contact) + self.contacts_list.setItemTextSelection(selected) + + def getContacts(self): + return self.contacts_list.getSelectedValues(True) + + +class RoomAndContactsChooser(DialogBox): + """Select a room and some users to invite in""" + + def __init__(self, host, callback, nb_contact=None, ok_button="OK", title="Group discussions", + title_room="Join room", title_invite="Invite contacts", visible=(True, True)): + DialogBox.__init__(self, centered=True) + self.host = host + self.callback = callback + self.title_room = title_room + self.title_invite = title_invite + button_panel = HorizontalPanel() button_panel.addStyleName("marginAuto") - self.choose_button = Button("Choose", self.onChoose) - if nb_contact and nb_contact[0] > 0: - self.choose_button.setEnabled(False) - button_panel.add(self.choose_button) + ok_button = Button("OK", self.onOK) + button_panel.add(ok_button) button_panel.add(Button("Cancel", self.onCancel)) - content.add(button_panel) - self.setHTML(text) - self.setWidget(content) + + self.room_panel = RoomChooser(host, "" if visible == (False, True) else DEFAULT_MUC) + self.contact_panel = ContactsChooser(host, nb_contact, ok_button) - def onChange(self, sender): - if self.nb_contact: - selected = len(self.contacts_list.getSelectedValues()) - if selected >= self.nb_contact[0] and selected <= self.nb_contact[1]: - self.choose_button.setEnabled(True) - else: - self.choose_button.setEnabled(False) + self.stack_panel = panels.ToggleStackPanel(Width="100%") + self.stack_panel.add(self.room_panel, title_room, visible=visible[0]) + self.stack_panel.add(self.contact_panel, title_invite, visible=visible[1]) + self.stack_panel.addStackChangeListener(self) + main_panel = VerticalPanel() + main_panel.setStyleName("room-contact-chooser") + main_panel.add(self.stack_panel) + main_panel.add(button_panel) - def getContacts(self): - """ - Actually ask to choose the contacts - """ - self.contacts_list.clear() - for contact in self.host.contact_panel.getConnected(): - if contact not in [room.bare for room in self.host.room_list]: - self.contacts_list.addItem(contact) + self.setWidget(main_panel) + self.setHTML(title) self.show() - def onChoose(self, sender): + def getRoom(self, asSuffix=False): + room = self.room_panel.getRoom() + if asSuffix: + return room if room == "" else ": %s" % room + else: + return room + + def getContacts(self, asSuffix=False): + contacts = self.contact_panel.getContacts() + if asSuffix: + return "" if contacts == [] else ": %s" % ", ".join(contacts) + else: + return contacts + + def onStackChanged(self, sender, index, visible=None): + if visible is None: + visible = sender.getWidget(index).getVisible() + if index == 0: + sender.setStackText(0, self.title_room + ("" if visible else self.getRoom(True))) + elif index == 1: + sender.setStackText(1, self.title_invite + ("" if visible else self.getContacts(True))) + if visible: + # update the contacts list in case someone recently logged in/out + self.contact_panel.setContacts(self.getContacts()) + + def onOK(self, sender): + room_jid = self.getRoom() + if room_jid != "" and "@" not in room_jid: + Window.alert('You must enter a room jid in the form room@chat.%s' % self.host._defaultDomain) self.hide() - self.callback(self.contacts_list.getSelectedValues()) + self.callback(room_jid, self.getContacts()) def onCancel(self, sender): self.hide() diff -r a76243c02074 -r 79970bf6af93 browser_side/menu.py --- a/browser_side/menu.py Sun Nov 17 17:53:37 2013 +0100 +++ b/browser_side/menu.py Sun Nov 17 17:57:14 2013 +0100 @@ -227,7 +227,7 @@ else: self.host.bridge.call('addContact', None, edit.getText(), '', _dialog.getSelectedGroups() ) - label = Label("new contact identifier (JID):") + label = Label("New contact identifier (JID):") edit.setText('@%s' % self.host._defaultDomain) edit.setWidth('100%') _dialog = dialog.GroupSelector([label, edit], self.host.contact_panel.getGroups(), [], @@ -291,52 +291,32 @@ #Group menu def onJoinRoom(self): - _dialog = None - _edit = None - def onOK(sender): - if not _edit.getText(): - Window.alert('You must enter a room jid in the form room@chat.%s' % self.host._defaultDomain) + def invite(room_jid, contacts): + for contact in contacts: + self.host.bridge.call('inviteMUC', None, contact, room_jid) + + def join(room_jid, contacts): if self.host.whoami: nick = self.host.whoami.node - self.host.bridge.call('joinMUC', None, _edit.getText(), nick) - _dialog.hide() - - def onCancel(sender): - _dialog.hide() + if room_jid not in [room.bare for room in self.host.room_list]: + self.host.bridge.call('joinMUC', lambda room_jid: invite(room_jid, contacts), room_jid, nick) + else: + self.host.getOrCreateLiberviaWidget(panels.ChatPanel, (room_jid, "group"), True, JID(room_jid).bare) + invite(room_jid, contacts) - _main_panel = VerticalPanel() - _label = Label("Discussion room:") - _edit = TextBox() - _edit.setText('sat@chat.jabberfr.org') - hpanel = HorizontalPanel() - hpanel.add(_label) - hpanel.add(_edit) - _main_panel.add(hpanel) - button_panel = HorizontalPanel() - button_panel.addStyleName("marginAuto") - button_panel.add(Button("Join", onOK)) - button_panel.add(Button("Cancel", onCancel)) - _main_panel.add(button_panel) - _dialog = DialogBox(centered=True) - _dialog.setHTML('Group discussions') - _dialog.setWidget(_main_panel) - _dialog.show() + dialog.RoomAndContactsChooser(self.host, join, ok_button="Join", visible=(True, False)) def onCollectiveRadio(self): - def onContactsSelected(contacts): - print("let's go :)") - self.host.bridge.call('launchRadioCollective', None, contacts) - dialog.ContactsChooser(self.host, onContactsSelected, None, text="Please select contacts to invite").getContacts() + def callback(room_jid, contacts): + self.host.bridge.call('launchRadioCollective', None, contacts, room_jid) + dialog.RoomAndContactsChooser(self.host, callback, ok_button="Choose", visible=(False, True)) #Game menu - def onTarotGame(self): - #Window.alert("Tarot selected") - #self.host.tab_panel.add(EmptyPanel(self.host), "Tarot") - def onPlayersSelected(other_players): - self.host.bridge.call('launchTarotGame', None, other_players) - dialog.ContactsChooser(self.host, onPlayersSelected, 3, text="Please select 3 other players").getContacts() + def onPlayersSelected(room_jid, other_players): + self.host.bridge.call('launchTarotGame', None, other_players, room_jid) + dialog.RoomAndContactsChooser(self.host, onPlayersSelected, 3, title_invite="Please select 3 other players", visible=(False, True)) def onXiangqiGame(self): Window.alert("A Xiangqi game is planed, but not available yet") diff -r a76243c02074 -r 79970bf6af93 libervia.tac --- a/libervia.tac Sun Nov 17 17:53:37 2013 +0100 +++ b/libervia.tac Sun Nov 17 17:57:14 2013 +0100 @@ -358,10 +358,18 @@ profile = ISATSession(self.session).profile return self.sat_host.bridge.getRoomsJoined(profile) - def jsonrpc_launchTarotGame(self, other_players): - """Create a room, invite the other players and start a Tarot game""" + def jsonrpc_launchTarotGame(self, other_players, room_jid=""): + """Create a room, invite the other players and start a Tarot game + @param room_jid: leave empty string to generate a unique room name + """ profile = ISATSession(self.session).profile - self.sat_host.bridge.tarotGameLaunch(other_players, profile) + try: + if room_jid != "": + room_jid = JID(room_jid).userhost() + except: + warning('Invalid room jid') + return + self.sat_host.bridge.tarotGameLaunch(other_players, room_jid, profile) def jsonrpc_getTarotCardsPaths(self): """Give the path of all the tarot cards""" @@ -384,10 +392,18 @@ profile = ISATSession(self.session).profile self.sat_host.bridge.tarotGamePlayCards(player_nick, referee, cards, profile) - def jsonrpc_launchRadioCollective(self, invited): - """Create a room, invite people, and start a radio collective""" + def jsonrpc_launchRadioCollective(self, invited, room_jid=""): + """Create a room, invite people, and start a radio collective + @param room_jid: leave empty string to generate a unique room name + """ profile = ISATSession(self.session).profile - self.sat_host.bridge.radiocolLaunch(invited, profile) + try: + if room_jid != "": + room_jid = JID(room_jid).userhost() + except: + warning('Invalid room jid') + return + self.sat_host.bridge.radiocolLaunch(invited, room_jid, profile) def jsonrpc_getEntityData(self, jid, keys): """Get cached data for an entit diff -r a76243c02074 -r 79970bf6af93 public/libervia.css --- a/public/libervia.css Sun Nov 17 17:53:37 2013 +0100 +++ b/public/libervia.css Sun Nov 17 17:57:14 2013 +0100 @@ -367,6 +367,7 @@ .contactsChooser { text-align: center; + margin:auto; } .infoDialogBody { @@ -1297,6 +1298,13 @@ .contactGroupButtonCell { vertical-align: baseline; width: 55px; +} + +/* Room and contacts chooser */ + +.room-contact-chooser { + width:380px; +} /* StackPanel */ @@ -1345,4 +1353,9 @@ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.6); cursor: pointer; } + +/* Radio buttons */ + +.gwt-RadioButton { + white-space: nowrap; } \ No newline at end of file