0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2025-12-24 14:12:40 +00:00

Cleanup and better handling of pre-save snapshot

This commit is contained in:
Trevor Buckner
2025-07-08 15:50:27 -04:00
parent 41daf8d172
commit 6414e73e7d
2 changed files with 43 additions and 47 deletions

View File

@@ -200,13 +200,17 @@ const EditPage = createClass({
if(!this.debounceSave) this.debounceSave = _.debounce(this.save, SAVE_TIMEOUT);
if(this.state.isSaving)
return;
if(immediate) {
this.debounceSave();
this.debounceSave.flush();
return;
}
if(this.hasChanges())
this.debounceSave();
else
this.debounceSave.cancel();
if(immediate) this.debounceSave.flush();
},
handleGoogleClick : function(){
@@ -252,33 +256,17 @@ const EditPage = createClass({
await updateHistory(this.state.brew).catch(console.error);
await versionHistoryGarbageCollection().catch(console.error);
const transfer = this.state.saveGoogle == _.isNil(this.state.brew.googleId);
const brew = { ...this.state.brew };
let jsonString = JSON.stringify(brew);
let bytes = new TextEncoder().encode(jsonString).length;
console.log(`Before size: ${bytes} bytes (${(bytes / 1024).toFixed(2)} KB)`);
const preSaveSnapshot = { ...this.state.brew }
//Prepare content to send to server
const brew = { ...this.state.brew };
brew.pageCount = ((brew.renderer=='legacy' ? brew.text.match(/\\page/g) : brew.text.match(/^\\page$/gm)) || []).length + 1;
brew.patches = makePatches(this.savedBrew.text, brew.text);
brew.hash = await md5(this.savedBrew.text);
brew.text = undefined;
brew.textBin = undefined;
brew.patches = makePatches(this.savedBrew.text, brew.text);
brew.hash = await md5(this.savedBrew.text);
brew.text = undefined;
brew.textBin = undefined;
console.log('Saving Brew', brew);
jsonString = JSON.stringify(brew);
bytes = new TextEncoder().encode(jsonString).length;
console.log(`After size: ${bytes} bytes (${(bytes / 1024).toFixed(2)} KB)`);
jsonString = JSON.stringify(brew.patches);
bytes = new TextEncoder().encode(jsonString).length;
console.log(`Patch size: ${bytes} bytes (${(bytes / 1024).toFixed(2)} KB)`);
const transfer = this.state.saveGoogle == _.isNil(this.state.brew.googleId);
const params = `${transfer ? `?${this.state.saveGoogle ? 'saveToGoogle' : 'removeFromGoogle'}=true` : ''}`;
const res = await request
.put(`/api/update/${brew.editId}${params}`)
@@ -290,20 +278,28 @@ const EditPage = createClass({
if(!res) return;
this.savedBrew = {
...this.state.brew,
...preSaveSnapshot,
googleId : res.body.googleId ? res.body.googleId : null,
editId : res.body.editId,
shareId : res.body.shareId,
version : res.body.version
};
history.replaceState(null, null, `/edit/${this.savedBrew.editId}`);
this.setState(()=>({
brew : this.savedBrew,
unsavedChanges : false,
this.setState((prevState) => ({
brew: {
...prevState.brew,
googleId : res.body.googleId ? res.body.googleId : null,
editId : res.body.editId,
shareId : res.body.shareId,
version : res.body.version
},
isSaving : false,
unsavedTime : new Date()
}));
}), ()=>{
this.setState({ unsavedChanges : this.hasChanges() });
});
history.replaceState(null, null, `/edit/${this.savedBrew.editId}`);
},
renderGoogleDriveIcon : function(){

View File

@@ -339,30 +339,30 @@ const api = {
// Initialize brew from request and body, destructure query params, and set the initial value for the after-save method
const brewFromClient = api.excludePropsFromUpdate(req.body);
const brewFromServer = req.brew;
const serverHash = md5(brewFromServer.text);
console.log({serverHash: serverHash});
console.log({clientHash: brewFromClient.hash});
splitTextStyleAndMetadata(brewFromServer);
if((brewFromServer?.version !== brewFromClient?.version)) {
console.log(`Version mismatch on brew ${brewFromClient.editId}`);
brewFromServer.hash = await md5(brewFromServer.text);
if((brewFromServer?.version !== brewFromClient?.version) || (brewFromServer?.hash !== brewFromClient?.hash)) {
if(brewFromClient?.version !== brewFromClient?.version)
console.log(`Version mismatch on brew ${brewFromClient.editId}`);
if(brewFromServer?.hash !== brewFromClient?.hash) {
console.log(`Hash mismatch on brew ${brewFromClient.editId}`);
}
res.setHeader('Content-Type', 'application/json');
return res.status(409).send(JSON.stringify({ message: `The server copy is out of sync with the saved brew. Please save your changes elsewhere, refresh, and try again.` }));
}
let brew = _.assign(brewFromServer, brewFromClient);
brew.title = brew.title.trim();
brew.description = brew.description.trim() || '';
brew.text = applyPatches(brewFromClient.patches, brewFromServer.text)[0];
brew.text = api.mergeBrewText(brew);
console.log(`Brewfromserver: ${JSON.stringify(brewFromServer)}`);
splitTextStyleAndMetadata(brewFromServer);
brewFromClient.text = applyPatches(brewFromClient.patches, brewFromServer.text)[0];
console.log(`Server Text: ${brewFromServer.text}`);
console.log(`Brew text: ${brewFromClient.text}`);
let brew = _.assign(brewFromServer, brewFromClient);
const googleId = brew.googleId;
const { saveToGoogle, removeFromGoogle } = req.query;
let afterSave = async ()=>true;
brew.title = brew.title.trim();
brew.description = brew.description.trim() || '';
brew.text = api.mergeBrewText(brew);
if(brew.googleId && removeFromGoogle) {
// If the google id exists and we're removing it from google, set afterSave to delete the google brew and mark the brew's google id as undefined
afterSave = async ()=>{