From da4110a4952389ced67a55089fa9e0b356336e0c Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Thu, 20 Nov 2025 19:40:20 +0530 Subject: [PATCH] feat: add retry loadWithRetry composable (#12873) --- .../components-next/message/bubbles/Image.vue | 26 +++++---- .../dashboard/composables/loadWithRetry.js | 57 +++++++++++++++++++ 2 files changed, 72 insertions(+), 11 deletions(-) create mode 100644 app/javascript/dashboard/composables/loadWithRetry.js diff --git a/app/javascript/dashboard/components-next/message/bubbles/Image.vue b/app/javascript/dashboard/components-next/message/bubbles/Image.vue index 2484bb06c..f41fdad9a 100644 --- a/app/javascript/dashboard/components-next/message/bubbles/Image.vue +++ b/app/javascript/dashboard/components-next/message/bubbles/Image.vue @@ -1,7 +1,8 @@ diff --git a/app/javascript/dashboard/composables/loadWithRetry.js b/app/javascript/dashboard/composables/loadWithRetry.js new file mode 100644 index 000000000..0246c1e44 --- /dev/null +++ b/app/javascript/dashboard/composables/loadWithRetry.js @@ -0,0 +1,57 @@ +import { ref } from 'vue'; + +export const useLoadWithRetry = (config = {}) => { + const maxRetry = config.max_retry || 3; + const backoff = config.backoff || 1000; + + const isLoaded = ref(false); + const hasError = ref(false); + + const loadWithRetry = async url => { + const attemptLoad = () => { + return new Promise((resolve, reject) => { + const img = new Image(); + + img.onload = () => { + isLoaded.value = true; + hasError.value = false; + resolve(); + }; + + img.onerror = () => { + reject(new Error('Failed to load image')); + }; + + img.src = url; + }); + }; + + const sleep = ms => { + return new Promise(resolve => { + setTimeout(resolve, ms); + }); + }; + + const retry = async (attempt = 0) => { + try { + await attemptLoad(); + } catch (error) { + if (attempt + 1 >= maxRetry) { + hasError.value = true; + isLoaded.value = false; + return; + } + await sleep(backoff * (attempt + 1)); + await retry(attempt + 1); + } + }; + + await retry(); + }; + + return { + isLoaded, + hasError, + loadWithRetry, + }; +};