diff --git a/.gitignore b/.gitignore index 838458f..178135c 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -/dist/ \ No newline at end of file +/dist/ diff --git a/src/index.css b/src/index.css new file mode 100644 index 0000000..c2c66bb --- /dev/null +++ b/src/index.css @@ -0,0 +1,44 @@ +:root{ + --buttonSize: 70px; + --buttonOffset: 10px; + --buttonRadius: 10px; + --previewWidth: 30vw; + --previewHeight: 100vh; + --previewXOffset: 0; + --previewYOffset: 0; + --animationDuration: 500ms; +} +#previewButton { + position: fixed; + width: var(--buttonSize); + height: var(--buttonSize); + bottom: var(--buttonOffset); + right: var(--buttonOffset); + border-radius: var(--buttonRadius); + z-index: 2; +} + +#previewButton > *{ + width: 100%; + height: 100%; +} + +#previewBlock{ + position: fixed; + top: var(--previewYOffset); + right: var(--previewXOffset); + width: var(--previewWidth); + height: var(--previewHeight); + z-index: 1; + transition: var(--animationDuration); + right: -100%; +} + +@media screen and (max-width: 1000px){ + #previewButton{ + display: none; + } + #previewBlock{ + display: none; + } +} \ No newline at end of file diff --git a/src/index.js b/src/index.js index dbbea67..bc64282 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,5 @@ const localStorageIgnore = ["photo"]; +const themeUrl = "https://cdn.jsdelivr.net/npm/linkfree-themes@1.1.0"; // Elements const addCustomLinkButton = document.querySelector("a.btn"); @@ -218,3 +219,152 @@ checkbox_preview.addEventListener("change", () => { checkbox_zip.addEventListener("change", () => { checkbox_preview.disabled = checkbox_zip.checked; }); + +/*****************************************************/ +/***************** Real Time Preview *****************/ +/*****************************************************/ + +// Get Window Elements +var previewButton = document.getElementById('previewButton'); +var previewBlock = document.getElementById('previewBlock'); +var additionalLinkButton = document.getElementById("additionalLink"); +var formData = document.getElementById('form'); +var theme = document.getElementById('theme'); + +// Real time variables +var preview = false; +var photo = ""; +var linkCount = Number(additionalLinkButton.getAttribute("data-index")); +const styleElement = document.createElement('style'); + +// Preview Button functionality +previewButton.addEventListener('click', () => { + preview = !preview; + if (preview) { + // previewBlock.style.display = 'block'; + previewBlock.style.right = '0'; + previewButton.style.filter = 'invert(1)'; + UpdatePreview(); + } else { + // previewBlock.style.display = 'none'; + previewBlock.style.right = '-100%'; + previewButton.style.filter = 'invert(0)'; + } +}); + +// Update Preview Photo On Input +formData['photo'].addEventListener('input', (e) => { + var photoData = e.target.files[0]; + if(photoData) { + const reader = new FileReader(); + reader.onload = (e) => { + photo = e.target.result; + UpdatePreview(); + } + reader.readAsDataURL(photoData); + } +}); + +// Add Listner for additionalLinkButton and for form data +additionalLinkButton.addEventListener('click', () => { + linkCount++; + var linkId = `links[${linkCount}]`; + document.getElementById(linkId + "[url]").addEventListener('input', UpdatePreview); + document.getElementById(linkId + "[name]").addEventListener('input', UpdatePreview); + document.getElementById(linkId + "[icon]").addEventListener('input', UpdatePreview); +}); + +// Update Prview Function +function UpdatePreview() { + var name = formData['name'].value; + var mainUrl= formData['url'].value; + var description = formData['description'].value; + var email = formData['email'].value; + var links = ""; + var photoCode = ""; + var themePath = ""; + + // Links + for (var i = 0; i < linkCount; i++) { + var linkId = `links[${i}]`; + var linkUrl = document.getElementById(linkId + "[url]").value; + var linkName = document.getElementById(linkId + "[name]").value; + var linkIcon = document.getElementById(linkId + "[icon]").value; + + if(linkUrl !== ""){ + if(linkIcon !== ""){ + links += + ` + + ${linkName} `; + } + else{ + links += + ` + ${linkName} `; + } + } + } + + // Check if data is added + if(photo !== '') photoCode = `User Photo`; + if(name !== '') name = `

${name}

`; + if(description !== '') description =`

${description}

`; + if(email !== '') email = ` Email`; + + // Add path to files + if(theme.value !== "") + { + let jsonString = theme.value.match(/{.*}/)[0]; + var json = JSON.parse(jsonString); + themePath = "themes/" + json.id; + } + else themePath = "themes/darkmode"; + + // Add Style + var themeStylePath = themeUrl + "/" + themePath+ "/" + "style.css"; + + // Add JS + var themeJSPath = themeUrl + "/" + themePath+ "/" + "index.js"; + + // Update Preview + var previewHTMLCode = + ` + + + + + + + ${photoCode} + ${name} + ${description} + + + + + + `; + + var blob = new Blob([previewHTMLCode], { type: 'text/html' }); + var url = URL.createObjectURL(blob); + previewBlock.innerHTML = ``; +}; + +// Add Listner for all links on file Load +for (var i = 0; i < linkCount; i++) { + var linkId = `links[${i}]`; + document.getElementById(linkId + "[url]").addEventListener('input', UpdatePreview); + document.getElementById(linkId + "[name]").addEventListener('input', UpdatePreview); + document.getElementById(linkId + "[icon]").addEventListener('input', UpdatePreview); +} + +// Add Listner for all forms inputs on file Load +formData['name'].addEventListener('input', UpdatePreview); +formData['url'].addEventListener('input', UpdatePreview); +formData['description'].addEventListener('input', UpdatePreview); +formData['email'].addEventListener('input', UpdatePreview); +theme.addEventListener('input', UpdatePreview); \ No newline at end of file diff --git a/src/index.php b/src/index.php index b27f214..86b4f89 100644 --- a/src/index.php +++ b/src/index.php @@ -43,7 +43,24 @@ + + + + + + + + + + + + + + + + LinkFree Generator + @@ -53,7 +70,7 @@

Fill out this form to generate your own single page website. All fields are optional except for your name. So, don't worry if you don't have all these accounts. The output will be a single index.html file that you can upload to any static hosting provider such as GitHub Pages, Cloudflare Pages, Vercel, Netlify, or DigitalOcean Apps.

-
+
@@ -102,7 +119,7 @@
- + Add Additional Link + + Add Additional Link
@@ -154,7 +171,11 @@
+ + +
- + +