mirror of
https://github.com/ihabunek/toot
synced 2024-12-23 07:27:12 +01:00
Implement character count indicator when composing
Attempts to load max char count from the server on init. issue #121
This commit is contained in:
parent
5695fdb504
commit
60efc13338
@ -99,6 +99,9 @@ class TUI(urwid.Frame):
|
||||
self.footer = Footer()
|
||||
self.footer.set_status("Loading...")
|
||||
|
||||
# Default max status length, updated on startup
|
||||
self.max_toot_chars = 500
|
||||
|
||||
self.timeline = None
|
||||
self.overlay = None
|
||||
self.exception = None
|
||||
@ -106,8 +109,9 @@ class TUI(urwid.Frame):
|
||||
super().__init__(self.body, header=self.header, footer=self.footer)
|
||||
|
||||
def run(self):
|
||||
self.loop.set_alarm_in(0, lambda *args:
|
||||
self.async_load_timeline(is_initial=True, timeline_name="home"))
|
||||
self.loop.set_alarm_in(0, lambda *args: self.async_load_instance())
|
||||
self.loop.set_alarm_in(0, lambda *args: self.async_load_timeline(
|
||||
is_initial=True, timeline_name="home"))
|
||||
self.loop.run()
|
||||
self.executor.shutdown(wait=False)
|
||||
|
||||
@ -269,6 +273,21 @@ class TUI(urwid.Frame):
|
||||
return self.run_in_thread(_load_statuses,
|
||||
done_callback=_done_initial if is_initial else _done_next)
|
||||
|
||||
def async_load_instance(self):
|
||||
"""
|
||||
Attempt to update max_toot_chars from instance data.
|
||||
Does not work on vanilla Mastodon, works on Pleroma.
|
||||
See: https://github.com/tootsuite/mastodon/issues/4915
|
||||
"""
|
||||
def _load_instance():
|
||||
return api.get_instance(self.app.instance)
|
||||
|
||||
def _done(instance):
|
||||
if "max_toot_chars" in instance:
|
||||
self.max_toot_chars
|
||||
|
||||
return self.run_in_thread(_load_instance, done_callback=_done)
|
||||
|
||||
def refresh_footer(self, timeline):
|
||||
"""Show status details in footer."""
|
||||
status, index, count = timeline.get_focused_status_with_counts()
|
||||
@ -296,7 +315,7 @@ class TUI(urwid.Frame):
|
||||
def _post(timeline, *args):
|
||||
self.post_status(*args)
|
||||
|
||||
composer = StatusComposer(in_reply_to)
|
||||
composer = StatusComposer(self.max_toot_chars, in_reply_to)
|
||||
urwid.connect_signal(composer, "close", _close)
|
||||
urwid.connect_signal(composer, "post", _post)
|
||||
self.open_overlay(composer, title="Compose status")
|
||||
|
@ -3,6 +3,7 @@ import logging
|
||||
|
||||
from .constants import VISIBILITY_OPTIONS
|
||||
from .widgets import Button, EditBox
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -12,17 +13,16 @@ class StatusComposer(urwid.Frame):
|
||||
"""
|
||||
signals = ["close", "post"]
|
||||
|
||||
def __init__(self, in_reply_to=None):
|
||||
def __init__(self, max_chars, in_reply_to=None):
|
||||
self.in_reply_to = in_reply_to
|
||||
text, edit_pos = '', None
|
||||
if in_reply_to is not None:
|
||||
text = '@{} '.format(in_reply_to.account)
|
||||
edit_pos = len(text)
|
||||
mentions = ['@{}'.format(m["acct"]) for m in in_reply_to.mentions]
|
||||
if mentions:
|
||||
text += '\n\n{}'.format(' '.join(mentions))
|
||||
self.content_edit = EditBox(edit_text=text, edit_pos=edit_pos,
|
||||
multiline=True, allow_tab=True)
|
||||
self.max_chars = max_chars
|
||||
|
||||
text = self.get_initial_text(in_reply_to)
|
||||
self.content_edit = EditBox(
|
||||
edit_text=text, edit_pos=len(text), multiline=True, allow_tab=True)
|
||||
urwid.connect_signal(self.content_edit.edit, "change", self.text_changed)
|
||||
|
||||
self.char_count = urwid.Text(["0/{}".format(max_chars)])
|
||||
|
||||
self.cw_edit = None
|
||||
self.cw_add_button = Button("Add content warning",
|
||||
@ -42,6 +42,23 @@ class StatusComposer(urwid.Frame):
|
||||
self.listbox = urwid.ListBox(self.walker)
|
||||
return super().__init__(self.listbox)
|
||||
|
||||
def get_initial_text(self, in_reply_to):
|
||||
if not in_reply_to:
|
||||
return ""
|
||||
|
||||
text = '@{} '.format(in_reply_to.account)
|
||||
mentions = ['@{}'.format(m["acct"]) for m in in_reply_to.mentions]
|
||||
if mentions:
|
||||
text += '\n\n{}'.format(' '.join(mentions))
|
||||
|
||||
return text
|
||||
|
||||
def text_changed(self, edit, text):
|
||||
count = self.max_chars - len(text)
|
||||
text = "{}/{}".format(count, self.max_chars)
|
||||
color = "warning" if count < 0 else ""
|
||||
self.char_count.set_text((color, text))
|
||||
|
||||
def generate_list_items(self):
|
||||
if self.in_reply_to:
|
||||
yield urwid.Text(("gray", "Replying to {}".format(self.in_reply_to.account)))
|
||||
@ -49,6 +66,7 @@ class StatusComposer(urwid.Frame):
|
||||
|
||||
yield urwid.Text("Status message")
|
||||
yield self.content_edit
|
||||
yield self.char_count
|
||||
yield urwid.Divider()
|
||||
|
||||
if self.cw_edit:
|
||||
|
@ -34,6 +34,7 @@ PALETTE = [
|
||||
('green_selected', 'white,bold', 'dark green'),
|
||||
('yellow', 'yellow', ''),
|
||||
('yellow_bold', 'yellow,bold', ''),
|
||||
('warning', 'light red', ''),
|
||||
]
|
||||
|
||||
VISIBILITY_OPTIONS = [
|
||||
|
@ -32,8 +32,8 @@ class SelectableColumns(Clickable, urwid.Columns):
|
||||
class EditBox(urwid.AttrWrap):
|
||||
"""Styled edit box."""
|
||||
def __init__(self, *args, **kwargs):
|
||||
edit = urwid.Edit(*args, **kwargs)
|
||||
return super().__init__(edit, "editbox", "editbox_focused")
|
||||
self.edit = urwid.Edit(*args, **kwargs)
|
||||
return super().__init__(self.edit, "editbox", "editbox_focused")
|
||||
|
||||
|
||||
class Button(urwid.AttrWrap):
|
||||
|
Loading…
Reference in New Issue
Block a user