feat(ProductDetailPage): implement attribute image loading and caching
- Add loadAttributeImages method to fetch and cache attribute images based on product attributes. - Update product detail loading logic to include attribute image loading when product data is cached. - Ensure efficient state management by caching results to minimize server requests.
This commit is contained in:
@@ -190,7 +190,11 @@ class ProductDetailPage extends Component {
|
|||||||
if (!this.state.product || this.state.upgrading) {
|
if (!this.state.product || this.state.upgrading) {
|
||||||
this.loadProductData();
|
this.loadProductData();
|
||||||
} else {
|
} else {
|
||||||
// Product is cached, but we still need to load komponenten if they exist
|
// Product is cached, but we still need to load attribute images and komponenten
|
||||||
|
if (this.state.attributes && this.state.attributes.length > 0) {
|
||||||
|
this.loadAttributeImages(this.state.attributes);
|
||||||
|
}
|
||||||
|
|
||||||
if (this.state.komponenten.length > 0 && !this.state.komponentenLoaded) {
|
if (this.state.komponenten.length > 0 && !this.state.komponentenLoaded) {
|
||||||
for(const komponent of this.state.komponenten) {
|
for(const komponent of this.state.komponenten) {
|
||||||
this.loadKomponent(komponent.id, komponent.count);
|
this.loadKomponent(komponent.id, komponent.count);
|
||||||
@@ -478,6 +482,75 @@ class ProductDetailPage extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadAttributeImages = (attributes) => {
|
||||||
|
// Initialize window-level attribute image cache if it doesn't exist
|
||||||
|
if (!window.attributeImageCache) {
|
||||||
|
window.attributeImageCache = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attributes && attributes.length > 0) {
|
||||||
|
const attributeImages = {};
|
||||||
|
|
||||||
|
for (const attribute of attributes) {
|
||||||
|
const cacheKey = attribute.kMerkmalWert;
|
||||||
|
|
||||||
|
if (attribute.cName == "Anzahl")
|
||||||
|
this.setState({ isSteckling: true });
|
||||||
|
|
||||||
|
// Check if we have a cached result (either URL or negative result)
|
||||||
|
if (window.attributeImageCache[cacheKey]) {
|
||||||
|
const cached = window.attributeImageCache[cacheKey];
|
||||||
|
if (cached.url) {
|
||||||
|
// Use cached URL
|
||||||
|
attributeImages[cacheKey] = cached.url;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Not in cache, fetch from server
|
||||||
|
console.log('getAttributePicture', cacheKey);
|
||||||
|
window.socketManager.emit(
|
||||||
|
"getAttributePicture",
|
||||||
|
{ id: cacheKey },
|
||||||
|
(res) => {
|
||||||
|
console.log("getAttributePicture", res);
|
||||||
|
if (res.success && !res.noPicture) {
|
||||||
|
const blob = new Blob([res.imageBuffer], {
|
||||||
|
type: "image/jpeg",
|
||||||
|
});
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
|
||||||
|
// Cache the successful URL
|
||||||
|
window.attributeImageCache[cacheKey] = {
|
||||||
|
url: url,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update state and force re-render
|
||||||
|
this.setState(prevState => ({
|
||||||
|
attributeImages: {
|
||||||
|
...prevState.attributeImages,
|
||||||
|
[cacheKey]: url
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
// Cache negative result to avoid future requests
|
||||||
|
// This handles both failure cases and success with noPicture: true
|
||||||
|
window.attributeImageCache[cacheKey] = {
|
||||||
|
noImage: true,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set initial state with cached images
|
||||||
|
if (Object.keys(attributeImages).length > 0) {
|
||||||
|
this.setState({ attributeImages });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
loadProductData = () => {
|
loadProductData = () => {
|
||||||
console.log('loadProductData', this.props.seoName);
|
console.log('loadProductData', this.props.seoName);
|
||||||
const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de';
|
const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de';
|
||||||
@@ -533,73 +606,8 @@ class ProductDetailPage extends Component {
|
|||||||
});
|
});
|
||||||
console.log("getProductView", res);
|
console.log("getProductView", res);
|
||||||
|
|
||||||
// Initialize window-level attribute image cache if it doesn't exist
|
// Load attribute images
|
||||||
if (!window.attributeImageCache) {
|
this.loadAttributeImages(res.attributes);
|
||||||
window.attributeImageCache = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res.attributes && res.attributes.length > 0) {
|
|
||||||
const attributeImages = {};
|
|
||||||
|
|
||||||
for (const attribute of res.attributes) {
|
|
||||||
const cacheKey = attribute.kMerkmalWert;
|
|
||||||
|
|
||||||
if (attribute.cName == "Anzahl")
|
|
||||||
this.setState({ isSteckling: true });
|
|
||||||
|
|
||||||
// Check if we have a cached result (either URL or negative result)
|
|
||||||
if (window.attributeImageCache[cacheKey]) {
|
|
||||||
const cached = window.attributeImageCache[cacheKey];
|
|
||||||
if (cached.url) {
|
|
||||||
// Use cached URL
|
|
||||||
attributeImages[cacheKey] = cached.url;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Not in cache, fetch from server
|
|
||||||
console.log('getAttributePicture', cacheKey);
|
|
||||||
window.socketManager.emit(
|
|
||||||
"getAttributePicture",
|
|
||||||
{ id: cacheKey },
|
|
||||||
(res) => {
|
|
||||||
console.log("getAttributePicture", res);
|
|
||||||
if (res.success && !res.noPicture) {
|
|
||||||
const blob = new Blob([res.imageBuffer], {
|
|
||||||
type: "image/jpeg",
|
|
||||||
});
|
|
||||||
const url = URL.createObjectURL(blob);
|
|
||||||
|
|
||||||
// Cache the successful URL
|
|
||||||
window.attributeImageCache[cacheKey] = {
|
|
||||||
url: url,
|
|
||||||
timestamp: Date.now(),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Update state and force re-render
|
|
||||||
this.setState(prevState => ({
|
|
||||||
attributeImages: {
|
|
||||||
...prevState.attributeImages,
|
|
||||||
[cacheKey]: url
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
// Cache negative result to avoid future requests
|
|
||||||
// This handles both failure cases and success with noPicture: true
|
|
||||||
window.attributeImageCache[cacheKey] = {
|
|
||||||
noImage: true,
|
|
||||||
timestamp: Date.now(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set initial state with cached images
|
|
||||||
if (Object.keys(attributeImages).length > 0) {
|
|
||||||
this.setState({ attributeImages });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
console.error(
|
console.error(
|
||||||
"Error loading product:",
|
"Error loading product:",
|
||||||
|
|||||||
Reference in New Issue
Block a user