init
This commit is contained in:
215
node_modules/matrix-js-sdk/lib/models/MSC3089Branch.js
generated
vendored
Normal file
215
node_modules/matrix-js-sdk/lib/models/MSC3089Branch.js
generated
vendored
Normal file
@@ -0,0 +1,215 @@
|
||||
import _objectSpread from "@babel/runtime/helpers/objectSpread2";
|
||||
/*
|
||||
Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { RelationType, UNSTABLE_MSC3089_BRANCH } from "../@types/event.js";
|
||||
import { EventTimeline } from "./event-timeline.js";
|
||||
/**
|
||||
* Represents a [MSC3089](https://github.com/matrix-org/matrix-doc/pull/3089) branch - a reference
|
||||
* to a file (leaf) in the tree. Note that this is UNSTABLE and subject to breaking changes
|
||||
* without notice.
|
||||
*/
|
||||
export class MSC3089Branch {
|
||||
constructor(client, indexEvent, directory) {
|
||||
this.client = client;
|
||||
this.indexEvent = indexEvent;
|
||||
this.directory = directory;
|
||||
} // Nothing to do
|
||||
|
||||
/**
|
||||
* The file ID.
|
||||
*/
|
||||
get id() {
|
||||
const stateKey = this.indexEvent.getStateKey();
|
||||
if (!stateKey) {
|
||||
throw new Error("State key not found for branch");
|
||||
}
|
||||
return stateKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this branch is active/valid.
|
||||
*/
|
||||
get isActive() {
|
||||
return this.indexEvent.getContent()["active"] === true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Version for the file, one-indexed.
|
||||
*/
|
||||
get version() {
|
||||
return this.indexEvent.getContent()["version"] ?? 1;
|
||||
}
|
||||
get roomId() {
|
||||
return this.indexEvent.getRoomId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the file from the tree, including all prior edits/versions.
|
||||
* @returns Promise which resolves when complete.
|
||||
*/
|
||||
async delete() {
|
||||
await this.client.sendStateEvent(this.roomId, UNSTABLE_MSC3089_BRANCH.name, {}, this.id);
|
||||
await this.client.redactEvent(this.roomId, this.id);
|
||||
const nextVersion = (await this.getVersionHistory())[1]; // [0] will be us
|
||||
if (nextVersion) await nextVersion.delete(); // implicit recursion
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name for this file.
|
||||
* @returns The name, or "Unnamed File" if unknown.
|
||||
*/
|
||||
getName() {
|
||||
return this.indexEvent.getContent()["name"] || "Unnamed File";
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name for this file.
|
||||
* @param name - The new name for this file.
|
||||
* @returns Promise which resolves when complete.
|
||||
*/
|
||||
async setName(name) {
|
||||
await this.client.sendStateEvent(this.roomId, UNSTABLE_MSC3089_BRANCH.name, _objectSpread(_objectSpread({}, this.indexEvent.getContent()), {}, {
|
||||
name: name
|
||||
}), this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether or not a file is locked.
|
||||
* @returns True if locked, false otherwise.
|
||||
*/
|
||||
isLocked() {
|
||||
return this.indexEvent.getContent()["locked"] || false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a file as locked or unlocked.
|
||||
* @param locked - True to lock the file, false otherwise.
|
||||
* @returns Promise which resolves when complete.
|
||||
*/
|
||||
async setLocked(locked) {
|
||||
await this.client.sendStateEvent(this.roomId, UNSTABLE_MSC3089_BRANCH.name, _objectSpread(_objectSpread({}, this.indexEvent.getContent()), {}, {
|
||||
locked: locked
|
||||
}), this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets information about the file needed to download it.
|
||||
* @returns Information about the file.
|
||||
*/
|
||||
async getFileInfo() {
|
||||
const event = await this.getFileEvent();
|
||||
const file = event.getOriginalContent()["file"];
|
||||
const httpUrl = this.client.mxcUrlToHttp(file["url"]);
|
||||
if (!httpUrl) {
|
||||
throw new Error(`No HTTP URL available for ${file["url"]}`);
|
||||
}
|
||||
return {
|
||||
info: file,
|
||||
httpUrl: httpUrl
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the event the file points to.
|
||||
* @returns Promise which resolves to the file's event.
|
||||
*/
|
||||
async getFileEvent() {
|
||||
const room = this.client.getRoom(this.roomId);
|
||||
if (!room) throw new Error("Unknown room");
|
||||
let event = room.getUnfilteredTimelineSet().findEventById(this.id);
|
||||
|
||||
// keep scrolling back if needed until we find the event or reach the start of the room:
|
||||
while (!event && room.getLiveTimeline().getState(EventTimeline.BACKWARDS).paginationToken) {
|
||||
await this.client.scrollback(room, 100);
|
||||
event = room.getUnfilteredTimelineSet().findEventById(this.id);
|
||||
}
|
||||
if (!event) throw new Error("Failed to find event");
|
||||
|
||||
// Sometimes the event isn't decrypted for us, so do that.
|
||||
await this.client.decryptEventIfNeeded(event);
|
||||
return event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new version of this file with contents in a type that is compatible with MatrixClient.uploadContent().
|
||||
* @param name - The name of the file.
|
||||
* @param encryptedContents - The encrypted contents.
|
||||
* @param info - The encrypted file information.
|
||||
* @param additionalContent - Optional event content fields to include in the message.
|
||||
* @returns Promise which resolves to the file event's sent response.
|
||||
*/
|
||||
async createNewVersion(name, encryptedContents, info, additionalContent) {
|
||||
const fileEventResponse = await this.directory.createFile(name, encryptedContents, info, _objectSpread(_objectSpread({}, additionalContent), {}, {
|
||||
"m.new_content": true,
|
||||
"m.relates_to": {
|
||||
rel_type: RelationType.Replace,
|
||||
event_id: this.id
|
||||
}
|
||||
}));
|
||||
|
||||
// Update the version of the new event
|
||||
await this.client.sendStateEvent(this.roomId, UNSTABLE_MSC3089_BRANCH.name, {
|
||||
active: true,
|
||||
name: name,
|
||||
version: this.version + 1
|
||||
}, fileEventResponse["event_id"]);
|
||||
|
||||
// Deprecate ourselves
|
||||
await this.client.sendStateEvent(this.roomId, UNSTABLE_MSC3089_BRANCH.name, _objectSpread(_objectSpread({}, this.indexEvent.getContent()), {}, {
|
||||
active: false
|
||||
}), this.id);
|
||||
return fileEventResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the file's version history, starting at this file.
|
||||
* @returns Promise which resolves to the file's version history, with the
|
||||
* first element being the current version and the last element being the first version.
|
||||
*/
|
||||
async getVersionHistory() {
|
||||
const fileHistory = [];
|
||||
fileHistory.push(this); // start with ourselves
|
||||
|
||||
const room = this.client.getRoom(this.roomId);
|
||||
if (!room) throw new Error("Invalid or unknown room");
|
||||
|
||||
// Clone the timeline to reverse it, getting most-recent-first ordering, hopefully
|
||||
// shortening the awful loop below. Without the clone, we can unintentionally mutate
|
||||
// the timeline.
|
||||
const timelineEvents = [...room.getLiveTimeline().getEvents()].reverse();
|
||||
|
||||
// XXX: This is a very inefficient search, but it's the best we can do with the
|
||||
// relations structure we have in the SDK. As of writing, it is not worth the
|
||||
// investment in improving the structure.
|
||||
let childEvent;
|
||||
let parentEvent = await this.getFileEvent();
|
||||
do {
|
||||
childEvent = timelineEvents.find(e => e.replacingEventId() === parentEvent.getId());
|
||||
if (childEvent) {
|
||||
const branch = this.directory.getFile(childEvent.getId());
|
||||
if (branch) {
|
||||
fileHistory.push(branch);
|
||||
parentEvent = childEvent;
|
||||
} else {
|
||||
break; // prevent infinite loop
|
||||
}
|
||||
}
|
||||
} while (childEvent);
|
||||
return fileHistory;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=MSC3089Branch.js.map
|
||||
Reference in New Issue
Block a user