support undoing a reaction

This commit is contained in:
Bruno Windels 2021-06-03 19:57:16 +02:00
parent 20abb01ee8
commit bb8acbefa3
7 changed files with 45 additions and 5 deletions

View file

@ -86,7 +86,11 @@ class ReactionViewModel extends ViewModel {
return this._annotation.count - other._annotation.count;
}
react() {
return this._parentEntry.react(this.key);
toggleReaction() {
if (this.haveReacted) {
return this._parentEntry.redactReaction(this.key);
} else {
return this._parentEntry.react(this.key);
}
}
}

View file

@ -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() {

View file

@ -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) {

View file

@ -130,4 +130,8 @@ export class EventEntry extends BaseEventEntry {
get annotations() {
return this._eventEntry.annotations;
}
getOwnAnnotationId(room, key) {
return room.getOwnAnnotationEventId(this.id, key);
}
}

View file

@ -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;
}
}

View file

@ -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%;

View file

@ -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();
}
}