Files
mini-programs/src/game_pages/detail/components/SharePopup/index.tsx
2025-12-09 17:10:56 +08:00

223 lines
7.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { forwardRef, useState, useEffect, useImperativeHandle } from "react";
import { View, Button, Image, Text } from "@tarojs/components";
import Taro, { useShareAppMessage } from "@tarojs/taro";
import dayjs from "dayjs";
import "dayjs/locale/zh-cn";
import classnames from "classnames";
import { generateShareImage } from "@/utils";
import DetailService from "@/services/detailService";
import { CommonPopup } from "@/components";
import DownloadIcon from "@/static/detail/download_icon.svg";
import WechatLogo from "@/static/detail/wechat_icon.svg";
// import WechatTimeline from "@/static/detail/wechat_timeline.svg";
import LinkIcon from "@/static/detail/link.svg";
import CrossIcon from "@/static/detail/cross.svg";
import { genNTRPRequirementText, navto } from "@/utils/helper";
import { waitForAuthInit } from "@/utils/authInit";
import { useUserActions } from "@/store/userStore";
import { OSS_BASE_URL } from "@/config/api";
import { generatePosterImage, base64ToTempFilePath, delay } from "@/utils";
import { DayOfWeekMap } from "../../config";
import styles from "./index.module.scss";
dayjs.locale("zh-cn");
// 分享弹窗
export default forwardRef(({ id, from, detail, userInfo }, ref) => {
const [visible, setVisible] = useState(false);
const [publishFlag, setPublishFlag] = useState(false);
const { fetchUserInfo } = useUserActions();
// const posterRef = useRef();
const { max_participants, participant_count } = detail || {};
// useEffect(() => {
// if (id) {
// changeMessageType();
// }
// }, [id]);
async function changeMessageType() {
try {
const res = await DetailService.getActivityId({
business_id: id,
business_type: "game",
is_private: false,
});
if (res.code === 0) {
Taro.updateShareMenu({
withShareTicket: false, // 是否需要返回 shareTicket
isUpdatableMessage: true, // 是否是动态消息(需要服务端配置过模版)
activityId: res.data.activity_id, // 动态消息的活动 id
});
}
} catch (e) {
Taro.showToast({ title: e.message, icon: "none" });
}
}
useImperativeHandle(ref, () => ({
show: (publish_flag = false) => {
setPublishFlag(publish_flag);
setVisible(true);
},
}));
useShareAppMessage(async (res) => {
const {
play_type,
skill_level_max,
skill_level_min,
start_time,
end_time,
location_name,
image_list,
} = detail || {};
const startTime = dayjs(start_time);
const endTime = dayjs(end_time);
const dayofWeek = DayOfWeekMap.get(startTime.day());
const gameLength = `${endTime.diff(startTime, "hour")}小时`;
await changeMessageType();
const url = await generateShareImage({
userAvatar: userInfo.avatar_url,
userNickname: userInfo.nickname,
gameType: play_type,
skillLevel: `NTRP ${genNTRPRequirementText(
skill_level_min,
skill_level_max
)}`,
gameDate: `${startTime.format("M月D日")} (${dayofWeek})`,
gameTime: `${startTime.format("ah")}${gameLength}`,
venueName: location_name,
venueImages: image_list ? image_list : [],
});
// console.log(res, "res");
return {
title: detail.title,
imageUrl: url || "https://img.yzcdn.cn/vant/cat.jpeg",
path: `/game_pages/detail/index?id=${id}&from=share`,
};
});
async function handleGenPoster() {
const {
id,
play_type,
skill_level_max,
skill_level_min,
start_time,
end_time,
location_name,
image_list,
title,
} = detail || {};
// 先等待静默登录完成
await waitForAuthInit();
const userInfo = await fetchUserInfo();
const { avatar_url, nickname } = userInfo;
const startTime = dayjs(start_time);
const endTime = dayjs(end_time);
const dayofWeek = DayOfWeekMap.get(startTime.day());
const gameLength = `${endTime.diff(startTime, "hour")}小时`;
Taro.showLoading({ title: "生成中..." });
const qrCodeUrlRes = await DetailService.getQrCodeUrl({
page: "game_pages/detail/index",
scene: `id=${id}`,
});
const qrCodeUrl = await base64ToTempFilePath(
qrCodeUrlRes.data.qr_code_base64
);
await delay(100);
const url = await generatePosterImage({
playType: play_type,
ntrp: `NTRP ${genNTRPRequirementText(skill_level_min, skill_level_max)}`,
mainCoursal:
image_list[0] && image_list[0].startsWith("http")
? image_list[0]
: `${OSS_BASE_URL}/images/0621b8cf-f7d6-43ad-b852-7dc39f29a782.png`,
nickname,
avatarUrl: avatar_url,
title,
locationName: location_name,
date: `${startTime.format("M月D日")} (${dayofWeek})`,
time: `${startTime.format("ah")}${gameLength}`,
qrCodeUrl,
});
Taro.hideLoading();
Taro.showShareImageMenu({
path: url,
});
}
async function handlePost() {
// navto(`/game_pages/sharePoster/index?id=${detail.id}`);
handleGenPoster();
setVisible(false);
}
function onClose() {
setVisible(false);
setPublishFlag(false);
}
return (
<>
<CommonPopup
title="分享至"
visible={visible}
onClose={onClose}
showHeader={false}
hideFooter
enableDragToClose={false}
style={{ minHeight: "100px" }}
zIndex={1000}
>
<View className={styles.shareContainer}>
<View catchMove className={styles.title}>
{publishFlag ? (
<Text className={styles.publishText}> 🎉</Text>
) : (
<Text></Text>
)}
<View className={styles.closeIconWrap} onClick={onClose}>
<Image className={styles.closeIcon} src={CrossIcon} />
</View>
</View>
{publishFlag && (
<View className={styles.shareTip}>
<Text>
<Text className={styles.specialCount}>
{" "}
{max_participants - participant_count}{" "}
</Text>
</Text>
</View>
)}
<View className={styles.shareItems}>
<Button className={styles.button} openType="share">
<View className={classnames(styles.icon, styles.wechatIcon)}>
<Image className={styles.wechat} src={WechatLogo} />
</View>
<Text></Text>
</Button>
<Button className={styles.button} onClick={handlePost}>
<View className={styles.icon}>
<Image className={styles.download} src={DownloadIcon} />
</View>
<Text></Text>
</Button>
<Button className={styles.button}>
<View className={styles.icon}>
<Image className={styles.linkIcon} src={LinkIcon} />
</View>
<Text></Text>
</Button>
</View>
</View>
</CommonPopup>
{/* <PosterPopup ref={posterRef} id={detail.id} /> */}
</>
);
});