editor: fix bugginess

Signed-off-by: Varun Patil <varunpatil@ucla.edu>
pull/579/head
Varun Patil 2023-04-16 10:02:51 -07:00
parent 7e88bc4248
commit 8c947000a5
6 changed files with 68 additions and 29 deletions

View File

@ -29,8 +29,9 @@ build-js-production:
rm -f js/* && npm run build rm -f js/* && npm run build
patch-external: patch-external:
patch -p1 < patches/scroller-perf.patch patch -p1 -N < patches/scroller-perf.patch || true
patch -p1 < patches/scroller-sticky.patch patch -p1 -N < patches/scroller-sticky.patch || true
bash ./patches/filerobot-patch.sh
watch-js: watch-js:
npm run watch npm run watch

View File

@ -0,0 +1,22 @@
/**
* Filerobot has issues with loading images from HTML elements.
* We need to wait for the react object to be created properly before loading.
* This is a monkey patch to select an existing image using a global, but after wait.
*/
import loadImageOriginal from './loadImageOriginal.js';
var loadImage = function() {
const image = globalThis._fileRobotOverrideImage;
if (image) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(image);
}, 0);
});
}
return loadImageOriginal.apply(this, arguments);
}
export default loadImage;

View File

@ -0,0 +1,17 @@
#!/bin/bash
target="node_modules/react-filerobot-image-editor/lib/utils"
if [ -f $target/loadImageOriginal.js ]; then
echo "Filerobot is already patched, copying patch again ..."
else
if [ ! -f $target/loadImage.js ]; then
echo "Filerobot not installed or patch outdated"
exit 1
fi
echo "Patching filerobot-image-editor ..."
cp $target/loadImage.js $target/loadImageOriginal.js
fi
cp patches/filerobot-loadImage.js $target/loadImage.js

View File

@ -52,7 +52,10 @@ export default defineComponent({
computed: { computed: {
config(): FilerobotImageEditorConfig & { theme: any } { config(): FilerobotImageEditorConfig & { theme: any } {
return { return {
source: "nonexistent", source:
this.photo.h && this.photo.w
? utils.getPreviewUrl(this.photo, false, "screen")
: API.IMAGE_DECODABLE(this.photo.fileid, this.photo.etag),
defaultSavedImageName: this.defaultSavedImageName, defaultSavedImageName: this.defaultSavedImageName,
defaultSavedImageType: this.defaultSavedImageType, defaultSavedImageType: this.defaultSavedImageType,
@ -145,10 +148,9 @@ export default defineComponent({
async mounted() { async mounted() {
await loadFilerobot(); await loadFilerobot();
const div = <HTMLElement>this.$refs.editor; globalThis._fileRobotOverrideImage = await this.getImage();
const config = this.config;
config.source = await this.getImg();
const div = <HTMLElement>this.$refs.editor;
this.imageEditor = new FilerobotImageEditor(div, this.config); this.imageEditor = new FilerobotImageEditor(div, this.config);
this.imageEditor.render(); this.imageEditor.render();
@ -160,29 +162,25 @@ export default defineComponent({
if (this.imageEditor) { if (this.imageEditor) {
this.imageEditor.terminate(); this.imageEditor.terminate();
} }
globalThis._fileRobotOverrideImage = undefined;
window.removeEventListener("keydown", this.handleKeydown, true); window.removeEventListener("keydown", this.handleKeydown, true);
}, },
methods: { methods: {
async getImg(): Promise<any> { async getImage(): Promise<HTMLImageElement> {
if (this.photo.w && this.photo.h) { const img = new Image();
// Fetch the image to a blob
const preview = utils.getPreviewUrl(this.photo, false, 2048);
// Fetch preview image await new Promise(async (resolve) => {
const img = new Image(); img.onload = resolve;
img.src = await fetchImage(<string>this.config.source);
});
if (this.photo.w && this.photo.h) {
img.height = this.photo.h; img.height = this.photo.h;
img.width = this.photo.w; img.width = this.photo.w;
await new Promise(async (resolve) => {
img.onload = resolve;
img.src = await fetchImage(preview);
});
return img;
} }
// If we don't have the size, we need to use the original image return img;
return API.IMAGE_DECODABLE(this.photo.fileid, this.photo.etag);
}, },
onClose(closingReason, haveNotSavedChanges) { onClose(closingReason, haveNotSavedChanges) {
@ -241,13 +239,9 @@ export default defineComponent({
// Success, emit an appropriate event // Success, emit an appropriate event
showSuccess(this.t("memories", "Image saved successfully")); showSuccess(this.t("memories", "Image saved successfully"));
console.log(state);
if (fileid !== this.photo.fileid) { if (fileid !== this.photo.fileid) {
console.log("Fileid changed", fileid);
emit("files:file:created", { fileid }); emit("files:file:created", { fileid });
} else { } else {
console.log("Fileid unchanged", fileid);
emit("files:file:updated", { fileid }); emit("files:file:updated", { fileid });
} }
this.onClose(undefined, false); this.onClose(undefined, false);

View File

@ -779,10 +779,7 @@ export default defineComponent({
/** Get base data object */ /** Get base data object */
getItemData(photo: IPhoto) { getItemData(photo: IPhoto) {
const sw = Math.floor(screen.width * devicePixelRatio); let previewUrl = utils.getPreviewUrl(photo, false, "screen");
const sh = Math.floor(screen.height * devicePixelRatio);
let previewUrl = utils.getPreviewUrl(photo, false, [sw, sh]);
const isvideo = photo.flag & this.c.FLAG_IS_VIDEO; const isvideo = photo.flag & this.c.FLAG_IS_VIDEO;
// Preview aren't animated // Preview aren't animated

View File

@ -5,8 +5,16 @@ import { API } from "../API";
export function getPreviewUrl( export function getPreviewUrl(
photo: IPhoto, photo: IPhoto,
square: boolean, square: boolean,
size: number | [number, number] size: number | [number, number] | "screen"
) { ) {
// Screen-appropriate size
if (size === "screen") {
const sw = Math.floor(screen.width * devicePixelRatio);
const sh = Math.floor(screen.height * devicePixelRatio);
size = [sw, sh];
}
// Convert to array
const [x, y] = typeof size === "number" ? [size, size] : size; const [x, y] = typeof size === "number" ? [size, size] : size;
return API.Q(API.IMAGE_PREVIEW(photo.fileid), { return API.Q(API.IMAGE_PREVIEW(photo.fileid), {