implementing the ability to edit messages rather than cancel them unexpectedly on certain keypresses #293

This is a bit hacky... left arrow does the same as delete, other control
character open up the editor for further message editing
This commit is contained in:
Maarten van Gompel 2022-12-13 00:16:03 +01:00
parent 2b0c0cf199
commit bef3838542
2 changed files with 34 additions and 4 deletions

View file

@ -318,7 +318,7 @@ class Controller:
self.present_info("Can't send msg in this chat") self.present_info("Can't send msg in this chat")
return return
self.tg.send_chat_action(chat_id, ChatAction.chatActionTyping) self.tg.send_chat_action(chat_id, ChatAction.chatActionTyping)
if msg := self.view.status.get_input(): if msg := self.view.status.get_input(view=self.view):
self.model.send_message(text=msg) self.model.send_message(text=msg)
self.present_info("Message sent") self.present_info("Message sent")
else: else:

View file

@ -2,6 +2,8 @@ import curses
import logging import logging
from datetime import datetime from datetime import datetime
from typing import Any, Dict, List, Optional, Tuple, Union, cast from typing import Any, Dict, List, Optional, Tuple, Union, cast
from tempfile import NamedTemporaryFile
import shlex
from _curses import window # type: ignore from _curses import window # type: ignore
@ -10,7 +12,7 @@ from tg.colors import bold, cyan, get_color, magenta, reverse, white, yellow
from tg.models import Model, UserModel from tg.models import Model, UserModel
from tg.msg import MsgProxy from tg.msg import MsgProxy
from tg.tdlib import ChatType, get_chat_type, is_group from tg.tdlib import ChatType, get_chat_type, is_group
from tg.utils import get_color_by_str, num, string_len_dwc, truncate_to_len from tg.utils import get_color_by_str, num, string_len_dwc, truncate_to_len, suspend
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -124,7 +126,7 @@ class StatusView:
self.win.addstr(0, 0, msg.replace("\n", " ")[: self.w]) self.win.addstr(0, 0, msg.replace("\n", " ")[: self.w])
self._refresh() self._refresh()
def get_input(self, prefix: str = "") -> Optional[str]: def get_input(self, prefix: str = "", view: Optional[View] = None) -> Optional[str]:
curses.curs_set(1) curses.curs_set(1)
buff = "" buff = ""
@ -140,10 +142,38 @@ class StatusView:
key = ord(key) key = ord(key)
if key == 10: # return if key == 10: # return
break break
elif key == 127 or key == 8: # del elif key in (127, 8): # del
if buff: if buff:
buff = buff[:-1] buff = buff[:-1]
elif key in (7, 27): # (^G, <esc>) cancel elif key in (7, 27): # (^G, <esc>) cancel
self.win.nodelay(True)
extra = []
while True:
c = self.win.getch()
if c == -1:
break
else:
extra.append(c)
self.win.nodelay(False)
curses.flushinp()
if len(extra) >= 2 and extra[0] == 91:
if extra[1] == 68: #left arrow, treat as delete
if buff:
buff = buff[:-1]
continue
elif view: #another control key, open editor
with NamedTemporaryFile("w+", suffix=".txt") as f, suspend(
view
) as s:
f.write(buff)
f.seek(0)
proc = s.call(config.LONG_MSG_CMD.format(file_path=shlex.quote(f.name)))
if proc.returncode == 0:
with open(f.name) as f:
buff = f.read().strip()
continue
else:
continue #ignore
return None return None
elif chr(key).isprintable(): elif chr(key).isprintable():
buff += chr(key) buff += chr(key)