99 lines
2.2 KiB
TypeScript
99 lines
2.2 KiB
TypeScript
import apiManager from '../../utils/api';
|
|
|
|
// Global memory cache for image URLs
|
|
const urlCache = new Map<string, string>();
|
|
// Track pending requests to avoid duplicate fetches for the same fileId
|
|
const pendingRequests = new Map<string, Promise<string>>();
|
|
|
|
Component({
|
|
virtualHost: true,
|
|
properties: {
|
|
fileId: {
|
|
type: String,
|
|
observer: 'loadUrl'
|
|
},
|
|
width: {
|
|
type: String,
|
|
value: '100%'
|
|
},
|
|
height: {
|
|
type: String,
|
|
value: '100%'
|
|
},
|
|
mode: {
|
|
type: String,
|
|
value: 'widthFix'
|
|
},
|
|
radius: {
|
|
type: String,
|
|
value: '0'
|
|
}
|
|
},
|
|
|
|
data: {
|
|
imageUrl: '',
|
|
isLoading: true,
|
|
isError: false
|
|
},
|
|
|
|
methods: {
|
|
async loadUrl(this: any, fileId: string) {
|
|
if (!fileId) {
|
|
this.setData({ imageUrl: '', isLoading: false });
|
|
return;
|
|
}
|
|
|
|
// Check cache first
|
|
if (urlCache.has(fileId)) {
|
|
this.setData({
|
|
imageUrl: urlCache.get(fileId),
|
|
isLoading: false,
|
|
isError: false
|
|
});
|
|
return;
|
|
}
|
|
|
|
this.setData({ isLoading: true, isError: false });
|
|
|
|
try {
|
|
let promise = pendingRequests.get(fileId);
|
|
if (!promise) {
|
|
promise = apiManager.getFileDisplayUrl(fileId);
|
|
pendingRequests.set(fileId, promise);
|
|
}
|
|
|
|
const url = await promise;
|
|
urlCache.set(fileId, url);
|
|
pendingRequests.delete(fileId);
|
|
|
|
// Ensure the fileId hasn't changed while we were fetching
|
|
if (this.data.fileId === fileId) {
|
|
console.log('[CloudImage] Loaded url for', fileId, url)
|
|
this.setData({
|
|
imageUrl: url,
|
|
isLoading: false
|
|
});
|
|
}
|
|
} catch (e) {
|
|
console.error('Failed to load image url for fileId:', fileId, e);
|
|
if (this.data.fileId === fileId) {
|
|
this.setData({
|
|
isLoading: false,
|
|
isError: true
|
|
});
|
|
}
|
|
pendingRequests.delete(fileId);
|
|
}
|
|
},
|
|
|
|
onLoad(this: any, e: any) {
|
|
this.triggerEvent('load', e);
|
|
},
|
|
|
|
onError(this: any, e: any) {
|
|
this.setData({ isError: true, isLoading: false });
|
|
this.triggerEvent('error', e);
|
|
}
|
|
}
|
|
});
|