Added text input for subreddit prompt, added escape key support.
This commit is contained in:
@@ -16,7 +16,6 @@ class BaseContent(object):
|
||||
data['object'] = comment
|
||||
data['level'] = comment.nested_level
|
||||
|
||||
|
||||
if isinstance(comment, praw.objects.MoreComments):
|
||||
data['type'] = 'MoreComments'
|
||||
data['body'] = 'More comments [{}]'.format(comment.count)
|
||||
@@ -147,8 +146,9 @@ class SubredditContent(BaseContent):
|
||||
self._submissions = self.r.get_front_page(limit=None)
|
||||
self.display_name = 'Front Page'
|
||||
else:
|
||||
self._submissions = self.r.get_subreddit(self.subreddit, limit=None)
|
||||
self.display_name = self._submissions.display_name
|
||||
sub = self.r.get_subreddit(self.subreddit)
|
||||
self._submissions = sub.get_hot()
|
||||
self.display_name = '/r/' + self.subreddit
|
||||
|
||||
|
||||
class SubmissionContent(BaseContent):
|
||||
|
||||
@@ -37,7 +37,7 @@ class SubmissionViewer(BaseViewer):
|
||||
self.draw()
|
||||
|
||||
# Go back
|
||||
elif cmd in (ord('b'), curses.KEY_LEFT):
|
||||
elif cmd in (ord('b'), 27, curses.KEY_LEFT):
|
||||
break
|
||||
|
||||
# Quit
|
||||
@@ -47,6 +47,13 @@ class SubmissionViewer(BaseViewer):
|
||||
else:
|
||||
curses.beep()
|
||||
|
||||
def refresh_content(self):
|
||||
|
||||
self.add_loading()
|
||||
self.content.reset()
|
||||
self.stdscr.clear()
|
||||
self.draw()
|
||||
|
||||
def draw(self):
|
||||
|
||||
n_rows, n_cols = self.stdscr.getmaxyx()
|
||||
|
||||
@@ -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
|
||||
from utils import curses_session, text_input
|
||||
|
||||
class SubredditViewer(BaseViewer):
|
||||
|
||||
@@ -31,7 +31,7 @@ class SubredditViewer(BaseViewer):
|
||||
|
||||
# Enter edit mode to change subreddit
|
||||
elif cmd == ord('/'):
|
||||
pass
|
||||
self.prompt_subreddit()
|
||||
|
||||
# Refresh page
|
||||
elif cmd in (curses.KEY_F5, ord('r')):
|
||||
@@ -47,6 +47,29 @@ class SubredditViewer(BaseViewer):
|
||||
else:
|
||||
curses.beep()
|
||||
|
||||
def refresh_content(self, subreddit=None):
|
||||
|
||||
self.add_loading()
|
||||
self.nav.page_index, self.nav.cursor_index = 0, 0
|
||||
self.nav.inverted = False
|
||||
self.content.reset(subreddit=subreddit)
|
||||
self.stdscr.clear()
|
||||
self.draw()
|
||||
|
||||
def prompt_subreddit(self):
|
||||
|
||||
prompt = 'Enter Subreddit: /r/'
|
||||
n_rows, n_cols = self.stdscr.getmaxyx()
|
||||
self.stdscr.addstr(n_rows-1, 0, prompt)
|
||||
self.stdscr.refresh()
|
||||
window = self.stdscr.derwin(n_rows-1, len(prompt))
|
||||
|
||||
out = text_input(window)
|
||||
if out is None:
|
||||
self.draw()
|
||||
else:
|
||||
self.refresh_content(subreddit=out)
|
||||
|
||||
def open_submission(self):
|
||||
"Select the current submission to view posts"
|
||||
|
||||
|
||||
48
rtv/utils.py
48
rtv/utils.py
@@ -1,7 +1,12 @@
|
||||
from datetime import datetime, timedelta
|
||||
from contextlib import contextmanager
|
||||
|
||||
import os
|
||||
import curses
|
||||
from curses import textpad
|
||||
|
||||
class EscapePressed(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def clean(unicode_string):
|
||||
"""
|
||||
@@ -46,10 +51,51 @@ def humanize_timestamp(utc_timestamp, verbose=False):
|
||||
years = months / 12
|
||||
return ('%d years ago' % years) if verbose else ('%dyr' % years)
|
||||
|
||||
|
||||
def validate(ch):
|
||||
"Filters characters for special key sequences"
|
||||
if ch == 27:
|
||||
raise EscapePressed
|
||||
return ch
|
||||
|
||||
def text_input(window):
|
||||
"""
|
||||
Transform a window into a text box that will accept user input and loop
|
||||
until an escape sequence is entered.
|
||||
|
||||
If enter is pressed, return the input text as a string.
|
||||
If escape is pressed, return None.
|
||||
"""
|
||||
|
||||
window.clear()
|
||||
curses.curs_set(2)
|
||||
textbox = textpad.Textbox(window, insert_mode=True)
|
||||
|
||||
# Wrapping in an exception block so that we can distinguish when the user
|
||||
# hits the return character from when the user tries to back out of the
|
||||
# input.
|
||||
try:
|
||||
out = textbox.edit(validate=validate)
|
||||
out = out.strip()
|
||||
except EscapePressed:
|
||||
out = None
|
||||
|
||||
curses.curs_set(0)
|
||||
return out
|
||||
|
||||
@contextmanager
|
||||
def curses_session():
|
||||
|
||||
try:
|
||||
# Curses must wait for some time after the Escape key is pressed to see
|
||||
# check if it is the beginning of an escape sequence indicating a
|
||||
# special key. The default wait time is 1 second, which means that
|
||||
# getch() will not return the escape key (ord(27)), until a full second
|
||||
# after it has been pressed. Turn this down to 25 ms, which is close to
|
||||
# what VIM uses.
|
||||
# http://stackoverflow.com/questions/27372068
|
||||
os.environ['ESCDELAY'] = '25'
|
||||
|
||||
# Initialize curses
|
||||
stdscr = curses.initscr()
|
||||
|
||||
|
||||
@@ -83,6 +83,7 @@ class BaseViewer(object):
|
||||
self.nav = Navigator(self.content.get, **kwargs)
|
||||
|
||||
self._subwindows = None
|
||||
self.add_loading()
|
||||
|
||||
def draw(self):
|
||||
raise NotImplementedError
|
||||
@@ -106,12 +107,6 @@ class BaseViewer(object):
|
||||
continue
|
||||
self.stdscr.nodelay(0)
|
||||
|
||||
def refresh_content(self):
|
||||
self.add_loading()
|
||||
self.content.reset()
|
||||
self.stdscr.clear()
|
||||
self.draw()
|
||||
|
||||
def add_loading(self):
|
||||
"Draw a `loading` popup dialog in the center of the screen"
|
||||
|
||||
@@ -132,7 +127,6 @@ class BaseViewer(object):
|
||||
|
||||
self._header_window.erase()
|
||||
self._header_window.addnstr(0, 0, self.content.display_name, n_cols-1)
|
||||
self._header_window.refresh()
|
||||
|
||||
def draw_content(self):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user