diff --git a/src/matrix/SessionContainer.js b/src/matrix/SessionContainer.js index 89325d49..7b0dfa1e 100644 --- a/src/matrix/SessionContainer.js +++ b/src/matrix/SessionContainer.js @@ -22,7 +22,7 @@ import {ObservableValue} from "../observable/ObservableValue"; import {HomeServerApi} from "./net/HomeServerApi.js"; import {Reconnector, ConnectionStatus} from "./net/Reconnector.js"; import {ExponentialRetryDelay} from "./net/ExponentialRetryDelay"; -import {MediaRepository} from "./net/MediaRepository.js"; +import {MediaRepository} from "./net/MediaRepository"; import {RequestScheduler} from "./net/RequestScheduler.js"; import {Sync, SyncStatus} from "./Sync.js"; import {Session} from "./Session.js"; diff --git a/src/matrix/net/MediaRepository.js b/src/matrix/net/MediaRepository.ts similarity index 71% rename from src/matrix/net/MediaRepository.js rename to src/matrix/net/MediaRepository.ts index a7875d99..0bf70149 100644 --- a/src/matrix/net/MediaRepository.js +++ b/src/matrix/net/MediaRepository.ts @@ -16,14 +16,20 @@ limitations under the License. import {encodeQueryParams} from "./common"; import {decryptAttachment} from "../e2ee/attachment.js"; +import {Platform} from "../../platform/web/Platform.js"; +import {BlobHandle} from "../../platform/web/dom/BlobHandle.js"; +import type {IAttachment, IEncryptedFile} from "./types/response"; export class MediaRepository { - constructor({homeserver, platform}) { + private readonly _homeserver: string; + private readonly _platform: Platform; + + constructor({homeserver, platform}: {homeserver:string, platform: Platform}) { this._homeserver = homeserver; this._platform = platform; } - mxcUrlThumbnail(url, width, height, method) { + mxcUrlThumbnail(url: string, width: number, height: number, method: "crop" | "scale"): string | null { const parts = this._parseMxcUrl(url); if (parts) { const [serverName, mediaId] = parts; @@ -33,7 +39,7 @@ export class MediaRepository { return null; } - mxcUrl(url) { + mxcUrl(url: string): string | null { const parts = this._parseMxcUrl(url); if (parts) { const [serverName, mediaId] = parts; @@ -43,7 +49,7 @@ export class MediaRepository { } } - _parseMxcUrl(url) { + _parseMxcUrl(url: string): string[] | null { const prefix = "mxc://"; if (url.startsWith(prefix)) { return url.substr(prefix.length).split("/", 2); @@ -52,24 +58,24 @@ export class MediaRepository { } } - async downloadEncryptedFile(fileEntry, cache = false) { + async downloadEncryptedFile(fileEntry: IEncryptedFile, cache: boolean = false): Promise { const url = this.mxcUrl(fileEntry.url); const {body: encryptedBuffer} = await this._platform.request(url, {method: "GET", format: "buffer", cache}).response(); const decryptedBuffer = await decryptAttachment(this._platform, encryptedBuffer, fileEntry); return this._platform.createBlob(decryptedBuffer, fileEntry.mimetype); } - async downloadPlaintextFile(mxcUrl, mimetype, cache = false) { + async downloadPlaintextFile(mxcUrl: string, mimetype: string, cache: boolean = false): Promise { const url = this.mxcUrl(mxcUrl); const {body: buffer} = await this._platform.request(url, {method: "GET", format: "buffer", cache}).response(); return this._platform.createBlob(buffer, mimetype); } - async downloadAttachment(content, cache = false) { + async downloadAttachment(content: IAttachment, cache: boolean = false): Promise { if (content.file) { return this.downloadEncryptedFile(content.file, cache); } else { - return this.downloadPlaintextFile(content.url, content.info?.mimetype, cache); + return this.downloadPlaintextFile(content.url!, content.info?.mimetype, cache); } } } diff --git a/src/matrix/net/types/response.ts b/src/matrix/net/types/response.ts new file mode 100644 index 00000000..762bd683 --- /dev/null +++ b/src/matrix/net/types/response.ts @@ -0,0 +1,54 @@ +/* +Copyright 2020 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. +*/ + +export interface IAttachment { + body: string; + info: IAttachmentInfo; + // todo: what about m.audio? + msgtype: "m.image" | "m.file" | "m.video"; + url?: string; + file?: IEncryptedFile; + filename?: string; +} + +export interface IEncryptedFile { + key: JsonWebKey; + iv: string; + hashes: { + sha256: string; + }; + url: string; + v: string; + mimetype?: string; +} + +interface IAttachmentInfo { + h?: number; + w?: number; + mimetype: string; + size: number; + duration?: number; + thumbnail_url?: string; + thumbnail_file?: IEncryptedFile; + thumbnail_info?: IThumbnailInfo; +} + +interface IThumbnailInfo { + h: number; + w: number; + mimetype: string; + size: number; +}