Add room bookmarking: bookmarks are always on top

Introduce a bookmark system for rooms:
a room bookmarked will always appear on top of every other
(for a given account).

Bookmarking can be done through context menu on targeted room
(as well as un-bookmarking) or through settings.json
(key roomBookmarkIDs) for permanent bookmark.
roomBookmarkIds is a {account_user_id: [room_id]} dict.
This commit is contained in:
koudja 2020-10-16 23:36:59 +02:00 committed by miruka
parent 38360b101a
commit 52b0bb18cb
6 changed files with 37 additions and 1 deletions

View File

@ -1142,6 +1142,18 @@ class MatrixClient(nio.AsyncClient):
response = await super().join(string) response = await super().join(string)
return response.room_id return response.room_id
async def toggle_bookmark(self, room_id: str) -> None:
room = self.models[self.user_id, "rooms"][room_id]
room.bookmarked = not room.bookmarked
settings = self.backend.ui_settings
bookmarks = settings["roomBookmarkIDs"].setdefault(self.user_id, [])
if room.bookmarked and room_id not in bookmarks:
bookmarks.append(room_id)
elif not room.bookmarked and room_id in bookmarks:
bookmarks.remove(room_id)
await self.backend.ui_settings.write(self.backend.ui_settings._data)
async def room_forget(self, room_id: str) -> None: async def room_forget(self, room_id: str) -> None:
"""Leave a joined room (or decline an invite) and forget its history. """Leave a joined room (or decline an invite) and forget its history.
@ -1854,6 +1866,7 @@ class MatrixClient(nio.AsyncClient):
) )
unverified_devices = registered.unverified_devices unverified_devices = registered.unverified_devices
bookmarks = self.backend.ui_settings["roomBookmarkIDs"]
room_item = Room( room_item = Room(
id = room.room_id, id = room.room_id,
for_account = self.user_id, for_account = self.user_id,
@ -1900,6 +1913,7 @@ class MatrixClient(nio.AsyncClient):
local_highlights = local_highlights, local_highlights = local_highlights,
lexical_sorting = self.backend.ui_settings["lexicalRoomSorting"], lexical_sorting = self.backend.ui_settings["lexicalRoomSorting"],
bookmarked = room.room_id in bookmarks.get(self.user_id, {}),
) )
self.models[self.user_id, "rooms"][room.room_id] = room_item self.models[self.user_id, "rooms"][room.room_id] = room_item

View File

@ -132,6 +132,7 @@ class Room(ModelItem):
local_highlights: bool = False local_highlights: bool = False
lexical_sorting: bool = False lexical_sorting: bool = False
bookmarked: bool = False
def __lt__(self, other: "Room") -> bool: def __lt__(self, other: "Room") -> bool:
"""Sort by membership, highlights/unread events, last event date, name. """Sort by membership, highlights/unread events, last event date, name.
@ -146,11 +147,13 @@ class Room(ModelItem):
if self.lexical_sorting: if self.lexical_sorting:
return ( return (
self.for_account, self.for_account,
other.bookmarked,
self.left, self.left,
other.inviter_id, other.inviter_id,
(self.display_name or self.id).lower(), (self.display_name or self.id).lower(),
) < ( ) < (
other.for_account, other.for_account,
self.bookmarked,
other.left, other.left,
self.inviter_id, self.inviter_id,
(other.display_name or other.id).lower(), (other.display_name or other.id).lower(),
@ -159,6 +162,7 @@ class Room(ModelItem):
# Left rooms may still have an inviter_id, so check left first. # Left rooms may still have an inviter_id, so check left first.
return ( return (
self.for_account, self.for_account,
other.bookmarked,
self.left, self.left,
other.inviter_id, other.inviter_id,
bool(other.highlights), bool(other.highlights),
@ -170,6 +174,7 @@ class Room(ModelItem):
) < ( ) < (
other.for_account, other.for_account,
self.bookmarked,
other.left, other.left,
self.inviter_id, self.inviter_id,
bool(self.highlights), bool(self.highlights),
@ -192,6 +197,7 @@ class AccountOrRoom(Account, Room):
self.account_order, self.account_order,
self.id if self.type is Account else self.for_account, self.id if self.type is Account else self.for_account,
other.type is Account, other.type is Account,
other.bookmarked,
self.left, self.left,
other.inviter_id, other.inviter_id,
(self.display_name or self.id).lower(), (self.display_name or self.id).lower(),
@ -199,6 +205,7 @@ class AccountOrRoom(Account, Room):
other.account_order, other.account_order,
other.id if other.type is Account else other.for_account, other.id if other.type is Account else other.for_account,
self.type is Account, self.type is Account,
self.bookmarked,
other.left, other.left,
self.inviter_id, self.inviter_id,
(other.display_name or other.id).lower(), (other.display_name or other.id).lower(),
@ -208,6 +215,7 @@ class AccountOrRoom(Account, Room):
self.account_order, self.account_order,
self.id if self.type is Account else self.for_account, self.id if self.type is Account else self.for_account,
other.type is Account, other.type is Account,
other.bookmarked,
self.left, self.left,
other.inviter_id, other.inviter_id,
bool(other.highlights), bool(other.highlights),
@ -221,6 +229,7 @@ class AccountOrRoom(Account, Room):
other.account_order, other.account_order,
other.id if other.type is Account else other.for_account, other.id if other.type is Account else other.for_account,
self.type is Account, self.type is Account,
self.bookmarked,
other.left, other.left,
self.inviter_id, self.inviter_id,
bool(self.highlights), bool(self.highlights),

View File

@ -291,6 +291,7 @@ class UISettings(JSONDataFile):
"theme": "Midnight.qpl", "theme": "Midnight.qpl",
"writeAliases": {}, "writeAliases": {},
"zoom": 1.0, "zoom": 1.0,
"roomBookmarkIDs": {},
"media": { "media": {
"autoLoad": True, "autoLoad": True,

View File

@ -63,7 +63,9 @@ HTile {
spacing: room.spacing spacing: room.spacing
TitleLabel { TitleLabel {
text: model.display_name || qsTr("Empty room") text:
(model.bookmarked ? "\u2665 " : "") +
(model.display_name || qsTr("Empty room"))
color: color:
model.local_unreads ? model.local_unreads ?
theme.mainPane.listView.room.unreadName : theme.mainPane.listView.room.unreadName :
@ -150,6 +152,14 @@ HTile {
}) })
} }
HMenuItem {
icon.name: model.bookmarked ? "bookmark-remove": "bookmark-add"
text: model.bookmarked ? qsTr("Remove bookmark"): qsTr("Bookmark")
onTriggered: py.callClientCoro(
model.for_account, "toggle_bookmark", [model.id]
)
}
HMenuItem { HMenuItem {
icon.name: "copy-room-id" icon.name: "copy-room-id"
text: qsTr("Copy room ID") text: qsTr("Copy room ID")

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M15.653 19.415c-1.162 1.141-2.389 2.331-3.653 3.585-6.43-6.381-12-11.147-12-15.808 0-4.005 3.098-6.192 6.281-6.192 2.197 0 4.434 1.042 5.719 3.248 1.279-2.195 3.521-3.238 5.726-3.238 3.177 0 6.274 2.171 6.274 6.182 0 1.269-.424 2.546-1.154 3.861l-1.483-1.484c.403-.836.637-1.631.637-2.377 0-2.873-2.216-4.182-4.274-4.182-3.257 0-4.976 3.475-5.726 5.021-.747-1.54-2.484-5.03-5.72-5.031-2.315-.001-4.28 1.516-4.28 4.192 0 3.442 4.742 7.85 10 13l2.239-2.191 1.414 1.414zm7.347-5.415h-3v-3h-2v3h-3v2h3v3h2v-3h3v-2z"/></svg>

After

Width:  |  Height:  |  Size: 612 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M15.582 19.485c-1.141 1.119-2.345 2.287-3.582 3.515-6.43-6.381-12-11.147-12-15.808 0-4.005 3.098-6.192 6.281-6.192 2.197 0 4.434 1.042 5.719 3.248 1.279-2.195 3.521-3.238 5.726-3.238 3.177 0 6.274 2.171 6.274 6.182 0 1.577-.649 3.168-1.742 4.828l-1.447-1.447c.75-1.211 1.189-2.341 1.189-3.381 0-2.873-2.216-4.182-4.274-4.182-3.257 0-4.976 3.475-5.726 5.021-.747-1.54-2.484-5.03-5.72-5.031-2.315-.001-4.28 1.516-4.28 4.192 0 3.442 4.742 7.85 10 13l2.168-2.121 1.414 1.414zm7.418-5.485h-8v2h8v-2z"/></svg>

After

Width:  |  Height:  |  Size: 596 B