Compare commits

...

20 Commits
0.4.3 ... 0.4.6

Author SHA1 Message Date
Mark Qvist
8b69947098 Updated readme 2024-01-18 16:05:45 +01:00
Mark Qvist
ca730ded3b Updated version 2024-01-18 16:00:28 +01:00
Mark Qvist
6a460d9600 Fixed ILB scrolling 2024-01-18 15:57:49 +01:00
markqvist
92a49c12c0 Merge pull request #48 from penguinolog/urwid_constants
Use urwid constants for widgets instead of string equivalents
2024-01-18 15:38:38 +01:00
markqvist
a876c09b4c Merge branch 'master' into urwid_constants 2024-01-18 15:38:11 +01:00
markqvist
bf0b08c154 Merge pull request #47 from penguinolog/urwid_regression_fixed
Ban `urwid==2.4.3` as containing UI regression.
2024-01-18 15:34:34 +01:00
Aleksei Stepanov
77eca5d23e Use urwid constants for widgets instead of string equivalents
* Reduce `DeprecationWarning` amount:
  `get_focus` -> `focus_position` for `Frame` and `focus` for `Pile`
  `set_focus` -> use property `focus_position`
2024-01-18 11:58:22 +01:00
Aleksei Stepanov
ed6ba63317 Ban urwid==2.4.3 as containing UI regression.
Fix urwid entities init: use correct `super()`,
hack `__super` is officially deprecated.
Method <Class>.method(self, ...) is only for fallback in corner cases
(normally not recommended to use).
2024-01-18 10:22:38 +01:00
Mark Qvist
d856f3fd28 Pin Urwid to 2.4.2 due to rendering bug in 2.4.3 2024-01-17 23:31:16 +01:00
Mark Qvist
24d850107d Updated LXMF dependency 2024-01-17 23:15:00 +01:00
Mark Qvist
9943cad15f Updated readme 2024-01-17 23:08:52 +01:00
Mark Qvist
dcd5f7df95 Updated readme 2024-01-15 20:26:10 +01:00
Mark Qvist
d840ca32ae Resolve merge 2024-01-15 19:42:48 +01:00
markqvist
37063932bb Merge pull request #46 from penguinolog/patch-1
Allow newer versions of urwid
2024-01-15 19:40:58 +01:00
Mark Qvist
0ed4e09b82 Updated nomadnet to use Urwid 2.4.2 2024-01-15 19:40:01 +01:00
Mark Qvist
910e527cc7 Terminate log tail when view is inactive 2024-01-15 19:30:26 +01:00
Alexey Stepanov
4eef326d6b Allow newer versions of urwid
Last urwid versions are backward-compatible with 2.1.2 (but may produce "DeprecationWarning" on legacy logic)
2024-01-15 10:39:35 +01:00
Mark Qvist
691f4df098 Updated versions 2024-01-14 01:08:10 +01:00
Mark Qvist
407cc8fb5f Updated version 2024-01-08 00:12:38 +01:00
Mark Qvist
1f7302903a Fixed missing timestamp update on page/file periodic scan 2024-01-08 00:10:55 +01:00
18 changed files with 628 additions and 294 deletions

View File

@@ -22,9 +22,6 @@ If you'd rather want to use an LXMF client with a graphical user interface, you
- An easy to use and bandwidth efficient markup language for writing pages
- Page caching in browser
## Current Status
The current version of the program should be considered a beta release. The program works well, but there will most probably be bugs and possibly sub-optimal performance in some scenarios. On the other hand, this is the ideal time to have an influence on the direction of the development of Nomad Network. To do so, join the discussion, report bugs and request features here on the GitHub project.
## How do I get started?
The easiest way to install Nomad Network is via pip:
@@ -121,6 +118,23 @@ $ docker run -d \
$ docker run -i ghcr.io/markqvist/nomadnet:master --daemon --console
```
## Tools & Extensions
Nomad Network is a very flexible and extensible platform, and a variety of community-provided tools, utilities and node-side extensions exist:
- [NomadForum](https://codeberg.org/AutumnSpark1226/nomadForum) ([GitHub mirror](https://github.com/AutumnSpark1226/nomadForum))
- [NomadForecast](https://github.com/faragher/NomadForecast)
- [micron-blog](https://github.com/randogoth/micron-blog)
- [md2mu](https://github.com/randogoth/md2mu)
- [Any2MicronConverter](https://github.com/SebastianObi/Any2MicronConverter)
- [Some nomadnet page examples](https://github.com/SebastianObi/NomadNet-Pages)
- [More nomadnet page examples](https://github.com/epenguins/NomadNet_pages)
- [LXMF-Bot](https://github.com/randogoth/lxmf-bot)
- [LXMF Messageboard](https://github.com/chengtripp/lxmf_messageboard)
- [LXMEvent](https://github.com/faragher/LXMEvent)
- [POPR](https://github.com/faragher/POPR)
- [LXMF Tools](https://github.com/SebastianObi/LXMF-Tools)
## Help & Discussion
For help requests, discussion, sharing ideas or anything else related to Nomad Network, please have a look at the [Nomad Network discussions pages](https://github.com/markqvist/Reticulum/discussions/categories/nomad-network).

View File

@@ -50,6 +50,8 @@ class Node:
def register_pages(self):
# TODO: Deregister previously registered pages
# that no longer exist.
self.servedpages = []
self.scan_pages(self.app.pagespath)
@@ -69,6 +71,8 @@ class Node:
)
def register_files(self):
# TODO: Deregister previously registered files
# that no longer exist.
self.servedfiles = []
self.scan_files(self.app.filespath)
@@ -230,10 +234,12 @@ class Node:
if self.page_refresh_interval > 0:
if now > self.last_page_refresh + self.page_refresh_interval*60:
self.register_pages()
self.last_page_refresh = time.time()
if self.file_refresh_interval > 0:
if now > self.last_file_refresh + self.file_refresh_interval*60:
self.register_files()
self.last_file_refresh = time.time()
time.sleep(self.job_interval)

View File

@@ -1077,6 +1077,22 @@ announce_at_start = Yes
# and generally you do not need to use it.
# prioritise_destinations = 41d20c727598a3fbbdf9106133a3a0ed, d924b81822ca24e68e2effea99bcb8cf
# Automatic rescan interval of the pages directory in minutes.
# Default: int = 0 (no rescan)
page_refresh_interval = 0
# You can specify the interval in minutes for
# rescanning the hosted pages path. By default,
# this option is disabled, and the pages path
# will only be scanned on startup.
# page_refresh_interval = 0
# You can specify the interval in minutes for
# rescanning the hosted files path. By default,
# this option is disabled, and the files path
# will only be scanned on startup.
# file_refresh_interval = 0
[printing]
# You can configure Nomad Network to print

View File

@@ -1 +1 @@
__version__ = "0.4.3"
__version__ = "0.4.6"

View File

@@ -27,13 +27,13 @@ class BrowserFrame(urwid.Frame):
self.delegate.save_node_dialog()
elif key == "ctrl g":
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.sub_displays.network_display.toggle_fullscreen()
elif self.get_focus() == "body":
elif self.focus_position == "body":
if key == "down" or key == "up":
try:
if hasattr(self.delegate, "page_pile") and self.delegate.page_pile:
def df(loop, user_data):
st = None
nf = self.delegate.page_pile.get_focus()
nf = self.delegate.page_pile.focus
if hasattr(nf, "key_timeout"):
st = nf
elif hasattr(nf, "original_widget"):
@@ -279,7 +279,10 @@ class Browser:
self.browser_footer = urwid.Text("")
self.page_pile = None
self.browser_body = urwid.Filler(urwid.Text("Disconnected\n"+self.g["arrow_l"]+" "+self.g["arrow_r"], align="center"), "middle")
self.browser_body = urwid.Filler(
urwid.Text("Disconnected\n"+self.g["arrow_l"]+" "+self.g["arrow_r"], align=urwid.CENTER),
urwid.MIDDLE,
)
self.frame = BrowserFrame(self.browser_body, header=self.browser_header, footer=self.browser_footer)
self.frame.delegate = self
@@ -306,28 +309,29 @@ class Browser:
self.update_display()
columns = urwid.Columns([
("weight", 0.5, urwid.Text(" ")),
(urwid.WEIGHT, 0.5, urwid.Text(" ")),
(8, urwid.Button("Back", on_press=back_action)),
("weight", 0.5, urwid.Text(" "))
(urwid.WEIGHT, 0.5, urwid.Text(" ")),
])
if len(self.attr_maps) > 0:
pile = urwid.Pile([
urwid.Text("!\n\n"+self.status_text()+"\n", align="center"),
urwid.Text("!\n\n"+self.status_text()+"\n", align=urwid.CENTER),
columns
])
else:
pile = urwid.Pile([
urwid.Text("!\n\n"+self.status_text(), align="center")
])
pile = urwid.Pile([urwid.Text("!\n\n"+self.status_text(), align=urwid.CENTER)])
return urwid.Filler(pile, "middle")
return urwid.Filler(pile, urwid.MIDDLE)
def update_display(self):
if self.status == Browser.DISCONECTED:
self.display_widget.set_attr_map({None: "inactive_text"})
self.page_pile = None
self.browser_body = urwid.Filler(urwid.Text("Disconnected\n"+self.g["arrow_l"]+" "+self.g["arrow_r"], align="center"), "middle")
self.browser_body = urwid.Filler(
urwid.Text("Disconnected\n"+self.g["arrow_l"]+" "+self.g["arrow_r"], align=urwid.CENTER),
urwid.MIDDLE,
)
self.browser_footer = urwid.Text("")
self.browser_header = urwid.Text("")
self.linebox.set_title("Remote Node")
@@ -354,7 +358,10 @@ class Browser:
elif self.status <= Browser.REQUEST_SENT:
if len(self.attr_maps) == 0:
self.browser_body = urwid.Filler(urwid.Text("Retrieving\n["+self.current_url()+"]", align="center"), "middle")
self.browser_body = urwid.Filler(
urwid.Text("Retrieving\n["+self.current_url()+"]", align=urwid.CENTER),
urwid.MIDDLE,
)
self.browser_footer = self.make_status_widget()
@@ -608,7 +615,7 @@ class Browser:
self.load_page()
def close_dialogs(self):
options = self.delegate.columns.options("weight", self.delegate.right_area_width)
options = self.delegate.columns.options(urwid.WEIGHT, self.delegate.right_area_width)
self.delegate.columns.contents[1] = (self.display_widget, options)
def url_dialog(self):
@@ -629,7 +636,11 @@ class Browser:
dialog = UrlDialogLineBox(
urwid.Pile([
e_url,
urwid.Columns([("weight", 0.45, urwid.Button("Cancel", on_press=dismiss_dialog)), ("weight", 0.1, urwid.Text("")), ("weight", 0.45, urwid.Button("Go", on_press=confirmed))])
urwid.Columns([
(urwid.WEIGHT, 0.45, urwid.Button("Cancel", on_press=dismiss_dialog)),
(urwid.WEIGHT, 0.1, urwid.Text("")),
(urwid.WEIGHT, 0.45, urwid.Button("Go", on_press=confirmed)),
])
]), title="Enter URL"
)
e_url.confirmed = confirmed
@@ -637,9 +648,18 @@ class Browser:
dialog.delegate = self
bottom = self.display_widget
overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 65), valign="middle", height="pack", left=2, right=2)
overlay = urwid.Overlay(
dialog,
bottom,
align=urwid.CENTER,
width=(urwid.RELATIVE, 65),
valign=urwid.MIDDLE,
height=urwid.PACK,
left=2,
right=2,
)
options = self.delegate.columns.options("weight", self.delegate.right_area_width)
options = self.delegate.columns.options(urwid.WEIGHT, self.delegate.right_area_width)
self.delegate.columns.contents[1] = (overlay, options)
self.delegate.columns.focus_position = 1
@@ -663,7 +683,11 @@ class Browser:
dialog = UrlDialogLineBox(
urwid.Pile([
urwid.Text("Save connected node"+disp_str+" "+RNS.prettyhexrep(self.destination_hash)+" to Known Nodes?\n"),
urwid.Columns([("weight", 0.45, urwid.Button("Cancel", on_press=dismiss_dialog)), ("weight", 0.1, urwid.Text("")), ("weight", 0.45, urwid.Button("Save", on_press=confirmed))])
urwid.Columns([
(urwid.WEIGHT, 0.45, urwid.Button("Cancel", on_press=dismiss_dialog)),
(urwid.WEIGHT, 0.1, urwid.Text("")),
(urwid.WEIGHT, 0.45, urwid.Button("Save", on_press=confirmed)),
])
]), title="Save Node"
)
@@ -671,9 +695,18 @@ class Browser:
dialog.delegate = self
bottom = self.display_widget
overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 50), valign="middle", height="pack", left=2, right=2)
overlay = urwid.Overlay(
dialog,
bottom,
align=urwid.CENTER,
width=(urwid.RELATIVE, 50),
valign=urwid.MIDDLE,
height=urwid.PACK,
left=2,
right=2,
)
options = self.delegate.columns.options("weight", self.delegate.right_area_width)
options = self.delegate.columns.options(urwid.WEIGHT, self.delegate.right_area_width)
self.delegate.columns.contents[1] = (overlay, options)
self.delegate.columns.focus_position = 1

View File

@@ -12,13 +12,13 @@ class ConfigDisplayShortcuts():
class ConfigFiller(urwid.WidgetWrap):
def __init__(self, widget, app):
self.app = app
self.filler = urwid.Filler(widget, "top")
urwid.WidgetWrap.__init__(self, self.filler)
self.filler = urwid.Filler(widget, urwid.TOP)
super().__init__(self.filler)
def keypress(self, size, key):
if key == "up":
self.app.ui.main_display.frame.set_focus("header")
self.app.ui.main_display.frame.focus_position = "header"
return super(ConfigFiller, self).keypress(size, key)
@@ -31,12 +31,20 @@ class ConfigDisplay():
self.editor_term = EditorTerminal(self.app, self)
self.widget = urwid.LineBox(self.editor_term)
self.app.ui.main_display.update_active_sub_display()
self.app.ui.main_display.frame.set_focus("body")
self.app.ui.main_display.frame.focus_position = "body"
self.editor_term.term.change_focus(True)
pile = urwid.Pile([
urwid.Text(("body_text", "\nTo change the configuration, edit the config file located at:\n\n"+self.app.configpath+"\n\nRestart Nomad Network for changes to take effect\n"), align="center"),
urwid.Padding(urwid.Button("Open Editor", on_press=open_editor), width=15, align="center"),
urwid.Text(
(
"body_text",
"\nTo change the configuration, edit the config file located at:\n\n"
+self.app.configpath
+"\n\nRestart Nomad Network for changes to take effect\n",
),
align=urwid.CENTER,
),
urwid.Padding(urwid.Button("Open Editor", on_press=open_editor), width=15, align=urwid.CENTER),
])
self.config_explainer = ConfigFiller(pile, self.app)
@@ -71,11 +79,11 @@ class EditorTerminal(urwid.WidgetWrap):
urwid.connect_signal(self.term, 'closed', quit_term)
urwid.WidgetWrap.__init__(self, self.term)
super().__init__(self.term)
def keypress(self, size, key):
# TODO: Decide whether there should be a way to get out while editing
#if key == "up":
# nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.set_focus("header")
# nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.focus_position = "header"
return super(EditorTerminal, self).keypress(size, key)

View File

@@ -37,9 +37,9 @@ class ConversationsArea(urwid.LineBox):
elif key == "ctrl g":
self.delegate.toggle_fullscreen()
elif key == "tab":
self.delegate.app.ui.main_display.frame.set_focus("header")
self.delegate.app.ui.main_display.frame.focus_position = "header"
elif key == "up" and (self.delegate.ilb.first_item_is_selected() or self.delegate.ilb.body_is_empty()):
self.delegate.app.ui.main_display.frame.set_focus("header")
self.delegate.app.ui.main_display.frame.focus_position = "header"
else:
return super(ConversationsArea, self).keypress(size, key)
@@ -69,10 +69,10 @@ class ConversationsDisplay():
self.columns_widget = urwid.Columns(
[
# ("weight", ConversationsDisplay.list_width, self.listbox),
# ("weight", 1-ConversationsDisplay.list_width, self.make_conversation_widget(None))
# (urwid.WEIGHT, ConversationsDisplay.list_width, self.listbox),
# (urwid.WEIGHT, 1-ConversationsDisplay.list_width, self.make_conversation_widget(None))
(ConversationsDisplay.given_list_width, self.listbox),
("weight", 1, self.make_conversation_widget(None))
(urwid.WEIGHT, 1, self.make_conversation_widget(None))
],
dividechars=0, focus_column=0, box_columns=[0]
)
@@ -105,7 +105,7 @@ class ConversationsDisplay():
highlight_offFocus="list_off_focus"
)
self.listbox = ConversationsArea(urwid.Filler(self.ilb, height=("relative", 100)), title="Conversations")
self.listbox = ConversationsArea(urwid.Filler(self.ilb, height=urwid.RELATIVE_100), title="Conversations")
self.listbox.delegate = self
def delete_selected_conversation(self):
@@ -127,17 +127,33 @@ class ConversationsDisplay():
dialog = DialogLineBox(
urwid.Pile([
urwid.Text("Delete conversation with\n"+self.app.directory.simplest_display_str(bytes.fromhex(source_hash))+"\n", align="center"),
urwid.Columns([("weight", 0.45, urwid.Button("Yes", on_press=confirmed)), ("weight", 0.1, urwid.Text("")), ("weight", 0.45, urwid.Button("No", on_press=dismiss_dialog))])
urwid.Text(
"Delete conversation with\n"+self.app.directory.simplest_display_str(bytes.fromhex(source_hash))+"\n",
align=urwid.CENTER,
),
urwid.Columns([
(urwid.WEIGHT, 0.45, urwid.Button("Yes", on_press=confirmed)),
(urwid.WEIGHT, 0.1, urwid.Text("")),
(urwid.WEIGHT, 0.45, urwid.Button("No", on_press=dismiss_dialog)),
])
]), title="?"
)
dialog.delegate = self
bottom = self.listbox
overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
overlay = urwid.Overlay(
dialog,
bottom,
align=urwid.CENTER,
width=urwid.RELATIVE_100,
valign=urwid.MIDDLE,
height=urwid.PACK,
left=2,
right=2,
)
# options = self.columns_widget.options("weight", ConversationsDisplay.list_width)
options = self.columns_widget.options("given", ConversationsDisplay.given_list_width)
# options = self.columns_widget.options(urwid.WEIGHT, ConversationsDisplay.list_width)
options = self.columns_widget.options(urwid.GIVEN, ConversationsDisplay.given_list_width)
self.columns_widget.contents[0] = (overlay, options)
def edit_selected_in_directory(self):
@@ -223,9 +239,12 @@ class ConversationsDisplay():
RNS.log("Could not save directory entry. The contained exception was: "+str(e), RNS.LOG_VERBOSE)
if not dialog_pile.error_display:
dialog_pile.error_display = True
options = dialog_pile.options(height_type="pack")
options = dialog_pile.options(height_type=urwid.PACK)
dialog_pile.contents.append((urwid.Text(""), options))
dialog_pile.contents.append((urwid.Text(("error_text", "Could not save entry. Check your input."), align="center"), options))
dialog_pile.contents.append((
urwid.Text(("error_text", "Could not save entry. Check your input."), align=urwid.CENTER),
options,)
)
source_is_known = self.app.directory.is_known(bytes.fromhex(source_hash_text))
if source_is_known:
@@ -234,13 +253,23 @@ class ConversationsDisplay():
def query_action(sender, user_data):
self.close_conversation_by_hash(user_data)
nomadnet.Conversation.query_for_peer(user_data)
options = dialog_pile.options(height_type="pack")
options = dialog_pile.options(height_type=urwid.PACK)
dialog_pile.contents = [
(urwid.Text("Query sent"), options),
(urwid.Button("OK", on_press=dismiss_dialog), options)
]
query_button = urwid.Button("Query network for keys", on_press=query_action, user_data=source_hash_text)
known_section = urwid.Pile([urwid.Divider(g["divider1"]), urwid.Text(g["info"]+"\n", align="center"), urwid.Text("The identity of this peer is not known, and you cannot currently send messages to it. You can query the network to obtain the identity.\n", align="center"), query_button, urwid.Divider(g["divider1"])])
known_section = urwid.Pile([
urwid.Divider(g["divider1"]),
urwid.Text(g["info"]+"\n", align=urwid.CENTER),
urwid.Text(
"The identity of this peer is not known, and you cannot currently send messages to it. "
"You can query the network to obtain the identity.\n",
align=urwid.CENTER,
),
query_button,
urwid.Divider(g["divider1"]),
])
dialog_pile = urwid.Pile([
selected_id_widget,
@@ -253,7 +282,11 @@ class ConversationsDisplay():
r_direct,
r_propagated,
known_section,
urwid.Columns([("weight", 0.45, urwid.Button("Save", on_press=confirmed)), ("weight", 0.1, urwid.Text("")), ("weight", 0.45, urwid.Button("Back", on_press=dismiss_dialog))])
urwid.Columns([
(urwid.WEIGHT, 0.45, urwid.Button("Save", on_press=confirmed)),
(urwid.WEIGHT, 0.1, urwid.Text("")),
(urwid.WEIGHT, 0.45, urwid.Button("Back", on_press=dismiss_dialog)),
])
])
dialog_pile.error_display = False
@@ -261,10 +294,19 @@ class ConversationsDisplay():
dialog.delegate = self
bottom = self.listbox
overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
overlay = urwid.Overlay(
dialog,
bottom,
align=urwid.CENTER,
width=urwid.RELATIVE_100,
valign=urwid.MIDDLE,
height=urwid.PACK,
left=2,
right=2,
)
# options = self.columns_widget.options("weight", ConversationsDisplay.list_width)
options = self.columns_widget.options("given", ConversationsDisplay.given_list_width)
# options = self.columns_widget.options(urwid.WEIGHT, ConversationsDisplay.list_width)
options = self.columns_widget.options(urwid.GIVEN, ConversationsDisplay.given_list_width)
self.columns_widget.contents[0] = (overlay, options)
def new_conversation(self):
@@ -312,9 +354,15 @@ class ConversationsDisplay():
RNS.log("Could not start conversation. The contained exception was: "+str(e), RNS.LOG_VERBOSE)
if not dialog_pile.error_display:
dialog_pile.error_display = True
options = dialog_pile.options(height_type="pack")
options = dialog_pile.options(height_type=urwid.PACK)
dialog_pile.contents.append((urwid.Text(""), options))
dialog_pile.contents.append((urwid.Text(("error_text", "Could not start conversation. Check your input."), align="center"), options))
dialog_pile.contents.append((
urwid.Text(
("error_text", "Could not start conversation. Check your input."),
align=urwid.CENTER,
),
options,
))
dialog_pile = urwid.Pile([
e_id,
@@ -324,7 +372,11 @@ class ConversationsDisplay():
r_unknown,
r_trusted,
urwid.Text(""),
urwid.Columns([("weight", 0.45, urwid.Button("Create", on_press=confirmed)), ("weight", 0.1, urwid.Text("")), ("weight", 0.45, urwid.Button("Back", on_press=dismiss_dialog))])
urwid.Columns([
(urwid.WEIGHT, 0.45, urwid.Button("Create", on_press=confirmed)),
(urwid.WEIGHT, 0.1, urwid.Text("")),
(urwid.WEIGHT, 0.45, urwid.Button("Back", on_press=dismiss_dialog)),
])
])
dialog_pile.error_display = False
@@ -332,10 +384,19 @@ class ConversationsDisplay():
dialog.delegate = self
bottom = self.listbox
overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
overlay = urwid.Overlay(
dialog,
bottom,
align=urwid.CENTER,
width=urwid.RELATIVE_100,
valign=urwid.MIDDLE,
height=urwid.PACK,
left=2,
right=2,
)
# options = self.columns_widget.options("weight", ConversationsDisplay.list_width)
options = self.columns_widget.options("given", ConversationsDisplay.given_list_width)
# options = self.columns_widget.options(urwid.WEIGHT, ConversationsDisplay.list_width)
options = self.columns_widget.options(urwid.GIVEN, ConversationsDisplay.given_list_width)
self.columns_widget.contents[0] = (overlay, options)
def ingest_lxm_uri(self):
@@ -366,7 +427,10 @@ class ConversationsDisplay():
rdialog_pile = urwid.Pile([
urwid.Text("Message was decoded, decrypted successfully, and added to your conversation list."),
urwid.Text(""),
urwid.Columns([("weight", 0.6, urwid.Text("")), ("weight", 0.4, urwid.Button("OK", on_press=dismiss_dialog))])
urwid.Columns([
(urwid.WEIGHT, 0.6, urwid.Text("")),
(urwid.WEIGHT, 0.4, urwid.Button("OK", on_press=dismiss_dialog)),
])
])
rdialog_pile.error_display = False
@@ -374,16 +438,28 @@ class ConversationsDisplay():
rdialog.delegate = self
bottom = self.listbox
roverlay = urwid.Overlay(rdialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
roverlay = urwid.Overlay(
rdialog,
bottom,
align=urwid.CENTER,
width=urwid.RELATIVE_100,
valign=urwid.MIDDLE,
height=urwid.PACK,
left=2,
right=2,
)
options = self.columns_widget.options("given", ConversationsDisplay.given_list_width)
options = self.columns_widget.options(urwid.GIVEN, ConversationsDisplay.given_list_width)
self.columns_widget.contents[0] = (roverlay, options)
elif ingest_result == duplicate_signal:
rdialog_pile = urwid.Pile([
urwid.Text("The decoded message has already been processed by the LXMF Router, and will not be ingested again."),
urwid.Text(""),
urwid.Columns([("weight", 0.6, urwid.Text("")), ("weight", 0.4, urwid.Button("OK", on_press=dismiss_dialog))])
urwid.Columns([
(urwid.WEIGHT, 0.6, urwid.Text("")),
(urwid.WEIGHT, 0.4, urwid.Button("OK", on_press=dismiss_dialog)),
])
])
rdialog_pile.error_display = False
@@ -391,9 +467,18 @@ class ConversationsDisplay():
rdialog.delegate = self
bottom = self.listbox
roverlay = urwid.Overlay(rdialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
roverlay = urwid.Overlay(
rdialog,
bottom,
align=urwid.CENTER,
width=urwid.RELATIVE_100,
valign=urwid.MIDDLE,
height=urwid.PACK,
left=2,
right=2,
)
options = self.columns_widget.options("given", ConversationsDisplay.given_list_width)
options = self.columns_widget.options(urwid.GIVEN, ConversationsDisplay.given_list_width)
self.columns_widget.contents[0] = (roverlay, options)
else:
@@ -405,7 +490,10 @@ class ConversationsDisplay():
rdialog_pile = urwid.Pile([
urwid.Text(propagation_text),
urwid.Text(""),
urwid.Columns([("weight", 0.6, urwid.Text("")), ("weight", 0.4, urwid.Button("OK", on_press=dismiss_dialog))])
urwid.Columns([
(urwid.WEIGHT, 0.6, urwid.Text("")),
(urwid.WEIGHT, 0.4, urwid.Button("OK", on_press=dismiss_dialog)),
])
])
rdialog_pile.error_display = False
@@ -413,23 +501,36 @@ class ConversationsDisplay():
rdialog.delegate = self
bottom = self.listbox
roverlay = urwid.Overlay(rdialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
roverlay = urwid.Overlay(
rdialog,
bottom,
align=urwid.CENTER,
width=urwid.RELATIVE_100,
valign=urwid.MIDDLE,
height=urwid.PACK,
left=2,
right=2,
)
options = self.columns_widget.options("given", ConversationsDisplay.given_list_width)
options = self.columns_widget.options(urwid.GIVEN, ConversationsDisplay.given_list_width)
self.columns_widget.contents[0] = (roverlay, options)
except Exception as e:
RNS.log("Could not ingest LXM URI. The contained exception was: "+str(e), RNS.LOG_VERBOSE)
if not dialog_pile.error_display:
dialog_pile.error_display = True
options = dialog_pile.options(height_type="pack")
options = dialog_pile.options(height_type=urwid.PACK)
dialog_pile.contents.append((urwid.Text(""), options))
dialog_pile.contents.append((urwid.Text(("error_text", "Could ingest LXM from URI data. Check your input."), align="center"), options))
dialog_pile.contents.append((urwid.Text(("error_text", "Could ingest LXM from URI data. Check your input."), align=urwid.CENTER), options))
dialog_pile = urwid.Pile([
e_uri,
urwid.Text(""),
urwid.Columns([("weight", 0.45, urwid.Button("Ingest", on_press=confirmed)), ("weight", 0.1, urwid.Text("")), ("weight", 0.45, urwid.Button("Back", on_press=dismiss_dialog))])
urwid.Columns([
(urwid.WEIGHT, 0.45, urwid.Button("Ingest", on_press=confirmed)),
(urwid.WEIGHT, 0.1, urwid.Text("")),
(urwid.WEIGHT, 0.45, urwid.Button("Back", on_press=dismiss_dialog)),
])
])
dialog_pile.error_display = False
@@ -437,9 +538,18 @@ class ConversationsDisplay():
dialog.delegate = self
bottom = self.listbox
overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
overlay = urwid.Overlay(
dialog,
bottom,
align=urwid.CENTER,
width=urwid.RELATIVE_100,
valign=urwid.MIDDLE,
height=urwid.PACK,
left=2,
right=2,
)
options = self.columns_widget.options("given", ConversationsDisplay.given_list_width)
options = self.columns_widget.options(urwid.GIVEN, ConversationsDisplay.given_list_width)
self.columns_widget.contents[0] = (overlay, options)
def delete_conversation(self, source_hash):
@@ -471,7 +581,7 @@ class ConversationsDisplay():
r_mall = urwid.RadioButton(max_messages_group, "Download all", state=True)
r_mlim = urwid.RadioButton(max_messages_group, "Limit to", state=False)
ie_lim = urwid.IntEdit("", 5)
rbs = urwid.GridFlow([r_mlim, ie_lim], 12, 1, 0, align="left")
rbs = urwid.GridFlow([r_mlim, ie_lim], 12, 1, 0, align=urwid.LEFT)
def sync_now(sender):
limit = None
@@ -495,7 +605,11 @@ class ConversationsDisplay():
else:
sync_button = hidden_sync_button
button_columns = urwid.Columns([("weight", 0.45, sync_button), ("weight", 0.1, urwid.Text("")), ("weight", 0.45, cancel_button)])
button_columns = urwid.Columns([
(urwid.WEIGHT, 0.45, sync_button),
(urwid.WEIGHT, 0.1, urwid.Text("")),
(urwid.WEIGHT, 0.45, cancel_button),
])
real_sync_button.bc = button_columns
pn_ident = None
@@ -518,7 +632,7 @@ class ConversationsDisplay():
dialog = DialogLineBox(
urwid.Pile([
urwid.Text(""+g["node"]+pn_display_str, align="center"),
urwid.Text(""+g["node"]+pn_display_str, align=urwid.CENTER),
urwid.Divider(g["divider1"]),
sync_progress,
urwid.Divider(g["divider1"]),
@@ -529,12 +643,23 @@ class ConversationsDisplay():
]), title="Message Sync"
)
else:
button_columns = urwid.Columns([("weight", 0.45, urwid.Text("" )), ("weight", 0.1, urwid.Text("")), ("weight", 0.45, cancel_button)])
button_columns = urwid.Columns([
(urwid.WEIGHT, 0.45, urwid.Text("" )),
(urwid.WEIGHT, 0.1, urwid.Text("")),
(urwid.WEIGHT, 0.45, cancel_button),
])
dialog = DialogLineBox(
urwid.Pile([
urwid.Text(""),
urwid.Text("No trusted nodes found, cannot sync!\n", align="center"),
urwid.Text("To syncronise messages from the network, one or more nodes must be marked as trusted in the Known Nodes list, or a node must manually be selected as the default propagation node. Nomad Network will then automatically sync from the nearest trusted node, or the manually selected one.", align="left"),
urwid.Text("No trusted nodes found, cannot sync!\n", align=urwid.CENTER),
urwid.Text(
"To synchronise messages from the network, "
"one or more nodes must be marked as trusted in the Known Nodes list, "
"or a node must manually be selected as the default propagation node. "
"Nomad Network will then automatically sync from the nearest trusted node, "
"or the manually selected one.",
align=urwid.LEFT,
),
urwid.Text(""),
button_columns
]), title="Message Sync"
@@ -550,10 +675,19 @@ class ConversationsDisplay():
self.sync_dialog = dialog
bottom = self.listbox
overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
overlay = urwid.Overlay(
dialog,
bottom,
align=urwid.CENTER,
width=urwid.RELATIVE_100,
valign=urwid.MIDDLE,
height=urwid.PACK,
left=2,
right=2,
)
# options = self.columns_widget.options("weight", ConversationsDisplay.list_width)
options = self.columns_widget.options("given", ConversationsDisplay.given_list_width)
# options = self.columns_widget.options(urwid.WEIGHT, ConversationsDisplay.list_width)
options = self.columns_widget.options(urwid.GIVEN, ConversationsDisplay.given_list_width)
self.columns_widget.contents[0] = (overlay, options)
def update_sync_dialog(self, loop = None, sender = None):
@@ -561,9 +695,9 @@ class ConversationsDisplay():
self.sync_dialog.sync_progress.set_completion(self.app.get_sync_progress())
if self.app.get_sync_status() == "Idle" or self.app.message_router.propagation_transfer_state >= LXMF.LXMRouter.PR_COMPLETE:
self.sync_dialog.bc.contents[0] = (self.sync_dialog.real_sync_button, self.sync_dialog.bc.options("weight", 0.45))
self.sync_dialog.bc.contents[0] = (self.sync_dialog.real_sync_button, self.sync_dialog.bc.options(urwid.WEIGHT, 0.45))
else:
self.sync_dialog.bc.contents[0] = (self.sync_dialog.hidden_sync_button, self.sync_dialog.bc.options("weight", 0.45))
self.sync_dialog.bc.contents[0] = (self.sync_dialog.hidden_sync_button, self.sync_dialog.bc.options(urwid.WEIGHT, 0.45))
self.app.ui.loop.set_alarm_in(0.2, self.update_sync_dialog)
@@ -574,13 +708,22 @@ class ConversationsDisplay():
def update_conversation_list(self):
ilb_position = self.ilb.get_selected_position()
self.update_listbox()
# options = self.columns_widget.options("weight", ConversationsDisplay.list_width)
options = self.columns_widget.options("given", ConversationsDisplay.given_list_width)
# options = self.columns_widget.options(urwid.WEIGHT, ConversationsDisplay.list_width)
options = self.columns_widget.options(urwid.GIVEN, ConversationsDisplay.given_list_width)
if not (self.dialog_open and self.sync_dialog != None):
self.columns_widget.contents[0] = (self.listbox, options)
else:
bottom = self.listbox
overlay = urwid.Overlay(self.sync_dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
overlay = urwid.Overlay(
self.sync_dialog,
bottom,
align=urwid.CENTER,
width=urwid.RELATIVE_100,
valign=urwid.MIDDLE,
height=urwid.PACK,
left=2,
right=2,
)
self.columns_widget.contents[0] = (overlay, options)
if ilb_position != None:
@@ -606,17 +749,17 @@ class ConversationsDisplay():
self.app.mark_conversation_read(self.currently_displayed_conversation)
self.currently_displayed_conversation = source_hash
# options = self.widget.options("weight", 1-ConversationsDisplay.list_width)
options = self.widget.options("weight", 1)
# options = self.widget.options(urwid.WEIGHT, 1-ConversationsDisplay.list_width)
options = self.widget.options(urwid.WEIGHT, 1)
self.widget.contents[1] = (self.make_conversation_widget(source_hash), options)
if source_hash == None:
self.widget.set_focus_column(0)
self.widget.focus_position = 0
else:
if self.app.conversation_is_unread(source_hash):
self.app.mark_conversation_read(source_hash)
self.update_conversation_list()
self.widget.set_focus_column(1)
self.widget.focus_position = 1
conversation_position = None
index = 0
for widget in self.list_widgets:
@@ -756,9 +899,9 @@ class MessageEdit(urwid.Edit):
y = self.get_cursor_coords(size)[1]
if y == 0:
if self.delegate.full_editor_active and self.name == "title_editor":
self.delegate.frame.set_focus("body")
self.delegate.frame.focus_position = "body"
elif not self.delegate.full_editor_active and self.name == "content_editor":
self.delegate.frame.set_focus("body")
self.delegate.frame.focus_position = "body"
else:
return super(MessageEdit, self).keypress(size, key)
else:
@@ -769,11 +912,11 @@ class MessageEdit(urwid.Edit):
class ConversationFrame(urwid.Frame):
def keypress(self, size, key):
if self.get_focus() == "body":
if self.focus_position == "body":
if key == "up" and self.delegate.messagelist.top_is_visible:
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.set_focus("header")
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.focus_position = "header"
elif key == "down" and self.delegate.messagelist.bottom_is_visible:
self.set_focus("footer")
self.focus_position = "footer"
else:
return super(ConversationFrame, self).keypress(size, key)
elif key == "ctrl k":
@@ -788,7 +931,7 @@ class ConversationWidget(urwid.WidgetWrap):
if source_hash == None:
self.frame = None
display_widget = urwid.LineBox(urwid.Filler(urwid.Text("\n No conversation selected"), "top"))
urwid.WidgetWrap.__init__(self, display_widget)
super().__init__(display_widget)
else:
if source_hash in ConversationsDisplay.cached_conversation_widgets:
return ConversationsDisplay.cached_conversation_widgets[source_hash]
@@ -815,7 +958,11 @@ class ConversationWidget(urwid.WidgetWrap):
header = None
if self.conversation.trust_level == DirectoryEntry.UNTRUSTED:
header = urwid.AttrMap(urwid.Padding(urwid.Text(g["warning"]+" Warning: Conversation with untrusted peer "+g["warning"], align="center")), "msg_warning_untrusted")
header = urwid.AttrMap(
urwid.Padding(
urwid.Text(g["warning"]+" Warning: Conversation with untrusted peer "+g["warning"], align=urwid.CENTER)),
"msg_warning_untrusted",
)
self.minimal_editor = urwid.AttrMap(msg_editor, "msg_editor")
self.minimal_editor.name = "minimal_editor"
@@ -852,7 +999,7 @@ class ConversationWidget(urwid.WidgetWrap):
self.frame
)
urwid.WidgetWrap.__init__(self, self.display_widget)
super().__init__(self.display_widget)
def clear_history_dialog(self):
def dismiss_dialog(sender):
@@ -867,17 +1014,30 @@ class ConversationWidget(urwid.WidgetWrap):
dialog = DialogLineBox(
urwid.Pile([
urwid.Text("Clear conversation history\n", align="center"),
urwid.Columns([("weight", 0.45, urwid.Button("Yes", on_press=confirmed)), ("weight", 0.1, urwid.Text("")), ("weight", 0.45, urwid.Button("No", on_press=dismiss_dialog))])
urwid.Text("Clear conversation history\n", align=urwid.CENTER),
urwid.Columns([
(urwid.WEIGHT, 0.45, urwid.Button("Yes", on_press=confirmed)),
(urwid.WEIGHT, 0.1, urwid.Text("")),
(urwid.WEIGHT, 0.45, urwid.Button("No", on_press=dismiss_dialog)),
])
]), title="?"
)
dialog.delegate = self
bottom = self.messagelist
overlay = urwid.Overlay(dialog, bottom, align="center", width=34, valign="middle", height="pack", left=2, right=2)
overlay = urwid.Overlay(
dialog,
bottom,
align=urwid.CENTER,
width=34,
valign=urwid.MIDDLE,
height=urwid.PACK,
left=2,
right=2,
)
self.frame.contents["body"] = (overlay, self.frame.options())
self.frame.set_focus("body")
self.frame.focus_position = "body"
def toggle_editor(self):
if self.full_editor_active:
@@ -894,7 +1054,17 @@ class ConversationWidget(urwid.WidgetWrap):
if allowed:
self.frame.contents["footer"] = (self.minimal_editor, None)
else:
warning = urwid.AttrMap(urwid.Padding(urwid.Text("\n"+g["info"]+"\n\nYou cannot currently message this peer, since it's identity keys are not known. The keys have been requested from the network and should arrive shortly, if available. Close this conversation and reopen it to try again.\n\nTo query the network manually, select this conversation in the conversation list, press Ctrl-E, and use the query button.\n", align="center")), "msg_header_caution")
warning = urwid.AttrMap(
urwid.Padding(urwid.Text(
"\n"+g["info"]+"\n\nYou cannot currently message this peer, since it's identity keys are not known. "
"The keys have been requested from the network and should arrive shortly, if available. "
"Close this conversation and reopen it to try again.\n\n"
"To query the network manually, select this conversation in the conversation list, "
"press Ctrl-E, and use the query button.\n",
align=urwid.CENTER,
)),
"msg_header_caution",
)
self.frame.contents["footer"] = (warning, None)
def toggle_focus_area(self):
@@ -905,9 +1075,9 @@ class ConversationWidget(urwid.WidgetWrap):
pass
if name == "messagelist":
self.frame.set_focus("footer")
self.frame.focus_position = "footer"
elif name == "minimal_editor" or name == "full_editor":
self.frame.set_focus("body")
self.frame.focus_position = "body"
def keypress(self, size, key):
if key == "tab":
@@ -982,17 +1152,20 @@ class ConversationWidget(urwid.WidgetWrap):
dialog = DialogLineBox(
urwid.Pile([
urwid.Text("The paper message was saved to:\n\n"+str(path)+"\n", align="center"),
urwid.Columns([("weight", 0.6, urwid.Text("")), ("weight", 0.4, urwid.Button("OK", on_press=dismiss_dialog))])
urwid.Text("The paper message was saved to:\n\n"+str(path)+"\n", align=urwid.CENTER),
urwid.Columns([
(urwid.WEIGHT, 0.6, urwid.Text("")),
(urwid.WEIGHT, 0.4, urwid.Button("OK", on_press=dismiss_dialog)),
])
]), title=g["papermsg"].replace(" ", "")
)
dialog.delegate = self
bottom = self.messagelist
overlay = urwid.Overlay(dialog, bottom, align="center", width=60, valign="middle", height="pack", left=2, right=2)
overlay = urwid.Overlay(dialog, bottom, align=urwid.CENTER, width=60, valign=urwid.MIDDLE, height=urwid.PACK, left=2, right=2)
self.frame.contents["body"] = (overlay, self.frame.options())
self.frame.set_focus("body")
self.frame.focus_position = "body"
def print_paper_message_qr(self):
content = self.content_editor.get_edit_text()
@@ -1044,25 +1217,28 @@ class ConversationWidget(urwid.WidgetWrap):
dialog = DialogLineBox(
urwid.Pile([
urwid.Text("Select the desired paper message output method.\nSaved files will be written to:\n\n"+str(self.app.downloads_path)+"\n", align="center"),
urwid.Text(
"Select the desired paper message output method.\nSaved files will be written to:\n\n"+str(self.app.downloads_path)+"\n",
align=urwid.CENTER,
),
urwid.Columns([
("weight", 0.5, urwid.Button("Print QR", on_press=print_qr)),
("weight", 0.1, urwid.Text("")),
("weight", 0.5, urwid.Button("Save QR", on_press=save_qr)),
("weight", 0.1, urwid.Text("")),
("weight", 0.5, urwid.Button("Save URI", on_press=save_uri)),
("weight", 0.1, urwid.Text("")),
("weight", 0.5, urwid.Button("Cancel", on_press=dismiss_dialog))
(urwid.WEIGHT, 0.5, urwid.Button("Print QR", on_press=print_qr)),
(urwid.WEIGHT, 0.1, urwid.Text("")),
(urwid.WEIGHT, 0.5, urwid.Button("Save QR", on_press=save_qr)),
(urwid.WEIGHT, 0.1, urwid.Text("")),
(urwid.WEIGHT, 0.5, urwid.Button("Save URI", on_press=save_uri)),
(urwid.WEIGHT, 0.1, urwid.Text("")),
(urwid.WEIGHT, 0.5, urwid.Button("Cancel", on_press=dismiss_dialog))
])
]), title="Create Paper Message"
)
dialog.delegate = self
bottom = self.messagelist
overlay = urwid.Overlay(dialog, bottom, align="center", width=60, valign="middle", height="pack", left=2, right=2)
overlay = urwid.Overlay(dialog, bottom, align=urwid.CENTER, width=60, valign=urwid.MIDDLE, height=urwid.PACK, left=2, right=2)
self.frame.contents["body"] = (overlay, self.frame.options())
self.frame.set_focus("body")
self.frame.focus_position = "body"
def paper_message_failed(self):
def dismiss_dialog(sender):
@@ -1071,17 +1247,23 @@ class ConversationWidget(urwid.WidgetWrap):
dialog = DialogLineBox(
urwid.Pile([
urwid.Text("Could not output paper message,\ncheck your settings. See the log\nfile for any error messages.\n", align="center"),
urwid.Columns([("weight", 0.6, urwid.Text("")), ("weight", 0.4, urwid.Button("OK", on_press=dismiss_dialog))])
urwid.Text(
"Could not output paper message,\ncheck your settings. See the log\nfile for any error messages.\n",
align=urwid.CENTER,
),
urwid.Columns([
(urwid.WEIGHT, 0.6, urwid.Text("")),
(urwid.WEIGHT, 0.4, urwid.Button("OK", on_press=dismiss_dialog)),
])
]), title="!"
)
dialog.delegate = self
bottom = self.messagelist
overlay = urwid.Overlay(dialog, bottom, align="center", width=34, valign="middle", height="pack", left=2, right=2)
overlay = urwid.Overlay(dialog, bottom, align=urwid.CENTER, width=34, valign=urwid.MIDDLE, height=urwid.PACK, left=2, right=2)
self.frame.contents["body"] = (overlay, self.frame.options())
self.frame.set_focus("body")
self.frame.focus_position = "body"
def close(self):
self.delegate.close_conversation(self)
@@ -1141,7 +1323,7 @@ class LXMessageWidget(urwid.WidgetWrap):
urwid.Text("")
])
urwid.WidgetWrap.__init__(self, display_widget)
super().__init__(display_widget)
class SyncProgressBar(urwid.ProgressBar):
def get_text(self):

View File

@@ -15,7 +15,7 @@ class DirectoryDisplay():
])
self.shortcuts_display = DirectoryDisplayShortcuts(self.app)
self.widget = urwid.Filler(pile, 'top')
self.widget = urwid.Filler(pile, urwid.TOP)
def shortcuts(self):
return self.shortcuts_display

View File

@@ -6,13 +6,13 @@ class IntroDisplay():
font = urwid.font.HalfBlock5x4Font()
big_text = urwid.BigText(("intro_title", self.app.config["textui"]["intro_text"]), font)
big_text = urwid.Padding(big_text, align="center", width="clip")
big_text = urwid.Padding(big_text, align=urwid.CENTER, width=urwid.CLIP)
intro = urwid.Pile([
big_text,
urwid.Text(("Version %s" % (str(self.app.version))), align="center"),
urwid.Text(("Version %s" % (str(self.app.version))), align=urwid.CENTER),
urwid.Divider(),
urwid.Text(("-= Starting =- "), align="center"),
urwid.Text(("-= Starting =- "), align=urwid.CENTER),
])
self.widget = urwid.Filler(intro)

View File

@@ -10,7 +10,7 @@ class GuideDisplayShortcuts():
self.app = app
g = app.ui.glyphs
self.widget = urwid.AttrMap(urwid.Padding(urwid.Text(""), align="left"), "shortcutbar")
self.widget = urwid.AttrMap(urwid.Padding(urwid.Text(""), align=urwid.LEFT), "shortcutbar")
class ListEntry(urwid.Text):
_selectable = True
@@ -75,7 +75,7 @@ class GuideEntry(urwid.WidgetWrap):
style = "topic_list_normal"
focus_style = "list_focus"
self.display_widget = urwid.AttrMap(widget, style, focus_style)
urwid.WidgetWrap.__init__(self, self.display_widget)
super().__init__(self.display_widget)
def display_topic(self, event, topic):
markup = TOPICS[topic]
@@ -125,12 +125,12 @@ class TopicList(urwid.WidgetWrap):
highlight_offFocus="list_off_focus"
)
urwid.WidgetWrap.__init__(self, urwid.LineBox(self.ilb, title="Topics"))
super().__init__(urwid.LineBox(self.ilb, title="Topics"))
def keypress(self, size, key):
if key == "up" and (self.ilb.first_item_is_selected()):
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.set_focus("header")
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.focus_position = "header"
return super(TopicList, self).keypress(size, key)
@@ -141,16 +141,16 @@ class GuideDisplay():
self.app = app
g = self.app.ui.glyphs
topic_text = urwid.Text("\n No topic selected", align="left")
topic_text = urwid.Text("\n No topic selected", align=urwid.LEFT)
self.left_area = TopicList(self.app, self)
self.right_area = urwid.LineBox(urwid.Filler(topic_text, "top"))
self.right_area = urwid.LineBox(urwid.Filler(topic_text, urwid.TOP))
self.columns = urwid.Columns(
[
("weight", GuideDisplay.list_width, self.left_area),
("weight", 1-GuideDisplay.list_width, self.right_area)
(urwid.WEIGHT, GuideDisplay.list_width, self.left_area),
(urwid.WEIGHT, 1-GuideDisplay.list_width, self.right_area)
],
dividechars=0, focus_column=0
)
@@ -163,9 +163,8 @@ class GuideDisplay():
entry.display_topic(entry.display_topic, entry.topic_name)
def set_content_widgets(self, new_content):
options = self.columns.options(width_type="weight", width_amount=1-GuideDisplay.list_width)
options = self.columns.options(width_type=urwid.WEIGHT, width_amount=1-GuideDisplay.list_width, box_widget=True)
pile = urwid.Pile(new_content)
#content = urwid.LineBox(urwid.Filler(pile, "top"))
content = urwid.LineBox(urwid.AttrMap(ScrollBar(Scrollable(pile), thumb_char="\u2503", trough_char=" "), "scrollbar"))
self.columns.contents[1] = (content, options)
@@ -398,7 +397,7 @@ You're currently located in the guide section of the program. I'm sorry I had to
To get the most out of Nomad Network, you will need a terminal that supports UTF-8 and at least 256 colors, ideally true-color. If your terminal supports true-color, you can go to the `![ Config ]`! menu item, launch the editor and change the configuration.
It is recommended to use a terminal size of at least 122x32. Nomad Network will work with smaller terminal sizes, but the interface might feel a bit cramped.
It is recommended to use a terminal size of at least 135x32. Nomad Network will work with smaller terminal sizes, but the interface might feel a bit cramped.
If you don't already have a Nerd Font installed (see https://www.nerdfonts.com/), I also highly recommend to do so, since it will greatly expand the amount of glyphs, icons and graphics that Nomad Network can use. Once you have your terminal set up with a Nerd Font, go to the `![ Config ]`! menu item and enable Nerd Fonts in the configuration instead of normal unicode glyphs.
@@ -624,7 +623,7 @@ Determines where the node server will look for hosted pages. Must be a readable
>>>
`!page_refresh_interval = 0`!
>>>>
Determines the interval in seconds for rescanning the hosted pages path. By default, this option is disabled, and the pages path will only be scanned on startup.
Determines the interval in minutes for rescanning the hosted pages path. By default, this option is disabled, and the pages path will only be scanned on startup.
<
>>>
@@ -636,7 +635,7 @@ Determines where the node server will look for downloadable files. Must be a rea
>>>
`!file_refresh_interval = 0`!
>>>>
Determines the interval in seconds for rescanning the hosted files path. By default, this option is disabled, and the files path will only be scanned on startup.
Determines the interval in minutes for rescanning the hosted files path. By default, this option is disabled, and the files path will only be scanned on startup.
<
>>>
@@ -1156,7 +1155,7 @@ To display literal content, for example source-code, or blocks of text that shou
`=
'''
TOPIC_MARKUP += TOPIC_MARKUP.replace("`=", "\\`=") + "[ micron source for document goes here, we don't want infinite recursion now, do we? ]\n\\`="
TOPIC_MARKUP += "\n`=\n\n>Closing Remarks\n\nIf you made it all the way here, you should be well equipped to write documents, pages and applications using micron and Nomad Network. Thank you for staying with me.\n\n`c\U0001F332\n"
TOPIC_MARKUP += "\n`=\n\n>Closing Remarks\n\nIf you made it all the way here, you should be well equipped to write documents, pages and applications using micron and Nomad Network. Thank you for staying with me.\n"
TOPICS = {

View File

@@ -10,13 +10,23 @@ class LogDisplayShortcuts():
class LogDisplay():
def __init__(self, app):
import urwid
self.app = app
self.log_term = LogTerminal(self.app)
self.log_term = None
self.shortcuts_display = LogDisplayShortcuts(self.app)
self.widget = None
def show(self):
if self.log_term == None:
self.log_term = LogTerminal(self.app)
self.widget = urwid.LineBox(self.log_term)
def kill(self):
if self.log_term != None:
self.log_term.terminate()
self.log_term = None
self.widget = None
def shortcuts(self):
return self.shortcuts_display
@@ -26,13 +36,17 @@ class LogTerminal(urwid.WidgetWrap):
self.log_term = urwid.Terminal(
("tail", "-fn50", self.app.logfilepath),
encoding='utf-8',
escape_sequence="up"
escape_sequence="up",
main_loop=self.app.ui.loop,
)
urwid.WidgetWrap.__init__(self, self.log_term)
super().__init__(self.log_term)
def terminate(self):
self.log_term.terminate()
def keypress(self, size, key):
if key == "up":
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.set_focus("header")
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.focus_position = "header"
return super(LogTerminal, self).keypress(size, key)

View File

@@ -1,5 +1,4 @@
import RNS
import time
from .Network import *
from .Conversations import *
@@ -116,6 +115,7 @@ class MainDisplay():
def show_log(self, user_data):
self.sub_displays.active_display = self.sub_displays.log_display
self.sub_displays.log_display.show()
self.update_active_sub_display()
def show_guide(self, user_data):
@@ -125,6 +125,8 @@ class MainDisplay():
def update_active_sub_display(self):
self.frame.contents["body"] = (self.sub_displays.active().widget, None)
self.update_active_shortcuts()
if self.sub_displays.active_display != self.sub_displays.log_display:
self.sub_displays.log_display.kill()
def update_active_shortcuts(self):
self.frame.contents["footer"] = (self.sub_displays.active().shortcuts().widget, None)
@@ -155,7 +157,7 @@ class MainDisplay():
class MenuColumns(urwid.Columns):
def keypress(self, size, key):
if key == "tab" or key == "down":
self.handler.frame.set_focus("body")
self.handler.frame.focus_position = "body"
return super(MenuColumns, self).keypress(size, key)
@@ -169,7 +171,7 @@ class MenuDisplay():
self.menu_indicator = urwid.Text("")
menu_text = ("pack", self.menu_indicator)
menu_text = (urwid.PACK, self.menu_indicator)
button_network = (11, MenuButton("Network", on_press=handler.show_network))
button_conversations = (17, MenuButton("Conversations", on_press=handler.show_conversations))
button_directory = (13, MenuButton("Directory", on_press=handler.show_directory))

View File

@@ -15,7 +15,7 @@ class MapDisplay():
])
self.shortcuts_display = MapDisplayShortcuts(self.app)
self.widget = urwid.Filler(pile, 'top')
self.widget = urwid.Filler(pile, urwid.TOP)
def shortcuts(self):
return self.shortcuts_display

View File

@@ -4,7 +4,6 @@ import random
import time
from urwid.util import is_mouse_press
from urwid.text_layout import calc_coords
import re
DEFAULT_FG_DARK = "ddd"
DEFAULT_FG_LIGHT = "222"
@@ -162,7 +161,7 @@ def parse_line(line, state, url_delegate):
else:
tw = urwid.Text(o, align=state["align"])
widgets.append(("pack", tw))
widgets.append((urwid.PACK, tw))
else:
if o["type"] == "field":
fw = o["width"]
@@ -608,7 +607,7 @@ class LinkSpec(urwid.AttrSpec):
self.link_target = link_target
self.link_fields = None
urwid.AttrSpec.__init__(self, orig_spec.foreground, orig_spec.background)
super().__init__(orig_spec.foreground, orig_spec.background)
class LinkableText(urwid.Text):
@@ -618,7 +617,7 @@ class LinkableText(urwid.Text):
signals = ["click", "change"]
def __init__(self, text, align=None, cursor_position=0, delegate=None):
self.__super.__init__(text, align=align)
super().__init__(text, align=align)
self.delegate = delegate
self._cursor_position = 0
self.key_timeout = 3
@@ -729,7 +728,7 @@ class LinkableText(urwid.Text):
def render(self, size, focus=False):
now = time.time()
c = self.__super.render(size, focus)
c = super().render(size, focus)
if focus and (self.delegate == None or now < self.delegate.last_keypress+self.key_timeout):
c = urwid.CompositeCanvas(c)

View File

@@ -52,7 +52,7 @@ class ListEntry(urwid.Text):
class AnnounceInfo(urwid.WidgetWrap):
def keypress(self, size, key):
if key == "esc":
options = self.parent.left_pile.options(height_type="weight", height_amount=1)
options = self.parent.left_pile.options(height_type=urwid.WEIGHT, height_amount=1)
self.parent.left_pile.contents[0] = (self.parent.announce_stream_display, options)
else:
return super(AnnounceInfo, self).keypress(size, key)
@@ -115,7 +115,7 @@ class AnnounceInfo(urwid.WidgetWrap):
style = "list_untrusted"
def show_announce_stream(sender):
options = self.parent.left_pile.options(height_type="weight", height_amount=1)
options = self.parent.left_pile.options(height_type=urwid.WEIGHT, height_amount=1)
self.parent.left_pile.contents[0] = (self.parent.announce_stream_display, options)
def connect(sender):
@@ -187,54 +187,66 @@ class AnnounceInfo(urwid.WidgetWrap):
RNS.log("Error while setting active propagation node from announce. The contained exception was: "+str(e), RNS.LOG_ERROR)
if is_node:
type_button = ("weight", 0.45, urwid.Button("Connect", on_press=connect))
msg_button = ("weight", 0.45, urwid.Button("Msg Op", on_press=msg_op))
save_button = ("weight", 0.45, urwid.Button("Save", on_press=save_node))
type_button = (urwid.WEIGHT, 0.45, urwid.Button("Connect", on_press=connect))
msg_button = (urwid.WEIGHT, 0.45, urwid.Button("Msg Op", on_press=msg_op))
save_button = (urwid.WEIGHT, 0.45, urwid.Button("Save", on_press=save_node))
elif is_pn:
type_button = ("weight", 0.45, urwid.Button("Use as default", on_press=use_pn))
type_button = (urwid.WEIGHT, 0.45, urwid.Button("Use as default", on_press=use_pn))
save_button = None
else:
type_button = ("weight", 0.45, urwid.Button("Converse", on_press=converse))
type_button = (urwid.WEIGHT, 0.45, urwid.Button("Converse", on_press=converse))
save_button = None
if is_node:
button_columns = urwid.Columns([("weight", 0.45, urwid.Button("Back", on_press=show_announce_stream)), ("weight", 0.1, urwid.Text("")), type_button, ("weight", 0.1, urwid.Text("")), msg_button, ("weight", 0.1, urwid.Text("")), save_button])
button_columns = urwid.Columns([
(urwid.WEIGHT, 0.45, urwid.Button("Back", on_press=show_announce_stream)),
(urwid.WEIGHT, 0.1, urwid.Text("")),
type_button,
(urwid.WEIGHT, 0.1, urwid.Text("")),
msg_button,
(urwid.WEIGHT, 0.1, urwid.Text("")),
save_button,
])
else:
button_columns = urwid.Columns([("weight", 0.45, urwid.Button("Back", on_press=show_announce_stream)), ("weight", 0.1, urwid.Text("")), type_button])
button_columns = urwid.Columns([
(urwid.WEIGHT, 0.45, urwid.Button("Back", on_press=show_announce_stream)),
(urwid.WEIGHT, 0.1, urwid.Text("")),
type_button,
])
pile_widgets = []
if is_pn:
pile_widgets = [
urwid.Text("Time : "+ts_string, align="left"),
urwid.Text("Addr : "+addr_str, align="left"),
urwid.Text("Type : "+type_string, align="left"),
urwid.Text("Time : "+ts_string, align=urwid.LEFT),
urwid.Text("Addr : "+addr_str, align=urwid.LEFT),
urwid.Text("Type : "+type_string, align=urwid.LEFT),
urwid.Divider(g["divider1"]),
button_columns
]
else:
pile_widgets = [
urwid.Text("Time : "+ts_string, align="left"),
urwid.Text("Addr : "+addr_str, align="left"),
urwid.Text("Type : "+type_string, align="left"),
urwid.Text("Name : "+display_str, align="left"),
urwid.Text(["Trust : ", (style, trust_str)], align="left"),
urwid.Text("Time : "+ts_string, align=urwid.LEFT),
urwid.Text("Addr : "+addr_str, align=urwid.LEFT),
urwid.Text("Type : "+type_string, align=urwid.LEFT),
urwid.Text("Name : "+display_str, align=urwid.LEFT),
urwid.Text(["Trust : ", (style, trust_str)], align=urwid.LEFT),
urwid.Divider(g["divider1"]),
urwid.Text(["Announce Data: \n", (data_style, data_str)], align="left"),
urwid.Text(["Announce Data: \n", (data_style, data_str)], align=urwid.LEFT),
urwid.Divider(g["divider1"]),
button_columns
]
if is_node:
operator_entry = urwid.Text("Oprtr : "+op_str, align="left")
operator_entry = urwid.Text("Oprtr : "+op_str, align=urwid.LEFT)
pile_widgets.insert(4, operator_entry)
pile = urwid.Pile(pile_widgets)
self.display_widget = urwid.Filler(pile, valign="top", height="pack")
self.display_widget = urwid.Filler(pile, valign=urwid.TOP, height=urwid.PACK)
urwid.WidgetWrap.__init__(self, urwid.LineBox(self.display_widget, title="Announce Info"))
super().__init__(urwid.LineBox(self.display_widget, title="Announce Info"))
class AnnounceStreamEntry(urwid.WidgetWrap):
@@ -296,13 +308,13 @@ class AnnounceStreamEntry(urwid.WidgetWrap):
urwid.connect_signal(widget, "click", self.display_announce, announce)
self.display_widget = urwid.AttrMap(widget, style, focus_style)
urwid.WidgetWrap.__init__(self, self.display_widget)
super().__init__(self.display_widget)
def display_announce(self, event, announce):
try:
parent = self.app.ui.main_display.sub_displays.network_display
info_widget = AnnounceInfo(announce, parent, self.app)
options = parent.left_pile.options(height_type="weight", height_amount=1)
options = parent.left_pile.options(height_type=urwid.WEIGHT, height_amount=1)
parent.left_pile.contents[0] = (info_widget, options)
except KeyError as e:
@@ -313,17 +325,21 @@ class AnnounceStreamEntry(urwid.WidgetWrap):
def close_req(sender):
self.delegate.parent.close_list_dialogs()
dialog_pile.contents[0] = (urwid.Text("\nKeys requested from network\n", align="center"), options)
dialog_pile.contents[0] = (urwid.Text("\nKeys requested from network\n", align=urwid.CENTER), options)
RNS.Transport.request_path(announce[1])
confirmed_button = urwid.Button("Request keys", on_press=confirmed)
dialog_pile = urwid.Pile([
urwid.Text("The keys for the announced destination could not be recalled. You can wait for an announce to arrive, or request the keys from the network.\n", align="center"),
urwid.Text(
"The keys for the announced destination could not be recalled. "
"You can wait for an announce to arrive, or request the keys from the network.\n",
align=urwid.CENTER,
),
urwid.Columns([
("weight", 0.45, confirmed_button),
("weight", 0.1, urwid.Text("")),
("weight", 0.45, urwid.Button("Close", on_press=dismiss_dialog)),
(urwid.WEIGHT, 0.45, confirmed_button),
(urwid.WEIGHT, 0.1, urwid.Text("")),
(urwid.WEIGHT, 0.45, urwid.Button("Close", on_press=dismiss_dialog)),
])
])
@@ -335,9 +351,18 @@ class AnnounceStreamEntry(urwid.WidgetWrap):
dialog.delegate = self.delegate.parent
bottom = self.delegate
overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
overlay = urwid.Overlay(
dialog,
bottom,
align=urwid.CENTER,
width=urwid.RELATIVE_100,
valign=urwid.MIDDLE,
height=urwid.PACK,
left=2,
right=2,
)
options = self.delegate.parent.left_pile.options("weight", 1)
options = self.delegate.parent.left_pile.options(urwid.WEIGHT, 1)
self.delegate.parent.left_pile.contents[0] = (overlay, options)
def timestamp(self):
@@ -365,11 +390,11 @@ class AnnounceStream(urwid.WidgetWrap):
)
self.display_widget = self.ilb
urwid.WidgetWrap.__init__(self, urwid.LineBox(self.display_widget, title="Announce Stream"))
super().__init__(urwid.LineBox(self.display_widget, title="Announce Stream"))
def keypress(self, size, key):
if key == "up" and (self.no_content or self.ilb.first_item_is_selected()):
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.set_focus("header")
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.focus_position = "header"
elif key == "ctrl x":
self.delete_selected_entry()
@@ -464,7 +489,7 @@ class ListDialogLineBox(urwid.LineBox):
class KnownNodeInfo(urwid.WidgetWrap):
def keypress(self, size, key):
if key == "esc":
options = self.parent.left_pile.options(height_type="weight", height_amount=1)
options = self.parent.left_pile.options(height_type=urwid.WEIGHT, height_amount=1)
self.parent.left_pile.contents[0] = (self.parent.known_nodes_display, options)
else:
return super(KnownNodeInfo, self).keypress(size, key)
@@ -559,7 +584,7 @@ class KnownNodeInfo(urwid.WidgetWrap):
op_str = "Unknown"
def show_known_nodes(sender):
options = self.parent.left_pile.options(height_type="weight", height_amount=1)
options = self.parent.left_pile.options(height_type=urwid.WEIGHT, height_amount=1)
self.parent.left_pile.contents[0] = (self.parent.known_nodes_display, options)
def connect(sender):
@@ -630,21 +655,21 @@ class KnownNodeInfo(urwid.WidgetWrap):
show_known_nodes(None)
back_button = ("weight", 0.2, urwid.Button("Back", on_press=show_known_nodes))
connect_button = ("weight", 0.2, urwid.Button("Connect", on_press=connect))
save_button = ("weight", 0.2, urwid.Button("Save", on_press=save_node))
msg_button = ("weight", 0.2, urwid.Button("Msg Op", on_press=msg_op))
bdiv = ("weight", 0.02, urwid.Text(""))
back_button = (urwid.WEIGHT, 0.2, urwid.Button("Back", on_press=show_known_nodes))
connect_button = (urwid.WEIGHT, 0.2, urwid.Button("Connect", on_press=connect))
save_button = (urwid.WEIGHT, 0.2, urwid.Button("Save", on_press=save_node))
msg_button = (urwid.WEIGHT, 0.2, urwid.Button("Msg Op", on_press=msg_op))
bdiv = (urwid.WEIGHT, 0.02, urwid.Text(""))
button_columns = urwid.Columns([back_button, bdiv, connect_button, bdiv, msg_button, bdiv, save_button])
pile_widgets = [
urwid.Text("Type : "+type_string, align="left"),
urwid.Text("Type : "+type_string, align=urwid.LEFT),
e_name,
urwid.Text("Node Addr : "+addr_str, align="left"),
urwid.Text("Node Addr : "+addr_str, align=urwid.LEFT),
e_sort,
urwid.Divider(g["divider1"]),
urwid.Text(lxmf_addr_str, align="center"),
urwid.Text(lxmf_addr_str, align=urwid.CENTER),
urwid.Divider(g["divider1"]),
propagation_node_checkbox,
connect_identify_checkbox,
@@ -656,7 +681,7 @@ class KnownNodeInfo(urwid.WidgetWrap):
button_columns
]
operator_entry = urwid.Text("Operator : "+op_str, align="left")
operator_entry = urwid.Text("Operator : "+op_str, align=urwid.LEFT)
pile_widgets.insert(3, operator_entry)
hops = RNS.Transport.hops_to(source_hash)
@@ -670,7 +695,7 @@ class KnownNodeInfo(urwid.WidgetWrap):
else:
hops_str = "Unknown"
operator_entry = urwid.Text("Distance : "+hops_str, align="left")
operator_entry = urwid.Text("Distance : "+hops_str, align=urwid.LEFT)
pile_widgets.insert(4, operator_entry)
pile = urwid.Pile(pile_widgets)
@@ -679,9 +704,9 @@ class KnownNodeInfo(urwid.WidgetWrap):
button_columns.focus_position = 0
self.display_widget = urwid.Filler(pile, valign="top", height="pack")
self.display_widget = urwid.Filler(pile, valign=urwid.TOP, height=urwid.PACK)
urwid.WidgetWrap.__init__(self, urwid.LineBox(self.display_widget, title="Node Info"))
super().__init__(urwid.LineBox(self.display_widget, title="Node Info"))
# Yes, this is weird. There is a bug in Urwid/ILB that causes
@@ -694,9 +719,9 @@ class ExceptionHandlingListBox(IndicativeListBox):
except Exception as e:
if key == "up":
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.set_focus("header")
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.focus_position = "header"
elif key == "down":
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.sub_displays.network_display.left_pile.set_focus(1)
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.sub_displays.network_display.left_pile.focus_position = 1
else:
RNS.log("An error occurred while processing an interface event. The contained exception was: "+str(e), RNS.LOG_ERROR)
@@ -723,14 +748,23 @@ class KnownNodes(urwid.WidgetWrap):
else:
self.no_content = True
widget_style = "inactive_text"
self.pile = urwid.Pile([urwid.Text(("warning_text", g["info"]+"\n"), align="center"), SelectText(("warning_text", "Currently, no nodes are saved\n\nCtrl+L to view the announce stream\n\n"), align="center")])
self.display_widget = urwid.Filler(self.pile, valign="top", height="pack")
self.pile = urwid.Pile([
urwid.Text(("warning_text", g["info"]+"\n"), align=urwid.CENTER),
SelectText(
(
"warning_text",
"Currently, no nodes are saved\n\nCtrl+L to view the announce stream\n\n",
),
align=urwid.CENTER,
),
])
self.display_widget = urwid.Filler(self.pile, valign=urwid.TOP, height=urwid.PACK)
urwid.WidgetWrap.__init__(self, urwid.AttrMap(urwid.LineBox(self.display_widget, title="Saved Nodes"), widget_style))
super().__init__(urwid.AttrMap(urwid.LineBox(self.display_widget, title="Saved Nodes"), widget_style))
def keypress(self, size, key):
if key == "up" and (self.no_content or self.ilb.first_item_is_selected()):
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.set_focus("header")
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.focus_position = "header"
elif key == "ctrl x":
self.delete_selected_entry()
@@ -757,27 +791,27 @@ class KnownNodes(urwid.WidgetWrap):
def show_info(sender):
info_widget = KnownNodeInfo(source_hash)
options = parent.left_pile.options(height_type="weight", height_amount=1)
options = parent.left_pile.options(height_type=urwid.WEIGHT, height_amount=1)
parent.left_pile.contents[0] = (info_widget, options)
dialog = ListDialogLineBox(
urwid.Pile([
urwid.Text("Connect to node\n"+self.app.directory.simplest_display_str(source_hash)+"\n", align="center"),
urwid.Text("Connect to node\n"+self.app.directory.simplest_display_str(source_hash)+"\n", align=urwid.CENTER),
urwid.Columns([
("weight", 0.45, urwid.Button("Yes", on_press=confirmed)),
("weight", 0.1, urwid.Text("")),
("weight", 0.45, urwid.Button("No", on_press=dismiss_dialog)),
("weight", 0.1, urwid.Text("")),
("weight", 0.45, urwid.Button("Info", on_press=show_info))])
(urwid.WEIGHT, 0.45, urwid.Button("Yes", on_press=confirmed)),
(urwid.WEIGHT, 0.1, urwid.Text("")),
(urwid.WEIGHT, 0.45, urwid.Button("No", on_press=dismiss_dialog)),
(urwid.WEIGHT, 0.1, urwid.Text("")),
(urwid.WEIGHT, 0.45, urwid.Button("Info", on_press=show_info))])
]), title="?"
)
dialog.delegate = self.delegate
bottom = self
overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
overlay = urwid.Overlay(dialog, bottom, align=urwid.CENTER, width=urwid.RELATIVE_100, valign=urwid.MIDDLE, height=urwid.PACK, left=2, right=2)
options = self.delegate.left_pile.options("weight", 1)
options = self.delegate.left_pile.options(urwid.WEIGHT, 1)
self.delegate.left_pile.contents[0] = (overlay, options)
def delete_selected_entry(self):
@@ -796,16 +830,29 @@ class KnownNodes(urwid.WidgetWrap):
dialog = ListDialogLineBox(
urwid.Pile([
urwid.Text("Delete Node\n"+self.app.directory.simplest_display_str(source_hash)+"\n", align="center"),
urwid.Columns([("weight", 0.45, urwid.Button("Yes", on_press=confirmed)), ("weight", 0.1, urwid.Text("")), ("weight", 0.45, urwid.Button("No", on_press=dismiss_dialog))])
urwid.Text("Delete Node\n"+self.app.directory.simplest_display_str(source_hash)+"\n", align=urwid.CENTER),
urwid.Columns([
(urwid.WEIGHT, 0.45, urwid.Button("Yes", on_press=confirmed)),
(urwid.WEIGHT, 0.1, urwid.Text("")),
(urwid.WEIGHT, 0.45, urwid.Button("No", on_press=dismiss_dialog)),
])
]), title="?"
)
dialog.delegate = self.delegate
bottom = self
overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
overlay = urwid.Overlay(
dialog,
bottom,
align=urwid.CENTER,
width=urwid.RELATIVE_100,
valign=urwid.MIDDLE,
height=urwid.PACK,
left=2,
right=2,
)
options = self.delegate.left_pile.options("weight", 1)
options = self.delegate.left_pile.options(urwid.WEIGHT, 1)
self.delegate.left_pile.contents[0] = (overlay, options)
@@ -869,7 +916,7 @@ class NodeEntry(urwid.WidgetWrap):
self.display_widget = urwid.AttrMap(widget, style, focus_style)
self.display_widget.source_hash = source_hash
urwid.WidgetWrap.__init__(self, self.display_widget)
super().__init__(self.display_widget)
class AnnounceTime(urwid.WidgetWrap):
@@ -880,7 +927,7 @@ class AnnounceTime(urwid.WidgetWrap):
self.display_widget = urwid.Text("")
self.update_time()
urwid.WidgetWrap.__init__(self, self.display_widget)
super().__init__(self.display_widget)
def update_time(self):
self.last_announce_string = "Never"
@@ -912,7 +959,7 @@ class NodeAnnounceTime(urwid.WidgetWrap):
self.display_widget = urwid.Text("")
self.update_time()
urwid.WidgetWrap.__init__(self, self.display_widget)
super().__init__(self.display_widget)
def update_time(self):
self.last_announce_string = "Never"
@@ -943,7 +990,7 @@ class NodeActiveConnections(urwid.WidgetWrap):
self.display_widget = urwid.Text("")
self.update_stat()
urwid.WidgetWrap.__init__(self, self.display_widget)
super().__init__(self.display_widget)
def update_stat(self):
self.stat_string = "None"
@@ -974,7 +1021,7 @@ class NodeStorageStats(urwid.WidgetWrap):
self.display_widget = urwid.Text("")
self.update_stat()
urwid.WidgetWrap.__init__(self, self.display_widget)
super().__init__(self.display_widget)
def update_stat(self):
self.stat_string = "None"
@@ -1017,7 +1064,7 @@ class NodeTotalConnections(urwid.WidgetWrap):
self.display_widget = urwid.Text("")
self.update_stat()
urwid.WidgetWrap.__init__(self, self.display_widget)
super().__init__(self.display_widget)
def update_stat(self):
self.stat_string = "None"
@@ -1049,7 +1096,7 @@ class NodeTotalPages(urwid.WidgetWrap):
self.display_widget = urwid.Text("")
self.update_stat()
urwid.WidgetWrap.__init__(self, self.display_widget)
super().__init__(self.display_widget)
def update_stat(self):
self.stat_string = "None"
@@ -1081,7 +1128,7 @@ class NodeTotalFiles(urwid.WidgetWrap):
self.display_widget = urwid.Text("")
self.update_stat()
urwid.WidgetWrap.__init__(self, self.display_widget)
super().__init__(self.display_widget)
def update_stat(self):
self.stat_string = "None"
@@ -1130,45 +1177,45 @@ class LocalPeer(urwid.WidgetWrap):
dialog = DialogLineBox(
urwid.Pile([
urwid.Text("\n\n\nSaved\n\n", align="center"),
urwid.Text("\n\n\nSaved\n\n", align=urwid.CENTER),
urwid.Button("OK", on_press=dismiss_dialog)
]), title=g["info"]
)
dialog.delegate = self
bottom = self
#overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=4, right=4)
#overlay = urwid.Overlay(dialog, bottom, align=urwid.CENTER, width=urwid.RELATIVE_100, valign=urwid.MIDDLE, height=urwid.PACK, left=4, right=4)
overlay = dialog
options = self.parent.left_pile.options(height_type="pack", height_amount=None)
options = self.parent.left_pile.options(height_type=urwid.PACK, height_amount=None)
self.dialog_open = True
self.parent.left_pile.contents[1] = (overlay, options)
def announce_query(sender):
def dismiss_dialog(sender):
self.dialog_open = False
options = self.parent.left_pile.options(height_type="pack", height_amount=None)
options = self.parent.left_pile.options(height_type=urwid.PACK, height_amount=None)
self.parent.left_pile.contents[1] = (LocalPeer(self.app, self.parent), options)
self.app.announce_now()
dialog = DialogLineBox(
urwid.Pile([
urwid.Text("\n\n\nAnnounce Sent\n\n\n", align="center"),
urwid.Text("\n\n\nAnnounce Sent\n\n\n", align=urwid.CENTER),
urwid.Button("OK", on_press=dismiss_dialog)
]), title=g["info"]
)
dialog.delegate = self
bottom = self
#overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=4, right=4)
#overlay = urwid.Overlay(dialog, bottom, align=urwid.CENTER, width=urwid.RELATIVE_100, valign=urwid.MIDDLE, height=urwid.PACK, left=4, right=4)
overlay = dialog
self.dialog_open = True
options = self.parent.left_pile.options(height_type="pack", height_amount=None)
options = self.parent.left_pile.options(height_type=urwid.PACK, height_amount=None)
self.parent.left_pile.contents[1] = (overlay, options)
def node_info_query(sender):
options = self.parent.left_pile.options(height_type="pack", height_amount=None)
options = self.parent.left_pile.options(height_type=urwid.PACK, height_amount=None)
self.parent.left_pile.contents[1] = (self.parent.node_info_display, options)
if LocalPeer.announce_timer == None:
@@ -1189,11 +1236,15 @@ class LocalPeer(urwid.WidgetWrap):
self.t_last_announce,
announce_button,
urwid.Divider(g["divider1"]),
urwid.Columns([("weight", 0.45, urwid.Button("Save", on_press=save_query)), ("weight", 0.1, urwid.Text("")), ("weight", 0.45, urwid.Button("Node Info", on_press=node_info_query))])
urwid.Columns([
(urwid.WEIGHT, 0.45, urwid.Button("Save", on_press=save_query)),
(urwid.WEIGHT, 0.1, urwid.Text("")),
(urwid.WEIGHT, 0.45, urwid.Button("Node Info", on_press=node_info_query)),
])
]
)
urwid.WidgetWrap.__init__(self, urwid.LineBox(self.display_widget, title="Local Peer Info"))
super().__init__(urwid.LineBox(self.display_widget, title="Local Peer Info"))
def start(self):
self.t_last_announce.start()
@@ -1217,7 +1268,7 @@ class NodeInfo(urwid.WidgetWrap):
widget_style = ""
def show_peer_info(sender):
options = self.parent.left_pile.options(height_type="pack", height_amount=None)
options = self.parent.left_pile.options(height_type=urwid.PACK, height_amount=None)
self.parent.left_pile.contents[1] = (LocalPeer(self.app, self.parent), options)
if self.app.enable_node:
@@ -1241,25 +1292,25 @@ class NodeInfo(urwid.WidgetWrap):
def announce_query(sender):
def dismiss_dialog(sender):
self.dialog_open = False
options = self.parent.left_pile.options(height_type="pack", height_amount=None)
options = self.parent.left_pile.options(height_type=urwid.PACK, height_amount=None)
self.parent.left_pile.contents[1] = (NodeInfo(self.app, self.parent), options)
self.app.node.announce()
dialog = DialogLineBox(
urwid.Pile([
urwid.Text("\n\n\nAnnounce Sent\n\n", align="center"),
urwid.Text("\n\n\nAnnounce Sent\n\n", align=urwid.CENTER),
urwid.Button("OK", on_press=dismiss_dialog)
]), title=g["info"]
)
dialog.delegate = self
bottom = self
#overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=4, right=4)
#overlay = urwid.Overlay(dialog, bottom, align=urwid.CENTER, width=urwid.RELATIVE_100, valign=urwid.MIDDLE, height=urwid.PACK, left=4, right=4)
overlay = dialog
self.dialog_open = True
options = self.parent.left_pile.options(height_type="pack", height_amount=None)
options = self.parent.left_pile.options(height_type=urwid.PACK, height_amount=None)
self.parent.left_pile.contents[1] = (overlay, options)
def connect_query(sender):
@@ -1308,7 +1359,7 @@ class NodeInfo(urwid.WidgetWrap):
self.t_total_files.update_stat()
lxmf_addr_str = g["sent"]+" LXMF Propagation Node Address is "+RNS.prettyhexrep(RNS.Destination.hash_from_name_and_identity("lxmf.propagation", self.app.node.destination.identity))
e_lxmf = urwid.Text(lxmf_addr_str, align="center")
e_lxmf = urwid.Text(lxmf_addr_str, align=urwid.CENTER)
announce_button = urwid.Button("Announce", on_press=announce_query)
connect_button = urwid.Button("Browse", on_press=connect_query)
@@ -1329,13 +1380,13 @@ class NodeInfo(urwid.WidgetWrap):
self.t_total_files,
urwid.Divider(g["divider1"]),
urwid.Columns([
("weight", 5, urwid.Button("Back", on_press=show_peer_info)),
("weight", 0.5, urwid.Text("")),
("weight", 6, connect_button),
("weight", 0.5, urwid.Text("")),
("weight", 8, reset_button),
("weight", 0.5, urwid.Text("")),
("weight", 7, announce_button),
(urwid.WEIGHT, 5, urwid.Button("Back", on_press=show_peer_info)),
(urwid.WEIGHT, 0.5, urwid.Text("")),
(urwid.WEIGHT, 6, connect_button),
(urwid.WEIGHT, 0.5, urwid.Text("")),
(urwid.WEIGHT, 8, reset_button),
(urwid.WEIGHT, 0.5, urwid.Text("")),
(urwid.WEIGHT, 7, announce_button),
])
])
else:
@@ -1351,25 +1402,25 @@ class NodeInfo(urwid.WidgetWrap):
self.t_total_files,
urwid.Divider(g["divider1"]),
urwid.Columns([
("weight", 5, urwid.Button("Back", on_press=show_peer_info)),
("weight", 0.5, urwid.Text("")),
("weight", 6, connect_button),
("weight", 0.5, urwid.Text("")),
("weight", 8, reset_button),
("weight", 0.5, urwid.Text("")),
("weight", 7, announce_button),
(urwid.WEIGHT, 5, urwid.Button("Back", on_press=show_peer_info)),
(urwid.WEIGHT, 0.5, urwid.Text("")),
(urwid.WEIGHT, 6, connect_button),
(urwid.WEIGHT, 0.5, urwid.Text("")),
(urwid.WEIGHT, 8, reset_button),
(urwid.WEIGHT, 0.5, urwid.Text("")),
(urwid.WEIGHT, 7, announce_button),
])
])
else:
pile = urwid.Pile([
urwid.Text("\n"+g["info"], align="center"),
urwid.Text("\nThis instance is not hosting a node\n\n", align="center"),
urwid.Padding(urwid.Button("Back", on_press=show_peer_info), "center", "pack")
urwid.Text("\n"+g["info"], align=urwid.CENTER),
urwid.Text("\nThis instance is not hosting a node\n\n", align=urwid.CENTER),
urwid.Padding(urwid.Button("Back", on_press=show_peer_info), urwid.CENTER, urwid.PACK)
])
self.display_widget = pile
urwid.WidgetWrap.__init__(self, urwid.AttrMap(urwid.LineBox(self.display_widget, title="Local Node Info"), widget_style))
super().__init__(urwid.AttrMap(urwid.LineBox(self.display_widget, title="Local Node Info"), widget_style))
def start(self):
if self.app.node != None:
@@ -1392,7 +1443,7 @@ class UpdatingText(urwid.WidgetWrap):
self.append_text = append_text
self.update()
urwid.WidgetWrap.__init__(self, self.display_widget)
super().__init__(self.display_widget)
def update(self):
self.value = self.value_method()
@@ -1434,7 +1485,7 @@ class NetworkStats(urwid.WidgetWrap):
self.display_widget = urwid.LineBox(pile, title="Network Stats")
urwid.WidgetWrap.__init__(self, self.display_widget)
super().__init__(self.display_widget)
def start(self):
self.w_heard_peers.start()
@@ -1486,9 +1537,9 @@ class NetworkDisplay():
self.list_display = 1
self.left_pile = NetworkLeftPile([
("weight", 1, self.known_nodes_display),
# ("pack", self.network_stats_display),
("pack", self.local_peer_display),
(urwid.WEIGHT, 1, self.known_nodes_display),
# (urwid.PACK, self.network_stats_display),
(urwid.PACK, self.local_peer_display),
])
self.left_pile.parent = self
@@ -1499,10 +1550,10 @@ class NetworkDisplay():
self.columns = urwid.Columns(
[
# ("weight", NetworkDisplay.list_width, self.left_area),
# ("weight", self.right_area_width, self.right_area)
# (urwid.WEIGHT, NetworkDisplay.list_width, self.left_area),
# (urwid.WEIGHT, self.right_area_width, self.right_area)
(NetworkDisplay.given_list_width, self.left_area),
("weight", 1, self.right_area)
(urwid.WEIGHT, 1, self.right_area)
],
dividechars=0, focus_column=0
)
@@ -1512,11 +1563,11 @@ class NetworkDisplay():
def toggle_list(self):
if self.list_display != 0:
options = self.left_pile.options(height_type="weight", height_amount=1)
options = self.left_pile.options(height_type=urwid.WEIGHT, height_amount=1)
self.left_pile.contents[0] = (self.announce_stream_display, options)
self.list_display = 0
else:
options = self.left_pile.options(height_type="weight", height_amount=1)
options = self.left_pile.options(height_type=urwid.WEIGHT, height_amount=1)
self.left_pile.contents[0] = (self.known_nodes_display, options)
self.list_display = 1
@@ -1531,7 +1582,7 @@ class NetworkDisplay():
self.widget.contents[0] = (self.left_area, options)
def show_peers(self):
options = self.left_pile.options(height_type="weight", height_amount=1)
options = self.left_pile.options(height_type=urwid.WEIGHT, height_amount=1)
self.left_pile.contents[0] = (self.lxmf_peers_display, options)
if self.list_display != 0:
@@ -1548,7 +1599,7 @@ class NetworkDisplay():
if selected_node_hash != None:
info_widget = KnownNodeInfo(selected_node_hash)
options = parent.left_pile.options(height_type="weight", height_amount=1)
options = parent.left_pile.options(height_type=urwid.WEIGHT, height_amount=1)
parent.left_pile.contents[0] = (info_widget, options)
def focus_lists(self):
@@ -1567,10 +1618,10 @@ class NetworkDisplay():
def close_list_dialogs(self):
if self.list_display == 0:
options = self.left_pile.options(height_type="weight", height_amount=1)
options = self.left_pile.options(height_type=urwid.WEIGHT, height_amount=1)
self.left_pile.contents[0] = (self.announce_stream_display, options)
else:
options = self.left_pile.options(height_type="weight", height_amount=1)
options = self.left_pile.options(height_type=urwid.WEIGHT, height_amount=1)
self.left_pile.contents[0] = (self.known_nodes_display, options)
def start(self):
@@ -1613,18 +1664,21 @@ class LXMFPeers(urwid.WidgetWrap):
else:
self.no_content = True
widget_style = "inactive_text"
self.pile = urwid.Pile([urwid.Text(("warning_text", g["info"]+"\n"), align="center"), SelectText(("warning_text", "Currently, no LXMF nodes are peered\n\n"), align="center")])
self.display_widget = urwid.Filler(self.pile, valign="top", height="pack")
self.pile = urwid.Pile([
urwid.Text(("warning_text", g["info"]+"\n"), align=urwid.CENTER),
SelectText(("warning_text", "Currently, no LXMF nodes are peered\n\n"), align=urwid.CENTER),
])
self.display_widget = urwid.Filler(self.pile, valign=urwid.TOP, height=urwid.PACK)
if hasattr(self, "peer_list") and self.peer_list:
pl = len(self.peer_list)
else:
pl = 0
urwid.WidgetWrap.__init__(self, urwid.AttrMap(urwid.LineBox(self.display_widget, title=f"LXMF Propagation Peers ({pl})"), widget_style))
super().__init__(urwid.AttrMap(urwid.LineBox(self.display_widget, title=f"LXMF Propagation Peers ({pl})"), widget_style))
def keypress(self, size, key):
if key == "up" and (self.no_content or self.ilb.first_item_is_selected()):
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.set_focus("header")
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.focus_position = "header"
elif key == "ctrl x":
self.delete_selected_entry()
elif key == "ctrl r":
@@ -1665,16 +1719,21 @@ class LXMFPeers(urwid.WidgetWrap):
dialog = ListDialogLineBox(
urwid.Pile([
urwid.Text("A delivery sync of all unhandled LXMs was manually requested for the selected node\n", align="center"),
urwid.Columns([("weight", 0.1, urwid.Text("")), ("weight", 0.45, urwid.Button("OK", on_press=dismiss_dialog))])
]), title="!"
urwid.Text("A delivery sync of all unhandled LXMs was manually requested for the selected node\n", align=urwid.CENTER),
urwid.Columns([
(urwid.WEIGHT, 0.1, urwid.Text("")),
(urwid.WEIGHT, 0.45, urwid.Button("OK", on_press=dismiss_dialog)),
])
]),
title="!",
)
dialog.delegate = self.delegate
bottom = self
overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
overlay = urwid.Overlay(dialog, bottom, align=urwid.CENTER, width=urwid.RELATIVE_100, valign=urwid.MIDDLE, height=urwid.PACK, left=2, right=2)
options = self.delegate.left_pile.options("weight", 1)
options = self.delegate.left_pile.options(urwid.WEIGHT, 1)
self.delegate.left_pile.contents[0] = (overlay, options)
@@ -1741,7 +1800,7 @@ class LXMFPeerEntry(urwid.WidgetWrap):
widget = ListEntry(sym+" "+display_str+"\n "+alive_string+", last heard "+pretty_date(int(peer.last_heard))+"\n "+str(len(peer.unhandled_messages))+" unhandled LXMs, "+RNS.prettysize(peer.link_establishment_rate/8, "b")+"/s LER")
self.display_widget = urwid.AttrMap(widget, style, focus_style)
self.display_widget.destination_hash = destination_hash
urwid.WidgetWrap.__init__(self, self.display_widget)
super().__init__(self.display_widget)
def pretty_date(time=False):

View File

@@ -268,10 +268,10 @@ class Scrollable(urwid.WidgetDecoration):
def _get_original_widget_size(self, size):
ow = self._original_widget
sizing = ow.sizing()
if FIXED in sizing:
return ()
elif FLOW in sizing:
if FLOW in sizing:
return (size[0],)
elif FIXED in sizing:
return ()
def get_scrollpos(self, size=None, focus=False):
"""Current scrolling position

View File

@@ -269,11 +269,13 @@ class IndicativeListBox(urwid.WidgetWrap):
# mousewheel up
elif button == 4.0:
was_handeled = self._pass_key_to_contained_listbox(modified_size, "page up")
# was_handeled = self._pass_key_to_contained_listbox(modified_size, "page up")
was_handeled = self._pass_key_to_contained_listbox(modified_size, "up")
# mousewheel down
elif button == 5.0:
was_handeled = self._pass_key_to_contained_listbox(modified_size, "page down")
# was_handeled = self._pass_key_to_contained_listbox(modified_size, "page down")
was_handeled = self._pass_key_to_contained_listbox(modified_size, "down")
focus_position_after_input = self.get_selected_position()

View File

@@ -30,6 +30,6 @@ setuptools.setup(
entry_points= {
'console_scripts': ['nomadnet=nomadnet.nomadnet:main']
},
install_requires=["rns>=0.6.4", "lxmf>=0.3.8", "urwid==2.1.2", "qrcode"],
install_requires=["rns>=0.7.0", "lxmf>=0.3.9", "urwid>=2.4.2,!=2.4.3", "qrcode"],
python_requires=">=3.6",
)