Alert (set urgency hint) on new messages

This commit is contained in:
miruka 2019-08-16 14:27:25 -04:00
parent da4bb55f43
commit 1061498160
3 changed files with 44 additions and 1 deletions

View File

@ -19,6 +19,7 @@ from . import __about__, utils
from .html_filter import HTML_FILTER from .html_filter import HTML_FILTER
from .models.items import Account, Event, Member, Room, TypeSpecifier from .models.items import Account, Event, Member, Room, TypeSpecifier
from .models.model_store import ModelStore from .models.model_store import ModelStore
from .pyotherside_events import AlertRequested
class UploadError(Enum): class UploadError(Enum):
@ -52,6 +53,7 @@ class MatrixClient(nio.AsyncClient):
self.sync_task: Optional[asyncio.Future] = None self.sync_task: Optional[asyncio.Future] = None
self.first_sync_happened: asyncio.Event = asyncio.Event() self.first_sync_happened: asyncio.Event = asyncio.Event()
self.first_sync_date: Optional[datetime] = None
self.send_locks: DefaultDict[str, asyncio.Lock] = \ self.send_locks: DefaultDict[str, asyncio.Lock] = \
DefaultDict(asyncio.Lock) # {room_id: lock} DefaultDict(asyncio.Lock) # {room_id: lock}
@ -299,6 +301,17 @@ class MatrixClient(nio.AsyncClient):
# Functions to register data into models # Functions to register data into models
async def event_is_past(self, ev: Union[nio.Event, Event]) -> bool:
if not self.first_sync_date:
return True
if isinstance(ev, Event):
return ev.date < self.first_sync_date
date = datetime.fromtimestamp(ev.server_timestamp / 1000)
return date < self.first_sync_date
async def set_room_last_event(self, room_id: str, item: Event) -> None: async def set_room_last_event(self, room_id: str, item: Event) -> None:
room = self.models[Room, self.user_id][room_id] room = self.models[Room, self.user_id][room_id]
@ -446,6 +459,9 @@ class MatrixClient(nio.AsyncClient):
with suppress(KeyError): with suppress(KeyError):
item.client_id = f"echo-{client.resolved_echoes[ev.event_id]}" item.client_id = f"echo-{client.resolved_echoes[ev.event_id]}"
elif not await self.event_is_past(ev):
AlertRequested()
self.models[Event, self.user_id, room.room_id][item.client_id] = item self.models[Event, self.user_id, room.room_id][item.client_id] = item
await self.set_room_last_event(room.room_id, item) await self.set_room_last_event(room.room_id, item)
@ -476,7 +492,8 @@ class MatrixClient(nio.AsyncClient):
if not self.first_sync_happened.is_set(): if not self.first_sync_happened.is_set():
asyncio.ensure_future(self.load_rooms_without_visible_events()) asyncio.ensure_future(self.load_rooms_without_visible_events())
self.first_sync_happened.set() self.first_sync_happened.set()
self.first_sync_date = datetime.now()
async def onErrorResponse(self, resp: nio.ErrorResponse) -> None: async def onErrorResponse(self, resp: nio.ErrorResponse) -> None:

View File

@ -8,6 +8,8 @@ from .models import SyncId
@dataclass @dataclass
class PyOtherSideEvent: class PyOtherSideEvent:
"""Event that will be sent to QML by PyOtherSide."""
def __post_init__(self) -> None: def __post_init__(self) -> None:
# CPython >= 3.6 or any Python >= 3.7 needed for correct dict order # CPython >= 3.6 or any Python >= 3.7 needed for correct dict order
args = [ args = [
@ -27,17 +29,36 @@ class PyOtherSideEvent:
@dataclass @dataclass
class ExitRequested(PyOtherSideEvent): class ExitRequested(PyOtherSideEvent):
"""Request for the application to exit."""
exit_code: int = 0 exit_code: int = 0
@dataclass
class AlertRequested(PyOtherSideEvent):
"""Request an alert to be shown for msec milliseconds.
If msec is 0 (default), the alert should be shown indefinitely until
the window is focused.
The Alert state for example sets the urgency hint on X11/Wayland,
or flashes the taskbar icon on Windows.
"""
msec: int = 0
@dataclass @dataclass
class CoroutineDone(PyOtherSideEvent): class CoroutineDone(PyOtherSideEvent):
"""Indicate that an asyncio coroutine finished."""
uuid: str = field() uuid: str = field()
result: Any = None result: Any = None
@dataclass @dataclass
class ModelUpdated(PyOtherSideEvent): class ModelUpdated(PyOtherSideEvent):
"""Indicate that a backend model's data changed."""
sync_id: SyncId = field() sync_id: SyncId = field()
data: List[Dict[str, Any]] = field() data: List[Dict[str, Any]] = field()

View File

@ -6,6 +6,11 @@ function onExitRequested(exitCode) {
} }
function onAlertRequested(msec) {
window.alert(msec)
}
function onCoroutineDone(uuid, result) { function onCoroutineDone(uuid, result) {
py.pendingCoroutines[uuid](result) py.pendingCoroutines[uuid](result)
delete pendingCoroutines[uuid] delete pendingCoroutines[uuid]