|
|
@@ -0,0 +1,117 @@
|
|
|
+import { Image } from "expo-image";
|
|
|
+import { useRouter } from "expo-router";
|
|
|
+import React, { useState } from "react";
|
|
|
+import {
|
|
|
+ Dimensions,
|
|
|
+ Modal,
|
|
|
+ Pressable,
|
|
|
+ StyleSheet,
|
|
|
+ TouchableOpacity,
|
|
|
+ View,
|
|
|
+} from "react-native";
|
|
|
+
|
|
|
+const { width: SCREEN_WIDTH } = Dimensions.get("window");
|
|
|
+
|
|
|
+export interface AdElement {
|
|
|
+ cover: string;
|
|
|
+ path?: { schema?: string; url?: string; params?: any };
|
|
|
+ title?: string;
|
|
|
+ subtitle?: string;
|
|
|
+}
|
|
|
+
|
|
|
+interface Props {
|
|
|
+ elements: AdElement[];
|
|
|
+ onClose: () => void;
|
|
|
+}
|
|
|
+
|
|
|
+export function SuperAdModal({ elements, onClose }: Props) {
|
|
|
+ const router = useRouter();
|
|
|
+ const [index, setIndex] = useState(0);
|
|
|
+
|
|
|
+ if (!elements || elements.length === 0) return null;
|
|
|
+ const current = elements[index];
|
|
|
+ if (!current) return null;
|
|
|
+
|
|
|
+ const handleClose = () => {
|
|
|
+ if (index < elements.length - 1) {
|
|
|
+ setIndex(index + 1);
|
|
|
+ } else {
|
|
|
+ setIndex(0);
|
|
|
+ onClose();
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleImagePress = () => {
|
|
|
+ const url = current.path?.url;
|
|
|
+ if (!url) return;
|
|
|
+ if (url.startsWith("http")) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ router.push(url as any);
|
|
|
+ };
|
|
|
+
|
|
|
+ return (
|
|
|
+ <Modal
|
|
|
+ visible
|
|
|
+ transparent
|
|
|
+ animationType="fade"
|
|
|
+ onRequestClose={handleClose}
|
|
|
+ >
|
|
|
+ <View style={styles.overlay}>
|
|
|
+ <Pressable style={StyleSheet.absoluteFill} onPress={handleClose} />
|
|
|
+ <Pressable onPress={handleImagePress}>
|
|
|
+ <Image
|
|
|
+ source={{ uri: current.cover }}
|
|
|
+ style={styles.image}
|
|
|
+ contentFit="contain"
|
|
|
+ />
|
|
|
+ </Pressable>
|
|
|
+ <TouchableOpacity
|
|
|
+ style={styles.closeBtn}
|
|
|
+ onPress={handleClose}
|
|
|
+ activeOpacity={0.8}
|
|
|
+ hitSlop={16}
|
|
|
+ >
|
|
|
+ <View style={[styles.closeLine, styles.closeLineA]} />
|
|
|
+ <View style={[styles.closeLine, styles.closeLineB]} />
|
|
|
+ </TouchableOpacity>
|
|
|
+ </View>
|
|
|
+ </Modal>
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+const styles = StyleSheet.create({
|
|
|
+ overlay: {
|
|
|
+ flex: 1,
|
|
|
+ backgroundColor: "rgba(0,0,0,0.6)",
|
|
|
+ justifyContent: "center",
|
|
|
+ alignItems: "center",
|
|
|
+ },
|
|
|
+ image: {
|
|
|
+ width: SCREEN_WIDTH,
|
|
|
+ height: SCREEN_WIDTH * 1.2,
|
|
|
+ },
|
|
|
+ closeBtn: {
|
|
|
+ position: "absolute",
|
|
|
+ bottom: 80,
|
|
|
+ alignSelf: "center",
|
|
|
+ width: 32,
|
|
|
+ height: 32,
|
|
|
+ borderRadius: 16,
|
|
|
+ backgroundColor: "#d8d8d8",
|
|
|
+ justifyContent: "center",
|
|
|
+ alignItems: "center",
|
|
|
+ },
|
|
|
+ closeLine: {
|
|
|
+ position: "absolute",
|
|
|
+ width: 14,
|
|
|
+ height: 1.5,
|
|
|
+ backgroundColor: "#000",
|
|
|
+ },
|
|
|
+ closeLineA: {
|
|
|
+ transform: [{ rotate: "45deg" }],
|
|
|
+ },
|
|
|
+ closeLineB: {
|
|
|
+ transform: [{ rotate: "-45deg" }],
|
|
|
+ },
|
|
|
+});
|