Files
jrshikoku/components/ActionSheetComponents/TrainIconUpdate.tsx
harukin-expo-dev-env 10df37d0a2 feat: Expo SDK 52→53 upgrade + full dark mode support
- Upgrade Expo SDK 52→53 (React 18→19, RN 0.76→0.79)
- Remove deprecated packages (native-base, react-native-elements)
- Migrate to @rneui/themed 5.0.0 + modular vector icons
- Fix breaking changes: defaultProps, BackHandler, notifications, key props
- Add Babel plugin for font scaling (replaces Text.defaultProps)
- Configure expo-font for native font preloading
- Add complete dark mode theme system (lib/theme/)
  - AppThemeProvider + useThemeColors hook
  - Light/dark/fixed color token definitions
  - Migrate ~60 files across all screens to use theme colors
- Set userInterfaceStyle to "automatic" for system dark mode
2026-03-17 22:19:46 +00:00

183 lines
5.3 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 React, { useEffect, useRef, useState } from "react";
import {
View,
Text,
TouchableOpacity,
Platform,
Image,
BackHandler,
} from "react-native";
import { MaterialCommunityIcons } from "@expo/vector-icons";
import ActionSheet, { SheetManager } from "react-native-actions-sheet";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import ViewShot from "react-native-view-shot";
import * as Sharing from "expo-sharing";
import icons from "../../assets/icons/icons";
import { getAppIconName } from "expo-alternate-app-icons";
import { AS } from "@/storageControl";
import { STORAGE_KEYS } from "@/constants";
import { useThemeColors } from "@/lib/theme";
export const TrainIconUpdate = () => {
const [iconList] = useState(icons());
const [currentIcon] = useState(getAppIconName());
const actionSheetRef = useRef(null);
const insets = useSafeAreaInsets();
const viewShot = useRef(null);
const { colors, fixed } = useThemeColors();
const onCapture = async () => {
const url = await viewShot.current.capture();
const ok = await Sharing.isAvailableAsync();
if (ok) {
await Sharing.shareAsync(
"file://" + url,
(options = { mimeType: "image/jpeg", dialogTitle: "Share this image" })
);
}
};
return (
<ActionSheet
gestureEnabled
CustomHeaderComponent={<></>}
onClose={() => {
AS.setItem(STORAGE_KEYS.ICON_SETTING, "false");
}}
ref={actionSheetRef}
isModal={Platform.OS == "ios"}
containerStyle={
Platform.OS == "android"
? {
paddingBottom: insets.bottom,
}
: {}
}
useBottomSafeAreaPadding={Platform.OS == "android"}
>
<Handler />
<View
style={{
backgroundColor: fixed.primary,
borderTopRadius: 5,
borderColor: "dark",
borderWidth: 1,
}}
>
<View style={{ height: 26, width: "100%", backgroundColor: fixed.primary }}>
<View
style={{
height: 6,
width: 45,
borderRadius: 100,
backgroundColor: colors.borderLight,
marginVertical: 10,
alignSelf: "center",
}}
/>
</View>
<ViewShot ref={viewShot} options={{ format: "jpg" }}>
<View
style={{
padding: 10,
flexDirection: "row",
alignItems: "center",
backgroundColor: fixed.primary,
}}
>
<Text style={{ fontSize: 30, fontWeight: "bold", color: fixed.textOnPrimary }}>
</Text>
<View style={{ flex: 1 }} />
</View>
{currentIcon ? (
<View
style={{
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
backgroundColor: colors.surface,
padding: 10,
}}
>
<Image
source={iconList.filter(({ id }) => id == currentIcon)[0].icon}
style={{
width: 50,
height: 50,
padding: 30,
borderWidth: 1,
borderRadius: 10,
borderColor: colors.border,
margin: 10,
backgroundColor: colors.surface,
}}
/>
<Text>JR四国非公式アプリ</Text>
</View>
) : (
<></>
)}
<View
style={{
padding: 10,
flexDirection: "row",
alignItems: "center",
backgroundColor: fixed.primary,
}}
>
<Text style={{ fontSize: 15, fontWeight: "bold", color: fixed.textOnPrimary }}>
JR四国非公式アプリを更新して好きなアイコンに変更してみよう
</Text>
</View>
</ViewShot>
<View
style={{
padding: 10,
backgroundColor: fixed.primary,
flexDirection: "row",
justifyContent: "space-between",
}}
>
<TouchableOpacity
style={{
padding: 10,
flexDirection: "row",
borderColor: fixed.textOnPrimary,
borderWidth: 1,
margin: 10,
borderRadius: 5,
alignItems: "center",
backgroundColor: fixed.primary,
flex: 1,
}}
onPress={onCapture}
>
<MaterialCommunityIcons name="share" color={fixed.textOnPrimary} size={30} />
<View style={{ flex: 1 }} />
<Text style={{ fontSize: 25, fontWeight: "bold", color: fixed.textOnPrimary }}>
</Text>
<View style={{ flex: 1 }} />
</TouchableOpacity>
</View>
</View>
</ActionSheet>
);
};
const Handler = () => {
useEffect(() => {
const backAction = () => {
SheetManager.hide("JRSTraInfo");
return true;
};
const backHandler = BackHandler.addEventListener(
"hardwareBackPress",
backAction
);
return () => backHandler.remove();
}, []);
return <></>;
};