Compare commits
2 Commits
be71df2ecd
...
d6fba57afc
| Author | SHA1 | Date |
|---|---|---|
|
|
d6fba57afc | |
|
|
c845ad2102 |
|
|
@ -1,8 +1,3 @@
|
||||||
|
|
||||||
@tailwind base;
|
|
||||||
@tailwind components;
|
|
||||||
@tailwind utilities;
|
|
||||||
|
|
||||||
#app{
|
#app{
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
|
|
|
||||||
|
|
@ -17,16 +17,28 @@ interface UseAdOptions {
|
||||||
onReward?: AdRewardCallback; // 观看完整广告后的奖励回调
|
onReward?: AdRewardCallback; // 观看完整广告后的奖励回调
|
||||||
onClose?: (isEnded: boolean) => void; // 广告关闭回调,传入是否完整观看
|
onClose?: (isEnded: boolean) => void; // 广告关闭回调,传入是否完整观看
|
||||||
}
|
}
|
||||||
|
// 创建平台广告实例
|
||||||
|
const factory = createPlatformFactory()
|
||||||
export function useAd(options?: UseAdOptions): UseAdReturn {
|
export function useAd(options?: UseAdOptions): UseAdReturn {
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [adAvailable, setAdAvailable] = useState(false);
|
const [adAvailable, setAdAvailable] = useState(false);
|
||||||
const adRef = useRef<RewardedVideoAd | null>(null);
|
const adRef = useRef<RewardedVideoAd | null>(null);
|
||||||
|
const platform = factory.getPlatform()
|
||||||
|
|
||||||
|
// 检查当前平台是否支持广告
|
||||||
|
const isAdSupportedPlatform = platform === 'bytedance';
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// 如果当前平台不支持广告,直接设置为不可用状态
|
||||||
|
if (!isAdSupportedPlatform) {
|
||||||
|
console.log(`当前平台 ${platform} 未开通广告,跳过广告初始化`);
|
||||||
|
setAdAvailable(false);
|
||||||
|
setLoading(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 创建平台广告实例
|
|
||||||
const factory = createPlatformFactory()
|
|
||||||
adRef.current = factory.createRewardedVideoAd();
|
adRef.current = factory.createRewardedVideoAd();
|
||||||
const ad = adRef.current!;
|
const ad = adRef.current!;
|
||||||
|
|
||||||
|
|
@ -35,91 +47,100 @@ export function useAd(options?: UseAdOptions): UseAdReturn {
|
||||||
console.warn('广告功能不可用,可能是流量主未开通');
|
console.warn('广告功能不可用,可能是流量主未开通');
|
||||||
setAdAvailable(false);
|
setAdAvailable(false);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
return () => {}; // 返回空的清理函数
|
return () => { }; // 返回空的清理函数
|
||||||
}
|
}
|
||||||
|
|
||||||
setAdAvailable(true);
|
setAdAvailable(true);
|
||||||
|
|
||||||
// 广告关闭回调处理
|
// 广告关闭回调处理
|
||||||
const onClose: RewardedVideoCloseCb = (res) => {
|
const onClose: RewardedVideoCloseCb = (res) => {
|
||||||
console.log('广告关闭:', res);
|
console.log('广告关闭:', res);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
|
||||||
// 判断用户是否完成播放
|
// 判断用户是否完成播放
|
||||||
const isEnded = Boolean(res?.isEnded);
|
const isEnded = Boolean(res?.isEnded);
|
||||||
|
|
||||||
if (isEnded) {
|
if (isEnded) {
|
||||||
// 播放完成的业务逻辑
|
// 播放完成的业务逻辑
|
||||||
console.log('用户观看完整广告,给予奖励');
|
console.log('用户观看完整广告,给予奖励');
|
||||||
|
|
||||||
// 执行奖励回调
|
// 执行奖励回调
|
||||||
options?.onReward?.();
|
options?.onReward?.();
|
||||||
|
|
||||||
// 可以在这里处理以下业务:
|
// 可以在这里处理以下业务:
|
||||||
// 1. 发放奖励(积分、道具等)
|
// 1. 发放奖励(积分、道具等)
|
||||||
// 2. 解锁功能或内容
|
// 2. 解锁功能或内容
|
||||||
// 3. 统计完成观看数据
|
// 3. 统计完成观看数据
|
||||||
// 4. 触发下一步操作
|
// 4. 触发下一步操作
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// 未完成播放的处理
|
// 未完成播放的处理
|
||||||
console.log('用户未完整观看广告');
|
console.log('用户未完整观看广告');
|
||||||
|
|
||||||
// 可以处理以下场景:
|
// 可以处理以下场景:
|
||||||
// 1. 提示用户观看完整广告才能获得奖励
|
// 1. 提示用户观看完整广告才能获得奖励
|
||||||
// 2. 记录未完成播放的统计
|
// 2. 记录未完成播放的统计
|
||||||
// 3. 可能的重试提示
|
// 3. 可能的重试提示
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行关闭回调,传入是否完整观看
|
||||||
|
options?.onClose?.(isEnded);
|
||||||
|
}
|
||||||
|
// 广告加载错误回调处理
|
||||||
|
const onError: RewardedVideoErrorCb = (res) => {
|
||||||
|
console.error('广告错误:', res);
|
||||||
|
setLoading(false);
|
||||||
|
|
||||||
|
// 根据错误类型判断广告是否不可用
|
||||||
|
const errorCode = res?.errCode;
|
||||||
|
if (errorCode && ['1004', '1008', '1009', 1004, 1008, 1009].includes(errorCode)) {
|
||||||
|
console.warn('广告服务不可用,可能是流量主未开通或被暂停');
|
||||||
|
setAdAvailable(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 执行关闭回调,传入是否完整观看
|
// 广告加载成功回调处理
|
||||||
options?.onClose?.(isEnded);
|
const onLoad = () => {
|
||||||
}
|
console.log('广告加载成功');
|
||||||
// 广告加载错误回调处理
|
setLoading(false);
|
||||||
const onError: RewardedVideoErrorCb = (res) => {
|
|
||||||
console.error('广告错误:', res);
|
|
||||||
setLoading(false);
|
|
||||||
|
|
||||||
// 根据错误类型判断广告是否不可用
|
|
||||||
const errorCode = res?.errCode;
|
|
||||||
if (errorCode && ['1004', '1008', '1009', 1004, 1008, 1009].includes(errorCode)) {
|
|
||||||
console.warn('广告服务不可用,可能是流量主未开通或被暂停');
|
|
||||||
setAdAvailable(false);
|
|
||||||
}
|
}
|
||||||
}
|
// 绑定广告事件监听
|
||||||
|
ad.onLoad(onLoad);
|
||||||
|
ad.onClose(onClose);
|
||||||
|
ad.onError(onError);
|
||||||
|
|
||||||
// 广告加载成功回调处理
|
// 清理函数:组件卸载时移除事件监听和销毁广告实例
|
||||||
const onLoad = () => {
|
return () => {
|
||||||
console.log('广告加载成功');
|
if (adRef.current) {
|
||||||
setLoading(false);
|
adRef.current.offClose(onClose)
|
||||||
}
|
adRef.current.offError(onError)
|
||||||
// 绑定广告事件监听
|
adRef.current.offLoad(onLoad)
|
||||||
ad.onLoad(onLoad);
|
adRef.current.destroy();
|
||||||
ad.onClose(onClose);
|
}
|
||||||
ad.onError(onError);
|
};
|
||||||
|
|
||||||
// 清理函数:组件卸载时移除事件监听和销毁广告实例
|
|
||||||
return () => {
|
|
||||||
if (adRef.current) {
|
|
||||||
adRef.current.offClose(onClose)
|
|
||||||
adRef.current.offError(onError)
|
|
||||||
adRef.current.offLoad(onLoad)
|
|
||||||
adRef.current.destroy();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('初始化广告失败:', error);
|
console.error('初始化广告失败:', error);
|
||||||
setAdAvailable(false);
|
setAdAvailable(false);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
return () => {}; // 返回空的清理函数
|
return () => { }; // 返回空的清理函数
|
||||||
}
|
}
|
||||||
}, [options]);
|
}, [options, isAdSupportedPlatform, platform]);
|
||||||
|
|
||||||
// 显示广告方法
|
// 显示广告方法
|
||||||
const showAd = useCallback(() => {
|
const showAd = useCallback(() => {
|
||||||
|
// 如果当前平台不支持广告,直接给予奖励并触发关闭回调
|
||||||
|
if (!isAdSupportedPlatform) {
|
||||||
|
console.log(`当前平台 ${platform} 未开通广告,直接给予奖励`);
|
||||||
|
options?.onReward?.();
|
||||||
|
options?.onClose?.(true); // 模拟广告播放完成
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!adAvailable) {
|
if (!adAvailable) {
|
||||||
console.warn('广告不可用,跳过广告播放');
|
console.warn('广告不可用,跳过广告播放');
|
||||||
// 如果广告不可用,直接给予奖励
|
// 如果广告不可用,直接给予奖励
|
||||||
options?.onReward?.();
|
options?.onReward?.();
|
||||||
|
options?.onClose?.(true); // 模拟广告播放完成
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -132,17 +153,24 @@ export function useAd(options?: UseAdOptions): UseAdReturn {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
// 如果显示失败,也给予奖励作为降级处理
|
// 如果显示失败,也给予奖励作为降级处理
|
||||||
options?.onReward?.();
|
options?.onReward?.();
|
||||||
|
options?.onClose?.(true); // 模拟广告播放完成
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [adAvailable, options]);
|
}, [adAvailable, options, isAdSupportedPlatform, platform]);
|
||||||
|
|
||||||
// 加载广告方法
|
// 加载广告方法
|
||||||
const loadAd = useCallback(() => {
|
const loadAd = useCallback(() => {
|
||||||
|
// 如果当前平台不支持广告,直接跳过加载
|
||||||
|
if (!isAdSupportedPlatform) {
|
||||||
|
console.log(`当前平台 ${platform} 未开通广告,跳过广告加载`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (adRef.current) {
|
if (adRef.current) {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
adRef.current.load();
|
adRef.current.load();
|
||||||
}
|
}
|
||||||
}, []);
|
}, [isAdSupportedPlatform, platform]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
showAd,
|
showAd,
|
||||||
|
|
|
||||||
|
|
@ -70,14 +70,13 @@ const ResultPage: React.FC = () => {
|
||||||
} else if (!adAvailable) {
|
} else if (!adAvailable) {
|
||||||
// 广告不可用(如流量主未开通),直接允许下载
|
// 广告不可用(如流量主未开通),直接允许下载
|
||||||
showToast({
|
showToast({
|
||||||
title: '已为您跳过广告,直接下载',
|
title: '已为您跳过广告',
|
||||||
icon: 'success',
|
icon: 'success',
|
||||||
duration: 2000
|
duration: 1500
|
||||||
})
|
})
|
||||||
setHasWatchedAd(true) // 标记为已"观看",允许下载
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
handleDownloadImages()
|
handleDownloadImages(true) // 跳过广告检查,直接下载
|
||||||
}, 500)
|
}, 800)
|
||||||
} else {
|
} else {
|
||||||
// 还没观看广告,先播放广告
|
// 还没观看广告,先播放广告
|
||||||
showAd()
|
showAd()
|
||||||
|
|
@ -85,8 +84,8 @@ const ResultPage: React.FC = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 下载图片到本地相册
|
// 下载图片到本地相册
|
||||||
const handleDownloadImages = async () => {
|
const handleDownloadImages = async (skipAdCheck: boolean = false) => {
|
||||||
if (!hasWatchedAd) {
|
if (!skipAdCheck && !hasWatchedAd) {
|
||||||
showToast({
|
showToast({
|
||||||
title: '请先观看广告',
|
title: '请先观看广告',
|
||||||
icon: 'none',
|
icon: 'none',
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue