アイコン更新画面を作成

This commit is contained in:
harukin-expo-dev-env 2025-03-10 15:24:11 +00:00
parent a9488b98bc
commit 0838414540
5 changed files with 210 additions and 19 deletions

View File

@ -1,6 +1,6 @@
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import { createStackNavigator } from "@react-navigation/stack"; import { createStackNavigator } from "@react-navigation/stack";
import { CommonActions } from "@react-navigation/native"; import { SheetManager } from "react-native-actions-sheet";
import { AS } from "./storageControl"; import { AS } from "./storageControl";
import TrainBase from "./components/trainbaseview"; import TrainBase from "./components/trainbaseview";
import HowTo from "./howto"; import HowTo from "./howto";
@ -9,7 +9,6 @@ import News from "./components/news";
import Setting from "./components/Settings/settings"; import Setting from "./components/Settings/settings";
import { useFavoriteStation } from "./stateBox/useFavoriteStation"; import { useFavoriteStation } from "./stateBox/useFavoriteStation";
import { optionData } from "./lib/stackOption"; import { optionData } from "./lib/stackOption";
import CurrentTrainListView from "./components/CurrentTrainListView";
import AllTrainDiagramView from "./components/AllTrainDiagramView"; import AllTrainDiagramView from "./components/AllTrainDiagramView";
import { useCurrentTrain } from "./stateBox/useCurrentTrain"; import { useCurrentTrain } from "./stateBox/useCurrentTrain";
import { useNavigation } from "@react-navigation/native"; import { useNavigation } from "@react-navigation/native";
@ -37,6 +36,11 @@ export function MenuPage() {
if (d != news) navigation.navigate("topMenu", { screen: "news" }); if (d != news) navigation.navigate("topMenu", { screen: "news" });
}) })
.catch(() => navigation.navigate("topMenu", { screen: "news" })); .catch(() => navigation.navigate("topMenu", { screen: "news" }));
AS.getItem("isSetIcon")
.then((isSetIcon) => {
if (isSetIcon == "true") SheetManager.show("TrainIconUpdate");
})
.catch((error) => console.error("Error fetching icon setting:", error));
}, []); }, []);
useEffect(() => { useEffect(() => {
const unsubscribe = addListener("tabPress", (e) => { const unsubscribe = addListener("tabPress", (e) => {

View File

@ -0,0 +1,180 @@
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";
export const TrainIconUpdate = () => {
const [iconList] = useState(icons());
const [currentIcon] = useState(getAppIconName());
const actionSheetRef = useRef(null);
const insets = useSafeAreaInsets();
const viewShot = useRef(null);
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("isSetIcon", "false");
}}
ref={actionSheetRef}
isModal={Platform.OS == "ios"}
containerStyle={
Platform.OS == "android"
? {
paddingBottom: insets.bottom,
}
: {}
}
useBottomSafeAreaPadding={Platform.OS == "android"}
>
<Handler />
<View
style={{
backgroundColor: "#0099CC",
borderTopRadius: 5,
borderColor: "dark",
borderWidth: 1,
}}
>
<ViewShot ref={viewShot} options={{ format: "jpg" }}>
<View
style={{ height: 26, width: "100%", backgroundColor: "#0099CC" }}
>
<View
style={{
height: 6,
width: 45,
borderRadius: 100,
backgroundColor: "#f0f0f0",
marginVertical: 10,
alignSelf: "center",
}}
/>
</View>
<View
style={{
padding: 10,
flexDirection: "row",
alignItems: "center",
backgroundColor: "#0099CC",
}}
>
<Text style={{ fontSize: 30, fontWeight: "bold", color: "white" }}>
</Text>
<View style={{ flex: 1 }} />
</View>
{currentIcon ? (
<View
style={{
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
backgroundColor: "#FFFFFFEE",
padding: 10,
}}
>
<Image
source={iconList.filter(({ id }) => id == currentIcon)[0].icon}
style={{
width: 50,
height: 50,
padding: 30,
borderWidth: 1,
borderRadius: 10,
borderColor: "white",
margin: 10,
backgroundColor: "white",
}}
/>
<Text>JR四国非公式アプリ</Text>
</View>
) : (
<></>
)}
<Text
style={{
fontSize: 15,
fontWeight: "bold",
color: "white",
backgroundColor: "#0099CC",
}}
>
JR四国非公式アプリを更新して好きなアイコンに変更してみよう
</Text>
</ViewShot>
<View
style={{
padding: 10,
backgroundColor: "#0099CC",
flexDirection: "row",
justifyContent: "space-between",
}}
>
<TouchableOpacity
style={{
padding: 10,
flexDirection: "row",
borderColor: "white",
borderWidth: 1,
margin: 10,
borderRadius: 5,
alignItems: "center",
backgroundColor: "#0099CC",
flex: 1,
}}
onPress={onCapture}
>
<MaterialCommunityIcons name="share" color="white" size={30} />
<View style={{ flex: 1 }} />
<Text style={{ fontSize: 25, fontWeight: "bold", color: "white" }}>
</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 <></>;
};

View File

@ -3,10 +3,12 @@ import { EachTrainInfo } from "./EachTrainInfo";
import { JRSTraInfo } from "./JRSTraInfo"; import { JRSTraInfo } from "./JRSTraInfo";
import { StationDeteilView } from "./StationDeteilView"; import { StationDeteilView } from "./StationDeteilView";
import { TrainMenuLineSelector } from "./TrainMenuLineSelector"; import { TrainMenuLineSelector } from "./TrainMenuLineSelector";
import { TrainIconUpdate } from "./TrainIconUpdate";
registerSheet("EachTrainInfo", EachTrainInfo); registerSheet("EachTrainInfo", EachTrainInfo);
registerSheet("JRSTraInfo", JRSTraInfo); registerSheet("JRSTraInfo", JRSTraInfo);
registerSheet("StationDetailView", StationDeteilView); registerSheet("StationDetailView", StationDeteilView);
registerSheet("TrainMenuLineSelector", TrainMenuLineSelector); registerSheet("TrainMenuLineSelector", TrainMenuLineSelector);
registerSheet("TrainIconUpdate", TrainIconUpdate);
export {}; export {};

View File

@ -1,23 +1,23 @@
import React, { useEffect, useState } from "react"; import React, { useState } from "react";
import { View, Text, TouchableOpacity, ScrollView, Image } from "react-native"; import {
View,
Text,
TouchableOpacity,
ScrollView,
Image,
ToastAndroid,
Platform,
} from "react-native";
import { useNavigation } from "@react-navigation/native"; import { useNavigation } from "@react-navigation/native";
import { CheckBox } from "react-native-elements";
import { AS } from "../../storageControl"; import { AS } from "../../storageControl";
import icons from "../../assets/icons/icons"; import icons from "../../assets/icons/icons";
import app from "../../app.json"; import { setAlternateAppIcon, getAppIconName } from "expo-alternate-app-icons";
import { ListItem } from "native-base";
import {
setAlternateAppIcon,
resetAppIcon,
getAppIconName,
supportsAlternateIcons,
} from "expo-alternate-app-icons";
import { widthPercentageToDP } from "react-native-responsive-screen"; import { widthPercentageToDP } from "react-native-responsive-screen";
export const LauncherIconSettings = ({ navigate }) => { export const LauncherIconSettings = ({ navigate }) => {
const { goBack } = useNavigation(); const { goBack } = useNavigation();
const [iconList, ] = useState(icons()); const [iconList] = useState(icons());
const [currentIcon, ] = useState(getAppIconName()); const [currentIcon] = useState(getAppIconName());
return ( return (
<View style={{ height: "100%", backgroundColor: "#0099CC" }}> <View style={{ height: "100%", backgroundColor: "#0099CC" }}>
<View style={{ backgroundColor: "#0099CC", flexDirection: "row" }}> <View style={{ backgroundColor: "#0099CC", flexDirection: "row" }}>
@ -81,9 +81,7 @@ export const LauncherIconSettings = ({ navigate }) => {
}} }}
> >
<Image <Image
source={ source={iconList.filter(({ id }) => id == currentIcon)[0].icon}
iconList.filter(({ id }) => id == currentIcon)[0].icon
}
style={{ style={{
width: 50, width: 50,
height: 50, height: 50,
@ -128,7 +126,13 @@ export const LauncherIconSettings = ({ navigate }) => {
onPress={() => { onPress={() => {
setAlternateAppIcon(id) setAlternateAppIcon(id)
.then((res) => { .then((res) => {
alert(res); AS.setItem("isSetIcon", "true");
if (Platform.OS === "android") {
ToastAndroid.show(
"アイコンを変更しました。アプリを再起動します。",
ToastAndroid.SHORT
);
}
}) })
.catch((err) => { .catch((err) => {
alert(err); alert(err);

View File

@ -1,6 +1,7 @@
import 'babel-polyfill'; import 'babel-polyfill';
import { registerRootComponent } from "expo"; import { registerRootComponent } from "expo";
import { registerWidgetTaskHandler } from "react-native-android-widget"; import { registerWidgetTaskHandler } from "react-native-android-widget";
import { Platform } from "react-native";
import App from "./App"; import App from "./App";
import { widgetTaskHandler } from "./components/AndroidWidget/widget-task-handler"; import { widgetTaskHandler } from "./components/AndroidWidget/widget-task-handler";