forked from mystiq/hydrogen-web
add setting for image compression level
This commit is contained in:
parent
764cddcdec
commit
9ab81eea02
7 changed files with 88 additions and 3 deletions
|
@ -200,7 +200,11 @@ export class RoomViewModel extends ViewModel {
|
||||||
if (!file.blob.mimeType.startsWith("image/")) {
|
if (!file.blob.mimeType.startsWith("image/")) {
|
||||||
return this._sendFile(file);
|
return this._sendFile(file);
|
||||||
}
|
}
|
||||||
const image = await this.platform.loadImage(file.blob);
|
let image = await this.platform.loadImage(file.blob);
|
||||||
|
const limit = await this.platform.settingsStorage.getInt("sentImageSizeLimit");
|
||||||
|
if (limit && image.maxDimension > limit) {
|
||||||
|
image = await image.scale(limit);
|
||||||
|
}
|
||||||
const content = {
|
const content = {
|
||||||
body: file.name,
|
body: file.name,
|
||||||
msgtype: "m.image",
|
msgtype: "m.image",
|
||||||
|
|
|
@ -36,10 +36,26 @@ export class SettingsViewModel extends ViewModel {
|
||||||
this._sessionBackupViewModel = this.track(new SessionBackupViewModel(this.childOptions({session})));
|
this._sessionBackupViewModel = this.track(new SessionBackupViewModel(this.childOptions({session})));
|
||||||
this._closeUrl = this.urlCreator.urlUntilSegment("session");
|
this._closeUrl = this.urlCreator.urlUntilSegment("session");
|
||||||
this._estimate = null;
|
this._estimate = null;
|
||||||
|
|
||||||
|
this.sentImageSizeLimit = null;
|
||||||
|
this.minSentImageSizeLimit = 400;
|
||||||
|
this.maxSentImageSizeLimit = 4000;
|
||||||
|
}
|
||||||
|
|
||||||
|
setSentImageSizeLimit(size) {
|
||||||
|
if (size > this.maxSentImageSizeLimit || size < this.minSentImageSizeLimit) {
|
||||||
|
this.sentImageSizeLimit = null;
|
||||||
|
this.platform.settingsStorage.remove("sentImageSizeLimit");
|
||||||
|
} else {
|
||||||
|
this.sentImageSizeLimit = Math.round(size);
|
||||||
|
this.platform.settingsStorage.setInt("sentImageSizeLimit", size);
|
||||||
|
}
|
||||||
|
this.emitChange("sentImageSizeLimit");
|
||||||
}
|
}
|
||||||
|
|
||||||
async load() {
|
async load() {
|
||||||
this._estimate = await this.platform.estimateStorageUsage();
|
this._estimate = await this.platform.estimateStorageUsage();
|
||||||
|
this.sentImageSizeLimit = await this.platform.settingsStorage.getInt("sentImageSizeLimit");
|
||||||
this.emitChange("");
|
this.emitChange("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ import {createFetchRequest} from "./dom/request/fetch.js";
|
||||||
import {xhrRequest} from "./dom/request/xhr.js";
|
import {xhrRequest} from "./dom/request/xhr.js";
|
||||||
import {StorageFactory} from "../../matrix/storage/idb/StorageFactory.js";
|
import {StorageFactory} from "../../matrix/storage/idb/StorageFactory.js";
|
||||||
import {SessionInfoStorage} from "../../matrix/sessioninfo/localstorage/SessionInfoStorage.js";
|
import {SessionInfoStorage} from "../../matrix/sessioninfo/localstorage/SessionInfoStorage.js";
|
||||||
|
import {SettingsStorage} from "./dom/SettingsStorage.js";
|
||||||
import {OlmWorker} from "../../matrix/e2ee/OlmWorker.js";
|
import {OlmWorker} from "../../matrix/e2ee/OlmWorker.js";
|
||||||
import {RootView} from "./ui/RootView.js";
|
import {RootView} from "./ui/RootView.js";
|
||||||
import {Clock} from "./dom/Clock.js";
|
import {Clock} from "./dom/Clock.js";
|
||||||
|
@ -78,7 +79,6 @@ async function loadOlmWorker(paths) {
|
||||||
return olmWorker;
|
return olmWorker;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export class Platform {
|
export class Platform {
|
||||||
constructor(container, paths, cryptoExtras = null) {
|
constructor(container, paths, cryptoExtras = null) {
|
||||||
this._paths = paths;
|
this._paths = paths;
|
||||||
|
@ -94,6 +94,7 @@ export class Platform {
|
||||||
this.crypto = new Crypto(cryptoExtras);
|
this.crypto = new Crypto(cryptoExtras);
|
||||||
this.storageFactory = new StorageFactory(this._serviceWorkerHandler);
|
this.storageFactory = new StorageFactory(this._serviceWorkerHandler);
|
||||||
this.sessionInfoStorage = new SessionInfoStorage("hydrogen_sessions_v1");
|
this.sessionInfoStorage = new SessionInfoStorage("hydrogen_sessions_v1");
|
||||||
|
this.settingsStorage = new SettingsStorage("hydrogen_setting_v1_");
|
||||||
this.estimateStorageUsage = estimateStorageUsage;
|
this.estimateStorageUsage = estimateStorageUsage;
|
||||||
this.random = Math.random;
|
this.random = Math.random;
|
||||||
if (typeof fetch === "function") {
|
if (typeof fetch === "function") {
|
||||||
|
|
37
src/platform/web/dom/SettingsStorage.js
Normal file
37
src/platform/web/dom/SettingsStorage.js
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
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 SettingsStorage {
|
||||||
|
constructor(prefix) {
|
||||||
|
this._prefix = prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
async setInt(key, value) {
|
||||||
|
window.localStorage.setItem(`${this._prefix}${key}`, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getInt(key) {
|
||||||
|
const value = window.localStorage.getItem(`${this._prefix}${key}`);
|
||||||
|
if (typeof value === "string") {
|
||||||
|
return parseInt(value, 10);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
async remove(key) {
|
||||||
|
window.localStorage.removeItem(`${this._prefix}${key}`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -677,6 +677,7 @@ only loads when the top comes into view*/
|
||||||
|
|
||||||
.Settings .row .content {
|
.Settings .row .content {
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Settings .row.code .content {
|
.Settings .row.code .content {
|
||||||
|
@ -688,6 +689,12 @@ only loads when the top comes into view*/
|
||||||
margin: 0 8px;
|
margin: 0 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.Settings .row .content input[type=range] {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 300px;
|
||||||
|
min-width: 160px;
|
||||||
|
}
|
||||||
|
|
||||||
.Settings .row {
|
.Settings .row {
|
||||||
margin: 4px 0px;
|
margin: 4px 0px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -94,7 +94,7 @@ export const TAG_NAMES = {
|
||||||
[HTML_NS]: [
|
[HTML_NS]: [
|
||||||
"br", "a", "ol", "ul", "li", "div", "h1", "h2", "h3", "h4", "h5", "h6",
|
"br", "a", "ol", "ul", "li", "div", "h1", "h2", "h3", "h4", "h5", "h6",
|
||||||
"p", "strong", "em", "span", "img", "section", "main", "article", "aside",
|
"p", "strong", "em", "span", "img", "section", "main", "article", "aside",
|
||||||
"pre", "button", "time", "input", "textarea", "label", "form", "progress"],
|
"pre", "button", "time", "input", "textarea", "label", "form", "progress", "output"],
|
||||||
[SVG_NS]: ["svg", "circle"]
|
[SVG_NS]: ["svg", "circle"]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -46,10 +46,30 @@ export class SettingsView extends TemplateView {
|
||||||
row(vm.i18n`Session key`, vm.fingerprintKey, "code"),
|
row(vm.i18n`Session key`, vm.fingerprintKey, "code"),
|
||||||
t.h3("Session Backup"),
|
t.h3("Session Backup"),
|
||||||
t.view(new SessionBackupSettingsView(vm.sessionBackupViewModel)),
|
t.view(new SessionBackupSettingsView(vm.sessionBackupViewModel)),
|
||||||
|
t.h3("Preferences"),
|
||||||
|
row(vm.i18n`Compress images when sending`, this._imageCompressionRange(t, vm)),
|
||||||
t.h3("Application"),
|
t.h3("Application"),
|
||||||
row(vm.i18n`Version`, version),
|
row(vm.i18n`Version`, version),
|
||||||
row(vm.i18n`Storage usage`, vm => `${vm.storageUsage} / ${vm.storageQuota}`),
|
row(vm.i18n`Storage usage`, vm => `${vm.storageUsage} / ${vm.storageQuota}`),
|
||||||
])
|
])
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_imageCompressionRange(t, vm) {
|
||||||
|
const step = 32;
|
||||||
|
const min = Math.ceil(vm.minSentImageSizeLimit / step) * step;
|
||||||
|
const max = (Math.floor(vm.maxSentImageSizeLimit / step) + 1) * step;
|
||||||
|
return [t.input({
|
||||||
|
type: "range",
|
||||||
|
step,
|
||||||
|
min,
|
||||||
|
max,
|
||||||
|
value: vm => vm.sentImageSizeLimit || max,
|
||||||
|
onInput: evt => vm.setSentImageSizeLimit(parseInt(evt.target.value, 10)),
|
||||||
|
}), " ", t.output(vm => {
|
||||||
|
return vm.sentImageSizeLimit ?
|
||||||
|
vm.i18n`resize to ${vm.sentImageSizeLimit}px` :
|
||||||
|
vm.i18n`no compression`;
|
||||||
|
})];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue