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._pendingCount = pendingCount;
this._parentEntry = parentEntry;
this._isToggling = false;
}
_tryUpdate(annotation) {
@ -143,14 +144,24 @@ class ReactionViewModel {
}
}
toggleReaction() {
const havePendingReaction = this._pendingCount > 0;
const haveRemoteReaction = this._annotation?.me;
const haveReaction = havePendingReaction || haveRemoteReaction;
if (haveReaction) {
return this._parentEntry.redactReaction(this.key);
} else {
return this._parentEntry.react(this.key);
async toggleReaction() {
if (this._isToggling) {
console.log("blocking toggleReaction, call ongoing");
return;
}
this._isToggling = true;
try {
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) {
return this.logger.wrapOrRun(log, "react", log => {
// this assumes the existing reaction is not a remote one
// we would need to do getOwnAnnotation(Id) and see if there are any pending redactions for it
const pee = this._entry.getPendingAnnotationEntry(key);
const redaction = pee?.pendingRedaction;
log.set("has_redaction", !!redaction);
log.set("has_redaction", !!redaction);
if (redaction && !redaction.hasStartedSending) {
return this.logger.wrapOrRun(log, "react", async log => {
const existingAnnotation = await this._entry.getOwnAnnotationEntry(this._timeline, key);
const redaction = existingAnnotation?.pendingRedaction;
if (redaction && !redaction.pendingEvent.hasStartedSending) {
log.set("abort_redaction", true);
return redaction.pendingEvent.abort();
await redaction.pendingEvent.abort();
} 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) {
return this.logger.wrapOrRun(log, "redactReaction", log => {
const id = await this._entry.getOwnAnnotationId(this._room, key);
if (id) {
this._room.sendRedaction(id, null, log);
redactReaction(key, log = null) {
return this.logger.wrapOrRun(log, "redactReaction", async log => {
const entry = await this._entry.getOwnAnnotationEntry(this._timeline, key);
if (entry) {
await this._room.sendRedaction(entry.id, null, log);
}
});
}

View file

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

View file

@ -452,7 +452,7 @@ export class BaseRoom extends EventEmitter {
return observable;
}
async getOwnAnnotationEventId(targetId, key) {
async getOwnAnnotationEntry(targetId, key) {
const txn = await this._storage.readWriteTxn([
this._storage.storeNames.timelineEvents,
this._storage.storeNames.timelineRelations,
@ -461,7 +461,9 @@ export class BaseRoom extends EventEmitter {
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;
const eventEntry = new EventEntry(annotation, this._fragmentIdComparer);
// add local relations
return eventEntry;
}
}
return null;

View file

@ -303,7 +303,7 @@ export class Room extends BaseRoom {
/** @public */
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);
return this._sendQueue.enqueueEvent(eventType, content, attachments, log);
});
@ -311,7 +311,7 @@ export class Room extends BaseRoom {
/** @public */
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);
return this._sendQueue.enqueueRedaction(eventIdOrTxnId, reason, log);
});

View file

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

View file

@ -22,7 +22,7 @@ import {TimelineReader} from "./persistence/TimelineReader.js";
import {PendingEventEntry} from "./entries/PendingEventEntry.js";
import {RoomMember} from "../members/RoomMember.js";
import {PowerLevels} from "./PowerLevels.js";
import {getRelationFromContent} from "./relations.js";
import {getRelationFromContent, getRelation, ANNOTATION_RELATION_TYPE} from "./relations.js";
export class Timeline {
constructor({roomId, storage, closeCallback, fragmentIdComparer, pendingEvents, clock}) {
@ -124,7 +124,6 @@ export class Timeline {
}
return params;
});
console.log("redactedEntry", redactedEntry);
if (redactedEntry) {
const redactedRelation = getRelationFromContent(redactedEntry.content);
if (redactedRelation?.event_id) {
@ -132,7 +131,6 @@ export class Timeline {
e => e.id === redactedRelation.event_id,
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) {
this._ownMember = member;
}

View file

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

View file

@ -131,12 +131,12 @@ export class EventEntry extends BaseEventEntry {
return this._eventEntry.annotations;
}
async getOwnAnnotationId(room, key) {
const localId = await super.getOwnAnnotationId(room, key);
async getOwnAnnotationEntry(timeline, key) {
const localId = await super.getOwnAnnotationEntry(timeline, key);
if (localId) {
return localId;
} 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 {
animation-name: glow-reaction-border;
animation-duration: 1s;
animation-duration: 0.8s;
animation-direction: alternate;
animation-iteration-count: infinite;
animation-timing-function: linear;