Skip to content

Commit 636242a

Browse files
Chris AndersonChris Anderson
Chris Anderson
authored and
Chris Anderson
committed
Add client
1 parent 2f4f022 commit 636242a

File tree

4 files changed

+286
-0
lines changed

4 files changed

+286
-0
lines changed

client/index.html

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<!DOCTYPE html>
2+
<html>
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<title>title</title>
7+
<meta name="author" content="Microsoft">
8+
<meta name="description" content="An Azure Functions and Azure Cognitive Services demo. Generate a Coder Card based on an image you upload">
9+
<meta name="keywords" content="azure,azure functions,azure cognitive services,coder cards">
10+
<link rel="shortcut icon" href="/public/favicon.ico" type="image/vnd.microsoft.icon">
11+
<link rel="stylesheet" href="/node_modules/dropzone/dist/dropzone.css" type="text/css">
12+
<link rel="stylesheet" href="/public/css/main.css" type="text/css">
13+
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
14+
<script src="/node_modules/dropzone/dist/dropzone.js" type="text/javascript"></script>
15+
<script type="text/javascript">
16+
// Disable autoDiscover
17+
Dropzone.autoDiscover = false;
18+
</script>
19+
<script src="https://use.fontawesome.com/bc4f54b80b.js"></script>
20+
</head>
21+
22+
<body>
23+
<div class="wrapper">
24+
<div class="box header">
25+
<h1><span class="fa fa-user-circle-o"></span> Coder Cards</h1>
26+
</div>
27+
<div class="box content">
28+
<hr>
29+
<h2>1. Upload a picture of yourself</h2>
30+
<div>
31+
<form class="dropzone needsclick dz-clickable" id="dropzone">
32+
<div class="dz-message needsclick">
33+
Drop files here or click to upload.<br>
34+
</div>
35+
</form>
36+
<!--
37+
<form id="form1">
38+
<input type="file" name="fileToUpload" id="fileToUpload" />
39+
<input type="button" onclick="uploadFiles()" value="Upload" />
40+
</form>
41+
-->
42+
</div>
43+
<h2>2. Your coder profile will appear below</h2>
44+
<div id="images">
45+
</div>
46+
</div>
47+
<div class="box footer">
48+
<hr>
49+
<div class="privacy">
50+
<p>This app has no official privacy policy. Your data will be uploaded to a service in order produce a picture. Your images will be public once you upload them and there is no automated way to remove them.</p>
51+
</div>
52+
</div>
53+
</div>
54+
<script src="/public/js/codercards.js" type="text/javascript"></script>
55+
</body>
56+
57+
</html>

client/package.json

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "client",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "index.js",
6+
"scripts": {
7+
"run": "live-server",
8+
"test": "echo \"Error: no test specified\" && exit 1"
9+
},
10+
"author": "",
11+
"license": "ISC",
12+
"dependencies": {
13+
"dropzone": "^4.3.0"
14+
},
15+
"devDependencies": {
16+
"live-server":"1.2.0"
17+
}
18+
}

client/public/css/main.css

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
html {
2+
min-height: 100%;
3+
}
4+
5+
body {
6+
min-height: 100%;
7+
margin-left: 50px;
8+
margin-right: 50px;
9+
font-family: Segoe UI,Frutiger,Frutiger Linotype,Dejavu Sans,Helvetica Neue,Arial,sans-serif;
10+
}
11+
12+
.content {
13+
grid-area: content;
14+
}
15+
16+
.header {
17+
grid-area: header;
18+
}
19+
20+
.footer {
21+
grid-area: footer;
22+
}
23+
24+
h1 {
25+
margin: 0;
26+
}
27+
28+
.wrapper {
29+
height: 100%;
30+
display: grid;
31+
grid-gap: 10px;
32+
grid-template-rows: auto auto 150px;
33+
grid-template-columns: auto;
34+
grid-template-areas:
35+
"header"
36+
"content"
37+
"footer";
38+
background-color: #fff;
39+
color: #444;
40+
}
41+
42+
43+
.box {
44+
font-size: 150%;
45+
}
46+
47+
.header,
48+
.footer {
49+
}
50+
51+
#imageUploader {
52+
border-radius: 5px;
53+
border-style: dashed;
54+
border-color: black;
55+
border-width: 1px;
56+
min-height: 100px;
57+
}
58+
59+
.dropzone { border: 2px dashed #0087F7; border-radius: 5px; background: white; }
60+
.dropzone .dz-message { font-weight: 400; }
61+
62+
#images {
63+
display: flex;
64+
justify-content: center;
65+
min-height: 300px;
66+
flex-wrap: wrap;
67+
}
68+
69+
.card {
70+
margin: 5px;
71+
height: 300px;
72+
width: 216px;
73+
padding: 2px;
74+
border: 2px solid black;
75+
border-radius: 5px;
76+
display: flex;
77+
align-items: center;
78+
justify-content: center;
79+
}
80+
81+
.loading {
82+
-webkit-animation: loadingAnimation 1s 20 ease;
83+
-moz-animation: loadingAnimation 1s 20 ease;
84+
-o-animation: loadingAnimation 1s 20 ease;
85+
}
86+
87+
@-webkit-keyframes loadingAnimation {
88+
from { -webkit-transform: rotate(4deg) scale(1) skew(1deg) translate(10px); }
89+
to { -webkit-transform: rotate(360deg) scale(0.795) skew(1deg) translate(0px); }
90+
}
91+
@-moz-keyframes loadingAnimation {
92+
from { -moz-transform: rotate(4deg) scale(1) skew(1deg) translate(10px); }
93+
to { -moz-transform: rotate(360deg) scale(0.795) skew(1deg) translate(0px); }
94+
}
95+
@-o-keyframes loadingAnimation {
96+
from { -o-transform: rotate(4deg) scale(1) skew(1deg) translate(10px); }
97+
to { -o-transform: rotate(360deg) scale(0.795) skew(1deg) translate(0px); }
98+
}
99+
100+
.pulse {
101+
-webkit-animation: pulseAnimation 1s infinite ease;
102+
-moz-animation: pulseAnimation 1s infinite ease;
103+
-o-animation: pulseAnimation 1s infinite ease;
104+
}
105+
@-webkit-keyframes pulseAnimation {
106+
from { -webkit-transform: rotate(0deg) scale(1) skew(0deg) translate(0px, 10px); }
107+
to { -webkit-transform: rotate(0deg) scale(1.5) skew(0deg) translate(0px, -10px); }
108+
}
109+
@-moz-keyframes pulseAnimation {
110+
from { -moz-transform: rotate(0deg) scale(1) skew(0deg) translate(0px, 10px); }
111+
to { -moz-transform: rotate(0deg) scale(1.5) skew(0deg) translate(0px, -10px); }
112+
}
113+
@-o-keyframes pulseAnimation {
114+
from { -o-transform: rotate(0deg) scale(1) skew(0deg) translate(0px, 10px); }
115+
to { -o-transform: rotate(0deg) scale(1.5) skew(0deg) translate(0px, -10px); }
116+
}
117+

client/public/js/codercards.js

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
console.log("loading");
2+
// After DOM is loaded set up Dropzone/etc.
3+
function autorun() {
4+
console.log("Dropzone configured");
5+
6+
var myDropzone = new Dropzone("form#dropzone", {
7+
autoQueue: false,
8+
url: (files) => {
9+
return `https://chrande-codercards.azurewebsites.net/upload/${files[0].name}`;
10+
},
11+
headers: {
12+
"x-ms-blob-type": "BlockBlob",
13+
"Content-Type": "image/jpeg"
14+
},
15+
clickable: true,
16+
method: "PUT",
17+
init: function () {
18+
this.on("success", function (file, response) {
19+
console.log(file.name);
20+
});
21+
this.on("addedfile", function (file) {
22+
uploadFile(file);
23+
const that = this;
24+
setTimeout(() => {
25+
that.removeFile(file);
26+
}, 1000);
27+
enqueueCard(file.name);
28+
});
29+
}
30+
31+
});
32+
}
33+
if (window.addEventListener) window.addEventListener("load", autorun, false);
34+
else if (window.attachEvent) window.attachEvent("onload", autorun);
35+
else window.onload = autorun;
36+
37+
function uploadFiles() {
38+
const files = document.getElementById("fileToUpload").files;
39+
for (const file of files) {
40+
uploadFile(file);
41+
}
42+
}
43+
44+
function enqueueCard(name) {
45+
const images = document.getElementById("images");
46+
const imageDiv = document.createElement("div");
47+
imageDiv.classList.add("card");
48+
const loading = document.createElement("span");
49+
loading.classList.add("loading");
50+
loading.classList.add("fa");
51+
loading.classList.add("fa-refresh");
52+
imageDiv.appendChild(loading);
53+
images.appendChild(imageDiv);
54+
imageDiv.id = `image-${name}`;
55+
let interval = setInterval(() => {
56+
console.log("Looking for file");
57+
getImage(name, (done) => {
58+
if (done) {
59+
console.log("Clearing interval");
60+
clearInterval(interval);
61+
}
62+
});
63+
}, 10000);
64+
}
65+
66+
function uploadFile(file) {
67+
const xhr = new XMLHttpRequest();
68+
xhr.open("PUT", `https://chrande-codercards.azurewebsites.net/upload/${file.name}`);
69+
xhr.setRequestHeader('x-ms-blob-type', 'BlockBlob');
70+
xhr.setRequestHeader('Content-Type', 'image/jpeg');
71+
xhr.send(file);
72+
}
73+
74+
function getImage(name, cb) {
75+
const xhr = new XMLHttpRequest();
76+
const imageUrl = `https://chrande-codercards.azurewebsites.net/card/${name}`;
77+
xhr.open("GET", imageUrl);
78+
xhr.responseType = "blob";
79+
xhr.onload = (e) => {
80+
if (xhr.status != 200) {
81+
console.log("Image does not exist yet");
82+
return cb(false);
83+
}
84+
let images = document.getElementById(`image-${name}`);
85+
images.innerHTML = '';
86+
let image = document.createElement('img');
87+
image.src = imageUrl;
88+
image.setAttribute("height", "300px");
89+
images.appendChild(image);
90+
console.log("Image created");
91+
return cb(true);
92+
}
93+
var results = xhr.send();
94+
}

0 commit comments

Comments
 (0)