Skip to content

Commit

Permalink
Abstract QCard logic in self-contained object
Browse files Browse the repository at this point in the history
  • Loading branch information
arran-nz committed Apr 17, 2021
1 parent 19d22b6 commit 8f69ae8
Show file tree
Hide file tree
Showing 10 changed files with 295 additions and 240 deletions.
4 changes: 2 additions & 2 deletions src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
import { fade } from 'svelte/transition';
import Home from "./pages/Home.svelte";
import Create from "./pages/CreateCard.svelte";
import View from "./pages/ViewCard.svelte";
import Create from "./pages/Create.svelte";
import View from "./pages/View.svelte";
export let url = "";
Expand Down
79 changes: 13 additions & 66 deletions src/ContactCard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -106,72 +106,19 @@

<script>
import Toast from 'svelte-toast'
import QRCode from './QRCode.svelte';
import { generateVCardString } from './plugins/vcard.js';
export let name;
export let title = "";
export let email = "";
export let phone = "";
export let website = "";
export let comment = "";
export let address = "";
export let xmpp = "";
export let vCardString;
export let selfLink;
let viewCardPrefixUrl = "https://qcard.link/card/#";
let vCardObj = {};
// Reactive to any variable changes in this component
$: {
var n = ["", name, "", "", ""];
setVCardProperty("fn", name);
setVCardProperty("n", n);
setVCardProperty("title", title);
setVCardProperty("email", email);
setVCardProperty("tel", phone);
setVCardProperty("url", website);
setVCardProperty("note", comment);
setVCardProperty("adr", address);
setVCardProperty("X-JABBER", xmpp);
vCardString = generateVCardString(
vCardObj,
true
);
selfLink = getSelfLink();
};
function setVCardProperty(key, value){
vCardObj[key] = [
{
'value': value,
}
]
};
function getSelfLink(){
var encodedVCard = encodeData(vCardString);
var selfLink = viewCardPrefixUrl + encodedVCard;
return selfLink;
}
function encodeData(str) {
// https://attacomsian.com/blog/javascript-base64-encode-decode
// first we use encodeURIComponent to get percent-encoded UTF-8,
// then we convert the percent encodings into raw bytes which
// can be fed into btoa.
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
function toSolidBytes(match, p1) {
return String.fromCharCode('0x' + p1);
}));
}
import QRCode from './QRCode.svelte'
export let qCard;
let selfLink = qCard.toUrl();
let name = qCard.name
let title = qCard.title
let email = qCard.email
let phone = qCard.phone
let website = qCard.website
let comment = qCard.comment
let address = qCard.address
let xmpp = qCard.xmpp
function DownloadVCard(){
var fileName = name + ".vcf";
Expand Down
29 changes: 16 additions & 13 deletions src/CreateForm.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
// Import Event Dispatcher
import { createEventDispatcher } from 'svelte'
import { afterUpdate } from 'svelte';
import QCard from './plugins/qcard'
const dispatch = createEventDispatcher()
let fields = [
Expand All @@ -91,15 +92,17 @@
// Call the `Submitted` event for which parent
// componets can subscribe to.
dispatch("Submitted",
{
name: form.target.nameField.value,
title: form.target.titleField ? form.target.titleField.value : "",
email: form.target.emailField ? form.target.emailField.value : "",
phone: form.target.phoneField ? form.target.phoneField.value : "",
website: form.target.websiteField ? form.target.websiteField.value : "",
comment: form.target.commentField ? form.target.commentField.value : "",
address: form.target.addressField ? form.target.addressField.value : "",
xmpp: form.target.xmppField ? form.target.xmppField.value : "",
{
qCard: new QCard(
form.target.nameField ? form.target.nameField.value : "",
form.target.titleField ? form.target.titleField.value : "",
form.target.emailField ? form.target.emailField.value : "",
form.target.phoneField ? form.target.phoneField.value : "",
form.target.websiteField ? form.target.websiteField.value : "",
form.target.commentField ? form.target.commentField.value : "",
form.target.addressField ? form.target.addressField.value : "",
form.target.xmppField ? form.target.xmppField.value : ""
)
});
}
Expand Down Expand Up @@ -133,11 +136,11 @@
{#each activeFields as field (field.id)}

<label class:required={field.required} for={field.id}>{field.displayName}</label>

{field.value}
{#if field.type == "textarea"}
<textarea class="field" placeholder={field.placeholder} id={field.id} required={field.required}></textarea>
<textarea class="field" placeholder={field.placeholder} id={field.id} required={field.required} value={field.value}></textarea>
{:else}
<input class="field" type={field.type} placeholder={field.placeholder} id={field.id} required={field.required}>
<input class="field" type={field.type} placeholder={field.placeholder} id={field.id} required={field.required} value={field.value}>
{/if}

{/each}
Expand All @@ -147,7 +150,7 @@
<button class="additionalField" on:click|once="{() => makeFieldActive(field)}">{field.displayName}</button>
{/each}

<input class="button bold" type="submit" value="Create">
<input class="button bold" type="submit" value="Create"/>
</fieldset>
</form>
</article>
Expand Down
43 changes: 19 additions & 24 deletions src/pages/CreateCard.svelte → src/pages/Create.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,43 @@
import CreateForm from '../CreateForm.svelte';
import AppHeader from '../AppHeader.svelte';
import Footer from '../Footer.svelte';
import { fromUrl } from '../plugins/qcardFactory';
import { onMount } from 'svelte';
import { writable} from 'svelte/store';
import { fromNothing } from '../plugins/qcardFactory'
let contactDetails = {
name: "",
title: "",
email: "",
phone: "",
website: "",
comment: "",
address: "",
xmpp: "",
};
let qCard = fromNothing()
let existingQCard;
// sleep time expects milliseconds
function sleep (time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
onMount(() => {
existingQCard = fromUrl(window.location.href.toString())
if (existingQCard != undefined){
qCard = existingQCard
}
})
</script>

<article>

<div id="app-header" class="mx-auto">
<AppHeader/>
</div>

<div class="flex-container mx-auto limit-width">
<div id="create-form" class="mx-auto limit-width">
<CreateForm
{existingQCard}

on:Submitted = {
event =>
{
contactDetails = event.detail;

qCard = event.detail.qCard;
// Must wait until the DOM object is rendered before scrolling.
sleep(50).then(() => {
document.getElementById("created-card").scrollIntoView({ behavior: "smooth", block: "center" });
Expand All @@ -50,19 +54,10 @@
/>
</div>

{#if contactDetails.name != ""}
{#if qCard.name != ""}
<div class="spacer" />
<div id="created-card" class="mx-auto">
<ContactCard
name = {contactDetails.name}
title = {contactDetails.title}
email = {contactDetails.email}
phone = {contactDetails.phone}
website = {contactDetails.website}
comment = {contactDetails.comment}
address = {contactDetails.address}
xmpp = {contactDetails.xmpp}
/>
<ContactCard {qCard}/>
</div>
{/if}
</div>
Expand Down
41 changes: 19 additions & 22 deletions src/pages/Home.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@
import AppHeader from '../AppHeader.svelte';
import Footer from '../Footer.svelte';
import QRCode from '../QRCode.svelte';
import QCard from "../plugins/qcard";
let qCard = new QCard(
"Julia",
"Senior Hacker",
"[email protected]",
"+555",
"https://qcard.link",
"We met at the 2021 FOSS Conference in Amsterdamn! 🍺🍺"
)
let name = "Kim"
let title = "DevOps Engineer"
let comment = "We met at the 2021 FOSS Conference in Amsterdamn! 🍺🍺"
let phone = "+555"
let email = "[email protected]"
let sampleVCard = "";
let sampleVCardLink = "";
</script>
<article class="limit-width mx-auto">

Expand All @@ -31,16 +34,7 @@
</div>

<div class="media card">
<ContactCard
name = {name}
title = {title}
comment = {comment}
phone = {phone}
email = {email}

bind:vCardString={sampleVCard}
bind:selfLink={sampleVCardLink}
/>
<ContactCard {qCard} />
</div>
</div>

Expand Down Expand Up @@ -72,30 +66,33 @@
</p>
<p>
The vCard is then encoded into <a target="_blank" href="https://en.wikipedia.org/wiki/Base64" alt="Base64 Wikipedia">Base64</a>
and appended to the URL <code>{sampleVCardLink.substring(0, 40)}...</code>
and appended to the URL <code>{qCard.toUrl().substring(0, 40)}...</code>
</p>
<br />

<p>
This URL is subsequently stored in the QR code at the top of a QCard.
</p>
<p>
When the QCard is visited, we simply decode the data and display it!
</p>
<br />
<p>
Completely <strong>knowledgeless</strong>!
Completely client-side and <strong>knowledgeless</strong>!
</p>


</div>
<div class="flex-code media">

<pre>
{sampleVCard}
{qCard.toVCardString()}
</pre>

<img class="icon" src="/icons/arrow-down.svg" alt="Arrow pointing down"/>

<div class="qrcode mx-auto">
<QRCode dataToEncode = {sampleVCardLink}/>
<QRCode dataToEncode = {qCard.toUrl()}/>
</div>
</div>
</div>
Expand All @@ -105,7 +102,7 @@
<div class="flex-container flex-dir-reverse">
<div class="explaination center">
<img style="width:50%" class="mx-auto" src="/images/undraw_professional_card.svg" alt="A person showing their personal information card"/>
<h1>You know what to do</h1>
<h1>You know what to do!</h1>
<a href="https://qcard.link/create" class="mx-auto bold button">Create a QCard</a>
</div>
</div>
Expand Down
62 changes: 62 additions & 0 deletions src/pages/View.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<script>
import { fly } from 'svelte/transition';
import { backOut } from 'svelte/easing';
import ContactCard from '../ContactCard.svelte';
import { fromUrl } from '../plugins/qcardFactory';
import { onMount } from 'svelte';
let loading = true;
let qCard;
onMount(() => {
qCard = fromUrl(window.location.href.toString())
if (qCard == undefined)
{
window.location.replace("/");
}
loading = false
})
</script>

<svelte:head>
{#if !loading}
<title>{qCard.name}'s QCard - QCard.link</title>
{/if}
</svelte:head>


{#if !loading}
<article>
<div id="contact-card-container" in:fly="{{ x: -100, duration: 600, easing: backOut }}">
<ContactCard {qCard} />
<div class="create-footer-link" in:fly="{{ y: -20, duration: 600, delay:800, easing: backOut}}">
<a href="https://qcard.link">Create your own <strong>QCard</strong></a>
</div>
</div>
</article>
{/if}

<style>
#contact-card-container {
margin: 2em auto;
max-width: 500px;
}
@media only screen and (max-width: 600px) {
#contact-card-container {
margin: 0 auto;
max-width: none;
}
}
.create-footer-link {
margin: 0.5em auto;
display:block;
font-weight: 300;
text-align: center;
}
</style>
Loading

0 comments on commit 8f69ae8

Please sign in to comment.