mirror of
https://github.com/tulir/gomuks.git
synced 2025-04-20 10:33:41 -05:00
hicli/database,web/roomlist: show marked unread status
This commit is contained in:
parent
ead1365c12
commit
80f9a8bb6b
11 changed files with 49 additions and 9 deletions
|
@ -23,7 +23,7 @@ const (
|
|||
getRoomBaseQuery = `
|
||||
SELECT room_id, creation_content, tombstone_content, name, name_quality, avatar, explicit_avatar, topic, canonical_alias,
|
||||
lazy_load_summary, encryption_event, has_member_list, preview_event_rowid, sorting_timestamp,
|
||||
unread_highlights, unread_notifications, unread_messages, prev_batch
|
||||
unread_highlights, unread_notifications, unread_messages, marked_unread, prev_batch
|
||||
FROM room
|
||||
`
|
||||
getRoomsBySortingTimestampQuery = getRoomBaseQuery + `WHERE sorting_timestamp < $1 AND sorting_timestamp > 0 ORDER BY sorting_timestamp DESC LIMIT $2`
|
||||
|
@ -50,7 +50,8 @@ const (
|
|||
unread_highlights = COALESCE($15, room.unread_highlights),
|
||||
unread_notifications = COALESCE($16, room.unread_notifications),
|
||||
unread_messages = COALESCE($17, room.unread_messages),
|
||||
prev_batch = COALESCE($18, room.prev_batch)
|
||||
marked_unread = COALESCE($18, room.marked_unread),
|
||||
prev_batch = COALESCE($19, room.prev_batch)
|
||||
WHERE room_id = $1
|
||||
`
|
||||
setRoomPrevBatchQuery = `
|
||||
|
@ -157,6 +158,7 @@ type Room struct {
|
|||
PreviewEventRowID EventRowID `json:"preview_event_rowid"`
|
||||
SortingTimestamp jsontime.UnixMilli `json:"sorting_timestamp"`
|
||||
UnreadCounts
|
||||
MarkedUnread *bool `json:"marked_unread,omitempty"`
|
||||
|
||||
PrevBatch string `json:"prev_batch"`
|
||||
}
|
||||
|
@ -220,6 +222,10 @@ func (r *Room) CheckChangesAndCopyInto(other *Room) (hasChanges bool) {
|
|||
other.UnreadMessages = r.UnreadMessages
|
||||
hasChanges = true
|
||||
}
|
||||
if r.MarkedUnread != other.MarkedUnread {
|
||||
other.MarkedUnread = r.MarkedUnread
|
||||
hasChanges = true
|
||||
}
|
||||
if r.PrevBatch != "" && other.PrevBatch == "" {
|
||||
other.PrevBatch = r.PrevBatch
|
||||
hasChanges = true
|
||||
|
@ -248,6 +254,7 @@ func (r *Room) Scan(row dbutil.Scannable) (*Room, error) {
|
|||
&r.UnreadHighlights,
|
||||
&r.UnreadNotifications,
|
||||
&r.UnreadMessages,
|
||||
&r.MarkedUnread,
|
||||
&prevBatch,
|
||||
)
|
||||
if err != nil {
|
||||
|
@ -278,6 +285,7 @@ func (r *Room) sqlVariables() []any {
|
|||
r.UnreadHighlights,
|
||||
r.UnreadNotifications,
|
||||
r.UnreadMessages,
|
||||
r.MarkedUnread,
|
||||
dbutil.StrPtr(r.PrevBatch),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
-- v0 -> v6 (compatible with v5+): Latest revision
|
||||
-- v0 -> v7 (compatible with v5+): Latest revision
|
||||
CREATE TABLE account (
|
||||
user_id TEXT NOT NULL PRIMARY KEY,
|
||||
device_id TEXT NOT NULL,
|
||||
|
@ -29,6 +29,7 @@ CREATE TABLE room (
|
|||
unread_highlights INTEGER NOT NULL DEFAULT 0,
|
||||
unread_notifications INTEGER NOT NULL DEFAULT 0,
|
||||
unread_messages INTEGER NOT NULL DEFAULT 0,
|
||||
marked_unread INTEGER NOT NULL DEFAULT false,
|
||||
|
||||
prev_batch TEXT,
|
||||
|
||||
|
|
2
pkg/hicli/database/upgrades/07-marked-unread.sql
Normal file
2
pkg/hicli/database/upgrades/07-marked-unread.sql
Normal file
|
@ -0,0 +1,2 @@
|
|||
-- v7 (compatible with v5+): Add room column for marking unread
|
||||
ALTER TABLE room ADD COLUMN marked_unread INTEGER NOT NULL DEFAULT false;
|
|
@ -151,6 +151,12 @@ func (h *HiClient) SendMessage(
|
|||
}
|
||||
|
||||
func (h *HiClient) MarkRead(ctx context.Context, roomID id.RoomID, eventID id.EventID, receiptType event.ReceiptType) error {
|
||||
room, err := h.DB.Room.Get(ctx, roomID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get room metadata: %w", err)
|
||||
} else if room == nil {
|
||||
return fmt.Errorf("unknown room")
|
||||
}
|
||||
content := &mautrix.ReqSetReadMarkers{
|
||||
FullyRead: eventID,
|
||||
}
|
||||
|
@ -161,10 +167,16 @@ func (h *HiClient) MarkRead(ctx context.Context, roomID id.RoomID, eventID id.Ev
|
|||
} else {
|
||||
return fmt.Errorf("invalid receipt type: %v", receiptType)
|
||||
}
|
||||
err := h.Client.SetReadMarkers(ctx, roomID, content)
|
||||
err = h.Client.SetReadMarkers(ctx, roomID, content)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to mark event as read: %w", err)
|
||||
}
|
||||
if ptr.Val(room.MarkedUnread) {
|
||||
err = h.Client.SetRoomAccountData(ctx, roomID, event.AccountDataMarkedUnread.Type, &event.MarkedUnreadEventContent{Unread: false})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to mark room as read: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
"go.mau.fi/util/emojirunes"
|
||||
"go.mau.fi/util/exzerolog"
|
||||
"go.mau.fi/util/jsontime"
|
||||
"go.mau.fi/util/ptr"
|
||||
"maunium.net/go/mautrix"
|
||||
"maunium.net/go/mautrix/crypto"
|
||||
"maunium.net/go/mautrix/crypto/olm"
|
||||
|
@ -772,6 +773,10 @@ func (h *HiClient) processStateAndTimeline(
|
|||
updatedRoom.Avatar = &dmAvatarURL
|
||||
}
|
||||
}
|
||||
mu, ok := accountData[event.AccountDataMarkedUnread]
|
||||
if ok {
|
||||
updatedRoom.MarkedUnread = ptr.Ptr(gjson.GetBytes(mu.Content, "unread").Bool())
|
||||
}
|
||||
|
||||
if len(receipts) > 0 {
|
||||
err = h.DB.Receipt.PutMany(ctx, room.ID, receipts...)
|
||||
|
|
|
@ -50,6 +50,7 @@ export interface RoomListEntry {
|
|||
unread_messages: number
|
||||
unread_notifications: number
|
||||
unread_highlights: number
|
||||
marked_unread: boolean
|
||||
}
|
||||
|
||||
export class StateStore {
|
||||
|
@ -102,6 +103,7 @@ export class StateStore {
|
|||
entry.meta.unread_messages !== oldEntry.meta.current.unread_messages ||
|
||||
entry.meta.unread_notifications !== oldEntry.meta.current.unread_notifications ||
|
||||
entry.meta.unread_highlights !== oldEntry.meta.current.unread_highlights ||
|
||||
entry.meta.marked_unread !== oldEntry.meta.current.marked_unread ||
|
||||
entry.meta.preview_event_rowid !== oldEntry.meta.current.preview_event_rowid ||
|
||||
entry.events.findIndex(evt => evt.rowid === entry.meta.preview_event_rowid) !== -1
|
||||
}
|
||||
|
@ -129,6 +131,7 @@ export class StateStore {
|
|||
unread_messages: entry.meta.unread_messages,
|
||||
unread_notifications: entry.meta.unread_notifications,
|
||||
unread_highlights: entry.meta.unread_highlights,
|
||||
marked_unread: entry.meta.marked_unread,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ export interface DBRoom {
|
|||
unread_highlights: number
|
||||
unread_notifications: number
|
||||
unread_messages: number
|
||||
marked_unread: boolean
|
||||
|
||||
prev_batch: string
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
--unread-counter-text-color: var(--inverted-text-color);
|
||||
--unread-counter-message-bg: rgba(0, 0, 0, 0.35);
|
||||
--unread-counter-notification-bg: rgba(50, 150, 0, 0.7);
|
||||
--unread-counter-marked-unread-bg: var(--unread-counter-notification-bg);
|
||||
--unread-counter-highlight-bg: rgba(200, 0, 0, 0.7);
|
||||
|
||||
--sender-color-0: #a4041d;
|
||||
|
|
|
@ -68,8 +68,9 @@ const EntryInner = ({ room }: InnerProps) => {
|
|||
<div className="room-name">{room.name}</div>
|
||||
{previewText && <div className="message-preview" title={previewText}>{croppedPreviewText}</div>}
|
||||
</div>
|
||||
{room.unread_messages ? <div className="room-entry-unreads">
|
||||
{(room.unread_messages || room.marked_unread) ? <div className="room-entry-unreads">
|
||||
<div className={`unread-count ${
|
||||
room.marked_unread ? "marked-unread" : ""} ${
|
||||
room.unread_notifications ? "notified" : ""} ${
|
||||
room.unread_highlights ? "highlighted" : ""}`}
|
||||
>
|
||||
|
|
|
@ -117,7 +117,7 @@ div.room-entry {
|
|||
line-height: 1;
|
||||
font-size: .75em;
|
||||
|
||||
&.notified, &.highlighted {
|
||||
&.notified, &.marked-unread, &.highlighted {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
padding-bottom: 0;
|
||||
|
@ -125,7 +125,11 @@ div.room-entry {
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
&.notified:not(.highlighted) {
|
||||
&.marked-unread {
|
||||
background-color: var(--unread-counter-marked-unread-bg);
|
||||
}
|
||||
|
||||
&.notified {
|
||||
background-color: var(--unread-counter-notification-bg);
|
||||
}
|
||||
|
||||
|
|
|
@ -75,10 +75,12 @@ const TimelineView = () => {
|
|||
&& focused
|
||||
&& newestEvent
|
||||
&& newestEvent.timeline_rowid > 0
|
||||
&& room.readUpToRow < newestEvent.timeline_rowid
|
||||
&& newestEvent.sender !== client.userID
|
||||
&& (room.meta.current.marked_unread
|
||||
|| (room.readUpToRow < newestEvent.timeline_rowid
|
||||
&& newestEvent.sender !== client.userID))
|
||||
) {
|
||||
room.readUpToRow = newestEvent.timeline_rowid
|
||||
room.meta.current.marked_unread = false
|
||||
const receiptType = roomCtx.store.preferences.send_read_receipts ? "m.read" : "m.read.private"
|
||||
client.rpc.markRead(room.roomID, newestEvent.event_id, receiptType).then(
|
||||
() => console.log("Marked read up to", newestEvent.event_id, newestEvent.timeline_rowid),
|
||||
|
|
Loading…
Add table
Reference in a new issue