moment/src/backend/models/special_models.py

109 lines
3.2 KiB
Python
Raw Normal View History

2020-05-06 14:26:52 +10:00
# SPDX-License-Identifier: LGPL-3.0-or-later
from dataclasses import asdict
from typing import Set
2020-05-11 04:26:26 +10:00
from .filters import FieldSubstringFilter, ModelFilter
from .items import Account, AccountOrRoom, Room
2020-05-06 14:26:52 +10:00
from .model import Model
2020-05-11 04:26:26 +10:00
from .model_item import ModelItem
2020-05-06 14:26:52 +10:00
class AllRooms(FieldSubstringFilter):
def __init__(self, accounts: Model) -> None:
2020-05-06 14:26:52 +10:00
super().__init__(sync_id="all_rooms", fields=("display_name",))
self.items_changed_callbacks.append(self.refilter_accounts)
2020-05-06 14:26:52 +10:00
self.accounts = accounts
self._collapsed: Set[str] = set()
def set_account_collapse(self, user_id: str, collapsed: bool) -> None:
def only_if(item):
return item.type is Room and item.for_account == user_id
if collapsed and user_id not in self._collapsed:
self._collapsed.add(user_id)
self.refilter(only_if)
if not collapsed and user_id in self._collapsed:
self._collapsed.remove(user_id)
self.refilter(only_if)
2020-05-06 14:26:52 +10:00
def accept_source(self, source: Model) -> bool:
return source.sync_id == "accounts" or (
2020-05-06 14:26:52 +10:00
isinstance(source.sync_id, tuple) and
len(source.sync_id) == 2 and
source.sync_id[1] == "rooms" # type: ignore
)
2020-05-11 04:26:26 +10:00
def convert_item(self, item: ModelItem) -> AccountOrRoom:
return AccountOrRoom(
**asdict(item),
type = type(item), # type: ignore
account_order =
item.order if isinstance(item, Account) else
self.accounts[item.for_account].order, # type: ignore
)
def accept_item(self, item: ModelItem) -> bool:
assert isinstance(item, AccountOrRoom) # nosec
if not self.filter and \
item.type is Room and \
item.for_account in self._collapsed:
return False
matches_filter = super().accept_item(item)
if item.type is not Account or not self.filter:
return matches_filter
return next(
(i for i in self.values() if i.for_account == item.id), False,
)
def refilter_accounts(self) -> None:
self.refilter(lambda i: i.type is Account) # type: ignore
2020-05-11 04:26:26 +10:00
class MatchingAccounts(ModelFilter):
def __init__(self, all_rooms: AllRooms) -> None:
self.all_rooms = all_rooms
self.all_rooms.items_changed_callbacks.append(self.refilter)
super().__init__(sync_id="matching_accounts")
2020-05-11 04:26:26 +10:00
def accept_source(self, source: Model) -> bool:
return source.sync_id == "accounts"
def accept_item(self, item: ModelItem) -> bool:
if not self.all_rooms.filter:
return True
return next(
(i for i in self.all_rooms.values() if i.id == item.id),
2020-05-11 04:26:26 +10:00
False,
)
class FilteredMembers(FieldSubstringFilter):
def __init__(self, user_id: str, room_id: str) -> None:
self.user_id = user_id
self.room_id = room_id
sync_id = (user_id, room_id, "filtered_members")
super().__init__(sync_id=sync_id, fields=("display_name",))
def accept_source(self, source: Model) -> bool:
return source.sync_id == (self.user_id, self.room_id, "members")