KlausSchaefers/vue-low-code

Using Images Locally.

Closed this issue · 8 comments

Hello @KlausSchaefers

Is it possible to use images locally instead of downloading from figma.
This usually cause the application to load very slowly, sometimes taking as much as 40 seconds to load.

So is it possible to disable loading images from Figma and using local images instead?

Hi,

the download script will copy all images into the 'public/img' folder and the app into the 'screen/views/app.json'. You have to import the JSON in the Home.vue and pass it instead of the config object.

<template>
  <div class="home">
    <Figma :figma="figmaConfig" v-model="viewModel"/>
  </div>
</template>

<script>
import Vue from "vue";
import Figma from 'vue-low-code'
import app from './app.json'
Vue.use(Figma);

export default {
  name: 'Home',
  data: function () {
    return {
      figmaConfig: app,
      viewModel: {
      }
    }
  },
  components: {
  },
  methods: {
  }
}
</script>

This should do the trick.

You download with the following command

node download.js <api token> <fileID>

You can find more info here https://github.com/KlausSchaefers/figma-low-code#deployment

Thank you

I tried downloading but I keep getting this error after a certain point:
(node:16096) UnhandledPromiseRejectionWarning: FetchError: request to https://s3-us-west-2.amazonaws.com/figma-alpha-api/img/40ef/b357/d954c697ab61ff46e3556f6234cfaca3 failed, reason: write EPROTO

It downloads some images but always fail at this point.

Hmmm. strange. I have to investigate that.

For me it worked like in the browser. I see the following output:

___ _                     _                    ___         _     
| __(_)__ _ _ __  __ _ ___| |   _____ __ _____ / __|___  __| |___ 
| _|| / _` | '  \/ _` |___| |__/ _ \ V  V /___| (__/ _ \/ _` / -_)
|_| |_\__, |_|_|_\__,_|   |____\___/\_/\_/     \___\___/\__,_\___|
      |___/                                             



Download Figma file...
igmaService.getImageTimeout () > Throttle requests. Delay request 0 by 0 ms
igmaService.getImageTimeout () > Throttle requests. Delay request 1 by 1000 ms
igmaService.getImageTimeout () > Throttle requests. Delay request 2 by 2000 ms
igmaService.getImageTimeout () > Throttle requests. Delay request 3 by 3000 ms
igmaService.getImageTimeout () > Throttle requests. Delay request 4 by 4000 ms
igmaService.getImageTimeout () > Throttle requests. Delay request 5 by 5000 ms
igmaService.getImageTimeout () > Throttle requests. Delay request 6 by 6000 ms
igmaService.getImageTimeout () > Throttle requests. Delay request 7 by 7000 ms
igmaService.getImageTimeout () > Throttle requests. Delay request 8 by 8000 ms
igmaService.getImageTimeout () > Throttle requests. Delay request 9 by 9000 ms
igmaService.getImageTimeout () > Throttle requests. Delay request 10 by 10000 ms
igmaService.getImageTimeout () > Throttle requests. Delay request 11 by 11000 ms
Download images:
  - public/img/w10017.png
  - public/img/w10026.png
 
....

  - public/img/w11876.png
  - public/img/w11880.png
  - public/img/w11882.png
Write app file...

Which OS and Node version are you using? I am on MacOS X and Node 12.14

OK, after several runs this issue also happened to me. Can you replace the content of the download.js with this

/* eslint-disable no-undef */
const fs = require('fs');
const fetch = require('node-fetch');
const util = require('util');
const chalk = require('chalk');
const vueLowCode = require('vue-low-code')

console.debug(`\n\n`)
console.debug(`___ _                     _                    ___         _     `)
console.debug(`| __(_)__ _ _ __  __ _ ___| |   _____ __ _____ / __|___  __| |___ `)
console.debug("| _|| / _` | '  \\/ _` |___| |__/ _ \\ V  V /___| (__/ _ \\/ _` / -_)")
console.debug("|_| |_\\__, |_|_|_\\__,_|   |____\\___/\\_/\\_/     \\___\\___/\\__,_\\___|")
console.debug("      |___/                                             ")
console.debug(`\n\n`)

/**
 * Change here the destimation folder. If you change the image folder
 * make sure to also update the conf object.
 */
const jsonFileTarget = 'src/views/app.json'
const fileFolderTarget = 'public/img'

/**
 * Get arguments from path
 */
const figmaAccessKey = process.argv[2]
const figmaFileId = process.argv[3]
const figmaPageId = process.argv[4]

/**
 * Check if inout is ok
 */
if (!figmaAccessKey || !figmaFileId) {
  console.debug(chalk.red('Plesse add the figma access token and file id'))
  console.debug('Example: node download.js <accessToken> <fileKey> <page name>*')
  return
}


/**
 * Enable fetch polyfill
 */
if (!globalThis.fetch) {
  globalThis.fetch = fetch;
  globalThis.Headers = fetch.Headers
}

var selectedPages = figmaPageId ? [figmaPageId] : []
/**
 * Start downloading
 */
const streamPipeline = util.promisify(require('stream').pipeline);
vueLowCode.setLogLevel(-5)

const figmaService = new vueLowCode.createFigmaService(figmaAccessKey)
console.debug(chalk.blue('Download Figma file...'))
if (figmaPageId) {
  console.debug(chalk.blue('Limit to page...' + figmaPageId))
}

figmaService.get(figmaFileId, true, false, selectedPages).then(async app => {
  console.debug(chalk.blue('Download images:'))

  const widgetsWithImages = Object.values(app.widgets).filter(w => {
    return w.props.figmaImage
  })
  var promisses = widgetsWithImages.map(async w => {
    const imageURL = w.props.figmaImage
    try {
      var imageFileTarget = fileFolderTarget + '/' + w.id +'.png'
      console.debug(chalk.blueBright('  - ' + imageFileTarget) , chalk.gray('(' + imageURL + ')'))
      const response = await fetch(imageURL);
      if (response.ok) {
        w.style.backgroundImage = {
          url: w.id +'.png'
        }
        return streamPipeline(response.body, fs.createWriteStream(imageFileTarget));
      }
    } catch (e) {
      console.debug(chalk.red(' ! Could not download element: ' + w.name + ' url:' + imageURL))
      return new Promise(resolve => resolve())
    }
  })
  await Promise.all(promisses)


  console.debug(chalk.blue('Write app file...'))
  var content = JSON.stringify(app, null, 2)
  fs.writeFileSync(jsonFileTarget, content)

  console.debug(`\n\n`)
  console.debug(chalk.green('Done!'), 'Now import the JSON file in', chalk.green('Home.vue'))
})

This should at least not crash the download. Some images might be missing, but better then nothing...

Awesome!!!
Thank you so much. 🙏
The new code worked for me without errors.

And the application loads a lot more faster now. :)
Thank you so much for your consistent support.
I really appreciate. 🙏