move MediaRepository out of HomeServerApi
so HomeServerApi becomes easier to wrap, only having methods that return a RequestResult.
This commit is contained in:
parent
6cd227b82d
commit
d7c25e3106
6 changed files with 101 additions and 64 deletions
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
52
src/matrix/net/MediaRepository.js
Normal file
52
src/matrix/net/MediaRepository.js
Normal 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
28
src/matrix/net/common.js
Normal 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("&");
|
||||||
|
}
|
|
@ -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 */
|
||||||
|
|
Reference in a new issue