Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/telephony/client/ui/main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -893,7 +893,7 @@ def _unblock():
if not item.is_saved:
add_action(_("Add to Existing Contact"), lambda: self.on_add_to_existing(item),
needs_eds=True, opens_flow=True)
add_action(_("Search Number"), lambda: self._search_number_online(item.number))
add_action(_("Search Number"), lambda: self.search_number_online(item.number))

add_action(_("Send Message"), lambda: self.present_chat(item.number))
add_action(_("Copy Number"), lambda: self.copy_to_clipboard(item.number))
Expand All @@ -914,7 +914,7 @@ def _unblock():

present_sheet_page(self, Adw.NavigationPage(title=_("Call Details"), child=toolbar))

def _search_number_online(self, number):
def search_number_online(self, number):
"""Open the configured search engine for a phone number."""
clean_num = number.replace("+", "")
engine = self.gsettings_mgr.get_setting("unknown_callers_engine") or "duckduckgo"
Expand Down
59 changes: 46 additions & 13 deletions src/telephony/client/ui/views/chat_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,24 @@ def _on_btn_menu_toggled(btn):

self.list_view = Gtk.ListView(model=self.selection, factory=factory)
self.scrolled = Gtk.ScrolledWindow(child=self.list_view, vexpand=True)
dismiss = Gtk.GestureClick()
dismiss.set_propagation_phase(Gtk.PropagationPhase.CAPTURE)

def _dismiss_top_panels(_gesture, _n_press, _x, _y):
"""Close the details panel and the search bar on a tap in the chat.

They slide in from the header rather than floating over the
list, so nothing dismisses them for us; the tap is left
unclaimed and still does whatever it was aimed at.
"""
if self.btn_menu.get_active():
self.btn_menu.set_active(False)
if self.btn_search.get_active() and not self.search_entry.get_text():
self.btn_search.set_active(False)

dismiss.connect("pressed", _dismiss_top_panels)
self.scrolled.add_controller(dismiss)

self.scrolled.add_css_class("inverted-list")

self.chat_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
Expand Down Expand Up @@ -696,17 +714,16 @@ def setup_details_panel(self):
scrolled.set_max_content_height(350)
scrolled.set_propagate_natural_height(True)

list_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8)
list_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)

block_buttons = {}
dialing_ok = self.app_window.ofono.dialing_available() if self.app_window.ofono else True

for rec in self.recipients:
hbox = Gtk.Box(spacing=12, css_classes=["card"])
hbox.set_margin_start(8)
hbox.set_margin_end(8)
hbox.set_margin_top(8)
hbox.set_margin_bottom(8)
card = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, css_classes=["card"])

inner = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
card.append(inner)

name = self.app_window.eds.get_display_name(rec)
if not name:
Expand All @@ -717,21 +734,19 @@ def setup_details_panel(self):
elif name == "Unknown":
name = _("Unknown")

vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=1)

lbl_name = Gtk.Label(label=name, xalign=0, css_classes=["body", "emphasized"])
lbl_name.set_ellipsize(Pango.EllipsizeMode.END)
lbl_name.set_max_width_chars(15)
vbox.append(lbl_name)

lbl_num = Gtk.Label(label=rec, xalign=0, css_classes=["caption", "dim-label"])
lbl_num.set_ellipsize(Pango.EllipsizeMode.END)
vbox.append(lbl_num)

hbox.append(vbox)
hbox.append(Gtk.Box(hexpand=True))
inner.append(vbox)

actions_box = Gtk.Box(spacing=12)
actions_box = Gtk.Box(spacing=8, halign=Gtk.Align.START)

is_saved = self.app_window.eds.get_contact_name(rec) is not None
icon_edit = "document-edit-symbolic" if is_saved else "contact-new-symbolic"
Expand All @@ -757,6 +772,24 @@ def _handle_edit_click(n=rec):
self._recipient_call_btns.append(b_call)
b_call.connect("clicked", lambda b, n=rec: GLib.idle_add(lambda: self.app_window.start_call(n) or False))

b_search = Gtk.Button(icon_name="system-search-symbolic", css_classes=["circular"])
b_search.set_valign(Gtk.Align.CENTER)
actions_box.append(b_search)

def _handle_search_click(n=rec):
self.btn_menu.set_active(False)
self.app_window.search_number_online(n)
b_search.connect("clicked", lambda b, n=rec: _handle_search_click(n))

b_copy = Gtk.Button(icon_name="edit-copy-symbolic", css_classes=["circular"])
b_copy.set_valign(Gtk.Align.CENTER)
actions_box.append(b_copy)

def _handle_copy_click(n=rec):
self.btn_menu.set_active(False)
self.app_window.copy_to_clipboard(n)
b_copy.connect("clicked", lambda b, n=rec: _handle_copy_click(n))

b_blk = Gtk.Button(icon_name="action-unavailable-symbolic", css_classes=["circular", "destructive-action"])
b_blk.set_valign(Gtk.Align.CENTER)
b_blk.set_sensitive(False)
Expand Down Expand Up @@ -789,8 +822,8 @@ def _after_toggle(did_unblock, target_btn=btn):

b_blk.connect("clicked", lambda b, n=rec: _toggle_block(b, n))

hbox.append(actions_box)
list_box.append(hbox)
inner.append(actions_box)
list_box.append(card)

def _fetch_block_states():
return {num: self.db.is_blocked(num) for num in block_buttons}
Expand Down
66 changes: 40 additions & 26 deletions src/telephony/client/ui/windows/settings_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,13 @@ def __init__(self, main_window, eds_manager, ofono_manager):
lambda: self._push_category(_("Notifications"), self._build_notifications_page),
icon="audio-volume-high-symbolic"))
if self.mode_calls:
grp_cats.add(self._nav_row(_("Unknown Callers"), _("Screening and lookup"),
grp_cats.add(self._nav_row(_("Unknown Callers"), _("Screening"),
lambda: self._push_category(_("Unknown Callers"), self._build_unknown_callers_page),
icon="dialog-question-symbolic"))
if self.mode_calls or self.mode_messages:
grp_cats.add(self._nav_row(_("Number Lookup"), _("Search engine for the search buttons"),
lambda: self._push_category(_("Number Lookup"), self._build_lookup_page),
icon="system-search-symbolic"))
grp_cats.add(self._nav_row(_("Network Services"), _("Forwarding, waiting and barring"),
lambda: self._open_network_services(None),
icon="network-cellular-signal-good-symbolic"))
Expand Down Expand Up @@ -750,10 +754,39 @@ def _build_unknown_callers_page(self, page):
grp_uc.add(self.row_uc_action)

self.sw_uc_search = Adw.SwitchRow(title=_(
"Add Search button to InCall window and Call History for unknown callers"))
"Search button for unknown callers during a call"))
self.sw_uc_search.set_title_lines(0)
grp_uc.add(self.sw_uc_search)

def _on_search_toggle(w, p):
self.main_window.gsettings_mgr.set_setting(
"unknown_callers_search", "true" if w.get_active() else "false")
self.sw_uc_search.connect("notify::active", _on_search_toggle)

uc_action = self.main_window.gsettings_mgr.get_setting(
"unknown_callers") or "none"
action_idx = next(
(i for i, (k, act_name) in enumerate(self.action_options) if k == uc_action), 0)
set_selector_options(self.row_uc_action,
[name for _key, name in self.action_options], action_idx)

self.sw_uc_search.set_active(self.main_window.gsettings_mgr.get_setting(
"unknown_callers_search") == "true")

def _build_lookup_page(self, page):
"""Build the number lookup category page.

Its own category rather than a corner of Unknown Callers,
because the buttons it serves are in both apps while the
screening options are call things, and an engine choice hidden
behind a call switch was unreachable from the surfaces that
used it.
"""
grp_lookup = Adw.PreferencesGroup()
grp_lookup.set_description(_(
"Used by the search buttons in calls, call history and group messages."))
page.add(grp_lookup)

self.row_uc_engine = build_selector_row(
_("Search Engine"), self._on_uc_engine_selected)
self.engine_options = [
Expand All @@ -769,24 +802,8 @@ def _build_unknown_callers_page(self, page):
btn_uc_info = self._info_button(self._show_custom_url_info)
self.entry_uc_custom.add_suffix(btn_uc_info)

grp_uc.add(self.row_uc_engine)
grp_uc.add(self.entry_uc_custom)

def _on_search_toggle(w, p):
self.main_window.gsettings_mgr.set_setting(
"unknown_callers_search", "true" if w.get_active() else "false")
self._update_uc_ui()
self.sw_uc_search.connect("notify::active", _on_search_toggle)

uc_action = self.main_window.gsettings_mgr.get_setting(
"unknown_callers") or "none"
action_idx = next(
(i for i, (k, act_name) in enumerate(self.action_options) if k == uc_action), 0)
set_selector_options(self.row_uc_action,
[name for _key, name in self.action_options], action_idx)

self.sw_uc_search.set_active(self.main_window.gsettings_mgr.get_setting(
"unknown_callers_search") == "true")
grp_lookup.add(self.row_uc_engine)
grp_lookup.add(self.entry_uc_custom)

engine = self.main_window.gsettings_mgr.get_setting(
"unknown_callers_engine") or "duckduckgo"
Expand Down Expand Up @@ -830,13 +847,10 @@ def _persist_sources(self):
run_in_background(self.eds.set_default_addressbook, default['uid'])

def _update_uc_ui(self):
search_active = self.sw_uc_search.get_active()
self.row_uc_engine.set_visible(search_active)
"""Show the custom URL field only while the custom engine is chosen."""
idx = self.row_uc_engine._selected_index
if search_active and idx >= 0 and self.engine_options[idx][0] == "custom":
self.entry_uc_custom.set_visible(True)
else:
self.entry_uc_custom.set_visible(False)
self.entry_uc_custom.set_visible(
idx >= 0 and self.engine_options[idx][0] == "custom")

def _get_gsettings_emergency(self):
"""Get emergency button setting via Gio.Settings."""
Expand Down