Skip to content

Commit 64ce3fa

Browse files
committed
Use etag as cache buster
Signed-off-by: Louis Chemineau <louis@chmn.me>
1 parent a50e7ad commit 64ce3fa

11 files changed

Lines changed: 155 additions & 40 deletions

File tree

js/viewer-main.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

js/viewer-main.js.LICENSE.txt

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,50 @@
9090
*
9191
*/
9292

93+
/**
94+
* @copyright Copyright (c) 2021 John Molakvoæ <skjnldsv@protonmail.com>
95+
*
96+
* @author John Molakvoæ <skjnldsv@protonmail.com>
97+
*
98+
* @license AGPL-3.0-or-later
99+
*
100+
* This program is free software: you can redistribute it and/or modify
101+
* it under the terms of the GNU Affero General Public License as
102+
* published by the Free Software Foundation, either version 3 of the
103+
* License, or (at your option) any later version.
104+
*
105+
* This program is distributed in the hope that it will be useful,
106+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
107+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
108+
* GNU Affero General Public License for more details.
109+
*
110+
* You should have received a copy of the GNU Affero General Public License
111+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
112+
*
113+
*/
114+
115+
/**
116+
* @copyright Copyright (c) 2022 John Molakvoæ <skjnldsv@protonmail.com>
117+
*
118+
* @author John Molakvoæ <skjnldsv@protonmail.com>
119+
*
120+
* @license AGPL-3.0-or-later
121+
*
122+
* This program is free software: you can redistribute it and/or modify
123+
* it under the terms of the GNU Affero General Public License as
124+
* published by the Free Software Foundation, either version 3 of the
125+
* License, or (at your option) any later version.
126+
*
127+
* This program is distributed in the hope that it will be useful,
128+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
129+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
130+
* GNU Affero General Public License for more details.
131+
*
132+
* You should have received a copy of the GNU Affero General Public License
133+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
134+
*
135+
*/
136+
93137
/**
94138
* @license nested-property https://github.com/cosmosio/nested-property
95139
*

js/viewer-main.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package-lock.json

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
"@nextcloud/axios": "^2.3.0",
4747
"@nextcloud/dialogs": "^4.0.1",
4848
"@nextcloud/event-bus": "^3.0.2",
49+
"@nextcloud/files": "^3.0.0-beta.10",
4950
"@nextcloud/initial-state": "^2.0.0",
5051
"@nextcloud/l10n": "^2.1.0",
5152
"@nextcloud/logger": "^2.5.0",

src/components/ImageEditor.vue

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ import { basename, dirname, extname, join } from 'path'
66
import { emit } from '@nextcloud/event-bus'
77
import { showError, showSuccess } from '@nextcloud/dialogs'
88
import axios from '@nextcloud/axios'
9+
import { Node } from '@nextcloud/files'
910
1011
import logger from '../services/logger.js'
1112
import translations from '../models/editorTranslations.js'
13+
import { rawStat } from '../services/FileInfo.js'
1214
1315
let TABS, TOOLS
1416
@@ -179,7 +181,20 @@ export default {
179181
emit('files:node:created', { fileid: parseInt(response?.headers?.['oc-fileid']?.split('oc')[0]) || null })
180182
} else {
181183
this.$emit('updated')
182-
emit('files:node:updated', { fileid: this.fileid })
184+
const updatedFile = await rawStat(origin, decodeURI(pathname))
185+
186+
const node = new Node({
187+
id: Number.parseInt(this.fileid),
188+
source: this.src,
189+
mtime: new Date(updatedFile.lastmod),
190+
...updatedFile,
191+
attributes: {
192+
...updatedFile,
193+
...updatedFile.props,
194+
},
195+
})
196+
197+
emit('files:node:updated', { fileid: this.fileid, node })
183198
}
184199
} catch (error) {
185200
logger.error('Error saving image', { error })

src/components/Images.vue

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
:mime="mime"
2626
:src="src"
2727
:fileid="fileid"
28-
@updated="onUpdate"
2928
@close="onClose" />
3029

3130
<img v-else-if="data !== null"
@@ -35,7 +34,7 @@
3534
loaded,
3635
zoomed: zoomRatio !== 1
3736
}"
38-
:src="`${data}${cacheBuster}`"
37+
:src="data"
3938
:style="{
4039
marginTop: shiftY + 'px',
4140
marginLeft: shiftX + 'px',
@@ -82,8 +81,6 @@ export default {
8281
shiftY: 0,
8382
zoomRatio: 1,
8483
fallback: false,
85-
cacheBuster: '',
86-
cacheBusterCounter: 0,
8784
}
8885
},
8986
@@ -267,10 +264,6 @@ export default {
267264
this.fallback = true
268265
}
269266
},
270-
271-
onUpdate() {
272-
this.cacheBuster = `?buster=${this.cacheBusterCounter++}`
273-
},
274267
},
275268
}
276269
</script>

src/mixins/PreviewUrl.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export default {
3939
previewUrl: this.previewUrl,
4040
hasPreview: this.hasPreview,
4141
davPath: this.davPath,
42+
etag: this.$attrs.etag,
4243
})
4344
},
4445

@@ -65,9 +66,10 @@ export default {
6566
* @param {boolean} data.hasPreview have the file an existing preview ?
6667
* @param {string} data.davPath the absolute dav path
6768
* @param {string} data.filename the file name
69+
* @param {string|null} data.etag the etag of the file
6870
* @return {string} the absolute url
6971
*/
70-
getPreviewIfAny({ fileid, filename, previewUrl, hasPreview, davPath }) {
72+
getPreviewIfAny({ fileid, filename, previewUrl, hasPreview, davPath, etag }) {
7173
if (previewUrl) {
7274
return previewUrl
7375
}
@@ -76,6 +78,7 @@ export default {
7678
+ `&x=${Math.floor(screen.width * devicePixelRatio)}`
7779
+ `&y=${Math.floor(screen.height * devicePixelRatio)}`
7880
+ '&a=true'
81+
+ (etag !== null ? `&etag=${etag.replace(/&quot;/g, '')}` : '')
7982

8083
if (hasPreview) {
8184
// TODO: find a nicer standard way of doing this?

src/services/DavClient.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import axios from '@nextcloud/axios'
2525

2626
import { getRootPath, getToken, isPublic } from '../utils/davUtils.js'
2727

28-
// Add this so the server knows it is an request from the browserg
28+
// Add this so the server knows it is an request from the browser
2929
axios.defaults.headers['X-Requested-With'] = 'XMLHttpRequest'
3030

3131
// force our axios

src/services/FileInfo.js

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -22,41 +22,64 @@
2222

2323
import client from './DavClient.js'
2424
import { genFileInfo } from '../utils/fileUtils.js'
25+
import { createClient } from 'webdav'
26+
27+
const statData = `<?xml version="1.0"?>
28+
<d:propfind xmlns:d="DAV:"
29+
xmlns:oc="http://owncloud.org/ns"
30+
xmlns:nc="http://nextcloud.org/ns"
31+
xmlns:ocs="http://open-collaboration-services.org/ns">
32+
<d:prop>
33+
<d:getlastmodified />
34+
<d:getcontenttype />
35+
<d:resourcetype />
36+
<d:getetag />
37+
<oc:fileid />
38+
<oc:permissions />
39+
<oc:size />
40+
<d:getcontentlength />
41+
<nc:has-preview />
42+
<nc:mount-type />
43+
<nc:is-encrypted />
44+
<ocs:share-permissions />
45+
<oc:tags />
46+
<oc:favorite />
47+
<oc:comments-unread />
48+
<oc:owner-id />
49+
<oc:owner-display-name />
50+
<oc:share-types />
51+
</d:prop>
52+
</d:propfind>`
53+
2554
/**
2655
* Retrieve the files list
2756
*
2857
* @param {string} path the path relative to the user root
2958
* @param {object} [options] optional options for axios
30-
* @return {Array} the file list
59+
* @return {Promise<Array>} the file list
3160
*/
3261
export default async function(path, options) {
3362
const response = await client.stat(path, Object.assign({
34-
data: `<?xml version="1.0"?>
35-
<d:propfind xmlns:d="DAV:"
36-
xmlns:oc="http://owncloud.org/ns"
37-
xmlns:nc="http://nextcloud.org/ns"
38-
xmlns:ocs="http://open-collaboration-services.org/ns">
39-
<d:prop>
40-
<d:getlastmodified />
41-
<d:getcontenttype />
42-
<d:resourcetype />
43-
<oc:fileid />
44-
<oc:permissions />
45-
<oc:size />
46-
<d:getcontentlength />
47-
<nc:has-preview />
48-
<nc:mount-type />
49-
<nc:is-encrypted />
50-
<ocs:share-permissions />
51-
<oc:tags />
52-
<oc:favorite />
53-
<oc:comments-unread />
54-
<oc:owner-id />
55-
<oc:owner-display-name />
56-
<oc:share-types />
57-
</d:prop>
58-
</d:propfind>`,
63+
data: statData,
5964
details: true,
6065
}, options))
6166
return genFileInfo(response.data)
6267
}
68+
69+
/**
70+
* Retrieve the files list
71+
*
72+
* @param {string} origin
73+
* @param {string} path the path relative to the user root
74+
* @param {object} [options] optional options for axios
75+
* @return {Promise<object>} the file list
76+
*/
77+
export async function rawStat(origin, path, options) {
78+
const response = await createClient(origin).stat(path, {
79+
...options,
80+
data: statData,
81+
details: true,
82+
})
83+
84+
return response.data
85+
}

0 commit comments

Comments
 (0)