Room context menu: notification setting checkmark
Indicate which notification override setting is currently active
This commit is contained in:
parent
af321d8eae
commit
0017a1562c
|
@ -41,8 +41,8 @@ from .errors import (
|
||||||
from .html_markdown import HTML_PROCESSOR as HTML
|
from .html_markdown import HTML_PROCESSOR as HTML
|
||||||
from .media_cache import Media, Thumbnail
|
from .media_cache import Media, Thumbnail
|
||||||
from .models.items import (
|
from .models.items import (
|
||||||
ZERO_DATE, Account, Event, Member, PushRule, Room, Transfer,
|
ZERO_DATE, Account, Event, Member, PushRule, Room,
|
||||||
TransferStatus, TypeSpecifier,
|
RoomNotificationOverride, Transfer, TransferStatus, TypeSpecifier,
|
||||||
)
|
)
|
||||||
from .models.model_store import ModelStore
|
from .models.model_store import ModelStore
|
||||||
from .nio_callbacks import NioCallbacks
|
from .nio_callbacks import NioCallbacks
|
||||||
|
@ -1919,13 +1919,25 @@ class MatrixClient(nio.AsyncClient):
|
||||||
await self.delete_pushrule("global", kind, rule_id)
|
await self.delete_pushrule("global", kind, rule_id)
|
||||||
|
|
||||||
|
|
||||||
|
def _rule_overrides_room(self, rule: PushRule) -> Optional[str]:
|
||||||
|
override = rule.kind is nio.PushRuleKind.override
|
||||||
|
one_cnd = len(rule.conditions) == 1
|
||||||
|
|
||||||
|
if not one_cnd:
|
||||||
|
return None
|
||||||
|
|
||||||
|
cnd = nio.PushCondition.from_dict(rule.conditions[0])
|
||||||
|
ev_match = isinstance(cnd, nio.PushEventMatch)
|
||||||
|
|
||||||
|
if override and ev_match and cnd.key == "room_id":
|
||||||
|
return cnd.pattern
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
async def _remove_room_override_rule(self, room_id: str) -> None:
|
async def _remove_room_override_rule(self, room_id: str) -> None:
|
||||||
for rule in self.models[self.user_id, "pushrules"].values():
|
for rule in self.models[self.user_id, "pushrules"].values():
|
||||||
override_kind = rule.kind is nio.PushRuleKind.override
|
if self._rule_overrides_room(rule) == room_id:
|
||||||
this_room_cnd = nio.PushEventMatch("room_id", room_id).as_value
|
|
||||||
|
|
||||||
if (override_kind and rule.conditions == [this_room_cnd]):
|
|
||||||
print(rule)
|
|
||||||
await self.remove_pushrule(rule.kind, rule.rule_id)
|
await self.remove_pushrule(rule.kind, rule.rule_id)
|
||||||
|
|
||||||
|
|
||||||
|
@ -2015,7 +2027,6 @@ class MatrixClient(nio.AsyncClient):
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Register/update a `nio.MatrixRoom` as a `models.items.Room`."""
|
"""Register/update a `nio.MatrixRoom` as a `models.items.Room`."""
|
||||||
|
|
||||||
# Add room
|
|
||||||
inviter = getattr(room, "inviter", "") or ""
|
inviter = getattr(room, "inviter", "") or ""
|
||||||
levels = room.power_levels
|
levels = room.power_levels
|
||||||
can_send_state = partial(levels.can_user_send_state, self.user_id)
|
can_send_state = partial(levels.can_user_send_state, self.user_id)
|
||||||
|
@ -2044,7 +2055,28 @@ class MatrixClient(nio.AsyncClient):
|
||||||
)
|
)
|
||||||
unverified_devices = registered.unverified_devices
|
unverified_devices = registered.unverified_devices
|
||||||
|
|
||||||
|
notification_setting = RoomNotificationOverride.UseDefaultSettings
|
||||||
|
|
||||||
|
for rule in self.models[self.user_id, "pushrules"].values():
|
||||||
|
overrides = self._rule_overrides_room(rule) == room.room_id
|
||||||
|
is_room_kind = rule.kind is nio.PushRuleKind.room
|
||||||
|
room_kind_match = is_room_kind and rule.rule_id == room.room_id
|
||||||
|
|
||||||
|
if overrides and not rule.actions:
|
||||||
|
notification_setting = RoomNotificationOverride.IgnoreEvents
|
||||||
|
break
|
||||||
|
elif overrides:
|
||||||
|
notification_setting = RoomNotificationOverride.AllEvents
|
||||||
|
break
|
||||||
|
elif room_kind_match and not rule.actions:
|
||||||
|
notification_setting = RoomNotificationOverride.HighlightsOnly
|
||||||
|
break
|
||||||
|
elif room_kind_match:
|
||||||
|
notification_setting = RoomNotificationOverride.AllEvents
|
||||||
|
break
|
||||||
|
|
||||||
pinned = self.backend.settings.RoomList.Pinned
|
pinned = self.backend.settings.RoomList.Pinned
|
||||||
|
|
||||||
room_item = Room(
|
room_item = Room(
|
||||||
id = room.room_id,
|
id = room.room_id,
|
||||||
for_account = self.user_id,
|
for_account = self.user_id,
|
||||||
|
@ -2088,6 +2120,7 @@ class MatrixClient(nio.AsyncClient):
|
||||||
unreads = room.unread_notifications,
|
unreads = room.unread_notifications,
|
||||||
highlights = room.unread_highlights,
|
highlights = room.unread_highlights,
|
||||||
local_unreads = local_unreads,
|
local_unreads = local_unreads,
|
||||||
|
notification_setting = notification_setting,
|
||||||
|
|
||||||
lexical_sorting = self.backend.settings.RoomList.lexical_sort,
|
lexical_sorting = self.backend.settings.RoomList.lexical_sort,
|
||||||
pinned = room.room_id in pinned.get(self.user_id, []),
|
pinned = room.room_id in pinned.get(self.user_id, []),
|
||||||
|
|
|
@ -38,6 +38,16 @@ class PingStatus(AutoStrEnum):
|
||||||
Failed = auto()
|
Failed = auto()
|
||||||
|
|
||||||
|
|
||||||
|
class RoomNotificationOverride(AutoStrEnum):
|
||||||
|
"""Possible per-room notification override settings, as displayed in the
|
||||||
|
left sidepane's context menu when right-clicking a room.
|
||||||
|
"""
|
||||||
|
UseDefaultSettings = auto()
|
||||||
|
AllEvents = auto()
|
||||||
|
HighlightsOnly = auto()
|
||||||
|
IgnoreEvents = auto()
|
||||||
|
|
||||||
|
|
||||||
@dataclass(eq=False)
|
@dataclass(eq=False)
|
||||||
class Homeserver(ModelItem):
|
class Homeserver(ModelItem):
|
||||||
"""A homeserver we can connect to. The `id` field is the server's URL."""
|
"""A homeserver we can connect to. The `id` field is the server's URL."""
|
||||||
|
@ -170,6 +180,9 @@ class Room(ModelItem):
|
||||||
highlights: int = 0
|
highlights: int = 0
|
||||||
local_unreads: bool = False
|
local_unreads: bool = False
|
||||||
|
|
||||||
|
notification_setting: RoomNotificationOverride = \
|
||||||
|
RoomNotificationOverride.UseDefaultSettings
|
||||||
|
|
||||||
lexical_sorting: bool = False
|
lexical_sorting: bool = False
|
||||||
pinned: bool = False
|
pinned: bool = False
|
||||||
|
|
||||||
|
@ -229,6 +242,12 @@ class Room(ModelItem):
|
||||||
|
|
||||||
@dataclass(eq=False)
|
@dataclass(eq=False)
|
||||||
class AccountOrRoom(Account, Room):
|
class AccountOrRoom(Account, Room):
|
||||||
|
"""The left sidepane in the GUI lists a mixture of accounts and rooms
|
||||||
|
giving a tree view illusion. Since all items in a QML ListView must have
|
||||||
|
the same available properties, this class inherits both
|
||||||
|
`Account` and `Room` to fulfill that purpose.
|
||||||
|
"""
|
||||||
|
|
||||||
type: Union[Type[Account], Type[Room]] = Account
|
type: Union[Type[Account], Type[Room]] = Account
|
||||||
account_order: int = -1
|
account_order: int = -1
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
import json
|
import json
|
||||||
import logging as log
|
import logging as log
|
||||||
from dataclasses import asdict, dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from html import escape
|
from html import escape
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
@ -783,6 +783,18 @@ class NioCallbacks:
|
||||||
# Account data callbacks
|
# Account data callbacks
|
||||||
|
|
||||||
async def onPushRulesEvent(self, ev: nio.PushRulesEvent) -> None:
|
async def onPushRulesEvent(self, ev: nio.PushRulesEvent) -> None:
|
||||||
|
async def update_affected_room(rule: PushRule) -> None:
|
||||||
|
affects_room: Optional[str]
|
||||||
|
|
||||||
|
if rule.kind == nio.PushRuleKind.room:
|
||||||
|
affects_room = rule.rule_id
|
||||||
|
else:
|
||||||
|
affects_room = self.client._rule_overrides_room(rule)
|
||||||
|
|
||||||
|
if affects_room in self.client.rooms:
|
||||||
|
nio_room = self.client.rooms[affects_room]
|
||||||
|
await self.client.register_nio_room(nio_room)
|
||||||
|
|
||||||
model = self.models[self.user_id, "pushrules"]
|
model = self.models[self.user_id, "pushrules"]
|
||||||
|
|
||||||
kinds: Dict[nio.PushRuleKind, List[nio.PushRule]] = {
|
kinds: Dict[nio.PushRuleKind, List[nio.PushRule]] = {
|
||||||
|
@ -800,9 +812,10 @@ class NioCallbacks:
|
||||||
new_keys.add((kind.value, rule.id))
|
new_keys.add((kind.value, rule.id))
|
||||||
|
|
||||||
with model.batch_remove():
|
with model.batch_remove():
|
||||||
for key in tuple(model):
|
for key, rule in list(model.items()):
|
||||||
if key not in new_keys:
|
if key not in new_keys:
|
||||||
del model[key]
|
del model[key]
|
||||||
|
await update_affected_room(rule)
|
||||||
|
|
||||||
# Then, add new rules/modify changed existing ones
|
# Then, add new rules/modify changed existing ones
|
||||||
|
|
||||||
|
@ -825,7 +838,7 @@ class NioCallbacks:
|
||||||
sound = str(tweaks.get("sound") or "")
|
sound = str(tweaks.get("sound") or "")
|
||||||
hint = tweaks.get("urgency_hint", bool(sound)) is not False
|
hint = tweaks.get("urgency_hint", bool(sound)) is not False
|
||||||
|
|
||||||
model[kind.value, rule.id] = PushRule(
|
rule_item = PushRule(
|
||||||
id = (kind.value, rule.id),
|
id = (kind.value, rule.id),
|
||||||
kind = kind,
|
kind = kind,
|
||||||
rule_id = rule.id,
|
rule_id = rule.id,
|
||||||
|
@ -841,6 +854,8 @@ class NioCallbacks:
|
||||||
sound = sound,
|
sound = sound,
|
||||||
urgency_hint = hint,
|
urgency_hint = hint,
|
||||||
)
|
)
|
||||||
|
model[kind.value, rule.id] = rule_item
|
||||||
|
await update_affected_room(rule_item)
|
||||||
|
|
||||||
self.client.push_rules = ev
|
self.client.push_rules = ev
|
||||||
|
|
||||||
|
|
|
@ -152,6 +152,7 @@ HTile {
|
||||||
|
|
||||||
HMenuItem {
|
HMenuItem {
|
||||||
text: qsTr("Use default account settings")
|
text: qsTr("Use default account settings")
|
||||||
|
checked: model.notification_setting === "UseDefaultSettings"
|
||||||
onTriggered: py.callClientCoro(
|
onTriggered: py.callClientCoro(
|
||||||
model.for_account, "room_pushrule_use_default", [model.id],
|
model.for_account, "room_pushrule_use_default", [model.id],
|
||||||
)
|
)
|
||||||
|
@ -159,6 +160,7 @@ HTile {
|
||||||
|
|
||||||
HMenuItem {
|
HMenuItem {
|
||||||
text: qsTr("All new messages")
|
text: qsTr("All new messages")
|
||||||
|
checked: model.notification_setting === "AllEvents"
|
||||||
onTriggered: py.callClientCoro(
|
onTriggered: py.callClientCoro(
|
||||||
model.for_account, "room_pushrule_all_events", [model.id],
|
model.for_account, "room_pushrule_all_events", [model.id],
|
||||||
)
|
)
|
||||||
|
@ -166,6 +168,7 @@ HTile {
|
||||||
|
|
||||||
HMenuItem {
|
HMenuItem {
|
||||||
text: qsTr("Highlights only (replies, keywords...)")
|
text: qsTr("Highlights only (replies, keywords...)")
|
||||||
|
checked: model.notification_setting === "HighlightsOnly"
|
||||||
onTriggered: py.callClientCoro(
|
onTriggered: py.callClientCoro(
|
||||||
model.for_account,
|
model.for_account,
|
||||||
"room_pushrule_highlights_only",
|
"room_pushrule_highlights_only",
|
||||||
|
@ -175,6 +178,7 @@ HTile {
|
||||||
|
|
||||||
HMenuItem {
|
HMenuItem {
|
||||||
text: qsTr("Ignore new messages")
|
text: qsTr("Ignore new messages")
|
||||||
|
checked: model.notification_setting === "IgnoreEvents"
|
||||||
onTriggered: py.callClientCoro(
|
onTriggered: py.callClientCoro(
|
||||||
model.for_account, "room_pushrule_ignore_all", [model.id],
|
model.for_account, "room_pushrule_ignore_all", [model.id],
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user