Sideband/sbapp/ui/messages.py

243 lines
10 KiB
Python
Raw Normal View History

2022-04-07 13:03:53 -06:00
import time
import RNS
import LXMF
from kivy.metrics import dp,sp
2022-04-07 13:03:53 -06:00
from kivy.core.clipboard import Clipboard
from kivymd.uix.card import MDCard
from kivymd.uix.menu import MDDropdownMenu
2022-10-08 10:01:33 -06:00
# from kivymd.uix.behaviors import RoundedRectangularElevationBehavior, FakeRectangularElevationBehavior
from kivymd.uix.behaviors import CommonElevationBehavior
2022-04-07 13:03:53 -06:00
from kivy.properties import StringProperty, BooleanProperty
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.clock import Clock
2022-04-07 13:03:53 -06:00
from kivymd.uix.button import MDRectangleFlatButton
2022-04-07 13:03:53 -06:00
from kivymd.uix.dialog import MDDialog
2022-07-07 14:16:10 -06:00
if RNS.vendor.platformutils.get_platform() == "android":
from ui.helpers import ts_format, mdc
2022-10-02 06:51:01 -06:00
from ui.helpers import color_received, color_delivered, color_propagated, color_failed, color_unknown, intensity_msgs_dark, intensity_msgs_light
2022-07-07 14:16:10 -06:00
else:
from .helpers import ts_format, mdc
2022-10-02 06:51:01 -06:00
from .helpers import color_received, color_delivered, color_propagated, color_failed, color_unknown, intensity_msgs_dark, intensity_msgs_light
2022-04-07 13:03:53 -06:00
2022-10-08 10:01:33 -06:00
class ListLXMessageCard(MDCard):
# class ListLXMessageCard(MDCard, FakeRectangularElevationBehavior):
2022-04-07 13:03:53 -06:00
text = StringProperty()
heading = StringProperty()
class Messages():
def __init__(self, app, context_dest):
self.app = app
self.context_dest = context_dest
self.messages = []
self.added_item_hashes = []
self.latest_message_timestamp = None
self.list = None
self.widgets = []
self.send_error_dialog = None
self.update()
def reload(self):
if self.list != None:
self.list.clear_widgets()
self.messages = []
self.added_item_hashes = []
self.latest_message_timestamp = None
self.widgets = []
self.update()
def update(self):
self.messages = self.app.sideband.list_messages(self.context_dest, self.latest_message_timestamp)
if self.list == None:
2022-10-02 09:17:55 -06:00
layout = GridLayout(cols=1, spacing=dp(16), padding=dp(16), size_hint_y=None)
2022-04-07 13:03:53 -06:00
layout.bind(minimum_height=layout.setter('height'))
self.list = layout
if len(self.messages) > 0:
self.update_widget()
2022-10-02 06:51:01 -06:00
if self.app.sideband.config["dark_ui"]:
intensity_msgs = intensity_msgs_dark
else:
intensity_msgs = intensity_msgs_light
2022-04-07 13:03:53 -06:00
for w in self.widgets:
m = w.m
2022-10-08 10:01:33 -06:00
if self.app.sideband.config["dark_ui"]:
w.line_color = (1.0, 1.0, 1.0, 0.25)
else:
w.line_color = (1.0, 1.0, 1.0, 0.5)
2022-04-07 13:03:53 -06:00
if m["state"] == LXMF.LXMessage.SENDING or m["state"] == LXMF.LXMessage.OUTBOUND:
msg = self.app.sideband.message(m["hash"])
if msg["state"] == LXMF.LXMessage.DELIVERED:
w.md_bg_color = msg_color = mdc(color_delivered, intensity_msgs)
txstr = time.strftime(ts_format, time.localtime(msg["sent"]))
titlestr = ""
if msg["title"]:
titlestr = "[b]Title[/b] "+msg["title"].decode("utf-8")+"\n"
w.heading = titlestr+"[b]Sent[/b] "+txstr+" [b]State[/b] Delivered"
m["state"] = msg["state"]
if msg["method"] == LXMF.LXMessage.PROPAGATED and msg["state"] == LXMF.LXMessage.SENT:
w.md_bg_color = msg_color = mdc(color_propagated, intensity_msgs)
txstr = time.strftime(ts_format, time.localtime(msg["sent"]))
titlestr = ""
if msg["title"]:
titlestr = "[b]Title[/b] "+msg["title"].decode("utf-8")+"\n"
w.heading = titlestr+"[b]Sent[/b] "+txstr+" [b]State[/b] On Propagation Net"
m["state"] = msg["state"]
if msg["state"] == LXMF.LXMessage.FAILED:
w.md_bg_color = msg_color = mdc(color_failed, intensity_msgs)
txstr = time.strftime(ts_format, time.localtime(msg["sent"]))
titlestr = ""
if msg["title"]:
titlestr = "[b]Title[/b] "+msg["title"].decode("utf-8")+"\n"
w.heading = titlestr+"[b]Sent[/b] "+txstr+" [b]State[/b] Failed"
m["state"] = msg["state"]
def update_widget(self):
2022-10-02 06:51:01 -06:00
if self.app.sideband.config["dark_ui"]:
intensity_msgs = intensity_msgs_dark
2022-10-02 17:36:21 -06:00
mt_color = [1.0, 1.0, 1.0, 0.8]
2022-10-02 06:51:01 -06:00
else:
intensity_msgs = intensity_msgs_light
2022-10-02 17:36:21 -06:00
mt_color = [1.0, 1.0, 1.0, 0.95]
2022-10-02 06:51:01 -06:00
2022-04-07 13:03:53 -06:00
for m in self.messages:
if not m["hash"] in self.added_item_hashes:
txstr = time.strftime(ts_format, time.localtime(m["sent"]))
rxstr = time.strftime(ts_format, time.localtime(m["received"]))
titlestr = ""
if m["title"]:
titlestr = "[b]Title[/b] "+m["title"].decode("utf-8")+"\n"
if m["source"] == self.app.sideband.lxmf_destination.hash:
if m["state"] == LXMF.LXMessage.DELIVERED:
msg_color = mdc(color_delivered, intensity_msgs)
heading_str = titlestr+"[b]Sent[/b] "+txstr+" [b]State[/b] Delivered"
elif m["method"] == LXMF.LXMessage.PROPAGATED and m["state"] == LXMF.LXMessage.SENT:
msg_color = mdc(color_propagated, intensity_msgs)
heading_str = titlestr+"[b]Sent[/b] "+txstr+" [b]State[/b] On Propagation Net"
elif m["state"] == LXMF.LXMessage.FAILED:
msg_color = mdc(color_failed, intensity_msgs)
heading_str = titlestr+"[b]Sent[/b] "+txstr+" [b]State[/b] Failed"
elif m["state"] == LXMF.LXMessage.OUTBOUND or m["state"] == LXMF.LXMessage.SENDING:
msg_color = mdc(color_unknown, intensity_msgs)
heading_str = titlestr+"[b]Sent[/b] "+txstr+" [b]State[/b] Sending "
else:
msg_color = mdc(color_unknown, intensity_msgs)
heading_str = titlestr+"[b]Sent[/b] "+txstr+" [b]State[/b] Unknown"
else:
2022-10-02 14:28:09 -06:00
msg_color = mdc(color_received, intensity_msgs)
2022-04-07 13:03:53 -06:00
heading_str = titlestr+"[b]Sent[/b] "+txstr+"\n[b]Received[/b] "+rxstr
item = ListLXMessageCard(
text=m["content"].decode("utf-8"),
heading=heading_str,
md_bg_color=msg_color,
)
item.sb_uid = m["hash"]
item.m = m
2022-10-02 17:36:21 -06:00
item.ids.heading_text.theme_text_color = "Custom"
item.ids.heading_text.text_color = mt_color
item.ids.content_text.theme_text_color = "Custom"
item.ids.content_text.text_color = mt_color
item.ids.msg_submenu.theme_text_color = "Custom"
item.ids.msg_submenu.text_color = mt_color
2022-04-07 13:03:53 -06:00
def gen_del(mhash, item):
def x():
yes_button = MDRectangleFlatButton(text="Yes",font_size=sp(18), theme_text_color="Custom", line_color=self.app.color_reject, text_color=self.app.color_reject)
no_button = MDRectangleFlatButton(text="No",font_size=sp(18))
2022-04-07 13:03:53 -06:00
dialog = MDDialog(
title="Delete message?",
2022-04-07 13:03:53 -06:00
buttons=[ yes_button, no_button ],
2022-10-02 16:56:39 -06:00
# elevation=0,
2022-04-07 13:03:53 -06:00
)
def dl_yes(s):
dialog.dismiss()
self.app.sideband.delete_message(mhash)
def cb(dt):
self.reload()
Clock.schedule_once(cb, 0.2)
2022-04-07 13:03:53 -06:00
def dl_no(s):
dialog.dismiss()
yes_button.bind(on_release=dl_yes)
no_button.bind(on_release=dl_no)
item.dmenu.dismiss()
dialog.open()
return x
def gen_copy(msg, item):
def x():
Clipboard.copy(msg)
RNS.log(str(item))
item.dmenu.dismiss()
return x
dm_items = [
{
"viewclass": "OneLineListItem",
"text": "Copy",
"height": dp(40),
2022-04-07 13:03:53 -06:00
"on_release": gen_copy(m["content"].decode("utf-8"), item)
},
{
"text": "Delete",
"viewclass": "OneLineListItem",
"height": dp(40),
2022-04-07 13:03:53 -06:00
"on_release": gen_del(m["hash"], item)
}
]
item.dmenu = MDDropdownMenu(
caller=item.ids.msg_submenu,
items=dm_items,
position="center",
width_mult=4,
2022-10-02 14:00:15 -06:00
elevation=1,
radius=dp(3),
opening_transition="linear",
opening_time=0.0,
2022-04-07 13:03:53 -06:00
)
def callback_factory(ref):
def x(sender):
ref.dmenu.open()
return x
# Bind menu open
item.ids.msg_submenu.bind(on_release=callback_factory(item))
self.added_item_hashes.append(m["hash"])
self.widgets.append(item)
self.list.add_widget(item)
if self.latest_message_timestamp == None or m["received"] > self.latest_message_timestamp:
self.latest_message_timestamp = m["received"]
def get_widget(self):
return self.list
def close_send_error_dialog(self, sender=None):
if self.send_error_dialog:
self.send_error_dialog.dismiss()