Added text input for subreddit prompt, added escape key support.

This commit is contained in:
Michael Lazar
2015-01-29 19:53:14 -08:00
parent bc40cf4fc7
commit a6ab60514c
5 changed files with 84 additions and 14 deletions

View File

@@ -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):

View File

@@ -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()

View File

@@ -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"

View File

@@ -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()

View File

@@ -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):
"""