Skip to content

Commit

Permalink
fix(load script): load script issue
Browse files Browse the repository at this point in the history
  • Loading branch information
Razzwan committed Nov 13, 2023
1 parent 33fe48f commit 10b2882
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 68 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@altiore/twa",
"version": "1.2.10",
"version": "1.2.11",
"description": "React components for Telegram WebApp",
"source": "./src/index.ts",
"type": "module",
Expand Down
77 changes: 10 additions & 67 deletions src/WebAppProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, {
PropsWithChildren,
ReactElement,
useCallback,
useEffect,
useMemo,
useState,
Expand All @@ -16,6 +15,7 @@ import {
createSystemContextValue,
} from './core';
import { WebApp } from './core/twa-types';
import { loadScript } from './core/utils';

export type WebAppProviderProps = PropsWithChildren<{
options?: Options;
Expand Down Expand Up @@ -71,82 +71,25 @@ const WebAppProvider = ({
return () => window.removeEventListener('beforeunload', forceHideButtons);
}, [options?.smoothButtonsTransition, webApp]);

const [isLoading, setIsLoading] = useState(false);
const [isLoading, setIsLoading] = useState(true);
const [isLoaded, setIsLoaded] = useState(false);

const subscribeScriptLoading = useCallback(
(scriptEle: HTMLScriptElement) => {
try {
const successListener = () => {
setIsLoaded(true);
setIsLoading(false);
setWebApp(
typeof window !== 'undefined' && window?.Telegram?.WebApp
? window.Telegram.WebApp
: null,
);
};

const errorListener = (ev: unknown) => {
console.error('Error on loading file', ev);
setIsLoaded(false);
setIsLoading(false);
};

scriptEle.addEventListener('load', successListener);
scriptEle.addEventListener('error', errorListener);

return () => {
scriptEle.removeEventListener('load', successListener);
scriptEle.removeEventListener('error', errorListener);
};
} catch (err) {
console.error(err);
}

return () => {};
},
[setIsLoaded, setIsLoading, setWebApp],
);

useEffect(() => {
try {
if (isLoaded || isLoading) {
return;
}
setIsLoading(true);
const existingScripts: NodeListOf<HTMLScriptElement> =
window.document.querySelectorAll(`script[src='${SCRIPT}']`);
if (existingScripts[0]) {
loadScript(SCRIPT)
.then(() => {
setIsLoaded(true);
setIsLoading(false);
setWebApp(
typeof window !== 'undefined' && window?.Telegram?.WebApp
? window.Telegram.WebApp
: null,
);
return () => {};
}

const scriptEle = document.createElement('script');

scriptEle.setAttribute('src', SCRIPT);
scriptEle.setAttribute('type', 'text/javascript');
scriptEle.setAttribute('async', 'true');

document.body.appendChild(scriptEle);

return subscribeScriptLoading(scriptEle);
} catch (err) {
console.error(err);
setIsLoaded(false);
setIsLoading(false);
}

return () => {};
// Осознанно, не должно быть зависимостей. Скрипт загружается только один раз
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
})
.catch(() => {
setIsLoaded(false);
setIsLoading(false);
});
}, [setIsLoading, setIsLoaded]);

const systemValue = useMemo(createSystemContextValue, []);

Expand Down
30 changes: 30 additions & 0 deletions src/core/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export const loadScript = (url: string): Promise<Event | true> => {
return new Promise((resolve, reject) => {
try {
const list: HTMLCollectionOf<HTMLScriptElement> = document.getElementsByTagName('script');
let i = list.length;
let wasAlreadyFound = false;
while (i--) {
if (list?.[i]?.src === url) {
wasAlreadyFound = true;
break;
}
}

if (!wasAlreadyFound) {
const script = document.createElement('script');
script.src = url;
script.onload = resolve;
script.onerror = reject;
script.onabort = reject;
script.async = true;
script.defer = true;
document.head.appendChild(script);
} else {
resolve(true);
}
} catch (err) {
reject(err);
}
});
};

0 comments on commit 10b2882

Please sign in to comment.