mirror of
https://github.com/markqvist/Sideband.git
synced 2025-03-14 17:56:29 -04:00
Added audio device config ui
This commit is contained in:
parent
3d7e894a9d
commit
4d9bba3e4c
@ -104,3 +104,4 @@ getrns:
|
||||
cleanrns:
|
||||
-(rm ./RNS -r)
|
||||
-(rm ./LXMF -r)
|
||||
-(rm ./LXST -r)
|
||||
|
@ -1457,6 +1457,8 @@ class SidebandApp(MDApp):
|
||||
self.close_sub_utilities_action()
|
||||
elif self.root.ids.screen_manager.current == "logviewer_screen":
|
||||
self.close_sub_utilities_action()
|
||||
elif self.root.ids.screen_manager.current == "voice_settings_screen":
|
||||
self.close_sub_voice_action()
|
||||
else:
|
||||
self.open_conversations(direction="right")
|
||||
|
||||
@ -1534,6 +1536,7 @@ class SidebandApp(MDApp):
|
||||
|
||||
def announce_now_action(self, sender=None):
|
||||
self.sideband.lxmf_announce()
|
||||
if self.sideband.telephone: self.sideband.telephone.announce()
|
||||
|
||||
yes_button = MDRectangleFlatButton(text="OK",font_size=dp(18))
|
||||
|
||||
|
@ -535,6 +535,9 @@ class SidebandCore():
|
||||
|
||||
# Voice
|
||||
self.config["voice_enabled"] = False
|
||||
self.config["voice_output"] = None
|
||||
self.config["voice_input"] = None
|
||||
self.config["voice_ringer"] = None
|
||||
|
||||
if not os.path.isfile(self.db_path):
|
||||
self.__db_init()
|
||||
@ -844,6 +847,12 @@ class SidebandCore():
|
||||
|
||||
if not "voice_enabled" in self.config:
|
||||
self.config["voice_enabled"] = False
|
||||
if not "voice_output" in self.config:
|
||||
self.config["voice_output"] = None
|
||||
if not "voice_input" in self.config:
|
||||
self.config["voice_input"] = None
|
||||
if not "voice_ringer" in self.config:
|
||||
self.config["voice_ringer"] = None
|
||||
|
||||
# Make sure we have a database
|
||||
if not os.path.isfile(self.db_path):
|
||||
@ -1233,11 +1242,6 @@ class SidebandCore():
|
||||
lxmf_destination_hash = RNS.Destination.hash_from_name_and_identity("lxmf.delivery", identity_hash)
|
||||
existing_voice = self._db_conversation(context_dest)
|
||||
existing_lxmf = self._db_conversation(lxmf_destination_hash)
|
||||
|
||||
print(RNS.prettyhexrep(lxmf_destination_hash))
|
||||
print(f"VOICE {existing_voice}")
|
||||
print(f"LXMF {existing_lxmf}")
|
||||
|
||||
if existing_lxmf: return self.peer_display_name(lxmf_destination_hash)
|
||||
else: return self.peer_display_name(identity_hash)
|
||||
|
||||
@ -3458,6 +3462,7 @@ class SidebandCore():
|
||||
if self.config["start_announce"] == True:
|
||||
time.sleep(12)
|
||||
self.lxmf_announce(attached_interface=self.interface_local)
|
||||
if self.telephone: self.telephone.announce(attached_interface=self.interface_local)
|
||||
threading.Thread(target=job, daemon=True).start()
|
||||
|
||||
if hasattr(self, "interface_rnode") and self.interface_rnode != None:
|
||||
@ -3545,6 +3550,7 @@ class SidebandCore():
|
||||
aif = announce_attached_interface
|
||||
time.sleep(delay)
|
||||
self.lxmf_announce(attached_interface=aif)
|
||||
if self.telephone: self.telephone.announce(attached_interface=aif)
|
||||
return x
|
||||
|
||||
threading.Thread(target=gen_announce_job(announce_delay, announce_attached_interface), daemon=True).start()
|
||||
@ -3759,6 +3765,7 @@ class SidebandCore():
|
||||
def da():
|
||||
time.sleep(8)
|
||||
self.lxmf_announce()
|
||||
if self.telephone: self.telephone.announce()
|
||||
self.last_if_change_announce = time.time()
|
||||
threading.Thread(target=da, daemon=True).start()
|
||||
|
||||
@ -5241,7 +5248,7 @@ class SidebandCore():
|
||||
RNS.log("Starting voice service", RNS.LOG_DEBUG)
|
||||
self.voice_running = True
|
||||
from .voice import ReticulumTelephone
|
||||
self.telephone = ReticulumTelephone(self.identity, owner=self)
|
||||
self.telephone = ReticulumTelephone(self.identity, owner=self, speaker=self.config["voice_output"], microphone=self.config["voice_input"], ringer=self.config["voice_ringer"])
|
||||
ringtone_path = os.path.join(self.asset_dir, "audio", "notifications", "soft1.opus")
|
||||
self.telephone.set_ringtone(ringtone_path)
|
||||
|
||||
|
@ -22,7 +22,7 @@ class ReticulumTelephone():
|
||||
WAIT_TIME = 60
|
||||
PATH_TIME = 10
|
||||
|
||||
def __init__(self, identity, owner = None, service = False):
|
||||
def __init__(self, identity, owner = None, service = False, speaker=None, microphone=None, ringer=None):
|
||||
self.identity = identity
|
||||
self.service = service
|
||||
self.owner = owner
|
||||
@ -37,9 +37,9 @@ class ReticulumTelephone():
|
||||
self.last_input = None
|
||||
self.first_run = False
|
||||
self.ringtone_path = None
|
||||
self.speaker_device = None
|
||||
self.microphone_device = None
|
||||
self.ringer_device = None
|
||||
self.speaker_device = speaker
|
||||
self.microphone_device = microphone
|
||||
self.ringer_device = ringer
|
||||
self.phonebook = {}
|
||||
self.aliases = {}
|
||||
self.names = {}
|
||||
@ -58,6 +58,21 @@ class ReticulumTelephone():
|
||||
self.ringtone_path = ringtone_path
|
||||
self.telephone.set_ringtone(self.ringtone_path)
|
||||
|
||||
def set_speaker(self, device):
|
||||
self.speaker_device = device
|
||||
self.telephone.set_speaker(self.speaker_device)
|
||||
|
||||
def set_microphone(self, device):
|
||||
self.microphone_device = device
|
||||
self.telephone.set_microphone(self.microphone_device)
|
||||
|
||||
def set_ringer(self, device):
|
||||
self.ringer_device = device
|
||||
self.telephone.set_ringer(self.ringer_device)
|
||||
|
||||
def announce(self, attached_interface=None):
|
||||
self.telephone.announce(attached_interface=attached_interface)
|
||||
|
||||
@property
|
||||
def is_available(self):
|
||||
return self.state == self.STATE_AVAILABLE
|
||||
@ -84,7 +99,6 @@ class ReticulumTelephone():
|
||||
|
||||
def start(self):
|
||||
if not self.should_run:
|
||||
self.telephone.announce()
|
||||
self.should_run = True
|
||||
self.run()
|
||||
|
||||
|
@ -40,7 +40,7 @@ class Utilities():
|
||||
self.screen.delegate = self
|
||||
self.app.root.ids.screen_manager.add_widget(self.screen)
|
||||
|
||||
self.screen.ids.telemetry_scrollview.effect_cls = ScrollEffect
|
||||
self.screen.ids.utilities_scrollview.effect_cls = ScrollEffect
|
||||
info = "This section contains various utilities and diagnostics tools, "
|
||||
info += "that can be helpful while using Sideband and Reticulum."
|
||||
|
||||
@ -220,7 +220,7 @@ MDScreen:
|
||||
]
|
||||
|
||||
ScrollView:
|
||||
id: telemetry_scrollview
|
||||
id: utilities_scrollview
|
||||
|
||||
MDBoxLayout:
|
||||
orientation: "vertical"
|
||||
|
@ -10,6 +10,7 @@ from kivymd.uix.recycleview import MDRecycleView
|
||||
from kivymd.uix.list import OneLineIconListItem
|
||||
from kivymd.uix.pickers import MDColorPicker
|
||||
from kivymd.uix.button import MDRectangleFlatButton
|
||||
from kivymd.uix.button import MDRectangleFlatIconButton
|
||||
from kivymd.uix.dialog import MDDialog
|
||||
from kivymd.icon_definitions import md_icons
|
||||
from kivymd.toast import toast
|
||||
@ -34,6 +35,11 @@ class Voice():
|
||||
self.dial_target = None
|
||||
self.ui_updater = None
|
||||
self.path_requesting = None
|
||||
self.output_devices = []
|
||||
self.input_devices = []
|
||||
self.listed_output_devices = []
|
||||
self.listed_input_devices = []
|
||||
self.listed_ringer_devices = []
|
||||
|
||||
if not self.app.root.ids.screen_manager.has_screen("voice_screen"):
|
||||
self.screen = Builder.load_string(layout_voice_screen)
|
||||
@ -42,13 +48,6 @@ class Voice():
|
||||
self.app.root.ids.screen_manager.add_widget(self.screen)
|
||||
|
||||
self.screen.ids.voice_scrollview.effect_cls = ScrollEffect
|
||||
# info = "Voice services UI"
|
||||
# info += ""
|
||||
|
||||
# if self.app.theme_cls.theme_style == "Dark":
|
||||
# info = "[color=#"+self.app.dark_theme_text_color+"]"+info+"[/color]"
|
||||
|
||||
# self.screen.ids.voice_info.text = info
|
||||
|
||||
def update_call_status(self, dt=None):
|
||||
if self.app.root.ids.screen_manager.current == "voice_screen":
|
||||
@ -170,6 +169,120 @@ class Voice():
|
||||
self.app.sideband.telephone.answer()
|
||||
self.update_call_status()
|
||||
|
||||
|
||||
### settings screen
|
||||
######################################
|
||||
|
||||
def settings_action(self, sender=None):
|
||||
if not self.app.root.ids.screen_manager.has_screen("voice_settings_screen"):
|
||||
self.voice_settings_screen = Builder.load_string(layout_voice_settings_screen)
|
||||
self.voice_settings_screen.app = self.app
|
||||
self.voice_settings_screen.delegate = self
|
||||
self.app.root.ids.screen_manager.add_widget(self.voice_settings_screen)
|
||||
|
||||
self.app.root.ids.screen_manager.transition.direction = "left"
|
||||
self.app.root.ids.screen_manager.current = "voice_settings_screen"
|
||||
self.voice_settings_screen.ids.voice_settings_scrollview.effect_cls = ScrollEffect
|
||||
self.app.sideband.setstate("app.displaying", self.app.root.ids.screen_manager.current)
|
||||
|
||||
self.update_settings_screen()
|
||||
|
||||
def update_devices(self):
|
||||
import LXST
|
||||
self.output_devices = []; self.input_devices = []
|
||||
for device in LXST.Sources.Backend().soundcard.all_speakers(): self.output_devices.append(device.name)
|
||||
for device in LXST.Sinks.Backend().soundcard.all_microphones(): self.input_devices.append(device.name)
|
||||
if self.app.sideband.config["voice_output"] != None:
|
||||
if not self.app.sideband.config["voice_output"] in self.output_devices: self.output_devices.append(self.app.sideband.config["voice_output"])
|
||||
if self.app.sideband.config["voice_input"] != None:
|
||||
if not self.app.sideband.config["voice_input"] in self.input_devices: self.input_devices.append(self.app.sideband.config["voice_input"])
|
||||
if self.app.sideband.config["voice_ringer"] != None:
|
||||
if not self.app.sideband.config["voice_ringer"] in self.output_devices: self.output_devices.append(self.app.sideband.config["voice_ringer"])
|
||||
|
||||
def update_settings_screen(self, sender=None):
|
||||
bp = 6; ml = 45; fs = 16; ics = 14
|
||||
self.update_devices()
|
||||
|
||||
# Output devices
|
||||
if not "system_default" in self.listed_output_devices:
|
||||
default_output_button = MDRectangleFlatIconButton(text="System Default", font_size=dp(fs), icon_size=dp(ics), on_release=self.output_device_action)
|
||||
default_output_button.device = None; default_output_button.size_hint = [1.0, None]
|
||||
if self.app.sideband.config["voice_output"] == None: default_output_button.icon = "check"
|
||||
self.voice_settings_screen.ids.output_devices.add_widget(default_output_button)
|
||||
self.listed_output_devices.append("system_default")
|
||||
|
||||
for device in self.output_devices:
|
||||
if not device in self.listed_output_devices:
|
||||
label = device if len(device) < ml else device[:ml-3]+"..."
|
||||
device_button = MDRectangleFlatIconButton(text=label, font_size=dp(fs), icon_size=dp(ics), on_release=self.output_device_action)
|
||||
device_button.padding = [dp(bp), dp(bp), dp(bp), dp(bp)]; device_button.size_hint = [1.0, None]
|
||||
if self.app.sideband.config["voice_output"] == device: device_button.icon = "check"
|
||||
device_button.device = device
|
||||
self.voice_settings_screen.ids.output_devices.add_widget(device_button)
|
||||
self.listed_output_devices.append(device)
|
||||
|
||||
# Input devices
|
||||
if not "system_default" in self.listed_input_devices:
|
||||
default_input_button = MDRectangleFlatIconButton(text="System Default", font_size=dp(fs), icon_size=dp(ics), on_release=self.input_device_action)
|
||||
default_input_button.device = None; default_input_button.size_hint = [1.0, None]
|
||||
if self.app.sideband.config["voice_output"] == None: default_input_button.icon = "check"
|
||||
self.voice_settings_screen.ids.input_devices.add_widget(default_input_button)
|
||||
self.listed_input_devices.append("system_default")
|
||||
|
||||
for device in self.input_devices:
|
||||
if not device in self.listed_input_devices:
|
||||
label = device if len(device) < ml else device[:ml-3]+"..."
|
||||
device_button = MDRectangleFlatIconButton(text=label, font_size=dp(fs), icon_size=dp(ics), on_release=self.input_device_action)
|
||||
device_button.padding = [dp(bp), dp(bp), dp(bp), dp(bp)]; device_button.size_hint = [1.0, None]
|
||||
if self.app.sideband.config["voice_input"] == device: device_button.icon = "check"
|
||||
device_button.device = device
|
||||
self.voice_settings_screen.ids.input_devices.add_widget(device_button)
|
||||
self.listed_input_devices.append(device)
|
||||
|
||||
# Ringer devices
|
||||
if not "system_default" in self.listed_ringer_devices:
|
||||
default_ringer_button = MDRectangleFlatIconButton(text="System Default", font_size=dp(fs), icon_size=dp(ics), on_release=self.ringer_device_action)
|
||||
default_ringer_button.device = None; default_ringer_button.size_hint = [1.0, None]
|
||||
if self.app.sideband.config["voice_ringer"] == None: default_ringer_button.icon = "check"
|
||||
self.voice_settings_screen.ids.ringer_devices.add_widget(default_ringer_button)
|
||||
self.listed_ringer_devices.append("system_default")
|
||||
|
||||
for device in self.output_devices:
|
||||
if not device in self.listed_ringer_devices:
|
||||
label = device if len(device) < ml else device[:ml-3]+"..."
|
||||
device_button = MDRectangleFlatIconButton(text=label, font_size=dp(fs), icon_size=dp(ics), on_release=self.ringer_device_action)
|
||||
device_button.padding = [dp(bp), dp(bp), dp(bp), dp(bp)]; device_button.size_hint = [1.0, None]
|
||||
if self.app.sideband.config["voice_ringer"] == device: device_button.icon = "check"
|
||||
device_button.device = device
|
||||
self.voice_settings_screen.ids.ringer_devices.add_widget(device_button)
|
||||
self.listed_ringer_devices.append(device)
|
||||
|
||||
|
||||
def output_device_action(self, sender=None):
|
||||
self.app.sideband.config["voice_output"] = sender.device
|
||||
self.app.sideband.save_configuration()
|
||||
for w in self.voice_settings_screen.ids.output_devices.children: w.icon = ""
|
||||
sender.icon = "check"
|
||||
if self.app.sideband.telephone:
|
||||
self.app.sideband.telephone.set_speaker(self.app.sideband.config["voice_output"])
|
||||
|
||||
def input_device_action(self, sender=None):
|
||||
self.app.sideband.config["voice_input"] = sender.device
|
||||
self.app.sideband.save_configuration()
|
||||
for w in self.voice_settings_screen.ids.input_devices.children: w.icon = ""
|
||||
sender.icon = "check"
|
||||
if self.app.sideband.telephone:
|
||||
self.app.sideband.telephone.set_microphone(self.app.sideband.config["voice_input"])
|
||||
|
||||
def ringer_device_action(self, sender=None):
|
||||
self.app.sideband.config["voice_ringer"] = sender.device
|
||||
self.app.sideband.save_configuration()
|
||||
for w in self.voice_settings_screen.ids.ringer_devices.children: w.icon = ""
|
||||
sender.icon = "check"
|
||||
if self.app.sideband.telephone:
|
||||
self.app.sideband.telephone.set_ringer(self.app.sideband.config["voice_ringer"])
|
||||
|
||||
|
||||
layout_voice_screen = """
|
||||
MDScreen:
|
||||
name: "voice_screen"
|
||||
@ -185,6 +298,7 @@ MDScreen:
|
||||
[['menu', lambda x: root.app.nav_drawer.set_state("open")]]
|
||||
right_action_items:
|
||||
[
|
||||
['wrench-cog', lambda x: root.delegate.settings_action(self)],
|
||||
['close', lambda x: root.app.close_any_action(self)],
|
||||
]
|
||||
|
||||
@ -231,3 +345,93 @@ MDScreen:
|
||||
on_release: root.delegate.dial_action(self)
|
||||
disabled: True
|
||||
"""
|
||||
|
||||
layout_voice_settings_screen = """
|
||||
MDScreen:
|
||||
name: "voice_settings_screen"
|
||||
|
||||
BoxLayout:
|
||||
orientation: "vertical"
|
||||
|
||||
MDTopAppBar:
|
||||
id: top_bar
|
||||
title: "Voice Configuration"
|
||||
anchor_title: "left"
|
||||
elevation: 0
|
||||
left_action_items:
|
||||
[['menu', lambda x: root.app.nav_drawer.set_state("open")]]
|
||||
right_action_items:
|
||||
[
|
||||
['close', lambda x: root.app.close_sub_voice_action(self)],
|
||||
]
|
||||
|
||||
MDScrollView:
|
||||
id: voice_settings_scrollview
|
||||
size_hint_x: 1
|
||||
size_hint_y: None
|
||||
size: [root.width, root.height-root.ids.top_bar.height]
|
||||
do_scroll_x: False
|
||||
do_scroll_y: True
|
||||
|
||||
MDBoxLayout:
|
||||
orientation: "vertical"
|
||||
size_hint_y: None
|
||||
height: self.minimum_height
|
||||
padding: [dp(28), dp(32), dp(28), dp(16)]
|
||||
|
||||
MDLabel:
|
||||
id: voice_settings_info
|
||||
markup: True
|
||||
text: "You can configure which audio devices Sideband will use for voice calls, by selecting either the system default device, or specific audio devices available."
|
||||
size_hint_y: None
|
||||
text_size: self.width, None
|
||||
height: self.texture_size[1]
|
||||
padding: [dp(0), dp(0), dp(0), dp(48)]
|
||||
|
||||
MDLabel:
|
||||
text: "Output Device"
|
||||
font_style: "H6"
|
||||
|
||||
MDBoxLayout:
|
||||
id: output_devices
|
||||
orientation: "vertical"
|
||||
spacing: "12dp"
|
||||
size_hint_y: None
|
||||
height: self.minimum_height
|
||||
padding: [dp(0), dp(35), dp(0), dp(48)]
|
||||
|
||||
# MDRectangleFlatIconButton:
|
||||
# id: output_default_button
|
||||
# text: "System Default"
|
||||
# padding: [dp(0), dp(14), dp(0), dp(14)]
|
||||
# icon_size: dp(24)
|
||||
# font_size: dp(16)
|
||||
# size_hint: [1.0, None]
|
||||
# on_release: root.delegate.output_device_action(self)
|
||||
# disabled: False
|
||||
|
||||
MDLabel:
|
||||
text: "Input Device"
|
||||
font_style: "H6"
|
||||
|
||||
MDBoxLayout:
|
||||
id: input_devices
|
||||
orientation: "vertical"
|
||||
spacing: "12dp"
|
||||
size_hint_y: None
|
||||
height: self.minimum_height
|
||||
padding: [dp(0), dp(35), dp(0), dp(48)]
|
||||
|
||||
MDLabel:
|
||||
text: "Ringer Device"
|
||||
font_style: "H6"
|
||||
|
||||
MDBoxLayout:
|
||||
id: ringer_devices
|
||||
orientation: "vertical"
|
||||
spacing: "12dp"
|
||||
size_hint_y: None
|
||||
height: self.minimum_height
|
||||
padding: [dp(0), dp(35), dp(0), dp(48)]
|
||||
|
||||
"""
|
Loading…
x
Reference in New Issue
Block a user