move MediaRepository out of HomeServerApi

so HomeServerApi becomes easier to wrap, only having methods
that return a RequestResult.
This commit is contained in:
Bruno Windels 2020-09-22 13:40:38 +02:00
parent 6cd227b82d
commit d7c25e3106
6 changed files with 101 additions and 64 deletions

View file

@ -42,10 +42,11 @@ const PICKLE_KEY = "DEFAULT_KEY";
export class Session { export class Session {
// sessionInfo contains deviceId, userId and homeServer // sessionInfo contains deviceId, userId and homeServer
constructor({clock, storage, hsApi, sessionInfo, olm, olmWorker, cryptoDriver}) { constructor({clock, storage, hsApi, sessionInfo, olm, olmWorker, cryptoDriver, mediaRepository}) {
this._clock = clock; this._clock = clock;
this._storage = storage; this._storage = storage;
this._hsApi = hsApi; this._hsApi = hsApi;
this._mediaRepository = mediaRepository;
this._syncInfo = null; this._syncInfo = null;
this._sessionInfo = sessionInfo; this._sessionInfo = sessionInfo;
this._rooms = new ObservableMap(); this._rooms = new ObservableMap();
@ -332,7 +333,8 @@ export class Session {
emitCollectionChange: this._roomUpdateCallback, emitCollectionChange: this._roomUpdateCallback,
hsApi: this._hsApi, hsApi: this._hsApi,
sendScheduler: this._sendScheduler, sendScheduler: this._sendScheduler,
pendingEvents, ._hsApi,
mediaRepository: this._mediaRep pendingEvents,
user: this._user, user: this._user,
createRoomEncryption: this._createRoomEncryption, createRoomEncryption: this._createRoomEncryption,
clock: this._clock clock: this._clock

View file

@ -19,6 +19,7 @@ import {ObservableValue} from "../observable/ObservableValue.js";
import {HomeServerApi} from "./net/HomeServerApi.js"; import {HomeServerApi} from "./net/HomeServerApi.js";
import {Reconnector, ConnectionStatus} from "./net/Reconnector.js"; import {Reconnector, ConnectionStatus} from "./net/Reconnector.js";
import {ExponentialRetryDelay} from "./net/ExponentialRetryDelay.js"; import {ExponentialRetryDelay} from "./net/ExponentialRetryDelay.js";
import {MediaRepository} from "./net/MediaRepository.js";
import {HomeServerError, ConnectionError, AbortError} from "./error.js"; import {HomeServerError, ConnectionError, AbortError} from "./error.js";
import {Sync, SyncStatus} from "./Sync.js"; import {Sync, SyncStatus} from "./Sync.js";
import {Session} from "./Session.js"; import {Session} from "./Session.js";
@ -158,9 +159,16 @@ export class SessionContainer {
if (this._workerPromise) { if (this._workerPromise) {
olmWorker = await this._workerPromise; olmWorker = await this._workerPromise;
} }
this._session = new Session({storage: this._storage, this._session = new Session({
sessionInfo: filteredSessionInfo, hsApi, olm, storage: this._storage,
clock: this._clock, olmWorker, cryptoDriver: this._cryptoDriver}); sessionInfo: filteredSessionInfo,
hsApi,
olm,
clock: this._clock,
olmWorker,
cryptoDriver: this._cryptoDriver,
mediaRepository: new MediaRepository(sessionInfo.homeServer)
});
await this._session.load(); await this._session.load();
this._status.set(LoadStatus.SessionSetup); this._status.set(LoadStatus.SessionSetup);
await this._session.beforeFirstSync(isNewLogin); await this._session.beforeFirstSync(isNewLogin);

View file

@ -1,5 +1,6 @@
/* /*
Copyright 2020 Bruno Windels <bruno@windels.cloud> Copyright 2020 Bruno Windels <bruno@windels.cloud>
Copyright 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -14,11 +15,8 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import { import {HomeServerError} from "../error.js";
HomeServerError, import {encodeQueryParams} from "./common.js";
ConnectionError,
AbortError
} from "../error.js";
class RequestWrapper { class RequestWrapper {
constructor(method, url, requestResult) { constructor(method, url, requestResult) {
@ -45,18 +43,6 @@ class RequestWrapper {
} }
} }
function encodeQueryParams(queryParams) {
return Object.entries(queryParams || {})
.filter(([, value]) => value !== undefined)
.map(([name, value]) => {
if (typeof value === "object") {
value = JSON.stringify(value);
}
return `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
})
.join("&");
}
export class HomeServerApi { export class HomeServerApi {
constructor({homeServer, accessToken, request, createTimeout, reconnector}) { constructor({homeServer, accessToken, request, createTimeout, reconnector}) {
// store these both in a closure somehow so it's harder to get at in case of XSS? // store these both in a closure somehow so it's harder to get at in case of XSS?
@ -66,7 +52,6 @@ export class HomeServerApi {
this._requestFn = request; this._requestFn = request;
this._createTimeout = createTimeout; this._createTimeout = createTimeout;
this._reconnector = reconnector; this._reconnector = reconnector;
this._mediaRepository = new MediaRepository(homeServer);
} }
_url(csPath) { _url(csPath) {
@ -196,45 +181,6 @@ export class HomeServerApi {
roomKeyForRoomAndSession(version, roomId, sessionId, options = null) { roomKeyForRoomAndSession(version, roomId, sessionId, options = null) {
return this._get(`/room_keys/keys/${encodeURIComponent(roomId)}/${encodeURIComponent(sessionId)}`, {version}, null, options); return this._get(`/room_keys/keys/${encodeURIComponent(roomId)}/${encodeURIComponent(sessionId)}`, {version}, null, options);
} }
get mediaRepository() {
return this._mediaRepository;
}
}
class MediaRepository {
constructor(homeserver) {
this._homeserver = homeserver;
}
mxcUrlThumbnail(url, width, height, method) {
const parts = this._parseMxcUrl(url);
if (parts) {
const [serverName, mediaId] = parts;
const httpUrl = `${this._homeserver}/_matrix/media/r0/thumbnail/${encodeURIComponent(serverName)}/${encodeURIComponent(mediaId)}`;
return httpUrl + "?" + encodeQueryParams({width, height, method});
}
return null;
}
mxcUrl(url) {
const parts = this._parseMxcUrl(url);
if (parts) {
const [serverName, mediaId] = parts;
return `${this._homeserver}/_matrix/media/r0/download/${encodeURIComponent(serverName)}/${encodeURIComponent(mediaId)}`;
} else {
return null;
}
}
_parseMxcUrl(url) {
const prefix = "mxc://";
if (url.startsWith(prefix)) {
return url.substr(prefix.length).split("/", 2);
} else {
return null;
}
}
} }
export function tests() { export function tests() {

View file

@ -0,0 +1,52 @@
/*
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.
*/
import {encodeQueryParams} from "./common.js";
export class MediaRepository {
constructor(homeserver) {
this._homeserver = homeserver;
}
mxcUrlThumbnail(url, width, height, method) {
const parts = this._parseMxcUrl(url);
if (parts) {
const [serverName, mediaId] = parts;
const httpUrl = `${this._homeserver}/_matrix/media/r0/thumbnail/${encodeURIComponent(serverName)}/${encodeURIComponent(mediaId)}`;
return httpUrl + "?" + encodeQueryParams({width, height, method});
}
return null;
}
mxcUrl(url) {
const parts = this._parseMxcUrl(url);
if (parts) {
const [serverName, mediaId] = parts;
return `${this._homeserver}/_matrix/media/r0/download/${encodeURIComponent(serverName)}/${encodeURIComponent(mediaId)}`;
} else {
return null;
}
}
_parseMxcUrl(url) {
const prefix = "mxc://";
if (url.startsWith(prefix)) {
return url.substr(prefix.length).split("/", 2);
} else {
return null;
}
}
}

28
src/matrix/net/common.js Normal file
View file

@ -0,0 +1,28 @@
/*
Copyright 2020 Bruno Windels <bruno@windels.cloud>
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 function encodeQueryParams(queryParams) {
return Object.entries(queryParams || {})
.filter(([, value]) => value !== undefined)
.map(([name, value]) => {
if (typeof value === "object") {
value = JSON.stringify(value);
}
return `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
})
.join("&");
}

View file

@ -31,11 +31,12 @@ import {DecryptionSource} from "../e2ee/common.js";
const EVENT_ENCRYPTED_TYPE = "m.room.encrypted"; const EVENT_ENCRYPTED_TYPE = "m.room.encrypted";
export class Room extends EventEmitter { export class Room extends EventEmitter {
constructor({roomId, storage, hsApi, emitCollectionChange, sendScheduler, pendingEvents, user, createRoomEncryption, getSyncToken, clock}) { constructor({roomId, storage, hsApi, mediaRepository, emitCollectionChange, sendScheduler, pendingEvents, user, createRoomEncryption, getSyncToken, clock}) {
super(); super();
this._roomId = roomId; this._roomId = roomId;
this._storage = storage; this._storage = storage;
this._hsApi = hsApi; this._hsApi = hsApi;
this._mediaRepository = mediaRepository;
this._summary = new RoomSummary(roomId, user.id); this._summary = new RoomSummary(roomId, user.id);
this._fragmentIdComparer = new FragmentIdComparer([]); this._fragmentIdComparer = new FragmentIdComparer([]);
this._syncWriter = new SyncWriter({roomId, fragmentIdComparer: this._fragmentIdComparer}); this._syncWriter = new SyncWriter({roomId, fragmentIdComparer: this._fragmentIdComparer});
@ -517,7 +518,7 @@ export class Room extends EventEmitter {
} }
get mediaRepository() { get mediaRepository() {
return this._hsApi.mediaRepository; return this._mediaRepository;
} }
/** @package */ /** @package */