diff --git a/client/modules/view/index.js b/client/modules/view/index.js index 0d34df22..26426429 100644 --- a/client/modules/view/index.js +++ b/client/modules/view/index.js @@ -124,7 +124,7 @@ async function show(data, options = {}) { Images.show.load(); const path = prefixURL + Info.path; - const type = options.raw ? '' : getType(path); + const type = options.raw ? '' : await getType(path); switch(type) { default: @@ -137,7 +137,7 @@ async function show(data, options = {}) { return viewHtml(path); case 'image': - return viewImage(prefixURL); + return viewImage(Info.path, prefixURL); case 'media': return await viewMedia(path); @@ -245,17 +245,18 @@ function hide() { modal.close(); } -function viewImage(prefixURL) { +function viewImage(path, prefixURL) { + const isSupportedImage = (a) => isImage(a) || a === path; const makeTitle = (path) => { return { - href: prefixURL + path, + href: `${prefixURL}${path}`, title: encode(basename(path)), }; }; const names = Info.files .map(DOM.getCurrentPath) - .filter(isImage); + .filter(isSupportedImage); const titles = names .map(makeTitle); diff --git a/client/modules/view/types.js b/client/modules/view/types.js index c1f8a7d9..dd7888bb 100644 --- a/client/modules/view/types.js +++ b/client/modules/view/types.js @@ -1,5 +1,6 @@ 'use strict'; +const {extname} = require('path'); const currify = require('currify'); const testRegExp = currify((name, reg) => reg.test(name)); const getRegExp = (ext) => RegExp(`\\.${ext}$`, 'i'); @@ -8,20 +9,25 @@ const isPDF = (a) => /\.pdf$/i.test(a); const isHTML = (a) => /\.html$/.test(a); const isMarkdown = (a) => /.\.md$/.test(a); -module.exports.getType = (name) => { - if (isPDF(name)) +module.exports.getType = async (path) => { + const ext = extname(path); + + if (!ext) + path = await detectType(path); + + if (isPDF(path)) return 'pdf'; - if (isImage(name)) + if (isImage(path)) return 'image'; - if (isMedia(name)) + if (isMedia(path)) return 'media'; - if (isHTML(name)) + if (isHTML(path)) return 'html'; - if (isMarkdown(name)) + if (isMarkdown(path)) return 'markdown'; }; @@ -54,3 +60,16 @@ function isAudio(name) { function isVideo(name) { return /\.(mp4|avi|webm)$/i.test(name); } + +module.exports._detectType = detectType; +async function detectType(path) { + const {headers} = await fetch(path); + + for (const [name, value] of headers) { + if (name === 'content-type') + return `.${value.split('/').pop()}`; + } + + return ''; +} + diff --git a/client/modules/view/types.spec.js b/client/modules/view/types.spec.js index f97dc125..d0e486f5 100644 --- a/client/modules/view/types.spec.js +++ b/client/modules/view/types.spec.js @@ -1,19 +1,51 @@ 'use strict'; -const test = require('supertape'); -const {isAudio} = require('./types'); +const {test, stub} = require('supertape'); +const {isAudio, _detectType} = require('./types'); -test('cloudcmd: client: view: isAudio', (t) => { +test('cloudcmd: client: view: types: isAudio', (t) => { const result = isAudio('hello.mp3'); t.ok(result); t.end(); }); -test('cloudcmd: client: view: isAudio: no', (t) => { +test('cloudcmd: client: view: types: isAudio: no', (t) => { const result = isAudio('hello'); t.notOk(result); t.end(); }); +test('cloudcmd: client: view: types: detectType', async (t) => { + const fetch = stub().returns({ + headers: [], + }); + + const originalFetch = global.fetch; + global.fetch = fetch; + await _detectType('/hello'); + + global.fetch = originalFetch; + + t.calledWith(fetch, ['/hello']); + t.end(); +}); + +test('cloudcmd: client: view: types: detectType: found', async (t) => { + const fetch = stub().returns({ + headers: [ + ['content-type', 'image/png'], + ], + }); + + const originalFetch = global.fetch; + global.fetch = fetch; + const result = await _detectType('/hello'); + + global.fetch = originalFetch; + + t.equal(result, '.png'); + t.end(); +}); + diff --git a/package.json b/package.json index 28812eea..e4c593b8 100644 --- a/package.json +++ b/package.json @@ -122,7 +122,7 @@ "putout": "^14.0.0", "redzip": "^1.6.4", "rendy": "^3.0.0", - "restafary": "^9.1.0", + "restafary": "^9.5.0", "restbox": "^3.0.0", "shortdate": "^2.0.0", "simport": "^1.0.1",