Daniel Brötzmann pushed to branch master at gajim / gajim
Commits: f01094e3 by wurstsalat at 2022-03-14T23:44:58+01:00 Add MUC localpart generator
- - - - - 9b72433a by wurstsalat at 2022-03-14T23:52:16+01:00 GroupchatCreation: Rework dialog
- - - - -
6 changed files:
- gajim/common/const.py - gajim/common/helpers.py - gajim/data/gui/groupchat_creation.ui - gajim/data/style/gajim.css - gajim/gtk/builder.pyi - gajim/gtk/groupchat_creation.py
Changes:
===================================== gajim/common/const.py ===================================== @@ -448,6 +448,12 @@ def __str__(self): }
+VOWELS = 'aeiou' + + +CONSONANTS = 'bcdfghjklmnpqrstvwxyz' + + THANKS = u"""\ Alexander Futász Alexander V. Butenko
===================================== gajim/common/helpers.py ===================================== @@ -94,6 +94,8 @@ from gajim.common.const import URIAction from gajim.common.const import GIO_TLS_ERRORS from gajim.common.const import SHOW_LIST +from gajim.common.const import CONSONANTS +from gajim.common.const import VOWELS from gajim.common.regex import INVALID_XML_CHARS_REGEX from gajim.common.regex import STH_AT_STH_DOT_STH_REGEX from gajim.common.structs import URI @@ -1394,6 +1396,19 @@ def get_muc_context(jid: JID) -> Optional[str]: return 'public'
+def get_random_muc_localpart() -> str: + rand = random.randrange(4) + is_vowel = bool(random.getrandbits(1)) + result = '' + for _ in range(rand * 2 + (5 - rand)): + if is_vowel: + result = f'{result}{VOWELS[random.randrange(len(VOWELS))]}' + else: + result = f'{result}{CONSONANTS[random.randrange(len(CONSONANTS))]}' + is_vowel = not is_vowel + return result + + def get_start_of_day(date_time: datetime) -> datetime: return date_time.replace(hour=0, minute=0,
===================================== gajim/data/gui/groupchat_creation.ui ===================================== @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.22.1 --> +<!-- Generated with glade 3.38.2 --> <interface> - <requires lib="gtk+" version="3.20"/> + <requires lib="gtk+" version="3.24"/> <object class="GtkListStore" id="account_liststore"> <columns> <!-- column-name id --> @@ -10,23 +10,25 @@ <column type="gchararray"/> </columns> </object> - <object class="GtkPopover" id="public_private_popover"> - <property name="can_focus">False</property> + <object class="GtkOverlay" id="create_group_chat"> + <property name="visible">True</property> + <property name="can-focus">False</property> <child> <object class="GtkBox"> + <property name="width-request">400</property> <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">center</property> - <property name="border_width">12</property> + <property name="can-focus">False</property> + <property name="border-width">18</property> <property name="orientation">vertical</property> - <property name="spacing">6</property> + <property name="spacing">18</property> <child> <object class="GtkLabel"> <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes">Public or Private?</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes">Create Group Chat</property> + <property name="wrap">True</property> <style> - <class name="bold16"/> + <class name="large-header"/> </style> </object> <packing> @@ -36,14 +38,264 @@ </packing> </child> <child> - <object class="GtkLabel"> + <!-- n-columns=2 n-rows=6 --> + <object class="GtkGrid" id="grid"> <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes"><b>Private:</b> If you plan to chat encrypted, you would typically want to create a private group chat. You have to invite people so they can join.</property> - <property name="use_markup">True</property> - <property name="wrap">True</property> - <property name="width_chars">40</property> - <property name="max_width_chars">40</property> + <property name="can-focus">False</property> + <property name="margin-top">12</property> + <property name="row-spacing">6</property> + <property name="column-spacing">12</property> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="halign">end</property> + <property name="label" translatable="yes">_Name</property> + <property name="use-underline">True</property> + <property name="mnemonic-widget">name_entry</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">1</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="halign">end</property> + <property name="label" translatable="yes">_Description</property> + <property name="use-underline">True</property> + <property name="mnemonic-widget">description_entry</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">2</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="name_entry"> + <property name="width-request">200</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="hexpand">True</property> + <signal name="changed" handler="_on_name_entry_changed" swapped="no"/> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">1</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="description_entry"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="show-emoji-icon">True</property> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">2</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="account_combo"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="no-show-all">True</property> + <property name="valign">center</property> + <property name="margin-bottom">12</property> + <property name="model">account_liststore</property> + <property name="id-column">0</property> + <signal name="changed" handler="_on_account_combo_changed" swapped="no"/> + <child> + <object class="GtkCellRendererText"/> + <attributes> + <attribute name="text">1</attribute> + </attributes> + </child> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="account_label"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="no-show-all">True</property> + <property name="halign">end</property> + <property name="margin-bottom">12</property> + <property name="label" translatable="yes">_Account</property> + <property name="use-underline">True</property> + <property name="mnemonic-widget">account_combo</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">0</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="address_entry"> + <property name="can-focus">True</property> + <property name="no-show-all">True</property> + <signal name="changed" handler="_on_address_entry_changed" swapped="no"/> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">5</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="address_label"> + <property name="can-focus">False</property> + <property name="no-show-all">True</property> + <property name="halign">end</property> + <property name="label" translatable="yes">_Address</property> + <property name="use-underline">True</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">5</property> + </packing> + </child> + <child> + <object class="GtkRadioButton" id="private_radio"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="margin-top">12</property> + <property name="active">True</property> + <property name="draw-indicator">True</property> + <property name="group">public_radio</property> + <signal name="toggled" handler="_on_public_private_toggled" swapped="no"/> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="halign">start</property> + <property name="margin-start">6</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="halign">start</property> + <property name="label" translatable="yes">Private</property> + <property name="use-markup">True</property> + <property name="wrap">True</property> + <property name="xalign">0</property> + <style> + <class name="bold"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="halign">start</property> + <property name="label" translatable="yes">You have to invite people so they can join</property> + <property name="wrap">True</property> + <property name="xalign">0</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">3</property> + </packing> + </child> + <child> + <object class="GtkRadioButton" id="public_radio"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="draw-indicator">True</property> + <property name="group">private_radio</property> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="margin-start">6</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="halign">start</property> + <property name="label" translatable="yes">Public</property> + <property name="use-markup">True</property> + <property name="xalign">0</property> + <style> + <class name="bold"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="halign">start</property> + <property name="label" translatable="yes">Anyone can join</property> + <property name="wrap">True</property> + <property name="xalign">0</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">4</property> + </packing> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> </object> <packing> <property name="expand">False</property> @@ -51,139 +303,17 @@ <property name="position">1</property> </packing> </child> - <child> - <object class="GtkLabel"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes"><b>Public:</b> Anyone who knows the address can join.</property> - <property name="use_markup">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">2</property> - </packing> - </child> - </object> - </child> - </object> - <object class="GtkBox" id="create_group_chat"> - <property name="width_request">400</property> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="border_width">18</property> - <property name="orientation">vertical</property> - <property name="spacing">18</property> - <child> - <object class="GtkLabel"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes">Create Group Chat</property> - <property name="wrap">True</property> - <style> - <class name="large-header"/> - </style> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkGrid" id="grid"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="margin_top">12</property> - <property name="row_spacing">6</property> - <property name="column_spacing">12</property> - <child> - <object class="GtkLabel"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">end</property> - <property name="label" translatable="yes">_Name</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">name_entry</property> - <style> - <class name="dim-label"/> - </style> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">1</property> - </packing> - </child> - <child> - <object class="GtkLabel"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">end</property> - <property name="label" translatable="yes">_Description</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">description_entry</property> - <style> - <class name="dim-label"/> - </style> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">2</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="name_entry"> - <property name="width_request">200</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hexpand">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">1</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="description_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="show_emoji_icon">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">2</property> - </packing> - </child> - <child> - <object class="GtkLabel"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">end</property> - <property name="valign">center</property> - <property name="margin_top">12</property> - <property name="label" translatable="yes">_Public</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">public_switch</property> - <style> - <class name="dim-label"/> - </style> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">3</property> - </packing> - </child> <child> <object class="GtkBox"> <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="margin_top">12</property> + <property name="can-focus">False</property> + <property name="halign">end</property> + <property name="margin-top">12</property> <property name="spacing">12</property> <child> - <object class="GtkSwitch" id="public_switch"> + <object class="GtkSpinner" id="spinner"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="valign">center</property> + <property name="can-focus">False</property> </object> <packing> <property name="expand">False</property> @@ -192,20 +322,17 @@ </packing> </child> <child> - <object class="GtkMenuButton"> + <object class="GtkButton" id="create_button"> + <property name="label" translatable="yes">_Create</property> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> <property name="halign">end</property> - <property name="relief">none</property> - <property name="popover">public_private_popover</property> - <child> - <object class="GtkImage"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="icon_name">dialog-information-symbolic</property> - </object> - </child> + <property name="use-underline">True</property> + <signal name="clicked" handler="_on_create_clicked" swapped="no"/> + <style> + <class name="suggested-action"/> + </style> </object> <packing> <property name="expand">False</property> @@ -215,130 +342,39 @@ </child> </object> <packing> - <property name="left_attach">1</property> - <property name="top_attach">3</property> - </packing> - </child> - <child> - <object class="GtkLabel"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">end</property> - <property name="label" translatable="yes">_Address</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">address_entry</property> - <style> - <class name="dim-label"/> - </style> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">4</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="address_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <signal name="activate" handler="_on_address_entry_activate" swapped="no"/> - <signal name="changed" handler="_on_address_entry_changed" swapped="no"/> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">4</property> - </packing> - </child> - <child> - <object class="GtkComboBox" id="account_combo"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="no_show_all">True</property> - <property name="valign">center</property> - <property name="model">account_liststore</property> - <property name="id_column">0</property> - <signal name="changed" handler="_on_account_combo_changed" swapped="no"/> - <child> - <object class="GtkCellRendererText"/> - <attributes> - <attribute name="text">1</attribute> - </attributes> - </child> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">0</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="account_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="no_show_all">True</property> - <property name="halign">end</property> - <property name="label" translatable="yes">_Account</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">account_combo</property> - <style> - <class name="dim-label"/> - </style> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack-type">end</property> + <property name="position">3</property> </packing> </child> </object> <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">1</property> + <property name="index">-1</property> </packing> </child> - <child> - <object class="GtkBox"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">end</property> - <property name="margin_top">12</property> - <property name="spacing">12</property> + <child type="overlay"> + <object class="GtkBox" id="no_connection_box"> + <property name="can-focus">False</property> + <property name="no-show-all">True</property> + <property name="opacity">0.90</property> <child> - <object class="GtkSpinner" id="spinner"> + <object class="GtkLabel"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes">You are not connected</property> + <property name="wrap">True</property> </object> <packing> - <property name="expand">False</property> + <property name="expand">True</property> <property name="fill">True</property> <property name="position">0</property> </packing> </child> - <child> - <object class="GtkButton" id="create_button"> - <property name="label" translatable="yes">_Create</property> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="halign">end</property> - <property name="use_underline">True</property> - <signal name="clicked" handler="_on_create_clicked" swapped="no"/> - <style> - <class name="suggested-action"/> - </style> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> + <style> + <class name="solid-background"/> + </style> </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="pack_type">end</property> - <property name="position">3</property> - </packing> </child> </object> </interface>
===================================== gajim/data/style/gajim.css ===================================== @@ -17,6 +17,10 @@ .dialog-margin > box { margin: 18px;}
#MessageWindow, #RosterWindow paned { background-color: @theme_base_color; }
+.solid-background { + background-color: @theme_base_color; +} + #DropArea {background-color: @theme_base_color;}
.chatcontrol-separator-top {margin-top: 5px;}
===================================== gajim/gtk/builder.pyi ===================================== @@ -452,17 +452,19 @@ class GroupchatControlBuilder(Builder):
class GroupchatCreationBuilder(Builder): account_liststore: Gtk.ListStore - public_private_popover: Gtk.Popover - create_group_chat: Gtk.Box + create_group_chat: Gtk.Overlay grid: Gtk.Grid name_entry: Gtk.Entry description_entry: Gtk.Entry - public_switch: Gtk.Switch - address_entry: Gtk.Entry account_combo: Gtk.ComboBox account_label: Gtk.Label + address_entry: Gtk.Entry + address_label: Gtk.Label + private_radio: Gtk.RadioButton + public_radio: Gtk.RadioButton spinner: Gtk.Spinner create_button: Gtk.Button + no_connection_box: Gtk.Box
class GroupchatDetailsBuilder(Builder):
===================================== gajim/gtk/groupchat_creation.py ===================================== @@ -12,7 +12,8 @@ # You should have received a copy of the GNU General Public License # along with Gajim. If not, see http://www.gnu.org/licenses/.
-from typing import Any +from typing import Optional +from typing import Union
import logging import random @@ -24,11 +25,16 @@ from nbxmpp.task import Task
from gajim.common import app +from gajim.common import ged from gajim.common.const import MUC_CREATION_EXAMPLES from gajim.common.const import MUC_DISCO_ERRORS -from gajim.common.i18n import _ +from gajim.common.events import AccountConnected +from gajim.common.events import AccountDisonnected +from gajim.common.ged import EventHelper +from gajim.common.helpers import get_random_muc_localpart from gajim.common.helpers import validate_jid from gajim.common.helpers import to_user_string +from gajim.common.i18n import _
from .dialogs import ErrorDialog from .builder import get_builder @@ -37,9 +43,10 @@ log = logging.getLogger('gajim.gui.groupchat_creation')
-class CreateGroupchatWindow(Gtk.ApplicationWindow): - def __init__(self, account: str) -> None: +class CreateGroupchatWindow(Gtk.ApplicationWindow, EventHelper): + def __init__(self, account: Optional[str]) -> None: Gtk.ApplicationWindow.__init__(self) + EventHelper.__init__(self) self.set_name('CreateGroupchat') self.set_application(app.app) self.set_position(Gtk.WindowPosition.CENTER) @@ -54,37 +61,53 @@ def __init__(self, account: str) -> None:
self._destroyed: bool = False
- self._account = self._fill_account_combo(account) - self._create_entry_completion() - self._fill_placeholders()
self._ui.connect_signals(self) self.connect('key-press-event', self._on_key_press) self.connect('destroy', self._on_destroy)
+ self.register_events([ + ('account-connected', ged.GUI2, self._on_account_state), + ('account-disconnected', ged.GUI2, self._on_account_state) + ]) + self.show_all() + + if app.get_number_of_connected_accounts() == 0: + # This can happen under rare circumstances + self._ui.no_connection_box.show() + return + + self._account = self._update_accounts(account) + self.set_focus(self._ui.address_entry)
- def _get_muc_service_jid(self) -> str: - client = app.get_client(self._account) - return str(client.get_module('MUC').service_jid or 'muc.example.com') + def _on_account_state(self, + _event: Union[AccountConnected, AccountDisonnected] + ) -> None: + any_account_connected = app.get_number_of_connected_accounts() > 0 + self._ui.no_connection_box.set_visible(not any_account_connected) + if any_account_connected: + self._account = self._update_accounts()
- def _fill_account_combo(self, account: str) -> str: + def _update_accounts(self, account: Optional[str] = None) -> str: accounts = app.get_enabled_accounts_with_labels(connected_only=True) account_liststore = self._ui.account_combo.get_model() + assert isinstance(account_liststore, Gtk.ListStore) + account_liststore.clear() + for acc in accounts: account_liststore.append(acc)
- # Hide account combobox if there is only one account - if len(accounts) == 1: - self._ui.account_combo.hide() - self._ui.account_label.hide() + self._ui.account_combo.set_visible(len(accounts) != 1) + self._ui.account_label.set_visible(len(accounts) != 1)
if account is None: account = accounts[0][0]
self._ui.account_combo.set_active_id(account) + self._fill_placeholders() return account
def _create_entry_completion(self) -> None: @@ -109,25 +132,25 @@ def _fill_placeholders(self) -> None: self._ui.address_entry.set_placeholder_text( f'{placeholder[2]}@{server}')
+ def _get_muc_service_jid(self) -> str: + assert self._account is not None + client = app.get_client(self._account) + return str(client.get_module('MUC').service_jid or 'muc.example.com') + def _on_key_press(self, _widget: Gtk.Widget, event: Gdk.EventKey) -> None: if event.keyval == Gdk.KEY_Escape: self.destroy()
def _on_account_combo_changed(self, combo: Gtk.ComboBox) -> None: self._account = combo.get_active_id() + if self._account is None: + model = combo.get_model() + iter_ = model.get_iter_first() + if not iter_: + return + self._account = model[iter_][0] self._fill_placeholders()
- def _update_entry_completion(self, entry: Gtk.Entry, text: str) -> None: - text = entry.get_text() - if '@' in text: - text = text.split('@', 1)[0] - - model = entry.get_completion().get_model() - model.clear() - - server = self._get_muc_service_jid() - model.append([f'{text}@{server}']) - def _validate_jid(self, text: str) -> None: if not text: self._set_warning_icon(False) @@ -168,7 +191,7 @@ def _set_warning(self, text: str) -> None: self._ui.create_button.set_sensitive(False)
def _set_warning_from_error(self, error: StanzaError) -> None: - condition = error.condition + condition = error.condition or '' if condition == 'gone': condition = 'already-exists' text = MUC_DISCO_ERRORS.get(condition, to_user_string(error)) @@ -177,22 +200,49 @@ def _set_warning_from_error(self, error: StanzaError) -> None: def _set_warning_from_error_code(self, error_code: str) -> None: self._set_warning(MUC_DISCO_ERRORS[error_code])
+ def _on_name_entry_changed(self, entry: Gtk.Entry) -> None: + if self._ui.private_radio.get_active(): + return + + name = entry.get_text() + server = self._get_muc_service_jid() + self._ui.address_entry.set_text(f'{name.lower()}@{server}') + def _on_address_entry_changed(self, entry: Gtk.Entry) -> None: text = entry.get_text() self._update_entry_completion(entry, text) self._validate_jid(text)
- def _on_address_entry_activate(self, _entry: Gtk.Entry) -> None: - self._on_create_clicked() + def _update_entry_completion(self, entry: Gtk.Entry, text: str) -> None: + text = entry.get_text() + if '@' in text: + text = text.split('@', 1)[0] + + model = entry.get_completion().get_model() + assert isinstance(model, Gtk.ListStore) + model.clear()
- def _on_create_clicked(self, *args: Any) -> None: + server = self._get_muc_service_jid() + model.append([f'{text}@{server}']) + + def _on_public_private_toggled(self, _radiobutton: Gtk.RadioButton) -> None: + is_public = self._ui.public_radio.get_active() + self._ui.address_label.set_visible(is_public) + self._ui.address_entry.set_visible(is_public) + + def _on_create_clicked(self, _button: Gtk.Button) -> None: + assert self._account is not None if not app.account_is_available(self._account): ErrorDialog( _('Not Connected'), _('You have to be connected to create a group chat.')) return
- room_jid = self._ui.address_entry.get_text() + if self._ui.public_radio.get_active(): + room_jid = self._ui.address_entry.get_text() + else: + server = self._get_muc_service_jid() + room_jid = f'{get_random_muc_localpart()}@{server}'
self._set_processing_state(True) client = app.get_client(self._account) @@ -205,6 +255,7 @@ def _disco_info_received(self, task: Task) -> None: result = task.finish() except StanzaError as error: if error.condition == 'item-not-found': + assert error.jid is not None self._create_muc(error.jid) return self._set_warning_from_error(error) @@ -218,7 +269,7 @@ def _disco_info_received(self, task: Task) -> None: def _create_muc(self, room_jid: str) -> None: name = self._ui.name_entry.get_text() description = self._ui.description_entry.get_text() - is_public = self._ui.public_switch.get_active() + is_public = self._ui.public_radio.get_active()
config = { # XEP-0045 options @@ -234,6 +285,7 @@ def _create_muc(self, room_jid: str) -> None: }
# Create new group chat by joining + assert self._account is not None app.interface.create_groupchat( self._account, str(room_jid), @@ -243,3 +295,5 @@ def _create_muc(self, room_jid: str) -> None:
def _on_destroy(self, _widget: Gtk.Widget) -> None: self._destroyed = True + self.unregister_events() + app.check_finalize(self)
View it on GitLab: https://dev.gajim.org/gajim/gajim/-/compare/9fe3d46bf5b8a8f6eb4d5405205afd0b...