This commit is contained in:
Bruno Windels 2021-06-08 16:56:17 +02:00
parent 2ebadb36c3
commit 206d18f498
10 changed files with 67 additions and 42 deletions

View file

@ -79,6 +79,7 @@ class ReactionViewModel {
this._annotation = annotation; this._annotation = annotation;
this._pendingCount = pendingCount; this._pendingCount = pendingCount;
this._parentEntry = parentEntry; this._parentEntry = parentEntry;
this._isToggling = false;
} }
_tryUpdate(annotation) { _tryUpdate(annotation) {
@ -143,14 +144,24 @@ class ReactionViewModel {
} }
} }
toggleReaction() { async toggleReaction() {
const havePendingReaction = this._pendingCount > 0; if (this._isToggling) {
const haveRemoteReaction = this._annotation?.me; console.log("blocking toggleReaction, call ongoing");
const haveReaction = havePendingReaction || haveRemoteReaction; return;
if (haveReaction) { }
return this._parentEntry.redactReaction(this.key); this._isToggling = true;
} else { try {
return this._parentEntry.react(this.key); const haveLocalRedaction = this._pendingCount < 0;
const havePendingReaction = this._pendingCount > 0;
const haveRemoteReaction = this._annotation?.me;
const haveReaction = havePendingReaction || (haveRemoteReaction && !haveLocalRedaction);
if (haveReaction) {
await this._parentEntry.redactReaction(this.key);
} else {
await this._parentEntry.react(this.key);
}
} finally {
this._isToggling = false;
} }
} }
} }

View file

@ -124,27 +124,23 @@ export class BaseMessageTile extends SimpleTile {
} }
react(key, log = null) { react(key, log = null) {
return this.logger.wrapOrRun(log, "react", log => { return this.logger.wrapOrRun(log, "react", async log => {
// this assumes the existing reaction is not a remote one const existingAnnotation = await this._entry.getOwnAnnotationEntry(this._timeline, key);
// we would need to do getOwnAnnotation(Id) and see if there are any pending redactions for it const redaction = existingAnnotation?.pendingRedaction;
const pee = this._entry.getPendingAnnotationEntry(key); if (redaction && !redaction.pendingEvent.hasStartedSending) {
const redaction = pee?.pendingRedaction;
log.set("has_redaction", !!redaction);
log.set("has_redaction", !!redaction);
if (redaction && !redaction.hasStartedSending) {
log.set("abort_redaction", true); log.set("abort_redaction", true);
return redaction.pendingEvent.abort(); await redaction.pendingEvent.abort();
} else { } else {
return this._room.sendEvent("m.reaction", this._entry.annotate(key), null, log); await this._room.sendEvent("m.reaction", this._entry.annotate(key), null, log);
} }
}); });
} }
async redactReaction(key, log = null) { redactReaction(key, log = null) {
return this.logger.wrapOrRun(log, "redactReaction", log => { return this.logger.wrapOrRun(log, "redactReaction", async log => {
const id = await this._entry.getOwnAnnotationId(this._room, key); const entry = await this._entry.getOwnAnnotationEntry(this._timeline, key);
if (id) { if (entry) {
this._room.sendRedaction(id, null, log); await this._room.sendRedaction(entry.id, null, log);
} }
}); });
} }

View file

@ -129,8 +129,12 @@ export class SimpleTile extends ViewModel {
return this._options.room; return this._options.room;
} }
get _timeline() {
return this._options.timeline;
}
get _powerLevels() { get _powerLevels() {
return this._options.timeline.powerLevels; return this._timeline.powerLevels;
} }
get _ownMember() { get _ownMember() {

View file

@ -452,7 +452,7 @@ export class BaseRoom extends EventEmitter {
return observable; return observable;
} }
async getOwnAnnotationEventId(targetId, key) { async getOwnAnnotationEntry(targetId, key) {
const txn = await this._storage.readWriteTxn([ const txn = await this._storage.readWriteTxn([
this._storage.storeNames.timelineEvents, this._storage.storeNames.timelineEvents,
this._storage.storeNames.timelineRelations, this._storage.storeNames.timelineRelations,
@ -461,7 +461,9 @@ export class BaseRoom extends EventEmitter {
for (const relation of relations) { for (const relation of relations) {
const annotation = await txn.timelineEvents.getByEventId(this.id, relation.sourceEventId); const annotation = await txn.timelineEvents.getByEventId(this.id, relation.sourceEventId);
if (annotation.event.sender === this._user.id && getRelation(annotation.event).key === key) { if (annotation.event.sender === this._user.id && getRelation(annotation.event).key === key) {
return annotation.event.event_id; const eventEntry = new EventEntry(annotation, this._fragmentIdComparer);
// add local relations
return eventEntry;
} }
} }
return null; return null;

View file

@ -303,7 +303,7 @@ export class Room extends BaseRoom {
/** @public */ /** @public */
sendEvent(eventType, content, attachments, log = null) { sendEvent(eventType, content, attachments, log = null) {
this._platform.logger.wrapOrRun(log, "send", log => { return this._platform.logger.wrapOrRun(log, "send", log => {
log.set("id", this.id); log.set("id", this.id);
return this._sendQueue.enqueueEvent(eventType, content, attachments, log); return this._sendQueue.enqueueEvent(eventType, content, attachments, log);
}); });
@ -311,7 +311,7 @@ export class Room extends BaseRoom {
/** @public */ /** @public */
sendRedaction(eventIdOrTxnId, reason, log = null) { sendRedaction(eventIdOrTxnId, reason, log = null) {
this._platform.logger.wrapOrRun(log, "redact", log => { return this._platform.logger.wrapOrRun(log, "redact", log => {
log.set("id", this.id); log.set("id", this.id);
return this._sendQueue.enqueueRedaction(eventIdOrTxnId, reason, log); return this._sendQueue.enqueueRedaction(eventIdOrTxnId, reason, log);
}); });

View file

@ -117,7 +117,7 @@ export class PendingEvent {
get error() { return this._error; } get error() { return this._error; }
get hasStartedSending() { get hasStartedSending() {
return this._status !== SendStatus.Sending && this._status !== SendStatus.Sent; return this._status === SendStatus.Sending || this._status === SendStatus.Sent;
} }
get attachmentsTotalBytes() { get attachmentsTotalBytes() {

View file

@ -22,7 +22,7 @@ import {TimelineReader} from "./persistence/TimelineReader.js";
import {PendingEventEntry} from "./entries/PendingEventEntry.js"; import {PendingEventEntry} from "./entries/PendingEventEntry.js";
import {RoomMember} from "../members/RoomMember.js"; import {RoomMember} from "../members/RoomMember.js";
import {PowerLevels} from "./PowerLevels.js"; import {PowerLevels} from "./PowerLevels.js";
import {getRelationFromContent} from "./relations.js"; import {getRelationFromContent, getRelation, ANNOTATION_RELATION_TYPE} from "./relations.js";
export class Timeline { export class Timeline {
constructor({roomId, storage, closeCallback, fragmentIdComparer, pendingEvents, clock}) { constructor({roomId, storage, closeCallback, fragmentIdComparer, pendingEvents, clock}) {
@ -124,7 +124,6 @@ export class Timeline {
} }
return params; return params;
}); });
console.log("redactedEntry", redactedEntry);
if (redactedEntry) { if (redactedEntry) {
const redactedRelation = getRelationFromContent(redactedEntry.content); const redactedRelation = getRelationFromContent(redactedEntry.content);
if (redactedRelation?.event_id) { if (redactedRelation?.event_id) {
@ -132,7 +131,6 @@ export class Timeline {
e => e.id === redactedRelation.event_id, e => e.id === redactedRelation.event_id,
relationTarget => relationTarget.addLocalRelation(redactedEntry) || false relationTarget => relationTarget.addLocalRelation(redactedEntry) || false
); );
console.log("found", found);
} }
} }
} }
@ -182,6 +180,24 @@ export class Timeline {
} }
} }
async getOwnAnnotationEntry(targetId, key) {
const txn = await this._storage.readWriteTxn([
this._storage.storeNames.timelineEvents,
this._storage.storeNames.timelineRelations,
]);
const relations = await txn.timelineRelations.getForTargetAndType(this._roomId, targetId, ANNOTATION_RELATION_TYPE);
for (const relation of relations) {
const annotation = await txn.timelineEvents.getByEventId(this._roomId, relation.sourceEventId);
if (annotation.event.sender === this._ownMember.userId && getRelation(annotation.event).key === key) {
const eventEntry = new EventEntry(annotation, this._fragmentIdComparer);
this._addLocalRelationsToNewRemoteEntries([eventEntry]);
return eventEntry;
}
}
return null;
}
updateOwnMember(member) { updateOwnMember(member) {
this._ownMember = member; this._ownMember = member;
} }

View file

@ -117,11 +117,7 @@ export class BaseEventEntry extends BaseEntry {
return this._pendingAnnotations?.aggregatedAnnotations; return this._pendingAnnotations?.aggregatedAnnotations;
} }
async getOwnAnnotationId(room, key) { async getOwnAnnotationEntry(timeline, key) {
return this.getPendingAnnotationEntry(key)?.id;
}
getPendingAnnotationEntry(key) {
return this._pendingAnnotations?.findForKey(key); return this._pendingAnnotations?.findForKey(key);
} }
} }

View file

@ -131,12 +131,12 @@ export class EventEntry extends BaseEventEntry {
return this._eventEntry.annotations; return this._eventEntry.annotations;
} }
async getOwnAnnotationId(room, key) { async getOwnAnnotationEntry(timeline, key) {
const localId = await super.getOwnAnnotationId(room, key); const localId = await super.getOwnAnnotationEntry(timeline, key);
if (localId) { if (localId) {
return localId; return localId;
} else { } else {
return room.getOwnAnnotationEventId(this.id, key); return timeline.getOwnAnnotationEntry(this.id, key);
} }
} }
} }

View file

@ -243,7 +243,7 @@ only loads when the top comes into view*/
.Timeline_messageReactions button.haveReacted.isPending { .Timeline_messageReactions button.haveReacted.isPending {
animation-name: glow-reaction-border; animation-name: glow-reaction-border;
animation-duration: 1s; animation-duration: 0.8s;
animation-direction: alternate; animation-direction: alternate;
animation-iteration-count: infinite; animation-iteration-count: infinite;
animation-timing-function: linear; animation-timing-function: linear;