dimension.tsx 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. import { Colors } from "@/constants/Colors";
  2. import { getDateTimeScope, getRoomTypePermission } from "@/services/dimension";
  3. import { useRouter } from "expo-router";
  4. import React, { useEffect, useState } from "react";
  5. import {
  6. Dimensions,
  7. ScrollView,
  8. StatusBar,
  9. StyleSheet,
  10. Text,
  11. TouchableOpacity,
  12. View,
  13. } from "react-native";
  14. import { useSafeAreaInsets } from "react-native-safe-area-context";
  15. const { width: SCREEN_WIDTH } = Dimensions.get("window");
  16. export default function DimensionScreen() {
  17. const router = useRouter();
  18. const insets = useSafeAreaInsets();
  19. const [showSection, setShowSection] = useState(false);
  20. const [startTime, setStartTime] = useState("");
  21. const [endTime, setEndTime] = useState("");
  22. const [wishSwitch, setWishSwitch] = useState(false);
  23. const [roomSwitch, setRoomSwitch] = useState(false);
  24. useEffect(() => {
  25. loadConfig();
  26. }, []);
  27. const loadConfig = async () => {
  28. try {
  29. const timeRes = await getDateTimeScope();
  30. if (timeRes && timeRes.startTime && timeRes.endTime) {
  31. setStartTime(timeRes.startTime.substring(0, 10));
  32. setEndTime(timeRes.endTime.substring(0, 10));
  33. setShowSection(true);
  34. }
  35. const permission = await getRoomTypePermission();
  36. setRoomSwitch(permission?.roomConfig !== 0);
  37. setWishSwitch(true);
  38. } catch (error) {
  39. console.error("加载次元配置失败:", error);
  40. }
  41. };
  42. const toRouter = (path: string) => {
  43. router.push(path as any); // Type assertion for dynamic routes
  44. };
  45. // Cyberpunk Card Component
  46. const CyberCard = ({ title, subtitle, color, onPress, children }: any) => (
  47. <TouchableOpacity
  48. style={[styles.card, { borderColor: color, shadowColor: color }]}
  49. activeOpacity={0.8}
  50. onPress={onPress}
  51. >
  52. <View style={[styles.cardHeader, { borderBottomColor: color }]}>
  53. <Text
  54. style={[styles.cardTitle, { color: color, textShadowColor: color }]}
  55. >
  56. {title}
  57. </Text>
  58. <View style={[styles.statusDot, { backgroundColor: color }]} />
  59. </View>
  60. <View style={styles.cardBody}>
  61. <Text style={styles.cardSubtitle}>{subtitle}</Text>
  62. {children}
  63. </View>
  64. {/* Decorative corners */}
  65. <View style={[styles.corner, styles.cornerTL, { borderColor: color }]} />
  66. <View style={[styles.corner, styles.cornerTR, { borderColor: color }]} />
  67. <View style={[styles.corner, styles.cornerBL, { borderColor: color }]} />
  68. <View style={[styles.corner, styles.cornerBR, { borderColor: color }]} />
  69. </TouchableOpacity>
  70. );
  71. return (
  72. <View style={styles.container}>
  73. <StatusBar barStyle="light-content" />
  74. {/* 顶部标题栏 */}
  75. <View style={[styles.header, { paddingTop: insets.top + 10 }]}>
  76. <View style={styles.headerContent}>
  77. <Text style={styles.headerTitle}>DIMENSION</Text>
  78. <Text style={styles.headerSubtitle}>次元领域 // ACCESS GRANTED</Text>
  79. </View>
  80. <View style={styles.headerLine} />
  81. </View>
  82. <ScrollView
  83. style={styles.scrollView}
  84. showsVerticalScrollIndicator={false}
  85. contentContainerStyle={styles.scrollContent}
  86. >
  87. {showSection && (
  88. <View style={styles.grid}>
  89. {roomSwitch && (
  90. <CyberCard
  91. title="每日补给"
  92. subtitle="DAILY SUPPLY"
  93. color={Colors.neonBlue}
  94. onPress={() => toRouter("/dimension/room")}
  95. >
  96. <View style={styles.timeTag}>
  97. <Text style={styles.timeText}>
  98. OPEN: {startTime} - {endTime}
  99. </Text>
  100. </View>
  101. </CyberCard>
  102. )}
  103. <CyberCard
  104. title="量子抓取"
  105. subtitle="QUANTUM CLAW"
  106. color={Colors.neonPink}
  107. onPress={() => toRouter("/dimension/catchDoll")}
  108. >
  109. <View style={styles.timeTag}>
  110. <Text style={styles.timeText}>
  111. OPEN: {startTime} - {endTime}
  112. </Text>
  113. </View>
  114. </CyberCard>
  115. {wishSwitch && (
  116. <CyberCard
  117. title="命运节点"
  118. subtitle="FATE NODE"
  119. color="#FFD700" // Gold
  120. onPress={() => toRouter("/dimension/wish")}
  121. >
  122. <View style={styles.timeTag}>
  123. <Text style={styles.timeText}>
  124. OPEN: {startTime} - {endTime}
  125. </Text>
  126. </View>
  127. </CyberCard>
  128. )}
  129. </View>
  130. )}
  131. <View style={styles.footerInfo}>
  132. <Text style={styles.footerText}>SYSTEM ONLINE</Text>
  133. <Text style={styles.footerText}>V.20.77</Text>
  134. </View>
  135. <View style={{ height: 100 }} />
  136. </ScrollView>
  137. </View>
  138. );
  139. }
  140. const styles = StyleSheet.create({
  141. container: {
  142. flex: 1,
  143. backgroundColor: Colors.darkBg,
  144. },
  145. header: {
  146. paddingHorizontal: 20,
  147. paddingBottom: 20,
  148. backgroundColor: Colors.darkBg,
  149. zIndex: 10,
  150. },
  151. headerContent: {
  152. marginBottom: 10,
  153. },
  154. headerTitle: {
  155. fontSize: 32,
  156. fontWeight: "bold",
  157. color: "#fff",
  158. fontStyle: "italic",
  159. letterSpacing: 2,
  160. textShadowColor: Colors.neonBlue,
  161. textShadowOffset: { width: 0, height: 0 },
  162. textShadowRadius: 10,
  163. },
  164. headerSubtitle: {
  165. fontSize: 12,
  166. color: Colors.neonBlue,
  167. marginTop: 5,
  168. letterSpacing: 1,
  169. },
  170. headerLine: {
  171. height: 2,
  172. backgroundColor: Colors.neonBlue,
  173. width: "60%",
  174. shadowColor: Colors.neonBlue,
  175. shadowOffset: { width: 0, height: 0 },
  176. shadowOpacity: 1,
  177. shadowRadius: 5,
  178. },
  179. scrollView: {
  180. flex: 1,
  181. },
  182. scrollContent: {
  183. paddingHorizontal: 20,
  184. paddingTop: 20,
  185. },
  186. grid: {
  187. gap: 20,
  188. },
  189. // Card Styles
  190. card: {
  191. backgroundColor: Colors.darkCard,
  192. borderRadius: 4,
  193. borderWidth: 1,
  194. padding: 1, // Inner spacing for border
  195. marginBottom: 20,
  196. minHeight: 120,
  197. position: "relative",
  198. shadowOffset: { width: 0, height: 4 },
  199. shadowOpacity: 0.3,
  200. shadowRadius: 10,
  201. elevation: 5,
  202. },
  203. cardHeader: {
  204. flexDirection: "row",
  205. justifyContent: "space-between",
  206. alignItems: "center",
  207. paddingHorizontal: 15,
  208. paddingVertical: 10,
  209. borderBottomWidth: 1,
  210. backgroundColor: "rgba(255, 255, 255, 0.03)",
  211. },
  212. cardTitle: {
  213. fontSize: 20,
  214. fontWeight: "bold",
  215. textShadowRadius: 5,
  216. },
  217. statusDot: {
  218. width: 8,
  219. height: 8,
  220. borderRadius: 4,
  221. shadowOpacity: 1,
  222. shadowRadius: 5,
  223. },
  224. cardBody: {
  225. padding: 15,
  226. justifyContent: "center",
  227. },
  228. cardSubtitle: {
  229. color: Colors.textSecondary,
  230. fontSize: 14,
  231. letterSpacing: 2,
  232. marginBottom: 10,
  233. fontWeight: "600",
  234. },
  235. timeTag: {
  236. backgroundColor: "rgba(0, 0, 0, 0.3)",
  237. paddingHorizontal: 8,
  238. paddingVertical: 4,
  239. borderRadius: 2,
  240. alignSelf: "flex-start",
  241. borderLeftWidth: 2,
  242. borderLeftColor: Colors.textTertiary,
  243. },
  244. timeText: {
  245. color: Colors.textTertiary,
  246. fontSize: 10,
  247. fontFamily: "Courier", // Monospace font if available
  248. },
  249. // Decoration Corners
  250. corner: {
  251. position: "absolute",
  252. width: 10,
  253. height: 10,
  254. borderWidth: 2,
  255. },
  256. cornerTL: { top: -1, left: -1, borderBottomWidth: 0, borderRightWidth: 0 },
  257. cornerTR: { top: -1, right: -1, borderBottomWidth: 0, borderLeftWidth: 0 },
  258. cornerBL: { bottom: -1, left: -1, borderTopWidth: 0, borderRightWidth: 0 },
  259. cornerBR: { bottom: -1, right: -1, borderTopWidth: 0, borderLeftWidth: 0 },
  260. footerInfo: {
  261. marginTop: 40,
  262. alignItems: "center",
  263. opacity: 0.5,
  264. },
  265. footerText: {
  266. color: Colors.textTertiary,
  267. fontSize: 10,
  268. letterSpacing: 2,
  269. marginBottom: 4,
  270. },
  271. });