forked from mystiq/hydrogen-web
replace usage of readPath with ?.
This commit is contained in:
parent
6813fd2264
commit
2526198251
5 changed files with 19 additions and 142 deletions
|
@ -15,7 +15,6 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import {MessageTile} from "./MessageTile.js";
|
||||
import {readPath, Type} from "../../../../../utils/validate.js";
|
||||
|
||||
const MAX_HEIGHT = 300;
|
||||
const MAX_WIDTH = 400;
|
||||
|
@ -27,40 +26,38 @@ export class ImageTile extends MessageTile {
|
|||
}
|
||||
|
||||
get thumbnailUrl() {
|
||||
try {
|
||||
const mxcUrl = readPath(this._getContent(), ["url"], Type.String);
|
||||
const mxcUrl = this._getContent()?.url;
|
||||
if (typeof mxcUrl === "string") {
|
||||
return this._room.mxcUrlThumbnail(mxcUrl, this.thumbnailWidth, this.thumbnailHeight, "scale");
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
get url() {
|
||||
try {
|
||||
const mxcUrl = readPath(this._getContent(), ["url"], Type.String);
|
||||
const mxcUrl = this._getContent()?.url;
|
||||
if (typeof mxcUrl === "string") {
|
||||
return this._room.mxcUrl(mxcUrl);
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
_scaleFactor() {
|
||||
const {info} = this._getContent();
|
||||
const scaleHeightFactor = MAX_HEIGHT / info.h;
|
||||
const scaleWidthFactor = MAX_WIDTH / info.w;
|
||||
const info = this._getContent()?.info;
|
||||
const scaleHeightFactor = MAX_HEIGHT / info?.h;
|
||||
const scaleWidthFactor = MAX_WIDTH / info?.w;
|
||||
// take the smallest scale factor, to respect all constraints
|
||||
// we should not upscale images, so limit scale factor to 1 upwards
|
||||
return Math.min(scaleWidthFactor, scaleHeightFactor, 1);
|
||||
}
|
||||
|
||||
get thumbnailWidth() {
|
||||
const {info} = this._getContent();
|
||||
return Math.round(info.w * this._scaleFactor());
|
||||
const info = this._getContent()?.info;
|
||||
return Math.round(info?.w * this._scaleFactor());
|
||||
}
|
||||
|
||||
get thumbnailHeight() {
|
||||
const {info} = this._getContent();
|
||||
return Math.round(info.h * this._scaleFactor());
|
||||
const info = this._getContent()?.info;
|
||||
return Math.round(info?.h * this._scaleFactor());
|
||||
}
|
||||
|
||||
get label() {
|
||||
|
|
|
@ -18,7 +18,6 @@ limitations under the License.
|
|||
import {AbortError} from "./error.js";
|
||||
import {ObservableValue} from "../observable/ObservableValue.js";
|
||||
import {createEnum} from "../utils/enum.js";
|
||||
import {readPath, Type} from "../utils/validate.js";
|
||||
|
||||
const INCREMENTAL_TIMEOUT = 30000;
|
||||
const SYNC_EVENT_LIMIT = 10;
|
||||
|
@ -47,8 +46,8 @@ function parseRooms(roomsSection, roomCallback) {
|
|||
|
||||
function timelineIsEmpty(roomResponse) {
|
||||
try {
|
||||
const events = readPath(roomResponse, ["timeline", "events"], Type.Array);
|
||||
return events.length === 0;
|
||||
const events = roomResponse?.timeline?.events;
|
||||
return Array.isArray(events) && events.length === 0;
|
||||
} catch (err) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -35,8 +35,7 @@ export class EventEntry extends BaseEntry {
|
|||
}
|
||||
|
||||
get prevContent() {
|
||||
const unsigned = this._eventEntry.event.unsigned;
|
||||
return unsigned && unsigned.prev_content;
|
||||
return this._eventEntry.event.unsigned?.prev_content;
|
||||
}
|
||||
|
||||
get eventType() {
|
||||
|
|
|
@ -15,13 +15,12 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import { StorageError } from "../common.js";
|
||||
import { readPath } from "../../../utils/validate.js";
|
||||
|
||||
class WrappedDOMException extends StorageError {
|
||||
constructor(request) {
|
||||
// protect against browsers not implementing any of these properties by using readPath
|
||||
const storeName = readPath(request, ["source", "name"], "<unknown store>");
|
||||
const databaseName = readPath(request, ["source", "transaction", "db", "name"], "<unknown db>");
|
||||
const source = request?.source;
|
||||
const storeName = source?.name || "<unknown store>";
|
||||
const databaseName = source?.transaction?.db?.name || "<unknown db>";
|
||||
super(`Failed IDBRequest on ${databaseName}.${storeName}`, request.error);
|
||||
this.storeName = storeName;
|
||||
this.databaseName = databaseName;
|
||||
|
|
|
@ -1,117 +0,0 @@
|
|||
/*
|
||||
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 class InvalidPathError extends Error {
|
||||
constructor(obj, path, field) {
|
||||
super(`Could not read path ${path.join("/")}, stopped at ${field}. Base value is ${obj}`);
|
||||
}
|
||||
|
||||
get name() {
|
||||
return "InvalidPathError";
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidTypeError extends Error {
|
||||
constructor(path, fieldValue, validator) {
|
||||
super(`Value ${path.join("/")} is not of type ${getTypeName(validator)} but is: ${fieldValue}`);
|
||||
}
|
||||
|
||||
get name() {
|
||||
return "InvalidTypeError";
|
||||
}
|
||||
}
|
||||
|
||||
function getTypeName(validator) {
|
||||
if (validator === Type.Array) {
|
||||
return "Array";
|
||||
}
|
||||
if (validator === Type.Integer) {
|
||||
return "Integer";
|
||||
}
|
||||
if (validator === Type.String) {
|
||||
return "String";
|
||||
}
|
||||
if (validator === Type.Object) {
|
||||
return "Object";
|
||||
}
|
||||
if (typeof validator === "function") {
|
||||
return "Custom";
|
||||
}
|
||||
return "None";
|
||||
}
|
||||
|
||||
export function readPath(obj, path, typeOrDefaultValue) {
|
||||
if (!obj) {
|
||||
throw new InvalidPathError(obj, path);
|
||||
}
|
||||
const hasDefaultValue = typeof typeOrDefaultValue !== "function";
|
||||
let currentValue = obj;
|
||||
for (const field of path) {
|
||||
currentValue = currentValue[field];
|
||||
if (typeof currentValue === "undefined") {
|
||||
if (hasDefaultValue) {
|
||||
return typeOrDefaultValue;
|
||||
} else {
|
||||
throw new InvalidPathError(obj, path, field);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!hasDefaultValue) {
|
||||
const validator = typeOrDefaultValue;
|
||||
if (!validator(currentValue)) {
|
||||
throw new InvalidTypeError(path, currentValue, validator);
|
||||
}
|
||||
}
|
||||
return currentValue;
|
||||
}
|
||||
|
||||
export const Type = Object.freeze({
|
||||
"Array": Array.isArray,
|
||||
"Integer": Number.isSafeInteger,
|
||||
"Boolean": value => value === true || value === false,
|
||||
"String": value => typeof value === "string",
|
||||
"Object": value => value !== null && typeof value === "object",
|
||||
});
|
||||
|
||||
export function tests() {
|
||||
return {
|
||||
"readPath value at top level": assert => {
|
||||
assert.strictEqual(readPath({a: 5}, ["a"]), 5);
|
||||
},
|
||||
"readPath value at deep level": assert => {
|
||||
assert.strictEqual(readPath({a: {b: {c: 5}}}, ["a", "b", "c"]), 5);
|
||||
},
|
||||
"readPath value with correct type": assert => {
|
||||
assert.strictEqual(readPath({a: 5}, ["a"], Type.Integer), 5);
|
||||
},
|
||||
"readPath value with failing type": assert => {
|
||||
assert.throws(
|
||||
() => readPath({a: 5}, ["a"], Type.String),
|
||||
{name: "InvalidTypeError"}
|
||||
);
|
||||
},
|
||||
"readPath value with failing path with intermediate field not being an object": assert => {
|
||||
assert.throws(
|
||||
() => readPath({a: {b: "bar"}}, ["a", "b", "c"], Type.Integer),
|
||||
{name: "InvalidPathError"}
|
||||
);
|
||||
},
|
||||
"readPath returns default value for incomplete path": assert => {
|
||||
assert.strictEqual(readPath({a: {b: "bar"}}, ["a", "b", "c"], 5), 5);
|
||||
},
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue