1
0
mirror of https://github.com/kremalicious/portfolio.git synced 2024-06-13 16:03:24 +02:00
portfolio/src/components/atoms/Vcard.jsx

112 lines
3.2 KiB
React
Raw Normal View History

2019-11-10 14:40:45 +01:00
import React from 'react'
2018-09-27 20:20:27 +02:00
import saveAs from 'file-saver'
2018-06-20 22:50:49 +02:00
import vCard from 'vcf'
2019-11-11 21:46:14 +01:00
import { useMeta } from '../../hooks/use-meta'
2019-08-11 21:47:22 +02:00
import { useResume } from '../../hooks/use-resume'
2021-03-13 01:03:23 +01:00
import { getSrc } from 'gatsby-plugin-image'
2019-11-10 14:40:45 +01:00
export default function Vcard() {
2019-11-11 21:46:14 +01:00
const metaYaml = useMeta()
2019-08-11 21:47:22 +02:00
const { basics } = useResume()
2021-03-13 01:03:23 +01:00
const photoSrc = getSrc(basics.picture)
2019-08-11 21:47:22 +02:00
const { name, label, email, profiles } = basics
const meta = {
...metaYaml,
photoSrc,
name,
label,
email,
profiles
}
2018-05-13 00:42:59 +02:00
2020-03-21 23:55:40 +01:00
const handleAddressbookClick = (e) => {
2019-11-10 14:40:45 +01:00
e.preventDefault()
2019-08-11 21:47:22 +02:00
init(meta)
2018-12-08 20:27:45 +01:00
}
2019-11-10 14:40:45 +01:00
return (
<a
// href is kinda fake, only there for usability
// so user knows what to expect when hovering the link before clicking
2019-08-11 21:47:22 +02:00
href={meta.addressbook}
2019-11-10 14:40:45 +01:00
onClick={handleAddressbookClick}
>
Add to addressbook
</a>
)
2018-12-08 20:27:45 +01:00
}
2018-05-13 00:42:59 +02:00
2020-03-21 23:55:40 +01:00
export const init = async (meta) => {
2019-04-16 21:21:01 +02:00
// first, convert the avatar to base64, then construct all vCard elements
2019-08-11 21:47:22 +02:00
const dataUrl = await toDataURL(meta.photoSrc, 'image/jpeg')
2019-11-17 16:03:57 +01:00
const vcard = await constructVcard(meta, dataUrl)
2019-04-16 21:21:01 +02:00
2019-11-17 16:03:57 +01:00
// Construct the download from a blob of the just constructed vCard,
2019-04-16 03:59:21 +02:00
const { addressbook } = meta
const name = addressbook.split('/').join('')
2019-11-17 16:03:57 +01:00
const blob = new Blob([vcard], {
type: 'text/x-vcard'
})
// save it to user's file system
2018-09-27 20:20:27 +02:00
saveAs(blob, name)
2018-09-06 14:28:01 +02:00
}
2020-03-21 23:55:40 +01:00
export const constructVcard = async (meta) => {
2018-09-06 14:28:01 +02:00
const contact = new vCard()
2019-11-08 23:00:47 +01:00
const blog = meta.profiles.filter(({ network }) => network === 'Blog')[0].url
const twitter = meta.profiles.filter(
({ network }) => network === 'Twitter'
)[0].url
const github = meta.profiles.filter(({ network }) => network === 'GitHub')[0]
.url
2018-09-06 14:28:01 +02:00
2019-04-16 21:21:01 +02:00
// stripping this data out of base64 string is required
// for vcard to actually display the image for whatever reason
// const dataUrlCleaned = dataUrl.split('data:image/jpeg;base64,').join('')
// contact.set('photo', dataUrlCleaned, { encoding: 'b', type: 'JPEG' })
2019-08-11 21:47:22 +02:00
contact.set('fn', meta.name)
contact.set('title', meta.label)
2019-04-16 21:21:01 +02:00
contact.set('email', meta.email)
2019-08-11 21:47:22 +02:00
contact.set('nickname', 'kremalicious')
2019-04-16 21:21:01 +02:00
contact.set('url', meta.url, { type: 'Portfolio' })
2019-11-08 23:00:47 +01:00
contact.add('url', blog, { type: 'Blog' })
contact.add('x-socialprofile', twitter, { type: 'twitter' })
contact.add('x-socialprofile', github, { type: 'GitHub' })
2019-04-16 21:21:01 +02:00
const vcard = contact.toString('3.0')
return vcard
2018-09-06 14:28:01 +02:00
}
2018-08-26 21:28:06 +02:00
// Helper function to create base64 string from avatar image
// without the need to read image file from file system
2019-11-17 16:03:57 +01:00
export async function toDataURL(photoSrc, outputFormat) {
2018-08-26 21:28:06 +02:00
const img = new Image()
img.crossOrigin = 'Anonymous'
2019-04-16 21:21:01 +02:00
img.src = photoSrc
2018-05-13 00:42:59 +02:00
2019-04-16 21:21:01 +02:00
img.onload = () => {}
2018-05-13 00:42:59 +02:00
2019-04-16 21:21:01 +02:00
// yeah, we're gonna create a fake canvas to render the image
// and then create a base64 string from the rendered result
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
let dataURL
2019-04-16 03:59:21 +02:00
2019-04-16 21:21:01 +02:00
canvas.height = img.naturalHeight
canvas.width = img.naturalWidth
ctx.drawImage(img, 0, 0)
dataURL = canvas.toDataURL(outputFormat)
// img.src = photoSrc
// if (img.complete || img.complete === undefined) {
// img.src =
// 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=='
// img.src = photoSrc
// }
return dataURL
2018-05-13 00:42:59 +02:00
}