1
0
mirror of https://github.com/ihabunek/toot.git synced 2024-06-30 06:35:24 +00:00

Load next when at bottom of list

This commit is contained in:
Ivan Habunek 2019-08-24 13:13:22 +02:00
parent c99999161d
commit f68f5d5716
No known key found for this signature in database
GPG Key ID: CDBD63C43A30BB95
2 changed files with 56 additions and 14 deletions

View File

@ -49,13 +49,13 @@ class Footer(urwid.Pile):
self.status.set_text(text) self.status.set_text(text)
def clear_status(self, text): def clear_status(self, text):
self.status.set_text(urwid.Text()) self.status.set_text("")
def set_message(self, text): def set_message(self, text):
self.message.set_text(text) self.message.set_text(text)
def clear_message(self): def clear_message(self):
self.message.set_text(urwid.Text()) self.message.set_text("")
class TUI(urwid.Frame): class TUI(urwid.Frame):
@ -82,8 +82,8 @@ class TUI(urwid.Frame):
self.loop = None # set in `create` self.loop = None # set in `create`
self.executor = ThreadPoolExecutor(max_workers=1) self.executor = ThreadPoolExecutor(max_workers=1)
# self.timeline_generator = api.home_timeline_generator(app, user, limit=40) self.timeline_generator = api.home_timeline_generator(app, user, limit=40)
self.timeline_generator = api.public_timeline_generator(app.instance, local=False, limit=40) # self.timeline_generator = api.public_timeline_generator(app.instance, local=False, limit=40)
self.body = urwid.Filler(urwid.Text("Loading toots...", align="center")) self.body = urwid.Filler(urwid.Text("Loading toots...", align="center"))
self.header = Header(app, user) self.header = Header(app, user)
@ -93,32 +93,50 @@ class TUI(urwid.Frame):
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):
self.loop.set_alarm_in(0, self.schedule_loading_toots) self.loop.set_alarm_in(0, self.schedule_load_statuses)
self.loop.run() self.loop.run()
self.executor.shutdown(wait=False) self.executor.shutdown(wait=False)
def run_in_thread(self, fn, args=[], kwargs={}, done_callback=None): def run_in_thread(self, fn, args=[], kwargs={}, done_callback=None):
future = self.executor.submit(self.load_toots) future = self.executor.submit(fn)
if done_callback: if done_callback:
future.add_done_callback(done_callback) future.add_done_callback(done_callback)
def schedule_loading_toots(self, *args): def schedule_load_statuses(self, *args):
self.run_in_thread(self.load_toots, done_callback=self.toots_loaded) self.run_in_thread(self.load_statuses, done_callback=self.statuses_loaded_initial)
def load_toots(self): def load_statuses(self):
data = next(self.timeline_generator) self.footer.set_message("Loading statuses...")
with open("tmp/statuses2.json", "w") as f: try:
import json data = next(self.timeline_generator)
json.dump(data, f, indent=4) except StopIteration:
return []
finally:
self.footer.clear_message()
# with open("tmp/statuses2.json", "w") as f:
# import json
# json.dump(data, f, indent=4)
return [Status(s, self.app.instance) for s in data] return [Status(s, self.app.instance) for s in data]
def toots_loaded(self, future): def schedule_load_next(self):
self.run_in_thread(self.load_statuses, done_callback=self.statuses_loaded_next)
def statuses_loaded_initial(self, future):
# TODO: handle errors in future
self.body = Timeline(self, future.result()) self.body = Timeline(self, future.result())
urwid.connect_signal(self.body, "status_focused", urwid.connect_signal(self.body, "status_focused",
lambda _, args: self.status_focused(*args)) lambda _, args: self.status_focused(*args))
urwid.connect_signal(self.body, "next",
lambda *args: self.schedule_load_next())
self.body.status_focused() # Draw first status self.body.status_focused() # Draw first status
def statuses_loaded_next(self, future):
# TODO: handle errors in future
self.body.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([
("footer_status_bold", "[home] "), status.id, ("footer_status_bold", "[home] "), status.id,

View File

@ -1,5 +1,6 @@
import logging import logging
import urwid import urwid
import webbrowser
from toot.utils import format_content from toot.utils import format_content
@ -18,6 +19,7 @@ class Timeline(urwid.Columns):
signals = [ signals = [
"status_focused", "status_focused",
"status_activated", "status_activated",
"next",
] ]
def __init__(self, tui, statuses): def __init__(self, tui, statuses):
@ -70,6 +72,28 @@ class Timeline(urwid.Columns):
count = len(self.statuses) count = len(self.statuses)
self._emit("status_focused", [status, index, count]) self._emit("status_focused", [status, index, count])
def keypress(self, size, key):
# If down is pressed on last status in list emit a signal to load more.
# TODO: Consider pre-loading statuses earlier
command = self._command_map[key]
if command in [urwid.CURSOR_DOWN, urwid.CURSOR_PAGE_DOWN]:
index = self.status_list.body.focus + 1
count = len(self.statuses)
if index >= count:
self._emit("next")
if key in ("v", "V"):
status = self.get_focused_status()
webbrowser.open(status.data["url"])
return
return super().keypress(size, key)
def add_statuses(self, statuses):
self.statuses += statuses
new_items = [self.build_list_item(status) for status in statuses]
self.status_list.body.extend(new_items)
class StatusDetails(urwid.Pile): class StatusDetails(urwid.Pile):
def __init__(self, status): def __init__(self, status):