support undoing a reaction
This commit is contained in:
parent
20abb01ee8
commit
bb8acbefa3
7 changed files with 45 additions and 5 deletions
|
@ -86,7 +86,11 @@ class ReactionViewModel extends ViewModel {
|
|||
return this._annotation.count - other._annotation.count;
|
||||
}
|
||||
|
||||
react() {
|
||||
toggleReaction() {
|
||||
if (this.haveReacted) {
|
||||
return this._parentEntry.redactReaction(this.key);
|
||||
} else {
|
||||
return this._parentEntry.react(this.key);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -123,7 +123,14 @@ export class BaseMessageTile extends SimpleTile {
|
|||
}
|
||||
|
||||
react(key) {
|
||||
this._room.sendEvent("m.reaction", this._entry.annotate(key));
|
||||
return this._room.sendEvent("m.reaction", this._entry.annotate(key));
|
||||
}
|
||||
|
||||
async redactReaction(key) {
|
||||
const id = await this._entry.getOwnAnnotationId(this._room, key);
|
||||
if (id) {
|
||||
this._room.sendRedaction(id);
|
||||
}
|
||||
}
|
||||
|
||||
_updateReactions() {
|
||||
|
|
|
@ -28,6 +28,7 @@ import {EventEntry} from "./timeline/entries/EventEntry.js";
|
|||
import {ObservedEventMap} from "./ObservedEventMap.js";
|
||||
import {DecryptionSource} from "../e2ee/common.js";
|
||||
import {ensureLogItem} from "../../logging/utils.js";
|
||||
import {ANNOTATION_RELATION_TYPE, getRelation} from "./timeline/relations.js";
|
||||
|
||||
const EVENT_ENCRYPTED_TYPE = "m.room.encrypted";
|
||||
|
||||
|
@ -451,6 +452,21 @@ export class BaseRoom extends EventEmitter {
|
|||
return observable;
|
||||
}
|
||||
|
||||
async getOwnAnnotationEventId(targetId, key) {
|
||||
const txn = await this._storage.readWriteTxn([
|
||||
this._storage.storeNames.timelineEvents,
|
||||
this._storage.storeNames.timelineRelations,
|
||||
]);
|
||||
const relations = await txn.timelineRelations.getForTargetAndType(this.id, targetId, ANNOTATION_RELATION_TYPE);
|
||||
for (const relation of relations) {
|
||||
const annotation = await txn.timelineEvents.getByEventId(this.id, relation.sourceEventId);
|
||||
if (annotation.event.sender === this._user.id && getRelation(annotation.event).key === key) {
|
||||
return annotation.event.event_id;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
async _readEventById(eventId) {
|
||||
let stores = [this._storage.storeNames.timelineEvents];
|
||||
if (this.isEncrypted) {
|
||||
|
|
|
@ -130,4 +130,8 @@ export class EventEntry extends BaseEventEntry {
|
|||
get annotations() {
|
||||
return this._eventEntry.annotations;
|
||||
}
|
||||
|
||||
getOwnAnnotationId(room, key) {
|
||||
return room.getOwnAnnotationEventId(this.id, key);
|
||||
}
|
||||
}
|
|
@ -85,4 +85,9 @@ export class PendingEventEntry extends BaseEventEntry {
|
|||
get relatedEventId() {
|
||||
return this._pendingEvent.relatedEventId;
|
||||
}
|
||||
|
||||
getOwnAnnotationId(_, key) {
|
||||
// TODO: implement this once local reactions are implemented
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -217,6 +217,11 @@ only loads when the top comes into view*/
|
|||
grid-area: reactions;
|
||||
}
|
||||
|
||||
.Timeline_messageReactions button.haveReacted {
|
||||
background-color: green;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.AnnouncementView {
|
||||
margin: 5px 0;
|
||||
padding: 5px 10%;
|
||||
|
|
|
@ -32,12 +32,11 @@ class ReactionView extends TemplateView {
|
|||
render(t, vm) {
|
||||
const haveReacted = vm => vm.haveReacted;
|
||||
return t.button({
|
||||
disabled: haveReacted,
|
||||
className: {haveReacted},
|
||||
}, [vm.key, " ", vm => `${vm.count}`]);
|
||||
}
|
||||
|
||||
onClick() {
|
||||
this.value.react();
|
||||
this.value.toggleReaction();
|
||||
}
|
||||
}
|
Reference in a new issue