Telegram-Mini-Apps / telegram-apps

Made from scratch TypeScript packages, examples and documentation you will surely need to start developing on Telegram Mini Apps.
https://docs.telegram-mini-apps.com/
MIT License
543 stars 134 forks source link

Error: Unable to get unit "webApp" as long as SDK is not initialized. #77

Closed Amurmurmur closed 1 year ago

Amurmurmur commented 1 year ago

Describe the bug Just copy pasted what was in the docs to setup a minimul Webapp

When I call this: in my App const webApp = useWebApp();

useEffect(() => { webApp.ready(); }, [webApp]);

To Reproduce Steps to reproduce the behavior: Follow the guide here: https://docs.twa.dev/docs/libraries/twa-js-sdk-react

Expected behavior A clear and concise description of what you expected to happen.

My main.tsx:

import React from "react";
import ReactDOM from "react-dom/client";

import "./index.css";
import { App } from "./app";

ReactDOM.createRoot(document.getElementById("root")!).render(
  <React.StrictMode>
      <App />
  </React.StrictMode>
);

my app.tsx

const options: InitOptions = {
    acceptScrollbarStyle: true,
    checkCompat: true,
    debug: true
  };
const AppWrapped = withSDK(Root);

export function App() {
  return (
    <SDKProvider initOptions={options}>
      <AppWrapped />
    </SDKProvider>
  );
}

my root.tsx


/**
 * This component is the layer controlling the application display. It displays
 * application in case, the SDK is initialized, displays an error if something
 * went wrong, and a loader if the SDK is warming up.
 */
function Loader({children}: PropsWithChildren<{}>) {
    const {didInit, components, error} = useSDK();

    // There were no calls of SDK's init function. It means, we did not
    // even try to do it.
    if (!didInit) {
      return <div>SDK init function is not yet called.</div>;
    }

    // Error occurred during SDK init.
    if (error !== null) {
      return <div>Something went wrong.</div>;
    }

    // If components is null, it means, SDK is not ready at the
    // moment and currently initializing. Usually, it takes like
    // several milliseconds or something like that, but we should
    // have this check.
    if (components === null) {
      return <div>Warming up SDK.</div>;
    }

    // Safely render application.
    return <>{children}</>;
  }

export function Root({ sdk }) {

  return (
    <Loader>
        <div>TEST app</div>
    </Loader>
  )
}

Loader gets stuck at Warming up SDK. When console logging the sdk: {components: null, didInit: true, error: null}

heyqbnk commented 1 year ago
  1. What Telegram application are you testing this code in?
  2. Have you tried this code in different Telegram applications?
Amurmurmur commented 1 year ago
  1. macOS telegram
  2. no
heyqbnk commented 1 year ago

Please, try opening your app in the different Telegram application. I assume, problem is specific to the Telegram app for macOS only. It is probably a bug in the platform, not in the package, but it seems like I know the solution

heyqbnk commented 1 year ago

As I found out with some other external developer, problem occurs due to the incorrect behaviour of the Telegram app for macOS. The reason is the native application is not responding to web_app_request_theme method, but it must.

The other important note here, that I could not reproduce this problem using the same native application version. I will release the solution today and will notify you about that.

heyqbnk commented 1 year ago

@twa.js/sdk and @twa.js/sdk-react were updated. Try using the latest versions and let me know if my solution doesn't solve the problem.

I also added project you could use to test the functionality. Just clone the repo and do the following:

cd apps/react-sdk-example
pnpm i
pnpm run dev
Amurmurmur commented 1 year ago

Just tested worked like a charm! 🚀🚀🚀🚀🚀🚀 however another issues from the example


import { useBackButton, useWebApp } from "@twa.js/sdk-react";
import { useEffect } from "react";

export const Root = () => {

  const backButton = useBackButton();
  const webApp = useWebApp();

  // When App is attached to DOM, lets show back button and
  // add "click" event handler, which should close current application.
  useEffect(() => {
    const listener = () => {
      console.log("CLICK")
      webApp.close();
    };
    backButton.on('click', listener);
    backButton.show();

    return () => {
      backButton.off('click', listener);
      backButton.hide();
    };
    // We know, that backButton and webApp will never change,
    // but let's follow React rules.
  }, [backButton, webApp]);  

return (
    <div style={{ color: 'red' }}>Root</div>
)
}

The listener doesnt get triggered. The back button appears but once I click one it, it doesnt fire an event.

EDIT: the sdk doesnt get initialised on iOS, using the latest Telegram app

Amurmurmur commented 1 year ago

ok solution is found I had

    <script src="https://telegram.org/js/telegram-web-app.js"></script>

in my index.html, removing it solved initialisation problems.

GG to @heyqbnk for resolving a matter so quickly !