From 1d37615e19902e66112e0ee8742274d4127842c9 Mon Sep 17 00:00:00 2001
From: Anas <93322743+bj-anas@users.noreply.github.com>
Date: Wed, 15 Mar 2023 02:03:48 +0100
Subject: [PATCH 1/5] upload image logic
---
assets/dropdown-menu.js | 2 +-
assets/product.css | 39 +++++++++++++++---
assets/product.js | 48 ----------------------
assets/upload-image.js | 70 ++++++++++++++++++++++++++++++++
sections/product-column.liquid | 8 +---
sections/product.liquid | 1 +
snippets/product-variants.liquid | 21 +++++++---
styles/product.scss | 44 +++++++++++++++++---
8 files changed, 162 insertions(+), 71 deletions(-)
create mode 100644 assets/upload-image.js
diff --git a/assets/dropdown-menu.js b/assets/dropdown-menu.js
index 279125f6..89d5f494 100644
--- a/assets/dropdown-menu.js
+++ b/assets/dropdown-menu.js
@@ -1,6 +1,6 @@
const dropdownBtn = $('.dropbtn');
const dropdownContent = $('.dropdown-content');
-const dropdownOptions = dropdownContent.querySelectorAll('li');
+const dropdownOptions = dropdownContent?.querySelectorAll('li');
function showDropDownMenu(customContent) {
if(customContent) {
diff --git a/assets/product.css b/assets/product.css
index b30ef354..149b75ed 100644
--- a/assets/product.css
+++ b/assets/product.css
@@ -194,11 +194,40 @@
gap: 30px;
}
}
-.yc-single-product .product-details .product-options .product-option .yc-upload-preview img {
- border: 1px solid var(--yc-neutral-light-color);
- padding: 5px;
- aspect-ratio: 1;
- height: 100px;
+.yc-single-product .product-details .product-options .product-option .yc-upload-preview {
+ display: none;
+ background: #F9F9F9;
+ height: auto;
+ border-radius: 8px;
+ padding: 14px 18px;
+}
+.yc-single-product .product-details .product-options .product-option .yc-upload-preview .yc-upload-wrapper {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 15px;
+}
+.yc-single-product .product-details .product-options .product-option .yc-upload-preview .yc-upload-wrapper .yc-image-preview {
+ display: flex;
+ align-items: center;
+ gap: 15px;
+}
+.yc-single-product .product-details .product-options .product-option .yc-upload-preview .yc-upload-wrapper .yc-image-preview img {
+ width: 67px;
+ height: auto;
+ border-radius: 4px;
+ object-fit: cover;
+}
+.yc-single-product .product-details .product-options .product-option .yc-upload-preview .yc-upload-wrapper .yc-image-preview .yc-image-info {
+ display: grid;
+ gap: 8px;
+ font-weight: 300;
+ font-size: 12px;
+ line-height: 120%;
+ color: var(--neutral-color);
+}
+.yc-single-product .product-details .product-options .product-option .yc-upload-preview .yc-upload-wrapper .yc-image-preview .yc-image-info .image-size {
+ color: #BABABA;
}
.yc-single-product .product-details .product-options .active {
border: 1px solid #000000;
diff --git a/assets/product.js b/assets/product.js
index 433100d1..53c688fe 100644
--- a/assets/product.js
+++ b/assets/product.js
@@ -6,54 +6,6 @@ function previewProductImage(element) {
setElementActive(element);
}
-/**
- * Upload image input handler
- * @param {HTMLElement} element
- */
-function uploadImage(element) {
- const parentSection = element.closest('.yc-single-product');
- const uploadInput = parentSection.querySelector('#yc-upload');
- let uploadedImageLink = parentSection.querySelector('#yc-upload-link');
-
- uploadInput.click();
-
- uploadInput.addEventListener('change', async function () {
- if (this.files && this.files[0]) {
- const reader = new FileReader();
- reader.readAsDataURL(this.files[0]);
-
- reader.onload = function () {
- const base64 = reader.result;
-
- const previews = parentSection.querySelectorAll(
- '.yc-upload-preview img'
- );
- previews.forEach((preview) => {
- preview.remove();
- });
-
- const uploadArea = parentSection.querySelector('.yc-upload');
- uploadArea.style.display = 'none';
-
- const preview = document.createElement('img');
- preview.src = base64;
-
- preview.addEventListener('click', function () {
- uploadArea.style.display = 'flex';
- uploadInput.value = '';
- preview.remove();
- });
- parentSection.querySelector('.yc-upload-preview').appendChild(preview);
- };
-
- const res = await youcanjs.product.upload(this.files[0]);
- if (res.error) return notify(res.error, 'error');
-
- uploadedImageLink.value = res.link;
- }
- });
-}
-
(function productImageHoverZoomer() {
const singleProductImagesPreview = document.querySelectorAll(
'.product-images-container'
diff --git a/assets/upload-image.js b/assets/upload-image.js
new file mode 100644
index 00000000..824fbd9c
--- /dev/null
+++ b/assets/upload-image.js
@@ -0,0 +1,70 @@
+/**
+ * Upload image input handler
+ * @param {HTMLElement} element
+ */
+function uploadImage(element) {
+ const parentSection = element.closest('.yc-single-product');
+ const uploadInput = parentSection.querySelector('#yc-upload');
+ const uploadArea = parentSection.querySelector('.yc-upload');
+ const imagePreview = parentSection.querySelector('.yc-upload-preview');
+ const imageWrapper = imagePreview.querySelector('.yc-image-preview');
+ const progressBar = imagePreview.querySelector('.progress-bar');
+ const closePreviewButton = $('#close-preview');
+ let uploadedImageLink = parentSection.querySelector('#yc-upload-link');
+
+ uploadInput.click();
+
+ uploadInput.addEventListener('change', async function () {
+ if (this.files && this.files[0]) {
+ const reader = new FileReader();
+ reader.readAsDataURL(this.files[0]);
+
+ reader.addEventListener("loadstart", () => {
+ console.log('file start uploading');
+ uploadArea.style.display = 'none';
+ imagePreview.style.display = 'block';
+ imageWrapper.style.opacity = 0.4;
+ progressBar.style.display = "block";
+ });
+
+ reader.addEventListener("load", () => {
+ console.log('File loaded successfully');
+ const base64 = reader.result;
+ const previews = parentSection.querySelectorAll('.yc-image-preview .yc-image img');
+
+ previews.forEach((preview) => {
+ preview.remove();
+ });
+ imageWrapper.style.opacity = 1;
+ progressBar.style.display = "none";
+
+ const preview = document.createElement('img');
+ preview.src = base64;
+ parentSection.querySelector('.yc-image-preview .yc-image').appendChild(preview);
+
+ closePreviewButton.addEventListener('click', function () {
+ uploadArea.style.display = 'flex';
+ imagePreview.style.display = 'none';
+ uploadInput.value = '';
+ preview.remove();
+ });
+ });
+
+ reader.addEventListener("progress", (event) => {
+ console.log('Progress event fired');
+ if (event.lengthComputable) {
+ const percent = (event.loaded / event.total) * 100;
+ progressBar.setAttribute("value", percent);
+ }
+ });
+
+ const res = await youcanjs.product.upload(this.files[0]);
+ if (res.error) return notify(res.error, 'error');
+
+ uploadedImageLink.value = res.link;
+ }
+ });
+}
+
+
+
diff --git a/sections/product-column.liquid b/sections/product-column.liquid
index 5bcdd0db..fbb405c8 100644
--- a/sections/product-column.liquid
+++ b/sections/product-column.liquid
@@ -6,16 +6,15 @@
padding-bottom: {{ section.settings.padding_bottom}}px;
}
- .product_customization {
+ .product_customization {
background-color: {{ section.settings.background_color.hex }};
- }
+ }
@media screen and (max-width: 768px) {
.product_customization {
display: {% if section.settings.show_product %}block{% else %}none{% endif %};
}
}
-
{%- endstyle -%}
{% for item in option.values %}
diff --git a/styles/product.scss b/styles/product.scss
index b1371f4a..25a6522d 100644
--- a/styles/product.scss
+++ b/styles/product.scss
@@ -117,7 +117,7 @@
.splide__arrow {
width: 16px;
height: 16px;
- display: flex !important;
+ display: flex !important;
@media screen and (max-width: 767px) {
width: 36px;
@@ -202,11 +202,43 @@
.product-option {
.yc-upload-preview {
- img {
- border: 1px solid var(--yc-neutral-light-color);
- padding: 5px;
- aspect-ratio: 1;
- height: 100px;
+ display: none;
+ background: #F9F9F9;
+ height: auto;
+ border-radius: 8px;
+ padding: 14px 18px;
+
+ .yc-upload-wrapper {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 15px;
+
+ .yc-image-preview {
+ display: flex;
+ align-items: center;
+ gap: 15px;
+
+ img {
+ width: 67px;
+ height: auto;
+ border-radius: 4px;
+ object-fit: cover;
+ }
+ }
+
+ .yc-image-preview .yc-image-info {
+ display: grid;
+ gap: 8px;
+ font-weight: 300;
+ font-size: 12px;
+ line-height: 120%;
+ color: var(--neutral-color);
+
+ .image-size {
+ color: #BABABA;
+ }
+ }
}
}
}
From 5bd7e832a30dd647b4cd4d8f8546620fa0d4e974 Mon Sep 17 00:00:00 2001
From: Anas <93322743+bj-anas@users.noreply.github.com>
Date: Wed, 15 Mar 2023 12:26:47 +0100
Subject: [PATCH 2/5] add progress bar
---
assets/main.css | 14 ++++++++--
assets/product.css | 15 +++++++++-
assets/upload-image.js | 47 ++++++++++++++++++--------------
locales/ar.default.json | 2 +-
snippets/product-variants.liquid | 6 ++--
styles/main.scss | 16 ++++++++---
styles/product.scss | 17 +++++++++++-
7 files changed, 84 insertions(+), 33 deletions(-)
diff --git a/assets/main.css b/assets/main.css
index bbbe41cd..9dffec20 100644
--- a/assets/main.css
+++ b/assets/main.css
@@ -290,19 +290,27 @@ input:not([type=radio]),
.yc-upload {
border: 1px dashed var(--yc-neutral-light-color);
+ color: var(--yc-neutral-color);
width: 100%;
height: 120px;
display: flex;
+ flex-direction: column;
align-items: center;
justify-content: center;
- gap: 10px;
+ border-radius: 8px;
+ gap: 12px;
+ font-weight: 300;
+ font-size: 12px;
+ line-height: 120%;
cursor: pointer;
}
.yc-upload input {
display: none;
}
-.yc-upload .upload-msg {
- margin-left: 5px;
+.yc-upload .upload-icon {
+ width: 22px;
+ height: 22px;
+ color: #A7A7A7;
}
.yc-number {
diff --git a/assets/product.css b/assets/product.css
index 149b75ed..375d662c 100644
--- a/assets/product.css
+++ b/assets/product.css
@@ -224,11 +224,24 @@
font-weight: 300;
font-size: 12px;
line-height: 120%;
- color: var(--neutral-color);
+ color: var(--yc-neutral-color);
}
.yc-single-product .product-details .product-options .product-option .yc-upload-preview .yc-upload-wrapper .yc-image-preview .yc-image-info .image-size {
color: #BABABA;
}
+.yc-single-product .product-details .product-options .product-option .yc-upload-preview .progress-container {
+ width: 100%;
+ height: 3px;
+ background-color: #cecece;
+ border-radius: 5px;
+}
+.yc-single-product .product-details .product-options .product-option .yc-upload-preview .progress-bar {
+ width: 0%;
+ height: 100%;
+ background-color: var(--yc-primary-color);
+ border-radius: 5px;
+ transition: width 1s ease-in-out;
+}
.yc-single-product .product-details .product-options .active {
border: 1px solid #000000;
}
diff --git a/assets/upload-image.js b/assets/upload-image.js
index 824fbd9c..a17003fc 100644
--- a/assets/upload-image.js
+++ b/assets/upload-image.js
@@ -8,7 +8,7 @@ function uploadImage(element) {
const uploadArea = parentSection.querySelector('.yc-upload');
const imagePreview = parentSection.querySelector('.yc-upload-preview');
const imageWrapper = imagePreview.querySelector('.yc-image-preview');
- const progressBar = imagePreview.querySelector('.progress-bar');
+ const progressContainer = imagePreview.querySelector('.progress-container');
const closePreviewButton = $('#close-preview');
let uploadedImageLink = parentSection.querySelector('#yc-upload-link');
@@ -19,24 +19,18 @@ function uploadImage(element) {
const reader = new FileReader();
reader.readAsDataURL(this.files[0]);
- reader.addEventListener("loadstart", () => {
- console.log('file start uploading');
- uploadArea.style.display = 'none';
- imagePreview.style.display = 'block';
- imageWrapper.style.opacity = 0.4;
- progressBar.style.display = "block";
- });
-
reader.addEventListener("load", () => {
- console.log('File loaded successfully');
const base64 = reader.result;
const previews = parentSection.querySelectorAll('.yc-image-preview .yc-image img');
previews.forEach((preview) => {
preview.remove();
});
- imageWrapper.style.opacity = 1;
- progressBar.style.display = "none";
+
+ uploadArea.style.display = 'none';
+ imagePreview.style.display = 'block';
+ imageWrapper.style.opacity = 0.4;
+ progressContainer.style.display = "block";
const preview = document.createElement('img');
preview.src = base64;
@@ -48,14 +42,8 @@ function uploadImage(element) {
uploadInput.value = '';
preview.remove();
});
- });
- reader.addEventListener("progress", (event) => {
- console.log('Progress event fired');
- if (event.lengthComputable) {
- const percent = (event.loaded / event.total) * 100;
- progressBar.setAttribute("value", percent);
- }
+ smoothProgressBar();
});
const res = await youcanjs.product.upload(this.files[0]);
@@ -64,7 +52,24 @@ function uploadImage(element) {
uploadedImageLink.value = res.link;
}
});
-}
-
+ function smoothProgressBar() {
+ const progressBar = document.querySelector('.progress-bar');
+ let progress = 0;
+ progressBar.style.width = progress;
+ const interval = setInterval(() => {
+ if (progress >= 100) {
+ setTimeout(() => {
+ progressContainer.style.display = 'none';
+ imageWrapper.style.opacity = 1;
+ }, 1000);
+ clearInterval(interval);
+ return;
+ }
+ progress += 10;
+ progressBar.style.width = `${progress}%`;
+ }, 200);
+ progressBar.style.transition = 'width 1s ease-in-out';
+ }
+}
diff --git a/locales/ar.default.json b/locales/ar.default.json
index ab72317c..dff1b4e7 100644
--- a/locales/ar.default.json
+++ b/locales/ar.default.json
@@ -67,7 +67,7 @@
"single_product": {
"quantity": "الكمية",
"variants": {
- "upload": "تحميل صورة"
+ "upload": "تحميل صورة (PNG, JPEG)"
}
},
"express_checkout": {
diff --git a/snippets/product-variants.liquid b/snippets/product-variants.liquid
index a2f9b78b..aa00bf99 100644
--- a/snippets/product-variants.liquid
+++ b/snippets/product-variants.liquid
@@ -61,7 +61,7 @@
{% when 'upload_image_zone' %}