Show status source

This commit is contained in:
Ivan Habunek 2019-08-25 14:30:57 +02:00
parent 2d8199646f
commit 2be8cb8438
No known key found for this signature in database
GPG key ID: CDBD63C43A30BB95
4 changed files with 71 additions and 8 deletions

View file

@ -3,3 +3,9 @@ https://github.com/CanonicalLtd/subiquity/blob/master/subiquitycore/core.py#L280
educational: educational:
https://github.com/TomasTomecek/sen/blob/master/sen/tui/ui.py https://github.com/TomasTomecek/sen/blob/master/sen/tui/ui.py
check out:
https://github.com/rndusr/stig/tree/master/stig/tui
Questions:
* is it possible to make a span a urwid.Text selectable? e.g. for urls and hashtags

View file

@ -1,3 +1,4 @@
import json
import logging import logging
import urwid import urwid
@ -8,6 +9,7 @@ from toot import api
from .constants import PALETTE from .constants import PALETTE
from .entities import Status from .entities import Status
from .timeline import Timeline from .timeline import Timeline
from .widgets import SelectableText
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -90,6 +92,9 @@ class TUI(urwid.Frame):
self.footer = Footer() self.footer = Footer()
self.footer.set_status("Loading...") self.footer.set_status("Loading...")
self.timeline = None
self.overlay = None
super().__init__(self.body, header=self.header, footer=self.footer) super().__init__(self.body, header=self.header, footer=self.footer)
def run(self): def run(self):
@ -126,17 +131,18 @@ class TUI(urwid.Frame):
def statuses_loaded_initial(self, future): def statuses_loaded_initial(self, future):
# TODO: handle errors in future # TODO: handle errors in future
self.body = Timeline(self, future.result()) self.timeline = Timeline(self, future.result())
urwid.connect_signal(self.body, "status_focused", urwid.connect_signal(self.timeline, "status_focused",
lambda _, args: self.status_focused(*args)) lambda _, args: self.status_focused(*args))
urwid.connect_signal(self.body, "next", urwid.connect_signal(self.timeline, "next",
lambda *args: self.schedule_load_next()) lambda *args: self.schedule_load_next())
self.body.status_focused() # Draw first status self.timeline.status_focused() # Draw first status
self.body = self.timeline
def statuses_loaded_next(self, future): def statuses_loaded_next(self, future):
# TODO: handle errors in future # TODO: handle errors in future
self.body.add_statuses(future.result()) self.timeline.add_statuses(future.result())
def status_focused(self, status, index, count): def status_focused(self, status, index, count):
self.footer.set_status([ self.footer.set_status([
@ -144,6 +150,53 @@ class TUI(urwid.Frame):
" - status ", str(index + 1), " of ", str(count), " - status ", str(index + 1), " of ", str(count),
]) ])
def show_status_source(self, status):
self.open_overlay(
widget=StatusSource(status),
title="Status source",
options={
"align": 'center',
"width": ('relative', 80),
"valign": 'middle',
"height": ('relative', 80),
},
)
# --- Overlay handling -----------------------------------------------------
def open_overlay(self, widget, options={}, title=""):
top_widget = urwid.LineBox(widget, title=title)
bottom_widget = self.body
self.overlay = urwid.Overlay(
top_widget,
bottom_widget,
**options
)
self.body = self.overlay
def close_overlay(self):
self.body = self.overlay.bottom_w
self.overlay = None
# --- Keys -----------------------------------------------------------------
def unhandled_input(self, key): def unhandled_input(self, key):
if key in ('q', 'Q'): if key in ('q', 'Q'):
if self.overlay:
self.close_overlay()
else:
raise urwid.ExitMainLoop() raise urwid.ExitMainLoop()
class StatusSource(urwid.ListBox):
"""Shows status data, as returned by the server, as formatted JSON."""
def __init__(self, status):
source = json.dumps(status.data, indent=4)
lines = source.splitlines()
focus_map = {None: "blue_selected"}
walker = urwid.SimpleFocusListWalker([
urwid.AttrMap(SelectableText(line), None, focus_map)
for line in lines
])
super().__init__(walker)

View file

@ -14,7 +14,7 @@ PALETTE = [
# Colors # Colors
('blue', 'light blue', ''), ('blue', 'light blue', ''),
('blue_bold', 'light blue, bold', ''), ('blue_bold', 'light blue, bold', ''),
('blue_selected', 'white,bold', 'dark blue'), ('blue_selected', 'white', 'dark blue'),
('cyan', 'dark cyan', ''), ('cyan', 'dark cyan', ''),
('cyan_bold', 'dark cyan,bold', ''), ('cyan_bold', 'dark cyan,bold', ''),
('gray', 'dark gray', ''), ('gray', 'dark gray', ''),

View file

@ -26,7 +26,6 @@ class Timeline(urwid.Columns):
def __init__(self, tui, statuses): def __init__(self, tui, statuses):
self.tui = tui self.tui = tui
self.statuses = statuses self.statuses = statuses
self.instance = tui.app.instance
self.status_list = self.build_status_list(statuses) self.status_list = self.build_status_list(statuses)
self.status_details = self.build_status_details(statuses[0]) self.status_details = self.build_status_details(statuses[0])
@ -89,6 +88,11 @@ class Timeline(urwid.Columns):
webbrowser.open(status.data["url"]) webbrowser.open(status.data["url"])
return return
if key in ("u", "U"):
status = self.get_focused_status()
self.tui.show_status_source(status)
return
return super().keypress(size, key) return super().keypress(size, key)
def add_statuses(self, statuses): def add_statuses(self, statuses):