Saturday, June 26, 2021

How to Create Custom Theme for UI using Grommet V2

 Hello,

In this blog we will understand how you can create custom theme for your using Grommet V2 in your React app.

Using Grommet v2, you can leverage the theme capabilities and define a customTheme as a JS object with your desired colors, margin padding etc. Let's see how we can do this. 

First define your custom theme as JS object. As you can see we have defined some existing grommet color like background, brand. Also we have defined our own color like custom-1, custom-2 etc and then used it in button. 

const customTheme = {

  global: {

    colors: {

      background: "#fff",

      brand: "#000",

      "custom-1": "#aaaaaa",

      "custom-2": "#bbbbbb",

      "custom-3": "#444444"

    }

  },

  button: {

    default: {

      background: "brand",

      color: "white"

    },

    primary: {

      background: "custom-1",

      color: "white"

    },

    secondary: {

      background: "custom-3",

      color: "dark-2"

    }

  }

}

For more information on theme customisation and JSON structure you can visit Official Grommet site

Now you can apply this theme to your application as below.

import { Grommet, Box } from 'grommet';

const DemoGrommet = () => (

  <Grommet theme={customTheme}>

     <Box background="custom-1" >

     </Box>

  </Grommet>

);

export default DemoGrommet;

In case you want to keep default values of Grommet theme and want to override only few things with your theme, you can use deepMerge function provided by grommet v2 utils. 

import { deepMerge } from 'grommet/utils';

import { generate } from 'grommet/themes/base';

const mergedTheme = deepMerge(generate(16), customTheme);

Here generate function generates default theme with 16 pixel font size and then it merge it with your custom theme and provide you updated theme.

How to Get Video Thumbnails with Javascript

Hello,

In this blog we will see how you can generate thumbnail of video using JavaScript.  Let's assume you have file upload in your HTML as following.

<input type="file" id="uploadVideo" accept="video/mp4" />

Now let's add an onChange listener for this.

document.querySelector("#uploadVideo").addEventListener('change', function() {
    var inputFile = document.querySelector("#uploadVideo").files[0];
    getVideoThumbnail(inputFile)
});

Now when you upload video it will call this function and you can access this video by using files property. Now we got the file. First step we will do is get blob URL of video so we can access metadata of video. Check below function. 

Here first what we are doing is creating video element and assigning blob URL to it from input file using URL.createObjectURL method.

Then we have added event listener for meta data. This is necessary as we can't get video data till them time meta data is loaded. 

Then we seek video to 0.0 second. You can add your own time here in case if you need. Then we have added seeked listener. By this time we have video data is available. Now we are using canvas to drawImage from video frame data.

Then using toDataURL method we get the base64Data. Here 0.60 is value of quality. If you don't want to compromise quality of image then you can pass 1 here.  

function getVideoThumbnail(inputFile) {
  try {
    let video = document.createElement('video');
    let blobSrc = URL.createObjectURL(inputFile);
    video.setAttribute('src', blobSrc);
    video.addEventListener('error', () => {
        console.log("Error")
    });
    video.addEventListener('loadedmetadata', () => {
        setTimeout(() => {
          video.currentTime = 0.0;
        }, 200);
        video.addEventListener('seeked', () => {
            let canvas = document.createElement('canvas');
            video.pause();
            canvas.width = 400
            canvas.height = 400;
            let ctx = canvas.getContext('2d');
            ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
            var base64Data = ctx.canvas.toDataURL(
                'image/png',
                0.60
            );
            // SET this data in SRC of image tag or you can add your own logic.
        });
    });
     video.load();
  } catch (err) {
  
  }
}

Hope this helps you.

Friday, March 19, 2021

How to solve proxy_fcgi:error AH01071: Got error 'Unable to open primary script

 Hello,

Recently I got stuck with strange bug on centOS server. After I updated document root for my primary domain which has Laravel App installed. 

When we try to access app through domain, we got following error. 

No input file specified.

I initially thought it's the permission issue on .htaccess issue. Tried changing permissions and adding some rewrite rules but it didn't work. When I checked apache error logs. I got following error. 

proxy_fcgi:error AH01071: Got error 'Unable to open primary script

I had no idea how to solve this error. So tried few things like

  • Restart apache
  • Restart php-fpm
  • Restart VPS
  • Removed and added account few times.
  • Disabling php-fpm
But nothing worked. I spent almost entire night in solving this issue but no luck. But finally I was able to solve the issue by following steps. It was actually the issue with php fpm, as it was not able to find out root folder for the domain. So here is what you have to do. 

First go to userdata directory 

/var/cpanel/userdata/<USERNAME>

Here you will find one file. 

yourdomain.com.php-fpm.yaml

Open this file with nano or vim editor and add following line at the end of it. 

php_admin_value_doc_root: { name: 'php_admin_value[doc_root]', value: /home/<USERNAME>/public_html/<DOCUMENT_ROOT> }

Save the file and then execute following commands one by one.

/scripts/php_fpm_config --rebuild 

/scripts/restartsrv_apache_php_fpm 

/scripts/restartsrv_httpd

This will rebuild php fpm config and restart php fpm service for apache. Now in the same folder open 

YOURDOMAIN.com 

YOURDOMAIN.com_SSL

Change document root here as well and run following commands.

/scripts/rebuildhttpdconf 

/scripts/restartsrv_httpd

This will rebuild apache config file and restart apache. 

This is it and now if you visit your domain, you will not have the issue of file missing. 

Hope this saves your time