React-native packager configuration - How to include .zip file in bundle? - react-native

My problem:
I have a zip file that contains a firmware update for my company's device
I want to be able to access it using react-native-fs with the code below
.
export function readAssetFile(name) {
if(Platform.OS === 'ios') {
return RNFS.readFile(`${RNFS.MainBundlePath}/assets/data/${name}`);
} else {
return RNFS.readFileAssets(`raw/${name}`, 'base64');
}
}
My project structure looks like:
ProjectDir
android
data
image1.png
image2.png
firmwarefile.zip
ios
The android branch works, because I added a build step in my .gradle to copy firmwarefile.zip into ProjectDir/android/app/src/main/assets/raw. So I can call readAssetFile('firmwarefile.zip'), and it returns the data.
On iOS, all the image files (Image1.png, Image2.png) are included in MyProject.app/assets/data/ without me having to do anything, but the zip file that sits beside them is not.
Looking into the actual packager code (from the metro project), it seems (based on metro/src/defaults.js) that zip files aren't included by default by the packager, but the packager can be configured to include other file types. But I can't find any documentation for how I'd go about doing that configuring.
Sorry for what feels like a really simple question, but I've been trying to get this zip included in my bundle for ~4 hours now. I'm resorting to manually putting in console.logs and error-throws to trace things inside metro to try and find where I should be sending in my config.
Versions:
React-native: 0.55.3
Metro: 0.30.2

This is a hack, but it gets it done:
Convert your zip binary to a base64 string
Stick it in a .js file, a la module.exports = "<your base64 data goes here>"
In your file that needs the zip file, use import myZipFileAsBase64 from './hacky-base64-file.js';
Here's a quick script to make your base64 files:
var fs = require('fs');
function prepareZip(file, outJs) {
const b64 = fs.readFileSync(file, 'base64');
fs.writeFileSync(outJs, `module.exports = ${JSON.stringify(b64)};`);
}
prepareZip('./data/myFirmware.zip', './hacky-base64-file.js');

Related

<video> tag. DOMException: The element has no supported sources, when not utilizing require()

I am trying to play a video when developing locally with VueJS 2.
My code is the following :
<video class="back_video" :src="`../videos/Space${videoIndex}.mp4`" id="background-video"></video>
...
data :
function() {
return {
videoIndex:1
}
}
...
const vid = document.getElementById("background-video");
vid.crossOrigin = 'anonymous';
let playPromise = vid.play();
if (playPromise !== undefined) {
playPromise.then(function() {
console.log("video playing");
}).catch(function(error) {
console.error(error);
});
}
This code is causing the exception given in title. Tried in several browsers, always the same.
If I change the src by :
:src="require(`../videos/Space${videoIndex}.mp4`)"
it works.
But in that case building time is very long as I have many different videos in my videos directory, because adding require() will force to copy all videos in the running directory at build phase (vue-cli serve), and this is really annoying. In other words I want to refer videos that are outside the build directory to avoid this (but also to avoid having videos in my git).
It is interesting to note that when I deploy server side, it works perfectly with my original code
:src="`../videos/Space${videoIndex}.mp4`"
Note also that if i replace my code with simply
src="../videos/Space1.mp4"
it works too. So the video itself, or its location, are not the source of the problem.
Any clue ?
You can host your videos on a CDN to have something faster and easier to debug/work with.
Otherwise, it will need to bundle it locally and may take some time.

How to read file from assets folder in react-native?

I have some data in android\app\src\main\assets and I am using rn-fetch-blob as filesystem.
But what is the schema path to assets folder in android? How to read data from it?
Is there any other way to ship pre pupolate data file in react-native ? Can I place file in react-native project root directory?
There is readFileAssets is a method in react-native-fs.
Place your file in android\app\src\main\assets.If there is no assets folder
then just create it.
import fs from "react-native-fs";
fs.readFileAssets("folder/file", "base64") // 'base64' for binary
.then(binary => {
// work with it
})
.catch(console.error)
Note: Path must be relative. If android\app\src\main\assets\folder\file then use folder\file
let path = RNFetchBlob.fs.asset('my-asset.jpg')
RNFetchBlob.fs.asset('bundle-assets://my-asset.jpg');
There is a method in doc assetfilenamestrings

Swagger-UI and Ktor how to import swagger.json or .yaml file and start Swagger-UI?

I have a problem, I have already generated OpenApi Swagger files (swagger.json and swagger.yaml) Is it possible somehow in Ktor (kotlin) import this files and start swagger-ui server on specific route ?
I have visited ktor-swagger project but could get how just to add json file to display swagger-ui.
Any suggestions ?
Make you json file accessible from static routing
Create "files" directory in resources dir
Use next code to routing static files from "files" dir
routing {
static("/static") {
resources("files")
}
//...
}
Lets name json file "test.json", then put you it in "files" folder
so now you run the app and see this file by http://localhost:8080/static/test.json
Then we need to install and configure OpenApiGen
Add OpenApiGen dependencies you can find how to do this here https://github.com/papsign/Ktor-OpenAPI-Generator
Then use the following code
install(OpenAPIGen) {
serveSwaggerUi = true
swaggerUiPath = "/swagger-ui"
}
now you can use http://localhost:8080/swagger-ui/index.html?url=/static/test.json URL to see your file through the swagger UI
Also, you can provide your own route to using redirection
get("/api") {
call.respondRedirect("/swagger-ui/index.html?url=/static/test.json", true)
}
this will allow you to use just http://localhost:8080/api

What's a good way to get and display all the folders and files of a directory in a Vue.js + Electron app?

I have a Vue.js + Electron app (electron-vue boilerplate)
What are the best practices of getting and displaying directory's folders and files?
Basically I want it to behave like a File Explorer (Windows) or Finder (Mac). You open a folder you get all the content displayed.
Let's say we have:
the main view called App.vue with a router inside of it.
there's an open folder button in App.vue.
And we also have FileExplorer.vue component that is getting displayed as a route inside that App.vue
How do I make this FileExplorer.vue component to get and display files and folders of, let's say, directory C:\test folder (on Windows) when we hit that open folder button in App.vue?
I know that I should use Node for that, but how exactly? What do I import and how do I use Vue to make it all work together?
All the projects on Github are too complicated for a newbie to understand how they work. For example this one is quite simple looking, but there's so much code in there that you don't even know where to start
Update:
I managed to get the content of a folder doing this:
<v-btn #click="readDirectory"></v-btn>
[...]
const fs = require('fs-extra')
export default {
name: "FileExplorer",
data () {
return {
dir:'C:/test',
files:[],
file:""
}
},
methods: {
readDirectory() {
fs.readdir(this.dir, (err, dir) => {
console.log(dir);
for(let filePath of dir)
console.log(filePath)
this.files = dir
})
},
}
}
And I displayed it like this:
<v-btn v-for="file in files" :key="file.id">
{{file}}
</v-btn>
But it doesn't really behave like a real file explorer...I get the folders and files on button click but I can't do anything with all those folders and files.
How do I make all the folders that it gets on click to behave in a similar way (to get its content) ?
And how do I display folders and files differently?
If you simply want to allow a user to select a folder in Electron I would suggest using the showOpenDialog API.
In the renderer process, you need to use the remote API to access the dialog API.
const { remote } = require('electron')
remote.dialog.showOpenDialog({
properties: ['openDirectory'],
defaultPath: current
}, names => {
console.log('selected directory:' + names[0]);
});
If you want to display the contents of a directory within your app you're going to have to use the node fs module and read the directory contents.
fs.readdir(path[, options], callback)
Will callback with all the file and directory paths which you'll then have to iterate over to get more info or to traverse recursively to get their contents. There are are node modules which make this process a little easier than writing it all yourself.
Once you've got an object tree containing all your files and directories you can use this to create a UI using vue.js.

sails.js less livereload with grunt watch not working

I got my less files compiled in css perfectly by grunt and I see result in .tmp/public/styles
So now livereload with grunt-contrib-watch should be made naturally in sails generated project ?
Or do I have to make a special configuration ?
I found that in tasks/pipeline.js file but not sure of what to do.
// CSS files to inject in order
//
// (if you're using LESS with the built-in default config, you'll want
// to change `assets/styles/importer.less` instead.)
var cssFilesToInject = [
'styles/**/*.css'
];
I saw in the file tasks/README.md :
###### `sails lift`
Runs the `default` task (`tasks/register/default.js`).
And in the file default.js we got :
module.exports = function (grunt) {
grunt.registerTask('default', ['compileAssets', 'linkAssets', 'watch']);
};
But watch.js file is missing in the folder...
What should it be ?
Watch does only looking for files that have changed and execute less, sass, injection and so on - but it doesn't make a reload.
You can add this in task/config/watch.js