Visual unread mentions counter
This commit is contained in:
parent
367fff8f4a
commit
ef2504ecae
|
@ -7,6 +7,7 @@ from typing import DefaultDict, Dict
|
||||||
from urllib.parse import unquote
|
from urllib.parse import unquote
|
||||||
|
|
||||||
import html_sanitizer.sanitizer as sanitizer
|
import html_sanitizer.sanitizer as sanitizer
|
||||||
|
import lxml.html # nosec
|
||||||
import mistune
|
import mistune
|
||||||
from html_sanitizer.sanitizer import Sanitizer
|
from html_sanitizer.sanitizer import Sanitizer
|
||||||
from lxml.html import HtmlElement, etree # nosec
|
from lxml.html import HtmlElement, etree # nosec
|
||||||
|
@ -173,6 +174,19 @@ class HTMLProcessor:
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def user_id_link_in_html(self, html: str, user_id: str) -> bool:
|
||||||
|
if not html.strip():
|
||||||
|
return False
|
||||||
|
|
||||||
|
regex = re.compile(rf"https?://matrix.to/#/{user_id}", re.IGNORECASE)
|
||||||
|
|
||||||
|
for _, _, href, _ in lxml.html.iterlinks(html):
|
||||||
|
if regex.match(unquote(href.strip())):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def from_markdown(
|
def from_markdown(
|
||||||
self,
|
self,
|
||||||
text: str,
|
text: str,
|
||||||
|
|
|
@ -1073,9 +1073,11 @@ class MatrixClient(nio.AsyncClient):
|
||||||
registered = self.models[self.user_id, "rooms"][room.room_id]
|
registered = self.models[self.user_id, "rooms"][room.room_id]
|
||||||
last_event_date = registered.last_event_date
|
last_event_date = registered.last_event_date
|
||||||
typing_members = registered.typing_members
|
typing_members = registered.typing_members
|
||||||
|
mentions = registered.mentions
|
||||||
except KeyError:
|
except KeyError:
|
||||||
last_event_date = datetime.fromtimestamp(0)
|
last_event_date = datetime.fromtimestamp(0)
|
||||||
typing_members = []
|
typing_members = []
|
||||||
|
mentions = 0
|
||||||
|
|
||||||
self.models[self.user_id, "rooms"][room.room_id] = Room(
|
self.models[self.user_id, "rooms"][room.room_id] = Room(
|
||||||
id = room.room_id,
|
id = room.room_id,
|
||||||
|
@ -1108,6 +1110,7 @@ class MatrixClient(nio.AsyncClient):
|
||||||
can_set_guest_access = can_send_state("m.room.guest_access"),
|
can_set_guest_access = can_send_state("m.room.guest_access"),
|
||||||
|
|
||||||
last_event_date = last_event_date,
|
last_event_date = last_event_date,
|
||||||
|
mentions = mentions,
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,8 @@ class Room(ModelItem):
|
||||||
|
|
||||||
last_event_date: datetime = ZeroDate
|
last_event_date: datetime = ZeroDate
|
||||||
|
|
||||||
|
mentions: int = 0
|
||||||
|
|
||||||
def __lt__(self, other: "Room") -> bool:
|
def __lt__(self, other: "Room") -> bool:
|
||||||
"""Sort by join state, then descending last event date, then name.
|
"""Sort by join state, then descending last event date, then name.
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,11 @@ class NioCallbacks:
|
||||||
|
|
||||||
room_id = room.room_id,
|
room_id = room.room_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if HTML_PROCESSOR.user_id_link_in_html(co, self.client.user_id):
|
||||||
|
rooms = self.client.models[self.client.user_id, "rooms"]
|
||||||
|
rooms[room.room_id].mentions += 1
|
||||||
|
|
||||||
await self.client.register_nio_event(room, ev, content=co)
|
await self.client.register_nio_event(room, ev, content=co)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import QtQuick.Layouts 1.12
|
||||||
HButton {
|
HButton {
|
||||||
id: tile
|
id: tile
|
||||||
|
|
||||||
|
|
||||||
signal leftClicked()
|
signal leftClicked()
|
||||||
signal rightClicked()
|
signal rightClicked()
|
||||||
|
|
||||||
|
@ -24,6 +25,7 @@ HButton {
|
||||||
|
|
||||||
property Component image
|
property Component image
|
||||||
|
|
||||||
|
|
||||||
contentItem: HRowLayout {
|
contentItem: HRowLayout {
|
||||||
id: contentItem
|
id: contentItem
|
||||||
spacing: tile.spacing
|
spacing: tile.spacing
|
||||||
|
@ -50,34 +52,37 @@ HButton {
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HLabel {
|
||||||
|
id: rightInfo
|
||||||
|
font.pixelSize: theme.fontSize.small
|
||||||
|
verticalAlignment: Qt.AlignVCenter
|
||||||
|
color: theme.colors.halfDimText
|
||||||
|
visible: Layout.maximumWidth > 0
|
||||||
|
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.maximumWidth:
|
||||||
|
text && tile.width >= 200 * theme.uiScale ?
|
||||||
|
implicitWidth : 0
|
||||||
|
|
||||||
|
Behavior on Layout.maximumWidth { HNumberAnimation {} }
|
||||||
|
}
|
||||||
|
|
||||||
HRowLayout {
|
HRowLayout {
|
||||||
id: additionalInfo
|
id: additionalInfo
|
||||||
visible: visibleChildren.length > 0
|
visible: visibleChildren.length > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
HLabel {
|
|
||||||
id: rightInfo
|
|
||||||
font.pixelSize: theme.fontSize.small
|
|
||||||
color: theme.colors.halfDimText
|
|
||||||
|
|
||||||
visible: Layout.maximumWidth > 0
|
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.maximumWidth:
|
|
||||||
text && tile.width >= 160 * theme.uiScale ?
|
|
||||||
implicitWidth : 0
|
|
||||||
|
|
||||||
Behavior on Layout.maximumWidth { HNumberAnimation {} }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HRichLabel {
|
HRichLabel {
|
||||||
id: subtitle
|
id: subtitle
|
||||||
textFormat: Text.StyledText
|
textFormat: Text.StyledText
|
||||||
font.pixelSize: theme.fontSize.small
|
font.pixelSize: theme.fontSize.small
|
||||||
|
verticalAlignment: Qt.AlignVCenter
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
color: theme.colors.dimText
|
color: theme.colors.dimText
|
||||||
|
|
||||||
visible: Layout.maximumHeight > 0
|
visible: Layout.maximumHeight > 0
|
||||||
|
|
||||||
Layout.maximumHeight: ! compact && text ? implicitHeight : 0
|
Layout.maximumHeight: ! compact && text ? implicitHeight : 0
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
|
|
@ -33,14 +33,36 @@ HTileDelegate {
|
||||||
title.color: theme.mainPane.listView.room.name
|
title.color: theme.mainPane.listView.room.name
|
||||||
title.text: model.display_name || qsTr("Empty room")
|
title.text: model.display_name || qsTr("Empty room")
|
||||||
|
|
||||||
additionalInfo.children: HIcon {
|
additionalInfo.children: [
|
||||||
|
HLabel {
|
||||||
|
text: model.mentions
|
||||||
|
font.pixelSize: theme.fontSize.small
|
||||||
|
verticalAlignment: Qt.AlignVCenter
|
||||||
|
leftPadding: theme.spacing / 4
|
||||||
|
rightPadding: leftPadding
|
||||||
|
|
||||||
|
scale: model.mentions === 0 ? 0 : 1
|
||||||
|
visible: scale > 0
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: theme.colors.alertBackground
|
||||||
|
radius: theme.radius / 4
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on scale { HNumberAnimation {} }
|
||||||
|
},
|
||||||
|
|
||||||
|
HIcon {
|
||||||
svgName: "invite-received"
|
svgName: "invite-received"
|
||||||
colorize: theme.colors.alertBackground
|
colorize: theme.colors.alertBackground
|
||||||
|
small: room.compact
|
||||||
|
visible: invited
|
||||||
|
|
||||||
Layout.maximumWidth: invited ? implicitWidth : 0
|
Layout.maximumWidth: invited ? implicitWidth : 0
|
||||||
|
|
||||||
Behavior on Layout.maximumWidth { HNumberAnimation {} }
|
Behavior on Layout.maximumWidth { HNumberAnimation {} }
|
||||||
}
|
}
|
||||||
|
]
|
||||||
|
|
||||||
subtitle.color: theme.mainPane.listView.room.subtitle
|
subtitle.color: theme.mainPane.listView.room.subtitle
|
||||||
subtitle.textFormat: Text.StyledText
|
subtitle.textFormat: Text.StyledText
|
||||||
|
|
Loading…
Reference in New Issue
Block a user