i need a cli to host the backend of my web application, i tried to install Heroku cli in visual studio but it didn’t work, or maybe i don’t know how to install it. I’m new to web development, can someone explain what a CLI is used for.
Category: javascript
Category Added in a WPeMatico Campaign
Adding new slides dynamically using AJAX to Swiper
I am currently using Swiper and I am facing an issue while adding new slides dynamically using AJAX. does anyone know how to fix the progress after adding new slides in Swiper?
Here’s a snippet of my code where I append a new slide:
<script>
let target = $('.parent-archive-stories[data-index-id="' + item_id + '"] .archive-stories').children().eq(0);
if (target.length) {
target.after(newBoxActiveStory);
if (typeof window.swiperSingle === "function") {
let storiesSingleSwiper = window.swiperSingle();
storiesSingleSwiper.isNewStoryJustAdded = true;
// If storiesSingleSwiper is already initialized, work with it
let swiperContainer = storiesSingleSwiper.el.stories.querySelector('.js-swiper-pagination-progress-with-thumbs-main-2[data-current-object-component="' + item_id + '"]');
if (swiperContainer && swiperContainer.swiper) {
let swiperInstanceSingle = swiperContainer.swiper;
console.log(swiperContainer);
// swiperInstanceSingle.params.skipNextContentCheck = true;
// Add a new slide
swiperInstanceSingle.prependSlide(response.data.storio_swiper_single_stories);
// Update Swiper
swiperInstanceSingle.update();
swiperInstanceSingle.pagination.update();
swiperInstanceSingle.updateSize();
swiperInstanceSingle.init();
// swiperInstanceSingle.destroy();
console.log(swiperInstanceSingle);
}
storiesSingleSwiper.init();
}
}
and here is the swiper code snippet
window.swiperSingle = function() {
var storiesSingleSwiper;
(function () {
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
// console.clear();
class StoriesSingle {
constructor() {
_defineProperty(this, "el", {});
_defineProperty(this, "autoDelay", 5000);
_defineProperty(this, "timer", null);
_defineProperty(this, "isPause", false);
this.audioPlaySvg = `
<svg width="14px" height="20px" viewBox="0 0 10 8" version="1.1" xmlns="http://www.w3.org/2000/svg">
</svg>`;
this.audioPauseSvg = `
<svg id="Audio_Wave_24" width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
</svg>`;
this.el.demo = document.querySelector('.archive-stories');
this.el.stories = document.querySelector('.stories-slider');
if (!this.el.demo && !this.el.stories) return false;
}
init() {
this.initDemo();
this.initStories();
this.setupKeyboardNavigation();
}
initDemo() {
const _self = this;
_self.el.demo.addEventListener('click', event => {
const ignoreSelectors = [
'.pause-video-with-thumbnail',
'.youzify-storie-menu-push-holder',
'.more-users-btn',
'.storio-story-views-count',
'.storio-story-likes-count'
];
const isIgnored = ignoreSelectors.some(selector => event.target.closest(selector));
if (isIgnored) {
return;
}
const target = event.target.closest('.storio-stories-archive-thumb');
if (target) {
event.preventDefault();
this.initStories();
const indexAttr = target.dataset.userIndex;
if (indexAttr === undefined) return;
const index = parseInt(indexAttr, 10);
if (!isNaN(index) && index >= 0) {
_self.storiesOpenUser(index);
}
}
});
}
initStories() {
const _self = this;
_self.applyDynamicBackground();
// Вешаем делегирование событие по клику
_self.el.stories.addEventListener('click', event => {
const SeeMoreStories = event.target.closest('.storio-story-text-description .storio-stories-see-more'); // если нажата кнопка закрытия..
if (SeeMoreStories) {
event.preventDefault();
const storyId = SeeMoreStories.getAttribute('data-story_id');
_self.SeeMoreStories(storyId);
event.stopPropagation();
};
const targetClickStories = event.target.closest('.storio-user-stories-slide');
if (targetClickStories) {
const swiperWrapper = _self.el.stories.querySelector('.swiper-wrapper');
const slides = swiperWrapper.querySelectorAll('.storio-user-stories-slide');
let targetIndex = Array.from(slides).indexOf(targetClickStories);
if (targetIndex !== -1 && _self.swiperUsers) {
_self.swiperUsers.slideTo(targetIndex, 500);
}
}
const targetClose = event.target.closest('button.stories-slider-close-button'); // если нажата кнопка закрытия..
if (targetClose) _self.storiesModalClose(); // .. то закрываем модалку
const buttonPrev = event.target.closest('.stories-slider-button.storio-stories-slider-button-prev');
if (buttonPrev) _self.buttonPrev();
const buttonNext = event.target.closest('.stories-slider-button.storio-stories-slider-button-next');
if (buttonNext) _self.buttonNext();
const MuteStoriesButton = event.target.closest('.button-mutesound-storio-stories');
if (MuteStoriesButton) _self.onMuteStoriesButtonClick();
const unMuteStoriesButton = event.target.closest('.button-unmutesound-storio-stories');
if (unMuteStoriesButton) _self.onUnMuteStoriesButtonClick();
const pauseStoriesButton = event.target.closest('.slider-actions-stories .btn-action-stories .button-pause-storio-stories');
if (pauseStoriesButton) {
event.preventDefault();
_self.onPauseStoriesButtonClick();
event.stopPropagation();
};
const playStoriesButton = event.target.closest('.button-play-storio-stories');
if (playStoriesButton) _self.onPlayStoriesButtonClick();
const threeOptionButton = event.target.closest('.button-dropdown-stories');
if (threeOptionButton) {
event.preventDefault();
const storyId = threeOptionButton.getAttribute('data-story_id');
const userId = threeOptionButton.getAttribute('data-user-id');
_self.showOptionStoriesButtonClick(storyId, userId);
event.stopPropagation();
}
const closeOptionButton = event.target.closest('.close-content-story');
if (closeOptionButton) {
event.preventDefault();
const storyId = closeOptionButton.getAttribute('data-story_id');
const userId = closeOptionButton.getAttribute('data-user-id');
_self.closeOptionStoriesButtonClick(storyId, userId);
event.stopPropagation();
}
const deleteButton = event.target.closest('.storio-delete-story');
if (deleteButton) {
event.preventDefault();
const storyId = deleteButton.getAttribute('data-story_id');
const userId = deleteButton.getAttribute('data-user-id');
_self.deleteStory(storyId, userId);
}
const likeButton = event.target.closest('.like-story-btn');
if (likeButton) {
event.preventDefault();
const storyId = likeButton.getAttribute('data-story_id');
const userId = likeButton.getAttribute('data-user_id');
_self.likeStory(storyId, userId);
event.stopPropagation();
}
});
// Вешаем событие окончания анимации на модалку
_self.el.stories.addEventListener('animationend', event => {
if (_self.el.stories.classList.contains('stories-slider-out')) { // Если у нас анимация закрытия модалки..
_self.el.stories.classList.remove('stories-slider-out'); // .. то после окончания анимации класс удалится.
}
if (_self.el.stories.classList.contains('stories-slider-in') && _self.swiperStories) { // Если анимация появления..
_self.checkContent();
_self.startProgress();
}
});
const slides = _self.el.stories.querySelectorAll('.js-swiper-pagination-progress-with-thumbs-main-2 .swiper-wrapper .storio-user-stories-slide .js-swiper-pagination-progress-with-thumbs-main .swiper-wrapper .swiper-slide.storio_per_slider');
// Создаём слайдер с пользователя (3д)
_self.swiperUsers = new Swiper(_self.el.stories.querySelector('.js-swiper-pagination-progress-with-thumbs-main-2'), {
effect: 'coverflow',
autoplay: false,
spaceBetween: 90,
slidesPerView: 'auto',
touchMove: false,
allowTouchMove: false,
coverflowEffect: {
rotate: 0,
stretch: 0,
depth: 100,
modifier: 1,
slideShadows: true,
},
on: {
afterInit: swiper => {
const getSwiperContent = swiper.slides;
getSwiperContent.forEach((slide, index) => {
const swiperPerSlider = slide.querySelector('.swiper-slide.storio_per_slider');
const background = swiperPerSlider.getAttribute('data-display-background');
if (background) {
swiperPerSlider.style.background = background;
} else {
console.log('No data-display-background attribute found');
}
});
},
transitionEnd: swiper => {
_self.changeSlide(swiper);
_self.checkContent();
// _self.onPlayStoriesButtonClick();
// alert("coba")
},
touchStart: () => {
_self.isPause = false;
if (_self.video) _self.video.pause();
if (_self.audio) _self.audio.pause();
if (_self.timerTouch) clearTimeout(_self.timerTouch);
_self.timerTouch = setTimeout(() => {
_self.isTouch = true;
}, 250);
},
touchEnd: () => {
_self.isPause = false;
if (_self.video) _self.video.play();
if (_self.audio) _self.audio.play();
if (_self.timerTouch) clearTimeout(_self.timerTouch);
_self.timerTouch = setTimeout(() => {
_self.isTouch = false;
}, 100);
}
}
});
// Проходим по всем слайдерам сторис
_self.el.stories.querySelectorAll('.js-swiper-pagination-progress-with-thumbs-main-2 .swiper').forEach(el => {
new Swiper(el, {
slidesPerView: 1,
effect: 'fade',
speed: 1,
pagination: { // Создаём кастомную пагинацию
type: 'custom',
el: el.querySelector('.storio-stories-slider-pagination'),
bulletClass: 'storio-stories-slider-pagination-bullet',
bulletActiveClass: 'storio-stories-slider-pagination-bullet-active',
renderCustom: (swiper, current, total) => {
current--;
const pagination = swiper.originalParams.pagination;
return Array(total).fill('').map((el, i) => {
const classes = [pagination.bulletClass]; // У каждой "точки" пагинации будет свой класс, который указан в параметрах свайпера
if (i === current) classes.push(pagination.bulletActiveClass); // Если "точка" активная, то выдаётся ей нужный класс
if (i < current) classes.push(pagination.bulletClass + '-viewed'); // Все предыдущие до активной будут иметь другой класс
return `<div class="${classes.join(' ')}"></div>`; // HTML код точки.
}).join('');
}
},
on: {
afterInit: swiper => {
const paginationLock = el.querySelector('.storio-stories-slider-pagination');
if (paginationLock) {
paginationLock.classList.remove('swiper-pagination-lock');
}
},
slideChange: swiper => { // При переключении слайда выполняем следующие действия:
_self.changeSlide(swiper); // триггерим смену слайда
_self.checkContent(); // определяем содержимое активного слайда сторис
}
}
});
});
}
startProgress() {
const _self = this;
if (!_self.swiperStories ) {
return;
}
_self.stopProgress();
_self.progress = 0;
const time = _self.autoDelay / 100;
_self.swiperStories.el.style.setProperty('--progress', _self.progress);
const activeSlide = this.swiperStories.slides[_self.swiperStories.activeIndex];
const indexitems = activeSlide.querySelector('.stories-slider-content');
const story_id = indexitems ? indexitems.getAttribute('data-story_id') : '';
const user_id = indexitems ? indexitems.getAttribute('data-user_id') : '';
const last_story = document.querySelector('.storio-user-stories-slide[data-user_id="' + user_id + '"]');
const last_story_id = last_story ? last_story.getAttribute('data-last-story-id') : null;
if ( story_id > last_story_id) {
window.parent.postMessage({
type: 'seenStories',
story_id: story_id,
last_story_id: last_story_id,
user_id: user_id,
}, '*');
}
_self.timer = setInterval(() => {
if (_self.video || _self.audio) {
_self.stopProgress();
return false;
}
_self.progress <= 100 && !_self.isPause ? (_self.progress += 1) : false;
_self.swiperStories?.el.style.setProperty("--progress", _self.progress);
if (_self.swiperStories?.isEnd && _self.progress === 100) {
_self.stopProgress();
_self.swiperUsers.isEnd ? _self.storiesModalClose() : false;
_self.swiperUsers.slideNext();
} else if (_self.progress === 100) {
_self.swiperStories?.slideNext();
}
}, time);
}
changeSlide(swiper) {
this.stopProgress(); // Останавливаем прогресс ..
this.startProgress(); // .. запускаем прогресс заново ..
this.getActiveSwiperStoriesInSwiperUsers(); // .. получаем активный слайдер сторис
const slides = swiper.slides;
slides.forEach(slide => {
const isActive = slide.classList.contains('swiper-slide-active');
const parentButton = slide.querySelector('.storio-stories-slider-parent-button');
const audioButton = slide.querySelector('.yzs-stories-audio .yzs-stories-loader'); // Assuming this is the button for audio
if (isActive) {
parentButton.style.opacity = '1';
parentButton.style.pointerEvents = 'auto';
if (audioButton) {
audioButton.innerHTML = this.audioPlaySvg; // Show play icon
}
} else {
parentButton.style.opacity = '0';
parentButton.style.pointerEvents = 'none';
if (audioButton) {
audioButton.innerHTML = this.audioPauseSvg; // Show pause icon
}
}
});
}
stopProgress() {
if (!this.swiperStories) return;
if (this.swiperStories && this.swiperStories.el) {
clearInterval(this.timer);
this.progress = 0;
this.swiperStories.el.style.setProperty('--progress', this.progress);
} else {
console.warn('Cannot stop progress: swiperStories is not initialized.');
}
}
onPauseStoriesButtonClick() {
const _self = this;
const activeSlide = _self.swiperStories?.slides[_self.swiperStories.activeIndex];
if (!activeSlide) return;
_self.isPause = true;
if (_self.audio) {
_self.audio.pause();
} else if (_self.video){
_self.video.pause();
}
const audioButton = activeSlide.querySelector('.yzs-stories-audio .yzs-stories-loader');
if (audioButton) {
audioButton.innerHTML = this.audioPauseSvg;
}
document.querySelectorAll('.button-pause-storio-stories').forEach(function(div) {
div.classList.remove('button-pause-storio-stories');
div.classList.add('button-play-storio-stories');
const icons = div.querySelectorAll('i');
icons.forEach(function(icon) {
const newIcon = document.createElement('i');
newIcon.className = 'fa-solid fa-play';
icon.parentNode.replaceChild(newIcon, icon);
});
});
}
onPlayStoriesButtonClick() {
const _self = this;
_self.isPause = false;
if (_self.audio) {
_self.audio.play();
} else if (_self.video){
_self.video.play();
}
const activeSlide = _self.swiperStories?.slides[_self.swiperStories.activeIndex];
if (!activeSlide) return;
const audioButton = activeSlide.querySelector('.yzs-stories-audio .yzs-stories-loader');
if (audioButton) {
audioButton.innerHTML = this.audioPlaySvg;
}
document.querySelectorAll('.button-play-storio-stories').forEach(function(div) {
div.classList.remove('button-play-storio-stories');
div.classList.add('button-pause-storio-stories');
const icons = div.querySelectorAll('i');
icons.forEach(function(icon) {
const newIcon = document.createElement('i');
newIcon.className = 'fa-solid fa-pause';
icon.parentNode.replaceChild(newIcon, icon);
});
});
}
storiesSingleSwiper = new StoriesSingle();
})();
return storiesSingleSwiper;
}
window.storiesSingleSwiper = window.swiperSingle();
</script>
I have tried
swiperInstanceSingle.update(); swiperInstanceSingle.pagination.update(); swiperInstanceSingle.updateSize(); swiperInstanceSingle.init();
but still if after the new appendslide then click the pause button the pagination progress bar keeps running and does not want to be paused, I am confused and just stack there
When hooking using Frida, certain locations are not hooked with Error(unable to intercept function at 0040101D; please file a bug at value)
First of all, I apologize for my English skills.
i’m hooking a simple example through frida.
However, there was a problem in progress, but my skills are not good, so I don’t know what to search for and get through.
If you know the answer, you can let me know, or I’m asking if there are any keywords I can search for.
The questions are below.
During hooking, some of the locations of the target program are not hooking properly.
target program with disassembler
**Error: unable to intercept function at 0040101D; please file a bug at value (frida/runtime/core.js:408) at <eval> (C:UserslaplaDocumentscodeengn 1.js:21)**
All parts except that part are hooking normally, but I’m not sure why.
I wonder if 32bit is the problem, so it’s the same even if I install python 32bit, and it works same even if I hooking same intruction “inc esi”, “dec eax” in different locations.
The problem only occurs in the above position, so may I know why?
The hooking target is the file at the following URL.(password is codeengn)
github.com/codeengn/codeengn-challenges/raw/main/RCE_Basic/…
And this is the code I used.
var Base = Module.findBaseAddress('01.exe');
var interloc = Base.add(0x101D);
console.log(Base);
console.log(Instruction.parse(ptr(interloc)).toString());
Interceptor.attach(interloc, {
onEnter(args) {
console.log('onEnter');
var reg = this.context;
console.log(JSON.stringify(reg, 0, 2));
console.log(reg.eax);
reg.eax = ptr('0x3')
},onLeave(retval) {
console.log('onLeave');
var reg = this.context;
console.log(JSON.stringify(reg, 0, 2));
}
});
I installed and ran a 32-bit python, but the same error occurred. Additionally, i try hooking the same command in another location, it will be normally hooked. I don’t even know how to search because I have little knowledge. Is there a way to know the cause?
Redirects to Previously Logged-in User
I am facing an issue with my application that integrates with the Spotify API for user authentication. Specifically, the problem occurs during the login process. When the user visits the login page, it redirects them to the previously logged-in user’s session instead of prompting for new credentials.
Details
Application Details:
Issue Description
Expected Behavior:
When the login page is accessed, the user should be prompted to log in with fresh credentials.
Observed Behavior:
The login page automatically redirects to the dashboard of the previously logged-in user without prompting for new credentials.
What I Have Tried
Added show_dialog=true to Login URL:
Ensures the Spotify login page forces re-authentication.
Cleared LocalStorage and SessionStorage:
Verified that spotify_access_token and spotify_token_expiration are properly removed during logout.
Spotify Logout URL:
Redirects to https://www.spotify.com/logout/ to log the user out of Spotify.
Routing Logic:
Ensured no auto-redirects to the dashboard exist when no token is found.
Environment Details
Frontend Framework: React (with React Router)
Spotify API: Using Implicit Grant Flow
Storage: localStorage for token and expiration data
Request for Help
How can I ensure the Spotify login page always prompts for fresh credentials?
Is there a better way to invalidate the Spotify session to avoid auto-login?
Are there specific Spotify API settings I might have misconfigured?
Any insights or suggestions to resolve this issue would be greatly appreciated. Thank you in advance!
Choosing Between React and Pure JavaScript for Lightweight UI Library as a Service with API Integration [closed]
I am working on building a UI library as a service that integrates with APIs and is framework-agnostic (usable with React, Vue, Angular, or even pure JavaScript applications). I aim to create lightweight, reusable components that are scalable and performant while ensuring the following considerations:
- Lightweight components: The library should be minimal and not
introduce unnecessary dependencies or complexity to the consuming
applications. e.g.: MUI is not light weight Framework compatibility: - It should work seamlessly across different frameworks (Vue, Angular,
React) without locking the client into a specific framework - Performance: High performance is critical, especially for real-time
updates in charts and tables. - State management: Limit the need for
extensive state management, especially to avoid unnecessary overhead in client applications. - Widgets provided: Includes filters, tables,
and charts as primary widgets. - Event pub-sub: Efficient
communication between widgets (e.g., filter widget updating a chart
widget). - Reusability: Components should be modular and reusable
across multiple projects. Scalability: Designed for growth in
features and client base.
Additionally, if we choose React:
What challenges might arise if there are runtime version mismatches between our package’s React version and the client’s React version?
How can we mitigate potential conflicts or issues caused by different React runtimes?
Would it be better to go with Pure JavaScript or another library to avoid these pitfalls?
Are there any other factors I should consider to ensure the library remains lightweight and framework-agnostic? Any insights or best practices would be appreciated.
Filtering product variants
[
[
{
"name": "RAM",
"id": 84,
"value": "8 GB"
},
{
"name": "ROM",
"id": 82,
"value": "128 GB"
},
{
"name": "Color",
"id": 85,
"value": "Black"
}
],
[
{
"name": "RAM",
"id": 84,
"value": "8 GB"
},
{
"name": "ROM",
"id": 82,
"value": "128 GB"
},
{
"name": "Color",
"id": 86,
"value": "White"
}
],
[
{
"name": "RAM",
"id": 83,
"value": "12 GB"
},
{
"name": "ROM",
"id": 81,
"value": "256 GB"
},
{
"name": "Color",
"id": 85,
"value": "Black"
}
],
[
{
"name": "RAM",
"id": 83,
"value": "12 GB"
},
{
"name": "ROM",
"id": 81,
"value": "256 GB"
},
{
"name": "Color",
"id": 86,
"value": "White"
}
]
]
The above list shows the variants of each product. Each table contains the characteristics of a particular variant with a division into RAM/ROM and Color.
So the product contains variants:
-
8GB/128GB/Black
-
8GB/128GB/White
-
12GB/256GB/Black
-
12GB/256GB/White
We always have additional information about the currently selected variant – in this case the selected variant is 8GB/128GB/Black
I created a script that creates groups of buttons based on product variants to easily create configurability:
const result = {};
variants.forEach(v => {
v.forEach(p => {
if (p.name in result == false) {
result[p.name] = new Map();
}
result[p.name].set(p.id, {
id: p.id,
value: p.value
})
})
});
Object.entries(result).map(([ key, value ]) => ({
name: key,
options: Array.from(value.values())
}))
This script returns the above data structure:
[
{
"name": "RAM",
"options": [
{
"id": 84,
"value": "8 GB"
},
{
"id": 83,
"value": "12 GB"
}
]
},
{
"name": "ROM",
"options": [
{
"id": 82,
"value": "128 GB"
},
{
"id": 81,
"value": "256 GB"
}
]
},
{
"name": "Color",
"options": [
{
"id": 85,
"value": "Black"
},
{
"id": 86,
"value": "White"
}
]
}
]
This allows you to create the buttons below to configure the variant.
Variants

But, this script doesn’t take into account the possible options for the currently selected variant – we always show all the buttons, so clicking on the 12GB RAM option will cause you to switch to the new variant, and its buttons will change to the 12GB/256GB/Black configuration. The same goes for the 256GB ROM.
As you can see, we don’t have to show any of the groups (8GB/12GB) or (128GB/256GB).
But I can’t find a solution to combine these variants into a certain dependency.
You should also remember that we can add another variant e.g. 12GB/128GB/White which complicates the matter even more.
I would like to dynamically achieve the following data structure: (As you can see, the ROM has only one option so the group is hidden):
Variants 2

[
{
"name": "RAM",
"options": [
{
"id": 84,
"value": "8 GB"
},
{
"id": 83,
"value": "12 GB"
}
]
},
{
"name": "ROM",
"options": [
{
"id": 82,
"value": "128 GB"
}
]
},
{
"name": "Color",
"options": [
{
"id": 85,
"value": "Black"
},
{
"id": 86,
"value": "White"
}
]
}
]
How to download images to pdf using html2-pdf
I am trying to download pdf with my DataTable records each record have download report button while hit on that button I want to download the pdf with respective row data so I’m using html2-pdf library when I hit on download report button pdf is being downloaded but when hit on first time on download report button a few images are being displayed in pdf and when hit on second time then all available images are being displayed in pdf. what is the issue and where I did mistake that and how do that am new to scripting.
<script>
//Handling pdf
$('#qcDetailsTable tbody').on('click', '.download-button', async function () {
const row = $(this).closest('tr'); // Get the clicked row
const rowData = $('#qcDetailsTable').DataTable().row(row).data(); // Get raw data from DataTable
// Collect and format image URLs
const images = $(rowData.images).map(function () {
return $(this).attr('href'); // Extract the href attribute (image URL) from each <a> tag
}).get(); // Convert jQuery object to a plain array
// Join the array into a single string with URLs separated by commas
const imagesString = images.join(", ");
// Extract values from HTML
const data = {
growerName: $(rowData.growerName).val(),
packingDate: $(rowData.packingDate).val(),
crop: $(rowData.crop).val(),
variety: $(rowData.variety).val(),
packingType: $(rowData.packingType).val(),
customerName: $(rowData.customerName).val(),
lotCode: $(rowData.lotCode).val(),
traceabilityCode: $(rowData.traceabilityCode).val(),
brand: $(rowData.brand).val(),
grade: $(rowData.grade).val(),
farmRegistrationNumber: $(rowData.farmRegistrationNumber).val(),
ggn: $(rowData.ggn).val(),
grossWeightPerCarton: $(rowData.grossWeightPerCarton).val(),
netWeightPerPunnet: $(rowData.netWeightPerPunnet).val(),
brix: $(rowData.brix).val(),
berrySize: $(rowData.berrySize).val(),
colorTone: $(rowData.colorTone).val(),
berryDrop: $(rowData.berryDrop).val(),
berryCracking: $(rowData.berryCracking).val(),
texture: $(rowData.texture).val(),
sunburn: $(rowData.sunburn).val(),
bruising: $(rowData.bruising).val(),
qualityScore: $(rowData.qualityScore).val(),
comment: $(rowData.comment).val(),
images: imagesString,
punnetLabelType: $(rowData.punnetLabelType).val(),
invoiceNo: $(rowData.invoiceNo).val()
};
// Get the logo URL from the hidden input field
const logoUrl = $('#bridge').val(); // Get the value of the hidden input
// Fetch the logo as base64
const logoBase64 = await fetchLogoBase64(logoUrl);
const imageUrls = data.images.split(','); // Assuming 'images' contains a comma-separated list of image URLs
const base64ImageString = await Promise.all(imageUrls.map(url => convertToBase64(url))); // Convert all images to base64
// Assuming the image URLs contain the image names (or you can have a separate array of names)
const imageNames = imageUrls.map(url => {
// Assuming the URL is something like /path/to/image/imagename.jpg
return url.split('/').pop(); // Extract the file name from the URL
});
console.log(imageUrls);
const htmlContent = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Quality Report</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
padding: 2mm;
width: 180mm;
}
.table td {
padding: 9px;
}
.image-caption {
text-align: left;
font-size: 10px; /* Reduced font size */
margin-top: 5px;
}
</style>
</head>
<body>
<div class="container">
<!-- Header Section -->
<div class="header-section my-1 d-flex justify-content-between align-items-center">
<img src="${logoBase64}" alt="Logo">
<div class="text-center mx-auto">
<h4><b>Quality Report</b></h4>
<h4><b>Magnus Farm Fresh</b></h4>
</div>
</div>
<!-- Grower Info Section -->
<div class="header-section my-3 align-items-center">
<div class="row mb-3 mt-1">
<div class="col-sm-6">
<h6>Grower Name: ${data.growerName}</h6>
<h6>Date: ${data.packingDate}</h6>
</div>
</div>
</div>
<!-- Table Section -->
<div class="table-section mt-1">
<div class="row">
<div class="col-md-12">
<div class="table-responsive">
<table class="table table-bordered">
<thead class="thead-dark">
<tr>
<th>Parameters</th>
<th>Values</th>
</tr>
</thead>
<tbody>
<tr>
<td>Grower Name</td>
<td>${data.growerName}</td>
</tr>
<tr>
<td>Packing Date</td>
<td>${data.packingDate}</td>
</tr>
<tr>
<td>Crop</td>
<td>${data.crop}</td>
</tr>
<tr>
<td>Packing Type</td>
<td>${data.packingType}</td>
</tr>
<tr>
<td>Variety</td>
<td>${data.variety}</td>
</tr>
<tr>
<td>Brand</td>
<td>${data.brand}</td>
</tr>
<tr>
<td>Lot Code</td>
<td>${data.lotCode}</td>
</tr>
<tr>
<td>Traceability Code</td>
<td>${data.traceabilityCode}</td>
</tr>
<tr>
<td>Grade</td>
<td>${data.grade}</td>
</tr>
<tr>
<td>Quality Score</td>
<td>${data.qualityScore}</td>
</tr>
<tr>
<td>Customer Name</td>
<td>${data.customerName}</td>
</tr>
<tr>
<td>Brix°Bx</td>
<td>${data.brix}</td>
</tr>
<tr>
<td>Berry Size</td>
<td>${data.berrySize}</td>
</tr>
<tr>
<td>Berry Drop%</td>
<td>${data.berryDrop}</td>
</tr>
<tr>
<td>Berry Cracking%</td>
<td>${data.berryCracking}</td>
</tr>
<tr>
<td>Texture</td>
<td>${data.texture}</td>
</tr>
<tr>
<td>Sunburn%</td>
<td>${data.sunburn}</td>
</tr>
<tr>
<td>Bruising%</td>
<td>${data.bruising}</td>
</tr>
<tr>
<td>Comment</td>
<td>${data.comment}</td>
</tr>
<tr>
<td>Color Tone</td>
<td>${data.colorTone}</td>
</tr>
<tr>
<td>Gross Weight per Carton</td>
<td>${data.grossWeightPerCarton}</td>
</tr>
<tr>
<td>Net Weight per Punnet</td>
<td>${data.netWeightPerPunnet}</td>
</tr>
<tr>
<td>Punnet Label Type</td>
<td>${data.punnetLabelType}</td>
</tr>
<tr>
<td>Invoice No</td>
<td>${data.invoiceNo}</td>
</tr>
<tr>
<td>Farm Registration Number</td>
<td>${data.farmRegistrationNumber}</td>
</tr>
<tr>
<td>GGN</td>
<td>${data.ggn}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- Images Section -->
<div class="text-center mt-1">
<h5>QC Images</h5>
<div class="container">
<div class="row">
${base64ImageString.map((base64, index) => `
<div class="col-md-6 mb-5">
<a href="${imageUrls[index]}" target="_blank">
<img src="data:image/jpeg;base64,${base64}" alt="Image ${index + 1}" class="img-fluid">
</a>
<div class="image-caption">${imageNames[index]}</div>
</div>
`).join('')}
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<h6 style="text-align: right; padding-right: 30px;">Magnus Farm Fresh</h6>
</div>
</div>
</div>
</body>
</html>`;
// Generate the PDF using html2pdf
html2pdf().from(htmlContent).set({
filename: `Quality_Report_${data.growerName}.pdf`,
html2canvas: {
scale: 1,
scrollY: 0,
logging: true,
letterRendering: true,
useCORS: true,
},
jsPDF: {
unit: 'in',
format: 'a4',
orientation: 'portrait',
autoPrint: true,
}
}).save();
});
function convertToBase64(imageUrls) {
return fetch(imageUrls, {
method: 'GET',
mode: 'cors'
})
.then(response => {
if (!response.ok) {
throw new Error('Failed to fetch image');
}
return response.arrayBuffer();
})
.then(buffer => {
let binaryString = '';
const uint8Array = new Uint8Array(buffer);
(new Uint8Array(buffer)).forEach(
(byte) => {binaryString += String.fromCharCode(byte)}
)
console.log(binaryString);
return btoa(binaryString);
});
}
function convertBlobToBase64(blob) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result);
reader.onerror = reject;
reader.readAsDataURL(blob);
});
}
//logo
async function fetchLogoBase64(logoUrl) {
try {
const response = await fetch(logoUrl);
if (!response.ok) {
throw new Error('Failed to fetch logo');
}
const buffer = await response.arrayBuffer();
let binaryString = '';
const uint8Array = new Uint8Array(buffer);
uint8Array.forEach(byte => {
binaryString += String.fromCharCode(byte);
});
return 'data:image/png;base64,' + btoa(binaryString); // Return base64 string
} catch (error) {
console.error('Error fetching logo:', error);
return ''; // Return empty string on error
}
}
</script>
I cant play this m3u8 file for the life of me
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Video Player</title>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
</head>
<body>
<video id="video" controls autoplay style="width: 100%; max-width: 800px;"></video>
<script>
const video = document.getElementById('video');
const videoSrc = 'http://66.242.170.53/hls/live/temp/index.m3u8';
if (Hls.isSupported()) {
const hls = new Hls();
hls.loadSource(videoSrc);
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED, function () {
video.play();
});
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
// For Safari
video.src = videoSrc;
video.addEventListener('loadedmetadata', function () {
video.play();
});
} else {
console.error('Your browser does not support HLS streaming.');
}
</script>
</body>
</html>
The video is not playing for the life of me in html.
I know the link works for sure “http://66.242.170.53/hls/live/temp/index.m3u8” because if you go to http://66.242.170.53 the video plays no problem. but it doesnt work to embed it. I extracted the .m3u8 as you see but the video doesnt work in html
How can I make the scroll bar significantly larger using CSS?
I am working on a webpage where I need the scroll bar to appear much larger than its default size. Specifically, I want to increase the width of the scroll bar and make it more prominent so users can easily interact with it. I attempted to achieve this by using CSS properties but was unable to make the scroll bar noticeably larger.
Here’s what I tried so far:
Using the ::-webkit-scrollbar pseudo-element to customize the width.
Adding styles like width and background to change its appearance.
Adjusting scrollbar-width for Firefox compatibility.
Despite these efforts, the changes are minimal, and the scroll bar doesn’t look “big enough” as intended. I need guidance on how to effectively make the scroll bar significantly larger across all browsers.
Chrome extension rejected – Violation reference ID: Red Potassium
My extension was rejected 3 times the first two times, the reason they gave me was understandable and I was able to fix the error, but this one I am not getting what to do and what they are asking from me.
Please help fix this.
This is the Error message they send me.
Violation reference ID: Red Potassium
Violation: The following functionality stated in the item’s description are not working or were not reproducible in our review:
Popup
How to rectify: Ensure the above functionality is working or remove the corresponding source code from the package.
Relevant section of the program policy:
If any of your Product’s content, title, icon, description or screenshots contains false or misleading information.
This is my folder structure :
This is the manifest.json
{
"manifest_version": 3,
"name": "******",
"description": "******",
"version": "1.0.0",
"host_permissions": ["https://www.linkedin.com/*"],
"action": {
"default_popup": "index.html",
"default_icon": {
"16": "icon-16.png",
"48": "icon-48.png",
"128": "icon-128.png"
}
},
"content_scripts": [
{
"matches": ["https://www.linkedin.com/*"],
"js": ["contentScript.js"],
"type": "module"
}
]
}
What I am doing wrong?
Replace double quotes inside string in array to single quotes after using split
I am having a column in database which has comma separated string saved like below:
2009,2010
Now i want this to convert to array of string in JavaScript so i used below str.split function which returns us an array of string:
str.split(',')
which returns me [ "2009", "2010" ]
Now i want the output in single quotes like below:
[ '2009', '2010' ]
I tried using below code as well:
str.split(',').map(item => `'${item}'`)
But this returns me:[ "'2009'", "'2010'" ]
Can anyone please help me ?
what triggers the change detection in an angular application when calling markForChange() method outside of Zonejs?
I am using the following code inside my component’s constructor. The component is using the OnPush change detection strategy. As we can see, setTimeout executes outside the Angular zone, meaning zonejs will not be aware when the setTimeout operation has completed.
In this case, who informs Angular that something has changed and that it should trigger a change detection cycle?
I understand that markForCheck is responsible for marking the component and its ancestors as dirty, but my confusion is: how does Angular know when to start change detection since setTimeout is running outside the Angular zone?
this.zone.runOutsideAngular(() => {
setTimeout(() => {
this.count = 5;
this.cdr.markForCheck();
}, 3000);
})
Cannot update a component (`App`) while rendering a different component (`Cart`)
i’m designing a e commerce, when comes the part to delete a item from the cart, i have this issue passing values from my return to my delete item from localStorage function
Specifically this error: Cart.jsx:24 Warning: Cannot update a component (App) while rendering a different component (Cart). To locate the bad setState() call inside Cart, follow the stack trace as described in
I’ve been tryied to put my usestate Set method inside a useeffect with [], but doesnt works
well, here you have my code:
import React, { useEffect, useState } from "react";
import Navbar from "./Navbar";
import { Link } from "react-router-dom";
import Footer from "./Footer";
function Cart({ cart, setCart }) {
const newCart = cart.flatMap((c) => c);
const replaced = newCart.map(e => e.price.replaceAll('.', ''));
let sum = 0
replaced.forEach((price) => {
sum += price * 1;
});
let finalSum = sum.toLocaleString()
//function to recharge page when empty all the localStorage
function handleSubmit(e) {
e.preventDefault();
localStorage.clear();
window.location.reload();
}
//function to delete my product
function deleteProd(id){
const updCart = newCart.filter(e => e.id !==id)
setCart(updCart) //HERE IS THE ERROR
localStorage.setItem('cart', JSON.stringify(updCart))
}
return (
<>
<Navbar />
<h1>Carrito de Compras</h1>
<div className="cartWrapper">
{newCart.map((c) => (
<div className="cartProd">
<img src={c.img} alt="" />
<h1>{c.prod}</h1>
<h2>precio: ${c.price}</h2>
<Link to={`/products/${c.id}`}>Ver producto</Link>
<button onClick={deleteProd(c.id)}>Eliminar</button> //HERE I PASS THE PRODUCT ID TO MY FUNCTION
</div>
))}
<div className="right-bar">
<button onClick={handleSubmit}>Vaciar Carrito</button>
<h1>Total: ${finalSum}</h1>
</div>
</div>
<Footer />
</>
);
}
export default Cart;
Any respose will be received!!! thanks
Dynamics 365 Sales OnPost event executed twice
I encountered an issue while testing a code that opens a related entity’s form in a new tab upon saving under specific conditions in Dynamics. The issue is that the postsave event is executed twice on a specific terminal, causing two forms to open.
This behavior occurs frequently when transitioning stages in the business process flow and happens on the development terminal using Edge. The exact conditions for this issue are unclear as it does not always occur with the same operations.
I have tried restarting the PC and clearing the cache and history, but neither resolved the issue. This problem does not occur on other terminals and does not happen in Chrome.
While monitoring with the developer tools, I noticed that the onsave event is executed only once, but the onpostsave event is executed twice. Could there be a script left somewhere in Edge?
If anyone has any insights or suggestions, I would greatly appreciate your help.
How to implement browser tab visibility in gwt
Motivation: I have a periodic call to server to supply fresh data to user. But my program can be run in multiply tabs. I want to decrease the load on the server by detecting which tab is active. If I can reach the state direcly or put the state of visibility of the tab to a variable, my periodic code can check that variable and decide not to call server.
Javascript code: I have found relevant code on javascipt at here
document.addEventListener("visibilitychange", () => {
var tabIsVisible = !document.hidden;
console.log("tabIsVisible: " + tabIsVisible);
});
In GWT I can rewrite the code as this
public static native void addEventListener_visibilityChange(){
$doc.addEventListener("visibilitychange", () => {
var tabIsVisible = !document.hidden;
console.log("tabIsVisible: " + tabIsVisible);
});
}
But it gives compile error
Compiling module com.tugalsan.app.table.App
Tracing compile failure path for type 'com.tugalsan.api.gui.client.browser.TGC_BrowserTabUtils'
[ERROR] Errors in 'jar:file:/C:/Users/me/.m2/repository/com/tugalsan/com.tugalsan.api.gui/1.0-SNAPSHOT/com.tugalsan.api.gui-1.0-SNAPSHOT.jar!/com/tugalsan/api/gui/client/browser/TGC_BrowserTabUtils.java'
[ERROR] Line 8: syntax error
> $doc.addEventListener("visibilitychange", () => {
And, how can I even reach the tabIsVisible variable?
