Added animated loading box.
This commit is contained in:
@@ -3,6 +3,7 @@ import praw
|
||||
|
||||
from utils import clean, strip_subreddit_url, humanize_timestamp
|
||||
|
||||
# TODO: rename, ... container?
|
||||
class BaseContent(object):
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -3,7 +3,7 @@ import curses
|
||||
import sys
|
||||
|
||||
from content_generators import SubmissionContent, SubredditContent
|
||||
from utils import curses_session
|
||||
from utils import curses_session, LoadScreen
|
||||
from viewer import BaseViewer
|
||||
|
||||
class SubmissionViewer(BaseViewer):
|
||||
@@ -50,6 +50,7 @@ class SubmissionViewer(BaseViewer):
|
||||
def refresh_content(self):
|
||||
|
||||
self.add_loading()
|
||||
with LoadScreen(self.stdscr):
|
||||
self.content.reset()
|
||||
self.stdscr.clear()
|
||||
self.draw()
|
||||
@@ -138,17 +139,3 @@ class SubmissionViewer(BaseViewer):
|
||||
win.addnstr(row, 1, text, n_cols)
|
||||
|
||||
win.border()
|
||||
|
||||
def main():
|
||||
|
||||
with curses_session() as stdscr:
|
||||
r = praw.Reddit(user_agent='reddit terminal viewer (rtv) v0.0')
|
||||
submission = SubredditContent(r).get(0)['object']
|
||||
generator = SubmissionContent(submission)
|
||||
|
||||
viewer = SubmissionViewer(stdscr, generator)
|
||||
viewer.loop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
main()
|
||||
@@ -6,7 +6,7 @@ import sys
|
||||
from content_generators import SubredditContent, SubmissionContent
|
||||
from submission_viewer import SubmissionViewer
|
||||
from viewer import BaseViewer
|
||||
from utils import curses_session, text_input
|
||||
from utils import curses_session, text_input, LoadScreen
|
||||
|
||||
class SubredditViewer(BaseViewer):
|
||||
|
||||
@@ -49,9 +49,9 @@ class SubredditViewer(BaseViewer):
|
||||
|
||||
def refresh_content(self, subreddit=None):
|
||||
|
||||
self.add_loading()
|
||||
self.nav.page_index, self.nav.cursor_index = 0, 0
|
||||
self.nav.inverted = False
|
||||
with LoadScreen(self.stdscr):
|
||||
self.content.reset(subreddit=subreddit)
|
||||
self.stdscr.clear()
|
||||
self.draw()
|
||||
@@ -73,8 +73,7 @@ class SubredditViewer(BaseViewer):
|
||||
def open_submission(self):
|
||||
"Select the current submission to view posts"
|
||||
|
||||
self.add_loading()
|
||||
|
||||
with LoadScreen(self.stdscr):
|
||||
submission = self.content.get(self.nav.absolute_index)['object']
|
||||
content = SubmissionContent(submission)
|
||||
viewer = SubmissionViewer(self.stdscr, content)
|
||||
|
||||
67
rtv/utils.py
67
rtv/utils.py
@@ -1,13 +1,76 @@
|
||||
from datetime import datetime, timedelta
|
||||
from contextlib import contextmanager
|
||||
import os
|
||||
import curses
|
||||
import time
|
||||
import threading
|
||||
from curses import textpad
|
||||
from datetime import datetime, timedelta
|
||||
from contextlib import contextmanager
|
||||
|
||||
class EscapePressed(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class LoadScreen(object):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
stdscr,
|
||||
message='Downloading',
|
||||
trail='...',
|
||||
delay=0.5,
|
||||
interval=0.4):
|
||||
|
||||
self._stdscr = stdscr
|
||||
self.message = message
|
||||
self.delay = delay
|
||||
self.interval=interval
|
||||
self.trail = trail
|
||||
|
||||
message_len = len(self.message) + len(self.trail)
|
||||
n_rows, n_cols = stdscr.getmaxyx()
|
||||
s_row = (n_rows - 2) / 2
|
||||
s_col = (n_cols - message_len - 1) / 2
|
||||
self.window = stdscr.derwin(3, message_len+2, s_row, s_col)
|
||||
|
||||
self._animator = threading.Thread(target=self.animate)
|
||||
self._animator.daemon = True
|
||||
self._is_running = None
|
||||
|
||||
def __enter__(self):
|
||||
|
||||
self._is_running = True
|
||||
self._animator.start()
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
|
||||
self._is_running = False
|
||||
self._animator.join()
|
||||
|
||||
del self.window
|
||||
self._stdscr.refresh()
|
||||
|
||||
def animate(self):
|
||||
|
||||
# Delay before popping up the animation to avoid flashing
|
||||
# the screen if the load time is effectively zero
|
||||
start = time.time()
|
||||
while (time.time() - start) < self.delay:
|
||||
if not self._is_running:
|
||||
return
|
||||
|
||||
while True:
|
||||
for i in xrange(len(self.trail)+1):
|
||||
|
||||
if not self._is_running:
|
||||
return
|
||||
|
||||
self.window.erase()
|
||||
self.window.border()
|
||||
self.window.addstr(1, 1, self.message + self.trail[:i])
|
||||
self.window.refresh()
|
||||
time.sleep(self.interval)
|
||||
|
||||
|
||||
def clean(unicode_string):
|
||||
"""
|
||||
Convert unicode string into ascii-safe characters.
|
||||
|
||||
@@ -83,7 +83,6 @@ class BaseViewer(object):
|
||||
self.nav = Navigator(self.content.get, **kwargs)
|
||||
|
||||
self._subwindows = None
|
||||
self.add_loading()
|
||||
|
||||
def draw(self):
|
||||
raise NotImplementedError
|
||||
@@ -107,20 +106,6 @@ class BaseViewer(object):
|
||||
continue
|
||||
self.stdscr.nodelay(0)
|
||||
|
||||
def add_loading(self):
|
||||
"Draw a `loading` popup dialog in the center of the screen"
|
||||
|
||||
message = 'Loading...'
|
||||
|
||||
n_rows, n_cols = self.stdscr.getmaxyx()
|
||||
win_rows, win_cols = 3, len(message)+2
|
||||
start_row = (n_rows - win_rows) / 2
|
||||
start_col = (n_cols - win_cols) / 2
|
||||
window = self.stdscr.derwin(win_rows, win_cols, start_row, start_col)
|
||||
window.border()
|
||||
window.addstr(1, 1, message)
|
||||
window.refresh()
|
||||
|
||||
def draw_header(self):
|
||||
|
||||
n_rows, n_cols = self._header_window.getmaxyx()
|
||||
|
||||
Reference in New Issue
Block a user