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");
  } 
相关推荐
CharlesYu0110 小时前
前端性能优化的第一性原理,是不断缩短“用户发起意图 → 获得可用结果”之间的时间
前端
平头哥技术团队10 小时前
Day 21 _ 页内锚点_给每段起个 id,目录写 href=_#id_,点一下页面就滚到那一段
前端·html·html5
子兮曰11 小时前
Bun v1.4.1 深度解析:从 Zig 到 Rust,一场 11 天、64 个 AI 代理的语言迁徙
前端·后端·bun
人民广场吃泡面12 小时前
什么是AI Agent?它又能给前端带来哪些效率提升?
前端·人工智能
中科三方12 小时前
两家域名注册商资质被ICANN终止:企业域名资产安全再受关注
前端·网络·安全·域名
bug总结12 小时前
uniapp vue3全局方法注册使用
前端·javascript·uni-app
华无丽言13 小时前
如何在宜搭中实现获取子表中的字段值赋值到父表中?
前端·javascript·低代码
IT_陈寒13 小时前
Vue的computed属性竟然坑了我一把
前端·人工智能·后端
威斯软科的老司机13 小时前
通俗讲解 CNN 图像识别、向量 Embedding、Softmax 概率计算这三块的简化原理
前端·人工智能·ui·数字孪生
泯泷14 小时前
手搓JSVM第 12 篇:完整最小 JSVM 实现与源码设计复盘
前端·javascript·前端框架