Refactored views

This commit is contained in:
Mark Qvist 2023-10-22 17:14:32 +02:00
parent 666af3fffa
commit 8416805f41
3 changed files with 161 additions and 128 deletions

View File

@ -1,4 +1,4 @@
__debug_build__ = True __debug_build__ = False
__disable_shaders__ = False __disable_shaders__ = False
__version__ = "0.6.3" __version__ = "0.6.3"
__variant__ = "beta" __variant__ = "beta"
@ -1223,16 +1223,26 @@ class SidebandApp(MDApp):
### Information/version screen ### Information/version screen
###################################### ######################################
def information_action(self, sender=None): def information_action(self, sender=None):
def link_exec(sender=None, event=None): if not self.root.ids.screen_manager.has_screen("information_screen"):
import webbrowser self.information_screen = Builder.load_string(layout_information_screen)
webbrowser.open("https://unsigned.io/donate") self.information_screen.app = self
self.root.ids.screen_manager.add_widget(self.information_screen)
self.root.ids.information_scrollview.effect_cls = ScrollEffect def link_exec(sender=None, event=None):
self.root.ids.information_logo.icon = self.sideband.asset_dir+"/rns_256.png" def lj():
import webbrowser
webbrowser.open("https://unsigned.io/donate")
if not RNS.vendor.platformutils.is_android():
threading.Thread(target=lj, daemon=True).start()
else:
lj()
self.information_screen.ids.information_scrollview.effect_cls = ScrollEffect
self.information_screen.ids.information_logo.icon = self.sideband.asset_dir+"/rns_256.png"
info = "This is Sideband v"+__version__+" "+__variant__+", on RNS v"+RNS.__version__+" and LXMF v"+LXMF.__version__+".\n\nHumbly build using the following open components:\n\n - [b]Reticulum[/b] (MIT License)\n - [b]LXMF[/b] (MIT License)\n - [b]KivyMD[/b] (MIT License)\n - [b]Kivy[/b] (MIT License)\n - [b]Python[/b] (PSF License)"+"\n\nGo to [u][ref=link]https://unsigned.io/donate[/ref][/u] to support the project.\n\nThe Sideband app is Copyright (c) 2022 Mark Qvist / unsigned.io\n\nPermission is granted to freely share and distribute binary copies of Sideband v"+__version__+" "+__variant__+", so long as no payment or compensation is charged for said distribution or sharing.\n\nIf you were charged or paid anything for this copy of Sideband, please report it to [b]license@unsigned.io[/b].\n\nTHIS IS EXPERIMENTAL SOFTWARE - SIDEBAND COMES WITH ABSOLUTELY NO WARRANTY - USE AT YOUR OWN RISK AND RESPONSIBILITY" info = "This is Sideband v"+__version__+" "+__variant__+", on RNS v"+RNS.__version__+" and LXMF v"+LXMF.__version__+".\n\nHumbly build using the following open components:\n\n - [b]Reticulum[/b] (MIT License)\n - [b]LXMF[/b] (MIT License)\n - [b]KivyMD[/b] (MIT License)\n - [b]Kivy[/b] (MIT License)\n - [b]Python[/b] (PSF License)"+"\n\nGo to [u][ref=link]https://unsigned.io/donate[/ref][/u] to support the project.\n\nThe Sideband app is Copyright (c) 2022 Mark Qvist / unsigned.io\n\nPermission is granted to freely share and distribute binary copies of Sideband v"+__version__+" "+__variant__+", so long as no payment or compensation is charged for said distribution or sharing.\n\nIf you were charged or paid anything for this copy of Sideband, please report it to [b]license@unsigned.io[/b].\n\nTHIS IS EXPERIMENTAL SOFTWARE - SIDEBAND COMES WITH ABSOLUTELY NO WARRANTY - USE AT YOUR OWN RISK AND RESPONSIBILITY"
self.root.ids.information_info.text = info self.information_screen.ids.information_info.text = info
self.root.ids.information_info.bind(on_ref_press=link_exec) self.information_screen.ids.information_info.bind(on_ref_press=link_exec)
self.root.ids.screen_manager.transition.direction = "left" self.root.ids.screen_manager.transition.direction = "left"
self.root.ids.screen_manager.current = "information_screen" self.root.ids.screen_manager.current = "information_screen"
self.root.ids.nav_drawer.set_state("closed") self.root.ids.nav_drawer.set_state("closed")
@ -1249,17 +1259,22 @@ class SidebandApp(MDApp):
self.root.ids.screen_manager.transition.direction = "left" self.root.ids.screen_manager.transition.direction = "left"
self.root.ids.nav_drawer.set_state("closed") self.root.ids.nav_drawer.set_state("closed")
if self.sideband.active_propagation_node != None: if self.sideband.active_propagation_node != None:
self.root.ids.settings_propagation_node_address.text = RNS.hexrep(self.sideband.active_propagation_node, delimit=False) self.settings_screen.ids.settings_propagation_node_address.text = RNS.hexrep(self.sideband.active_propagation_node, delimit=False)
self.root.ids.screen_manager.current = "settings_screen" self.root.ids.screen_manager.current = "settings_screen"
self.sideband.setstate("app.displaying", self.root.ids.screen_manager.current) self.sideband.setstate("app.displaying", self.root.ids.screen_manager.current)
def settings_init(self, sender=None): def settings_init(self, sender=None):
if not self.settings_ready: if not self.settings_ready:
self.root.ids.settings_scrollview.effect_cls = ScrollEffect if not self.root.ids.screen_manager.has_screen("settings_screen"):
self.settings_screen = Builder.load_string(layout_settings_screen)
self.settings_screen.app = self
self.root.ids.screen_manager.add_widget(self.settings_screen)
self.settings_screen.ids.settings_scrollview.effect_cls = ScrollEffect
def save_disp_name(sender=None, event=None): def save_disp_name(sender=None, event=None):
if not sender.focus: if not sender.focus:
in_name = self.root.ids.settings_display_name.text in_name = self.settings_screen.ids.settings_display_name.text
if in_name == "": if in_name == "":
new_name = "Anonymous Peer" new_name = "Anonymous Peer"
else: else:
@ -1270,12 +1285,12 @@ class SidebandApp(MDApp):
def save_prop_addr(sender=None, event=None): def save_prop_addr(sender=None, event=None):
if not sender.focus: if not sender.focus:
in_addr = self.root.ids.settings_propagation_node_address.text in_addr = self.settings_screen.ids.settings_propagation_node_address.text
new_addr = None new_addr = None
if in_addr == "": if in_addr == "":
new_addr = None new_addr = None
self.root.ids.settings_propagation_node_address.error = False self.settings_screen.ids.settings_propagation_node_address.error = False
else: else:
if len(in_addr) != RNS.Reticulum.TRUNCATED_HASHLENGTH//8*2: if len(in_addr) != RNS.Reticulum.TRUNCATED_HASHLENGTH//8*2:
new_addr = None new_addr = None
@ -1286,137 +1301,137 @@ class SidebandApp(MDApp):
new_addr = None new_addr = None
if new_addr == None: if new_addr == None:
self.root.ids.settings_propagation_node_address.error = True self.settings_screen.ids.settings_propagation_node_address.error = True
else: else:
self.root.ids.settings_propagation_node_address.error = False self.settings_screen.ids.settings_propagation_node_address.error = False
self.sideband.config["lxmf_propagation_node"] = new_addr self.sideband.config["lxmf_propagation_node"] = new_addr
self.sideband.set_active_propagation_node(self.sideband.config["lxmf_propagation_node"]) self.sideband.set_active_propagation_node(self.sideband.config["lxmf_propagation_node"])
def save_dark_ui(sender=None, event=None): def save_dark_ui(sender=None, event=None):
self.sideband.config["dark_ui"] = self.root.ids.settings_dark_ui.active self.sideband.config["dark_ui"] = self.settings_screen.ids.settings_dark_ui.active
self.sideband.save_configuration() self.sideband.save_configuration()
self.update_ui_theme() self.update_ui_theme()
def save_eink_mode(sender=None, event=None): def save_eink_mode(sender=None, event=None):
self.sideband.config["eink_mode"] = self.root.ids.settings_eink_mode.active self.sideband.config["eink_mode"] = self.settings_screen.ids.settings_eink_mode.active
self.sideband.save_configuration() self.sideband.save_configuration()
self.update_ui_theme() self.update_ui_theme()
def save_advanced_stats(sender=None, event=None): def save_advanced_stats(sender=None, event=None):
self.sideband.config["advanced_stats"] = self.root.ids.settings_advanced_statistics.active self.sideband.config["advanced_stats"] = self.settings_screen.ids.settings_advanced_statistics.active
self.sideband.save_configuration() self.sideband.save_configuration()
def save_notifications_on(sender=None, event=None): def save_notifications_on(sender=None, event=None):
self.sideband.config["notifications_on"] = self.root.ids.settings_notifications_on.active self.sideband.config["notifications_on"] = self.settings_screen.ids.settings_notifications_on.active
self.sideband.save_configuration() self.sideband.save_configuration()
def save_start_announce(sender=None, event=None): def save_start_announce(sender=None, event=None):
self.sideband.config["start_announce"] = self.root.ids.settings_start_announce.active self.sideband.config["start_announce"] = self.settings_screen.ids.settings_start_announce.active
self.sideband.save_configuration() self.sideband.save_configuration()
def save_lxmf_delivery_by_default(sender=None, event=None): def save_lxmf_delivery_by_default(sender=None, event=None):
self.sideband.config["propagation_by_default"] = self.root.ids.settings_lxmf_delivery_by_default.active self.sideband.config["propagation_by_default"] = self.settings_screen.ids.settings_lxmf_delivery_by_default.active
self.sideband.save_configuration() self.sideband.save_configuration()
def save_lxmf_ignore_unknown(sender=None, event=None): def save_lxmf_ignore_unknown(sender=None, event=None):
self.sideband.config["lxmf_ignore_unknown"] = self.root.ids.settings_lxmf_ignore_unknown.active self.sideband.config["lxmf_ignore_unknown"] = self.settings_screen.ids.settings_lxmf_ignore_unknown.active
self.sideband.save_configuration() self.sideband.save_configuration()
def save_lxmf_sync_limit(sender=None, event=None): def save_lxmf_sync_limit(sender=None, event=None):
self.sideband.config["lxmf_sync_limit"] = self.root.ids.settings_lxmf_sync_limit.active self.sideband.config["lxmf_sync_limit"] = self.settings_screen.ids.settings_lxmf_sync_limit.active
self.sideband.save_configuration() self.sideband.save_configuration()
def save_debug(sender=None, event=None): def save_debug(sender=None, event=None):
self.sideband.config["debug"] = self.root.ids.settings_debug.active self.sideband.config["debug"] = self.settings_screen.ids.settings_debug.active
self.sideband.save_configuration() self.sideband.save_configuration()
def save_print_command(sender=None, event=None): def save_print_command(sender=None, event=None):
if not sender.focus: if not sender.focus:
in_cmd = self.root.ids.settings_print_command.text in_cmd = self.settings_screen.ids.settings_print_command.text
if in_cmd == "": if in_cmd == "":
new_cmd = "lp" new_cmd = "lp"
else: else:
new_cmd = in_cmd new_cmd = in_cmd
self.sideband.config["print_command"] = new_cmd.strip() self.sideband.config["print_command"] = new_cmd.strip()
self.root.ids.settings_print_command.text = self.sideband.config["print_command"] self.settings_screen.ids.settings_print_command.text = self.sideband.config["print_command"]
self.sideband.save_configuration() self.sideband.save_configuration()
def save_lxmf_periodic_sync(sender=None, event=None, save=True): def save_lxmf_periodic_sync(sender=None, event=None, save=True):
if self.root.ids.settings_lxmf_periodic_sync.active: if self.settings_screen.ids.settings_lxmf_periodic_sync.active:
self.widget_hide(self.root.ids.lxmf_syncslider_container, False) self.widget_hide(self.settings_screen.ids.lxmf_syncslider_container, False)
else: else:
self.widget_hide(self.root.ids.lxmf_syncslider_container, True) self.widget_hide(self.settings_screen.ids.lxmf_syncslider_container, True)
if save: if save:
self.sideband.config["lxmf_periodic_sync"] = self.root.ids.settings_lxmf_periodic_sync.active self.sideband.config["lxmf_periodic_sync"] = self.settings_screen.ids.settings_lxmf_periodic_sync.active
self.sideband.save_configuration() self.sideband.save_configuration()
def sync_interval_change(sender=None, event=None, save=True): def sync_interval_change(sender=None, event=None, save=True):
interval = (self.root.ids.settings_lxmf_sync_interval.value//300)*300 interval = (self.settings_screen.ids.settings_lxmf_sync_interval.value//300)*300
interval_text = RNS.prettytime(interval) interval_text = RNS.prettytime(interval)
pre = self.root.ids.settings_lxmf_sync_periodic.text pre = self.settings_screen.ids.settings_lxmf_sync_periodic.text
self.root.ids.settings_lxmf_sync_periodic.text = "Auto sync every "+interval_text self.settings_screen.ids.settings_lxmf_sync_periodic.text = "Auto sync every "+interval_text
if save: if save:
self.sideband.config["lxmf_sync_interval"] = interval self.sideband.config["lxmf_sync_interval"] = interval
self.sideband.save_configuration() self.sideband.save_configuration()
self.root.ids.settings_lxmf_address.text = RNS.hexrep(self.sideband.lxmf_destination.hash, delimit=False) self.settings_screen.ids.settings_lxmf_address.text = RNS.hexrep(self.sideband.lxmf_destination.hash, delimit=False)
self.root.ids.settings_identity_hash.text = RNS.hexrep(self.sideband.lxmf_destination.identity.hash, delimit=False) self.settings_screen.ids.settings_identity_hash.text = RNS.hexrep(self.sideband.lxmf_destination.identity.hash, delimit=False)
self.root.ids.settings_display_name.text = self.sideband.config["display_name"] self.settings_screen.ids.settings_display_name.text = self.sideband.config["display_name"]
self.root.ids.settings_display_name.bind(focus=save_disp_name) self.settings_screen.ids.settings_display_name.bind(focus=save_disp_name)
if RNS.vendor.platformutils.is_android(): if RNS.vendor.platformutils.is_android():
self.widget_hide(self.root.ids.settings_print_command, True) self.widget_hide(self.settings_screen.ids.settings_print_command, True)
else: else:
self.root.ids.settings_print_command.text = self.sideband.config["print_command"] self.settings_screen.ids.settings_print_command.text = self.sideband.config["print_command"]
self.root.ids.settings_print_command.bind(focus=save_print_command) self.settings_screen.ids.settings_print_command.bind(focus=save_print_command)
if self.sideband.config["lxmf_propagation_node"] == None: if self.sideband.config["lxmf_propagation_node"] == None:
prop_node_addr = "" prop_node_addr = ""
else: else:
prop_node_addr = RNS.hexrep(self.sideband.config["lxmf_propagation_node"], delimit=False) prop_node_addr = RNS.hexrep(self.sideband.config["lxmf_propagation_node"], delimit=False)
self.root.ids.settings_propagation_node_address.text = prop_node_addr self.settings_screen.ids.settings_propagation_node_address.text = prop_node_addr
self.root.ids.settings_propagation_node_address.bind(focus=save_prop_addr) self.settings_screen.ids.settings_propagation_node_address.bind(focus=save_prop_addr)
if not RNS.vendor.platformutils.is_android() or android_api_version >= 26: if not RNS.vendor.platformutils.is_android() or android_api_version >= 26:
self.root.ids.settings_notifications_on.active = self.sideband.config["notifications_on"] self.settings_screen.ids.settings_notifications_on.active = self.sideband.config["notifications_on"]
self.root.ids.settings_notifications_on.bind(active=save_notifications_on) self.settings_screen.ids.settings_notifications_on.bind(active=save_notifications_on)
else: else:
self.root.ids.settings_notifications_on.active = False self.settings_screen.ids.settings_notifications_on.active = False
self.root.ids.settings_notifications_on.disabled = True self.settings_screen.ids.settings_notifications_on.disabled = True
self.root.ids.settings_dark_ui.active = self.sideband.config["dark_ui"] self.settings_screen.ids.settings_dark_ui.active = self.sideband.config["dark_ui"]
self.root.ids.settings_dark_ui.bind(active=save_dark_ui) self.settings_screen.ids.settings_dark_ui.bind(active=save_dark_ui)
self.root.ids.settings_eink_mode.active = self.sideband.config["eink_mode"] self.settings_screen.ids.settings_eink_mode.active = self.sideband.config["eink_mode"]
self.root.ids.settings_eink_mode.bind(active=save_eink_mode) self.settings_screen.ids.settings_eink_mode.bind(active=save_eink_mode)
self.root.ids.settings_advanced_statistics.active = self.sideband.config["advanced_stats"] self.settings_screen.ids.settings_advanced_statistics.active = self.sideband.config["advanced_stats"]
self.root.ids.settings_advanced_statistics.bind(active=save_advanced_stats) self.settings_screen.ids.settings_advanced_statistics.bind(active=save_advanced_stats)
self.root.ids.settings_start_announce.active = self.sideband.config["start_announce"] self.settings_screen.ids.settings_start_announce.active = self.sideband.config["start_announce"]
self.root.ids.settings_start_announce.bind(active=save_start_announce) self.settings_screen.ids.settings_start_announce.bind(active=save_start_announce)
self.root.ids.settings_lxmf_delivery_by_default.active = self.sideband.config["propagation_by_default"] self.settings_screen.ids.settings_lxmf_delivery_by_default.active = self.sideband.config["propagation_by_default"]
self.root.ids.settings_lxmf_delivery_by_default.bind(active=save_lxmf_delivery_by_default) self.settings_screen.ids.settings_lxmf_delivery_by_default.bind(active=save_lxmf_delivery_by_default)
self.root.ids.settings_lxmf_ignore_unknown.active = self.sideband.config["lxmf_ignore_unknown"] self.settings_screen.ids.settings_lxmf_ignore_unknown.active = self.sideband.config["lxmf_ignore_unknown"]
self.root.ids.settings_lxmf_ignore_unknown.bind(active=save_lxmf_ignore_unknown) self.settings_screen.ids.settings_lxmf_ignore_unknown.bind(active=save_lxmf_ignore_unknown)
self.root.ids.settings_lxmf_periodic_sync.active = self.sideband.config["lxmf_periodic_sync"] self.settings_screen.ids.settings_lxmf_periodic_sync.active = self.sideband.config["lxmf_periodic_sync"]
self.root.ids.settings_lxmf_periodic_sync.bind(active=save_lxmf_periodic_sync) self.settings_screen.ids.settings_lxmf_periodic_sync.bind(active=save_lxmf_periodic_sync)
save_lxmf_periodic_sync(save=False) save_lxmf_periodic_sync(save=False)
def sync_interval_change_cb(sender=None, event=None): def sync_interval_change_cb(sender=None, event=None):
sync_interval_change(sender=sender, event=event, save=False) sync_interval_change(sender=sender, event=event, save=False)
self.root.ids.settings_lxmf_sync_interval.bind(value=sync_interval_change_cb) self.settings_screen.ids.settings_lxmf_sync_interval.bind(value=sync_interval_change_cb)
self.root.ids.settings_lxmf_sync_interval.bind(on_touch_up=sync_interval_change) self.settings_screen.ids.settings_lxmf_sync_interval.bind(on_touch_up=sync_interval_change)
self.root.ids.settings_lxmf_sync_interval.value = self.sideband.config["lxmf_sync_interval"] self.settings_screen.ids.settings_lxmf_sync_interval.value = self.sideband.config["lxmf_sync_interval"]
sync_interval_change(save=False) sync_interval_change(save=False)
if self.sideband.config["lxmf_sync_limit"] == None or self.sideband.config["lxmf_sync_limit"] == False: if self.sideband.config["lxmf_sync_limit"] == None or self.sideband.config["lxmf_sync_limit"] == False:
@ -1424,11 +1439,11 @@ class SidebandApp(MDApp):
else: else:
sync_limit = True sync_limit = True
self.root.ids.settings_lxmf_sync_limit.active = sync_limit self.settings_screen.ids.settings_lxmf_sync_limit.active = sync_limit
self.root.ids.settings_lxmf_sync_limit.bind(active=save_lxmf_sync_limit) self.settings_screen.ids.settings_lxmf_sync_limit.bind(active=save_lxmf_sync_limit)
self.root.ids.settings_debug.active = self.sideband.config["debug"] self.settings_screen.ids.settings_debug.active = self.sideband.config["debug"]
self.root.ids.settings_debug.bind(active=save_debug) self.settings_screen.ids.settings_debug.bind(active=save_debug)
self.settings_ready = True self.settings_ready = True
@ -1783,10 +1798,10 @@ class SidebandApp(MDApp):
self.root.ids.screen_manager.current = "repository_screen" self.root.ids.screen_manager.current = "repository_screen"
self.root.ids.nav_drawer.set_state("closed") self.root.ids.nav_drawer.set_state("closed")
if not RNS.vendor.platformutils.is_android(): if not RNS.vendor.platformutils.is_android():
self.widget_hide(self.root.ids.repository_enable_button) self.widget_hide(self.repository_screen.ids.repository_enable_button)
self.widget_hide(self.root.ids.repository_disable_button) self.widget_hide(self.repository_screen.ids.repository_disable_button)
self.widget_hide(self.root.ids.repository_download_button) self.widget_hide(self.repository_screen.ids.repository_download_button)
self.root.ids.repository_info.text = "\nThe [b]Repository Webserver[/b] feature is currently only available on mobile devices." self.repository_screen.ids.repository_info.text = "\nThe [b]Repository Webserver[/b] feature is currently only available on mobile devices."
self.sideband.setstate("app.displaying", self.root.ids.screen_manager.current) self.sideband.setstate("app.displaying", self.root.ids.screen_manager.current)
@ -1833,15 +1848,15 @@ class SidebandApp(MDApp):
ms = "" if len(ips) == 1 else "es" ms = "" if len(ips) == 1 else "es"
info += "The repository server is running at the following address"+ms+":\n"+ipstr info += "The repository server is running at the following address"+ms+":\n"+ipstr
self.root.ids.repository_enable_button.disabled = True self.repository_screen.ids.repository_enable_button.disabled = True
self.root.ids.repository_disable_button.disabled = False self.repository_screen.ids.repository_disable_button.disabled = False
else: else:
self.root.ids.repository_enable_button.disabled = False self.repository_screen.ids.repository_enable_button.disabled = False
self.root.ids.repository_disable_button.disabled = True self.repository_screen.ids.repository_disable_button.disabled = True
info += "\n" info += "\n"
self.root.ids.repository_info.text = info self.repository_screen.ids.repository_info.text = info
def repository_start_action(self, sender=None): def repository_start_action(self, sender=None):
self.sideband.start_webshare() self.sideband.start_webshare()
@ -1873,10 +1888,10 @@ class SidebandApp(MDApp):
apk_version = release["tag_name"] apk_version = release["tag_name"]
RNS.log(f"Found version {apk_version} artefact {pkgname} at {apk_url}") RNS.log(f"Found version {apk_version} artefact {pkgname} at {apk_url}")
except Exception as e: except Exception as e:
self.root.ids.repository_update.text = f"Downloading release info failed with the error:\n"+str(e) self.repository_screen.ids.repository_update.text = f"Downloading release info failed with the error:\n"+str(e)
return return
self.root.ids.repository_update.text = "Downloading: "+str(apk_url) self.repository_screen.ids.repository_update.text = "Downloading: "+str(apk_url)
with requests.get(apk_url, stream=True) as response: with requests.get(apk_url, stream=True) as response:
with open("./dl_tmp", "wb") as tmp_file: with open("./dl_tmp", "wb") as tmp_file:
cs = 32*1024 cs = 32*1024
@ -1884,25 +1899,30 @@ class SidebandApp(MDApp):
for chunk in response.iter_content(chunk_size=cs): for chunk in response.iter_content(chunk_size=cs):
tmp_file.write(chunk) tmp_file.write(chunk)
tds += cs tds += cs
self.root.ids.repository_update.text = "Downloaded "+RNS.prettysize(tds)+" of "+str(pkgname) self.repository_screen.ids.repository_update.text = "Downloaded "+RNS.prettysize(tds)+" of "+str(pkgname)
os.rename("./dl_tmp", f"./share/pkg/{pkgname}") os.rename("./dl_tmp", f"./share/pkg/{pkgname}")
self.root.ids.repository_update.text = f"Added {pkgname} to the repository!" self.repository_screen.ids.repository_update.text = f"Added {pkgname} to the repository!"
except Exception as e: except Exception as e:
self.root.ids.repository_update.text = f"Downloading contents failed with the error:\n"+str(e) self.repository_screen.ids.repository_update.text = f"Downloading contents failed with the error:\n"+str(e)
self.root.ids.repository_update.text = "Starting package download..." self.repository_screen.ids.repository_update.text = "Starting package download..."
def start_update_job(sender=None): def start_update_job(sender=None):
threading.Thread(target=update_job, daemon=True).start() threading.Thread(target=update_job, daemon=True).start()
Clock.schedule_once(start_update_job, 0.5) Clock.schedule_once(start_update_job, 0.5)
def repository_init(self, sender=None): def repository_init(self, sender=None):
if not self.repository_ready: if not self.repository_ready:
self.root.ids.hardware_scrollview.effect_cls = ScrollEffect if not self.root.ids.screen_manager.has_screen("repository_screen"):
self.repository_screen = Builder.load_string(layout_repository_screen)
self.repository_screen.app = self
self.root.ids.screen_manager.add_widget(self.repository_screen)
self.repository_screen.ids.repository_scrollview.effect_cls = ScrollEffect
self.repository_update_info() self.repository_update_info()
self.root.ids.repository_update.text = "" self.repository_screen.ids.repository_update.text = ""
self.repository_ready = True self.repository_ready = True
def close_repository_action(self, sender=None): def close_repository_action(self, sender=None):
@ -2748,18 +2768,18 @@ class SidebandApp(MDApp):
### Keys screen ### Keys screen
###################################### ######################################
def keys_action(self, sender=None): def keys_action(self, sender=None):
# def link_exec(sender=None, event=None): if not self.root.ids.screen_manager.has_screen("keys_screen"):
# import webbrowser self.keys_screen = Builder.load_string(layout_keys_screen)
# webbrowser.open("https://unsigned.io/sideband") self.keys_screen.app = self
# self.root.ids.keys_info.bind(on_ref_press=link_exec) self.root.ids.screen_manager.add_widget(self.keys_screen)
self.root.ids.keys_scrollview.effect_cls = ScrollEffect self.keys_screen.ids.keys_scrollview.effect_cls = ScrollEffect
info = "Your primary encryption keys are stored in a Reticulum Identity within the Sideband app. If you want to backup this Identity for later use on this or another device, you can export it as a plain text blob, with the key data encoded in Base32 format. This will allow you to restore your address in Sideband or other LXMF clients at a later point.\n\n[b]Warning![/b] Anyone that gets access to the key data will be able to control your LXMF address, impersonate you, and read your messages. In is [b]extremely important[/b] that you keep the Identity data secure if you export it.\n\nBefore displaying or exporting your Identity data, make sure that no machine or person in your vicinity is able to see, copy or record your device screen or similar." info = "Your primary encryption keys are stored in a Reticulum Identity within the Sideband app. If you want to backup this Identity for later use on this or another device, you can export it as a plain text blob, with the key data encoded in Base32 format. This will allow you to restore your address in Sideband or other LXMF clients at a later point.\n\n[b]Warning![/b] Anyone that gets access to the key data will be able to control your LXMF address, impersonate you, and read your messages. In is [b]extremely important[/b] that you keep the Identity data secure if you export it.\n\nBefore displaying or exporting your Identity data, make sure that no machine or person in your vicinity is able to see, copy or record your device screen or similar."
if not RNS.vendor.platformutils.get_platform() == "android": if not RNS.vendor.platformutils.get_platform() == "android":
self.widget_hide(self.root.ids.keys_share) self.widget_hide(self.keys_screen.ids.keys_share)
self.root.ids.keys_info.text = info self.keys_screen.ids.keys_info.text = info
self.root.ids.screen_manager.transition.direction = "left" self.root.ids.screen_manager.transition.direction = "left"
self.root.ids.screen_manager.current = "keys_screen" self.root.ids.screen_manager.current = "keys_screen"
self.root.ids.nav_drawer.set_state("closed") self.root.ids.nav_drawer.set_state("closed")
@ -2816,7 +2836,7 @@ class SidebandApp(MDApp):
c_dialog.dismiss() c_dialog.dismiss()
def c_dl_yes(s): def c_dl_yes(s):
c_dialog.dismiss() c_dialog.dismiss()
b32_text = self.root.ids.key_restore_text.text b32_text = self.keys_screen.ids.key_restore_text.text
try: try:
key_bytes = base64.b32decode(b32_text) key_bytes = base64.b32decode(b32_text)
@ -3294,9 +3314,19 @@ class SidebandApp(MDApp):
self.open_conversations(direction="right") self.open_conversations(direction="right")
def guide_action(self, sender=None): def guide_action(self, sender=None):
if not self.root.ids.screen_manager.has_screen("guide_screen"):
self.guide_screen = Builder.load_string(layout_guide_screen)
self.guide_screen.app = self
self.root.ids.screen_manager.add_widget(self.guide_screen)
def link_exec(sender=None, event=None): def link_exec(sender=None, event=None):
import webbrowser def lj():
webbrowser.open("https://unsigned.io/donate") import webbrowser
webbrowser.open("https://unsigned.io/donate")
if not RNS.vendor.platformutils.is_android():
threading.Thread(target=lj, daemon=True).start()
else:
lj()
guide_text1 = """ guide_text1 = """
[size=18dp][b]Introduction[/b][/size][size=5dp]\n \n[/size]Welcome to [i]Sideband[/i], an LXMF client for Android, Linux and macOS. With Sideband, you can communicate with other people or LXMF-compatible systems over Reticulum networks using LoRa, Packet Radio, WiFi, I2P, or anything else Reticulum supports. [size=18dp][b]Introduction[/b][/size][size=5dp]\n \n[/size]Welcome to [i]Sideband[/i], an LXMF client for Android, Linux and macOS. With Sideband, you can communicate with other people or LXMF-compatible systems over Reticulum networks using LoRa, Packet Radio, WiFi, I2P, or anything else Reticulum supports.
@ -3363,17 +3393,17 @@ Thank you very much for using Free Communications Systems.
info7 = "[color=#"+dark_theme_text_color+"]"+info7+"[/color]" info7 = "[color=#"+dark_theme_text_color+"]"+info7+"[/color]"
info8 = "[color=#"+dark_theme_text_color+"]"+info8+"[/color]" info8 = "[color=#"+dark_theme_text_color+"]"+info8+"[/color]"
info9 = "[color=#"+dark_theme_text_color+"]"+info9+"[/color]" info9 = "[color=#"+dark_theme_text_color+"]"+info9+"[/color]"
self.root.ids.guide_info1.text = info1 self.guide_screen.ids.guide_info1.text = info1
self.root.ids.guide_info2.text = info2 self.guide_screen.ids.guide_info2.text = info2
self.root.ids.guide_info3.text = info3 self.guide_screen.ids.guide_info3.text = info3
self.root.ids.guide_info4.text = info4 self.guide_screen.ids.guide_info4.text = info4
self.root.ids.guide_info5.text = info5 self.guide_screen.ids.guide_info5.text = info5
self.root.ids.guide_info6.text = info6 self.guide_screen.ids.guide_info6.text = info6
self.root.ids.guide_info7.text = info7 self.guide_screen.ids.guide_info7.text = info7
self.root.ids.guide_info8.text = info8 self.guide_screen.ids.guide_info8.text = info8
self.root.ids.guide_info9.text = info9 self.guide_screen.ids.guide_info9.text = info9
self.root.ids.guide_info9.bind(on_ref_press=link_exec) self.guide_screen.ids.guide_info9.bind(on_ref_press=link_exec)
self.root.ids.guide_scrollview.effect_cls = ScrollEffect self.guide_screen.ids.guide_scrollview.effect_cls = ScrollEffect
self.root.ids.screen_manager.transition.direction = "left" self.root.ids.screen_manager.transition.direction = "left"
self.root.ids.screen_manager.current = "guide_screen" self.root.ids.screen_manager.current = "guide_screen"
self.root.ids.nav_drawer.set_state("closed") self.root.ids.nav_drawer.set_state("closed")
@ -3385,10 +3415,13 @@ Thank you very much for using Free Communications Systems.
def broadcasts_action(self, sender=None): def broadcasts_action(self, sender=None):
def link_exec(sender=None, event=None): def link_exec(sender=None, event=None):
def lejob(): def lj():
import webbrowser import webbrowser
webbrowser.open("https://unsigned.io/donate") webbrowser.open("https://unsigned.io/donate")
threading.Thread(target=lejob, daemon=True).start() if not RNS.vendor.platformutils.is_android():
threading.Thread(target=lj, daemon=True).start()
else:
lj()
if not self.root.ids.screen_manager.has_screen("broadcasts_screen"): if not self.root.ids.screen_manager.has_screen("broadcasts_screen"):
self.broadcasts_screen = Builder.load_string(layout_broadcasts_screen) self.broadcasts_screen = Builder.load_string(layout_broadcasts_screen)

View File

@ -364,11 +364,11 @@ MDScreen:
] ]
right_action_items: right_action_items:
[ [
['access-point', lambda x: root.ids.screen_manager.app.announce_now_action(self)], ['access-point', lambda x: root.app.announce_now_action(self)],
['webhook', lambda x: root.ids.screen_manager.app.connectivity_status(self)], ['webhook', lambda x: root.app.connectivity_status(self)],
['qrcode', lambda x: root.ids.screen_manager.app.ingest_lxm_action(self)], ['qrcode', lambda x: root.app.ingest_lxm_action(self)],
['email-sync', lambda x: root.ids.screen_manager.app.lxmf_sync_action(self)], ['email-sync', lambda x: root.app.lxmf_sync_action(self)],
['account-plus', lambda x: root.ids.screen_manager.app.new_conversation_action(self)], ['account-plus', lambda x: root.app.new_conversation_action(self)],
] ]
ScrollView: ScrollView:

View File

@ -590,7 +590,7 @@ MDScreen:
icon_size: dp(24) icon_size: dp(24)
font_size: dp(16) font_size: dp(16)
size_hint: [1.0, None] size_hint: [1.0, None]
on_release: root.ids.screen_manager.app.rpc_copy_action(self) on_release: root.app.rpc_copy_action(self)
MDBoxLayout: MDBoxLayout:
orientation: "horizontal" orientation: "horizontal"
@ -1396,7 +1396,7 @@ MDScreen:
icon_size: dp(24) icon_size: dp(24)
font_size: dp(16) font_size: dp(16)
size_hint: [1.0, None] size_hint: [1.0, None]
on_release: root.ids.screen_manager.app.identity_display_action(self) on_release: root.app.identity_display_action(self)
MDRectangleFlatIconButton: MDRectangleFlatIconButton:
id: keys_copy id: keys_copy
@ -1406,7 +1406,7 @@ MDScreen:
icon_size: dp(24) icon_size: dp(24)
font_size: dp(16) font_size: dp(16)
size_hint: [1.0, None] size_hint: [1.0, None]
on_release: root.ids.screen_manager.app.identity_copy_action(self) on_release: root.app.identity_copy_action(self)
MDRectangleFlatIconButton: MDRectangleFlatIconButton:
id: keys_share id: keys_share
@ -1416,7 +1416,7 @@ MDScreen:
icon_size: dp(24) icon_size: dp(24)
font_size: dp(16) font_size: dp(16)
size_hint: [1.0, None] size_hint: [1.0, None]
on_release: root.ids.screen_manager.app.identity_share_action(self) on_release: root.app.identity_share_action(self)
MDBoxLayout: MDBoxLayout:
orientation: "vertical" orientation: "vertical"
@ -1440,7 +1440,7 @@ MDScreen:
icon_size: dp(24) icon_size: dp(24)
font_size: dp(16) font_size: dp(16)
size_hint: [1.0, None] size_hint: [1.0, None]
on_release: root.ids.screen_manager.app.identity_restore_action(self) on_release: root.app.identity_restore_action(self)
""" """
layout_settings_screen = """ layout_settings_screen = """
@ -1785,7 +1785,7 @@ MDScreen:
icon_size: dp(24) icon_size: dp(24)
font_size: dp(16) font_size: dp(16)
size_hint: [1.0, None] size_hint: [1.0, None]
on_release: root.ids.screen_manager.app.repository_start_action(self) on_release: root.app.repository_start_action(self)
MDRectangleFlatIconButton: MDRectangleFlatIconButton:
id: repository_disable_button id: repository_disable_button
@ -1795,7 +1795,7 @@ MDScreen:
icon_size: dp(24) icon_size: dp(24)
font_size: dp(16) font_size: dp(16)
size_hint: [1.0, None] size_hint: [1.0, None]
on_release: root.ids.screen_manager.app.repository_stop_action(self) on_release: root.app.repository_stop_action(self)
disabled: True disabled: True
MDRectangleFlatIconButton: MDRectangleFlatIconButton:
@ -1806,7 +1806,7 @@ MDScreen:
icon_size: dp(24) icon_size: dp(24)
font_size: dp(16) font_size: dp(16)
size_hint: [1.0, None] size_hint: [1.0, None]
on_release: root.ids.screen_manager.app.repository_download_action(self) on_release: root.app.repository_download_action(self)
disabled: False disabled: False
MDLabel: MDLabel:
@ -1874,7 +1874,7 @@ MDScreen:
icon_size: dp(24) icon_size: dp(24)
font_size: dp(16) font_size: dp(16)
size_hint: [1.0, None] size_hint: [1.0, None]
on_release: root.ids.screen_manager.app.hardware_rnode_action(self) on_release: root.app.hardware_rnode_action(self)
MDRectangleFlatIconButton: MDRectangleFlatIconButton:
id: hardware_modem_button id: hardware_modem_button
@ -1884,7 +1884,7 @@ MDScreen:
icon_size: dp(24) icon_size: dp(24)
font_size: dp(16) font_size: dp(16)
size_hint: [1.0, None] size_hint: [1.0, None]
on_release: root.ids.screen_manager.app.hardware_modem_action(self) on_release: root.app.hardware_modem_action(self)
disabled: False disabled: False
MDRectangleFlatIconButton: MDRectangleFlatIconButton:
@ -1895,7 +1895,7 @@ MDScreen:
icon_size: dp(24) icon_size: dp(24)
font_size: dp(16) font_size: dp(16)
size_hint: [1.0, None] size_hint: [1.0, None]
on_release: root.ids.screen_manager.app.hardware_serial_action(self) on_release: root.app.hardware_serial_action(self)
disabled: False disabled: False
""" """
@ -2102,7 +2102,7 @@ MDScreen:
icon_size: dp(24) icon_size: dp(24)
font_size: dp(16) font_size: dp(16)
size_hint: [1.0, None] size_hint: [1.0, None]
on_release: root.ids.screen_manager.app.hardware_rnode_export(self) on_release: root.app.hardware_rnode_export(self)
MDRectangleFlatIconButton: MDRectangleFlatIconButton:
id: rnode_mote_import id: rnode_mote_import
@ -2112,7 +2112,7 @@ MDScreen:
icon_size: dp(24) icon_size: dp(24)
font_size: dp(16) font_size: dp(16)
size_hint: [1.0, None] size_hint: [1.0, None]
on_release: root.ids.screen_manager.app.hardware_rnode_import(self) on_release: root.app.hardware_rnode_import(self)
MDLabel: MDLabel:
text: "Radio Options" text: "Radio Options"
@ -2264,7 +2264,7 @@ MDScreen:
icon_size: dp(24) icon_size: dp(24)
font_size: dp(16) font_size: dp(16)
size_hint: [1.0, None] size_hint: [1.0, None]
on_release: root.ids.screen_manager.app.hardware_rnode_bt_on_action(self) on_release: root.app.hardware_rnode_bt_on_action(self)
MDRectangleFlatIconButton: MDRectangleFlatIconButton:
id: hardware_rnode_bt_off_button id: hardware_rnode_bt_off_button
@ -2274,7 +2274,7 @@ MDScreen:
icon_size: dp(24) icon_size: dp(24)
font_size: dp(16) font_size: dp(16)
size_hint: [1.0, None] size_hint: [1.0, None]
on_release: root.ids.screen_manager.app.hardware_rnode_bt_off_action(self) on_release: root.app.hardware_rnode_bt_off_action(self)
disabled: False disabled: False
MDRectangleFlatIconButton: MDRectangleFlatIconButton:
@ -2285,7 +2285,7 @@ MDScreen:
icon_size: dp(24) icon_size: dp(24)
font_size: dp(16) font_size: dp(16)
size_hint: [1.0, None] size_hint: [1.0, None]
on_release: root.ids.screen_manager.app.hardware_rnode_bt_pair_action(self) on_release: root.app.hardware_rnode_bt_pair_action(self)
disabled: False disabled: False
MDTextField: MDTextField: