Skip to content

Conversation

@vpzomtrrfrt
Copy link

@vpzomtrrfrt vpzomtrrfrt commented Sep 19, 2023

Hopefully a step toward jitsi/jitsi-meet#13776

Example RoomFileInterface might look like this: (Assuming localhost:9000 is running a simple writable file server (I tested with MinIO). note: this example doesn't handle encryption)

const FILES_URL = "http://localhost:9000/exc-test";

function fetchWithError(...args) {
    return fetch(...args)
        .then(res => {
            if(res.status < 200 || res.status >= 300) {
                return res.text()
                    .then(text => {
                        throw new Error(text);
                    });
            }
            return res;
        });
}

const roomFileInterface = {
    async saveFiles(roomId, roomKey, data) {
        const erroredFiles = new Map();
        const savedFiles = new Map();

        await Promise.all(Array.from(data.addedFiles, async ([id, data]) => {
            try {
                const content = await fetchWithError(data.dataURL).then(res => res.blob());
                await fetchWithError(
                    FILES_URL + "/" + encodeURIComponent(roomId) + "/" + encodeURIComponent(id),
                    {method: "PUT", headers: {"Content-Type": data.mimeType}, body: content},
                );
                savedFiles.set(id, true);
            } catch(ex) {
                console.error(ex);
                erroredFiles.set(id, true);
            }
        }));

        console.log(erroredFiles, savedFiles);

        return {erroredFiles, savedFiles};
    },
    async getFiles(roomId, roomKey, fileIds) {
        const erroredFiles = new Map();
        const loadedFiles = [];

        await Promise.all(fileIds.map(async (id) => {
            try {
                const res = await fetchWithError(
                    FILES_URL + "/" + encodeURIComponent(roomId) + "/" + encodeURIComponent(id),
                );
                loadedFiles.push({
                    mimeType: res.headers.get("Content-Type"),
                    id,
                    created: new Date(res.headers.get("Date")).getTime(),
                    dataURL: await res.blob()
                        .then(blob => {
                            // I would hope there's a better way to do this but I couldn't find one
                            return new Promise((resolve, reject) => {
                                const reader = new FileReader();
                                reader.addEventListener("load", () => {
                                    resolve(reader.result);
                                });
                                reader.addEventListener("error", reject);
                                reader.readAsDataURL(blob);
                            });
                        }),
                });
            } catch(ex) {
                console.error(ex);
                erroredFiles.set(id, true);
            }
        }));

        return {erroredFiles, loadedFiles};
    },
};

@vpzomtrrfrt
Copy link
Author

vpzomtrrfrt commented Sep 19, 2023

Or maybe the encryption should be a level deeper and the RoomFileInterface would just deal with the encrypted blobs? Since otherwise the encryption code would need to be exposed somehow

@saghul
Copy link
Member

saghul commented Sep 20, 2023

Could you please submit this upstream too?

I think the broader Excalidraw community would benefit from it and it would allow us to keep a simpler fork.

@vpzomtrrfrt
Copy link
Author

vpzomtrrfrt commented Sep 20, 2023

Looks like the upstream package doesn't actually expose collaboration to embedders, so I don't know where this would fit in there

Several other approaches have been taken in various forks but apparently never merged

@saghul
Copy link
Member

saghul commented Sep 20, 2023

IMHO getting the conversation started at least would be helpful.

We have not been successful in that front FWIW.

@vpzomtrrfrt
Copy link
Author

Well excalidraw#6426 is still open, but this comment from 2021 said they don't plan to accept such a change

Their expectation for embedding pages seems to be for everyone to separately reimplement the collaboration feature

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants