本节主要讲设置导航栏和监听事件
导入依赖宝
bash
<script
src="https://telegram.org/js/telegram-web-app.js"
strategy="beforeInteractive"
></script>
定义全局Context
bash
"use client";
import { createContext, useContext, useEffect, useMemo, useState } from "react";
interface ITelegramUser {
id: number;
first_name: string;
last_name: string;
username: string;
language_code: string;
}
/**
* https://www.jackygu.me/posts/a-telegram-mini-app/
*/
interface IWebApp {
initData: string;
initDataUnsafe: {
query_id: string;
user: ITelegramUser;
auth_date: string;
hash: string;
};
version: string;
platform: string;
colorScheme: string;
themeParams: {
link_color: string;
button_color: string;
button_text_color: string;
secondary_bg_color: string;
hint_color: string;
bg_color: string;
text_color: string;
};
isExpanded: boolean;
viewportHeight: number;
viewportStableHeight: number;
isClosingConfirmationEnabled: boolean;
headerColor: string;
backgroundColor: string;
BackButton: {
isVisible: boolean;
show: Function;
hide: Function;
onClick: Function;
};
MainButton: {
text: string;
color: string;
textColor: string;
isVisible: boolean;
isProgressVisible: boolean;
isActive: boolean;
};
HapticFeedback: {
/**
impactOccurred(style)
* 用于指示发生了触觉反馈。Telegram可以根据传递的style值播放适当的触觉反馈。
style可以是以下值之一:
- light,表示小型或轻量级UI对象之间的碰撞,
- medium,表示中等大小或中等重量的UI对象之间的碰撞,
- heavy,表示大型或重型UI对象之间的碰撞,
- rigid,表示硬或不可弯曲的UI对象之间的碰撞,
- soft,表示柔软或可弯曲的UI对象之间的碰撞
*/
impactOccurred: Function;//
};//用于触感反馈的对象
onEvent: Function;
openTelegramLink: Function;//在Telegram内打开Telegram链接的方法,这时小程序将被关闭
openLink: Function;//在外部浏览器中打开链接。
setHeaderColor:Function;//一个以#RRGGBB格式设置应用程序背景颜色的方法。还可以使用关键字bg_color和secondary_bg_color
enableClosingConfirmation: Function;//启用在用户尝试关闭小程序时显示确认对话框
ready: Function;//通知Telegram小程序已准备好显示。建议尽早调用此方法,即在加载所有必要的界面元素后立即调用。一旦调用了此方法,加载占位符将被隐藏,小程序将显示出来。如果未调用此方法,占位符将仅在页面完全加载后被隐藏
expand: Function;//将小程序展开到最大可用高度的方法。要了解小程序是否已展开到最大高度,请参考Telegram.WebApp.isExpanded参数的值
}
interface ITelegramContext {
webApp: IWebApp | null;
initData: string;
}
const TelegramContext = createContext<ITelegramContext>({
webApp: null,
initData: "",
});
export const TelegramProvider = ({
children,
}: {
children: React.ReactNode;
}) => {
const [webApp, setWebApp] = useState<IWebApp | null>(null);
const [initData, setInitData] = useState<string>( );
useEffect(() => {
const app = (window as any).Telegram?.WebApp;
if (app) {
app.ready();
setWebApp(app);
// 检查是否支持全屏模式
if (app.expand) {
// 请求全屏模式
app.expand();
} else {
// 如果不支持全屏模式,可以显示一个提示消息或采取其他措施
console.log("Fullscreen mode is not supported on this platform.");
}
}
}, [setWebApp]);
useEffect(() => {
webApp && setInitData && webApp.initData && setInitData(webApp.initData);
}, [webApp, setInitData]);
return (
<TelegramContext.Provider
value={{
initData: initData || "",
webApp,
}}
>
{children}
</TelegramContext.Provider>
);
};
export const useTelegram = () => useContext(TelegramContext);
页面引用,设置导航栏
bash
import { useTelegram } from "@/providers/TelegramProvider";
const {webApp} = useTelegram()
useEffect(() => {
if (webApp) {
try {
webApp.setHeaderColor("#000000");
webApp.BackButton.hide();
webApp.enableClosingConfirmation();
} catch (e) {}
}
}, [webApp]);
页面引用,触发手机震动效果
bash
import { useTelegram } from "@/providers/TelegramProvider";
const {webApp} = useTelegram()
if (navigator.vibrate) {
// 震动100毫秒
navigator.vibrate(100);
} else {
// postEvent("web_app_trigger_haptic_feedback", {
// type: "impact",
// impact_style: "medium",
// });
webApp?.HapticFeedback.impactOccurred("medium");
}