Telegram miniApp开发(三)

本节主要讲设置导航栏和监听事件
导入依赖宝
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");
  } 
相关推荐
罗_三金4 分钟前
微信小程序读写NFC标签(实现NFC标签快速拉起小程序)实战
前端·javascript·微信小程序·小程序
大大。1 小时前
el-input 只能输入数字和一个小数点,或者只能输入正整数
前端·javascript·vue.js
盼盼盼1 小时前
如何避免在使用 Context API 时出现状态管理的常见问题?
前端·javascript·react.js
Amd7942 小时前
Nuxt Kit 中的布局管理
前端·web开发·nuxt.js·布局管理·代码示例·addlayout·页面结构
超雄代码狂2 小时前
JavaScript web API完结篇---多案例
开发语言·前端·javascript
程序员小羊!2 小时前
切换淘宝最新镜像源npm详细讲解
前端·npm·node.js
小白小白从不日白2 小时前
react 动画_样式处理
前端·react.js
SaxoZhao3 小时前
Vue 中阻止点击事件穿透
前端·javascript·vue.js
1234Wu3 小时前
高德地图2.0 绘制、编辑多边形覆盖物(电子围栏)
前端·vue
用你的胜利博我一笑吧3 小时前
vue3+ts+supermap iclient3d for cesium功能集合
前端·javascript·vue.js·3d·cesium·supermap