Browse Source

feat: file manager thumbnail preview

NGPixel 2 years ago
parent
commit
0605f65465

+ 1 - 2
package.json

@@ -10,8 +10,7 @@
     "dev": "nodemon server",
     "dev": "nodemon server",
     "legacy:dev": "NODE_OPTIONS=--openssl-legacy-provider node dev",
     "legacy:dev": "NODE_OPTIONS=--openssl-legacy-provider node dev",
     "legacy:build": "NODE_OPTIONS=--openssl-legacy-provider webpack --profile --config dev/webpack/webpack.prod.js",
     "legacy:build": "NODE_OPTIONS=--openssl-legacy-provider webpack --profile --config dev/webpack/webpack.prod.js",
-    "test": "eslint --format codeframe --ext .js,.vue . && pug-lint server/views && jest",
-    "cypress:open": "cypress open"
+    "test": "eslint --format codeframe --ext .js,.vue . && pug-lint server/views && jest"
   },
   },
   "repository": {
   "repository": {
     "type": "git",
     "type": "git",

+ 24 - 21
server/controllers/common.js

@@ -5,8 +5,6 @@ const _ = require('lodash')
 const CleanCSS = require('clean-css')
 const CleanCSS = require('clean-css')
 const moment = require('moment')
 const moment = require('moment')
 const path = require('path')
 const path = require('path')
-
-const tmplCreateRegex = /^[0-9]+(,[0-9]+)?$/
 const siteAssetsPath = path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, 'assets')
 const siteAssetsPath = path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, 'assets')
 
 
 /**
 /**
@@ -78,30 +76,35 @@ router.get('/_site/:siteId?/:resource', async (req, res, next) => {
 /**
 /**
  * Asset Thumbnails / Download
  * Asset Thumbnails / Download
  */
  */
-router.get('/_asset/:siteId/:mode/*', async (req, res, next) => {
-  const site = req.params.siteId ? WIKI.sites[req.params.siteId] : await WIKI.db.sites.getSiteByHostname({ hostname: req.hostname })
-  if (!site) {
-    return res.status(404).send('Site Not Found')
-  }
-  const filePath = req.params[0]
-  console.info(filePath)
-  switch (req.params.mode) {
-    case 'thumb': {
-      try {
+router.get('/_thumb/:id.png', async (req, res, next) => {
+  const thumb = await WIKI.db.assets.getThumbnail({
+    id: req.params.id
+  })
 
 
-      } catch (err) {
+  if (thumb) {
+    // TODO: Check permissions
 
 
+    switch (thumb.previewState) {
+      case 'pending': {
+        res.send('PENDING')
+        break
+      }
+      case 'ready': {
+        res.set('Content-Type', 'image/png')
+        res.send(thumb.preview)
+        break
+      }
+      case 'failed': {
+        res.status(500).send('Thumbnail Preview Failed').end()
+        break
+      }
+      default: {
+        return res.status(500).send('Invalid Thumbnail Preview State')
       }
       }
-      break
-    }
-    case 'download': {
-      break
-    }
-    default: {
-      return res.status(404).send('Invalid Site Resource')
     }
     }
+  } else {
+    return res.sendStatus(404)
   }
   }
-  return res.send('BOB').end()
 })
 })
 
 
 /**
 /**

+ 3 - 0
server/core/system.js

@@ -10,6 +10,9 @@ module.exports = {
     minimumNodeRequired: '18.0.0'
     minimumNodeRequired: '18.0.0'
   },
   },
   init () {
   init () {
+    fs.ensureDir(path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, 'assets'))
+    fs.ensureDir(path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, 'uploads'))
+
     // Clear content cache
     // Clear content cache
     fs.emptyDir(path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, 'cache'))
     fs.emptyDir(path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, 'cache'))
 
 

+ 5 - 8
server/graph/resolvers/asset.js

@@ -258,7 +258,7 @@ module.exports = {
           const asset = assetRaw[0]
           const asset = assetRaw[0]
 
 
           // Add to tree
           // Add to tree
-          const treeAsset = await WIKI.db.tree.addAsset({
+          await WIKI.db.tree.addAsset({
             id: asset.id,
             id: asset.id,
             parentPath: folder.folderPath ? `${folder.folderPath}.${folder.fileName}` : folder.fileName,
             parentPath: folder.folderPath ? `${folder.folderPath}.${folder.fileName}` : folder.fileName,
             fileName: formattedFilename,
             fileName: formattedFilename,
@@ -309,13 +309,7 @@ module.exports = {
               WIKI.logger.warn('Cannot generate asset thumbnail because the Sharp extension is not installed.')
               WIKI.logger.warn('Cannot generate asset thumbnail because the Sharp extension is not installed.')
             } else {
             } else {
               WIKI.logger.debug(`Generating thumbnail of asset ${sanitizedFilename}...`)
               WIKI.logger.debug(`Generating thumbnail of asset ${sanitizedFilename}...`)
-              const previewDestFolder = path.resolve(
-                WIKI.ROOTPATH,
-                WIKI.config.dataPath,
-                'assets'
-              )
-              const previewDestPath = path.join(previewDestFolder, `asset-thumb-${treeAsset.hash}.png`)
-              await fs.ensureDir(previewDestFolder)
+              const previewDestPath = path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, `uploads/${tempFileId}-thumb.png`)
               // -> Resize
               // -> Resize
               await WIKI.extensions.ext.sharp.resize({
               await WIKI.extensions.ext.sharp.resize({
                 format: 'png',
                 format: 'png',
@@ -332,6 +326,9 @@ module.exports = {
                 preview: await fs.readFile(previewDestPath),
                 preview: await fs.readFile(previewDestPath),
                 previewState: 'ready'
                 previewState: 'ready'
               })
               })
+
+              // -> Delete
+              await fs.remove(previewDestPath)
             }
             }
           }
           }
 
 

+ 14 - 1
server/models/assets.js

@@ -3,6 +3,7 @@ const moment = require('moment')
 const path = require('path')
 const path = require('path')
 const fs = require('fs-extra')
 const fs = require('fs-extra')
 const _ = require('lodash')
 const _ = require('lodash')
+const commonHelper = require('../helpers/common')
 
 
 /**
 /**
  * Users model
  * Users model
@@ -160,7 +161,19 @@ module.exports = class Asset extends Model {
     }
     }
   }
   }
 
 
-  static async getAsset(assetPath, res) {
+  static async getThumbnail ({ id, path, locale, siteId }) {
+    return WIKI.db.tree.query()
+      .select('tree.*', 'assets.preview', 'assets.previewState')
+      .innerJoin('assets', 'tree.id', 'assets.id')
+      .where(id ? { 'tree.id': id } : {
+        'tree.hash': commonHelper.generateHash(path),
+        'tree.localeCode': locale,
+        'tree.siteId': siteId
+      })
+      .first()
+  }
+
+  static async getAsset({ path, locale, siteId }, res) {
     try {
     try {
       const fileInfo = '' // assetHelper.getPathInfo(assetPath)
       const fileInfo = '' // assetHelper.getPathInfo(assetPath)
       const fileHash = '' // assetHelper.generateHash(assetPath)
       const fileHash = '' // assetHelper.generateHash(assetPath)

+ 4 - 2
server/modules/extensions/sharp/ext.js

@@ -51,7 +51,8 @@ module.exports = {
     width = null,
     width = null,
     height = null,
     height = null,
     fit = 'cover',
     fit = 'cover',
-    background = { r: 0, g: 0, b: 0, alpha: 0 }
+    background = { r: 0, g: 0, b: 0, alpha: 0 },
+    kernel = 'lanczos3'
   }) {
   }) {
     this.load()
     this.load()
 
 
@@ -75,7 +76,8 @@ module.exports = {
         width,
         width,
         height,
         height,
         fit,
         fit,
-        background
+        background,
+        kernel
       }).toFormat(format)
       }).toFormat(format)
 
 
       return pipeline([inputStream, transformer, outputStream])
       return pipeline([inputStream, transformer, outputStream])

+ 3 - 3
server/views/base.pug

@@ -44,7 +44,7 @@ html(lang=siteConfig.lang)
     link(
     link(
       type='text/css'
       type='text/css'
       rel='stylesheet'
       rel='stylesheet'
-      href='/_assets-legacy/css/app.36b4c9522aa279325701.css'
+      href='/_assets-legacy/css/app.c05740c020721e44657c.css'
     )
     )
       
       
     
     
@@ -54,14 +54,14 @@ html(lang=siteConfig.lang)
       
       
     script(
     script(
       type='text/javascript'
       type='text/javascript'
-      src='/_assets-legacy/js/runtime.js?1671237890'
+      src='/_assets-legacy/js/runtime.js?1674373130'
       )
       )
       
       
     
     
       
       
     script(
     script(
       type='text/javascript'
       type='text/javascript'
-      src='/_assets-legacy/js/app.js?1671237890'
+      src='/_assets-legacy/js/app.js?1674373130'
       )
       )
       
       
     
     

+ 5 - 4
ux/quasar.config.js

@@ -102,11 +102,12 @@ module.exports = configure(function (/* ctx */) {
     devServer: {
     devServer: {
       // https: true
       // https: true
       open: false, // opens browser window automatically
       open: false, // opens browser window automatically
-      port: 5001,
+      port: 3001,
       proxy: {
       proxy: {
-        '/_graphql': 'http://localhost:5000/_graphql',
-        '/_site': 'http://localhost:5000',
-        '/_user': 'http://localhost:5000'
+        '/_graphql': 'http://127.0.0.1:3000/_graphql',
+        '/_site': 'http://127.0.0.1:3000',
+        '/_thumb': 'http://127.0.0.1:3000',
+        '/_user': 'http://127.0.0.1:3000'
       }
       }
     },
     },
 
 

+ 5 - 2
ux/src/components/FileManager.vue

@@ -68,7 +68,7 @@ q-layout.fileman(view='hHh lpR lFr', container)
       .q-pa-md
       .q-pa-md
         template(v-if='currentFileDetails')
         template(v-if='currentFileDetails')
           q-img.rounded-borders.q-mb-md(
           q-img.rounded-borders.q-mb-md(
-            src='/_assets/illustrations/fileman-page.svg'
+            :src='currentFileDetails.thumbnail'
             width='100%'
             width='100%'
             fit='cover'
             fit='cover'
             :ratio='16/10'
             :ratio='16/10'
@@ -450,8 +450,10 @@ const currentFileDetails = computed(() => {
         value: item.title
         value: item.title
       }
       }
     ]
     ]
+    let thumbnail = ''
     switch (item.type) {
     switch (item.type) {
       case 'page': {
       case 'page': {
+        thumbnail = '/_assets/illustrations/fileman-page.svg'
         items.push({
         items.push({
           label: t('fileman.detailsPageType'),
           label: t('fileman.detailsPageType'),
           value: t(`fileman.${item.pageType}PageType`)
           value: t(`fileman.${item.pageType}PageType`)
@@ -471,6 +473,7 @@ const currentFileDetails = computed(() => {
         break
         break
       }
       }
       case 'asset': {
       case 'asset': {
+        thumbnail = `/_thumb/${item.id}.png`
         items.push({
         items.push({
           label: t('fileman.detailsAssetType'),
           label: t('fileman.detailsAssetType'),
           value: fileTypes[item.fileExt] ? t(`fileman.${item.fileExt}FileType`) : t('fileman.unknownFileType', { type: item.fileExt.toUpperCase() })
           value: fileTypes[item.fileExt] ? t(`fileman.${item.fileExt}FileType`) : t('fileman.unknownFileType', { type: item.fileExt.toUpperCase() })
@@ -483,7 +486,7 @@ const currentFileDetails = computed(() => {
       }
       }
     }
     }
     return {
     return {
-      thumbnail: '',
+      thumbnail,
       items
       items
     }
     }
   } else {
   } else {