diff --git a/App.js b/App.js index b7cbed9..6ba4a20 100644 --- a/App.js +++ b/App.js @@ -57,10 +57,10 @@ export default function App() { ); } export function AppContainer() { - const { areaInfo, setAreaInfo } = useAreaInfo(); - + const { areaInfo } = useAreaInfo(); + const navigationRef = React.useRef(); return ( - + @@ -72,8 +72,9 @@ export function AppContainer() { gestureEnabled: true, tabBarIcon: initIcon("barchart", "AntDesign"), }} - component={Top} - /> + > + {(props) => } + } /> - + { +export const Top = ({ navigationRef }) => { + const { webview, getCurrentTrain } = useCurrentTrain(); const navigation = useNavigation(); const { navigate, addListener } = navigation; + //地図用 const [mapsStationData, setMapsStationData] = useState(undefined); useEffect(() => { getStationList2().then(setMapsStationData); }, []); + const [mapSwitch, setMapSwitch] = React.useState("false"); + const ASCore = ({ k, s, d }) => + AS.getItem(k) + .then((d) => (d ? s(d) : AS.setItem(k, d))) + .catch(() => AS.setItem(k, d)); + useEffect(() => { + //地図スイッチ + ASCore({ k: "mapSwitch", s: setMapSwitch, d: "false" }); + }, []); useEffect(() => { - const unsubscribe = addListener("tabLongPress", (e) => + const unsubscribe = addListener("tabLongPress", () => navigate("favoriteList") ); - return unsubscribe; }, [navigation]); + useEffect(() => { + const unsubscribe = navigation.addListener("tabPress", () => { + if (navigationRef.current?.getCurrentRoute().name == "Apps") { + if (mapSwitch == "true") { + navigation.navigate("trainMenu"); + } else { + webview.current?.injectJavaScript(`AccordionClassEvent()`); + } + } else { + navigation.navigate("Apps"); + } + }); + return unsubscribe; + }, [navigation, mapSwitch]); return ( diff --git a/assets/configuration/icon_default.jpg b/assets/configuration/icon_default.jpg new file mode 100644 index 0000000..a59537a Binary files /dev/null and b/assets/configuration/icon_default.jpg differ diff --git a/assets/configuration/icon_original.jpg b/assets/configuration/icon_original.jpg new file mode 100644 index 0000000..b4e2b48 Binary files /dev/null and b/assets/configuration/icon_original.jpg differ diff --git a/assets/configuration/menu_default.jpg b/assets/configuration/menu_default.jpg new file mode 100644 index 0000000..bf589c7 Binary files /dev/null and b/assets/configuration/menu_default.jpg differ diff --git a/assets/configuration/menu_original.jpg b/assets/configuration/menu_original.jpg new file mode 100644 index 0000000..6a83ad6 Binary files /dev/null and b/assets/configuration/menu_original.jpg differ diff --git a/assets/configuration/station_default.jpg b/assets/configuration/station_default.jpg new file mode 100644 index 0000000..06e789d Binary files /dev/null and b/assets/configuration/station_default.jpg differ diff --git a/assets/configuration/station_original.jpg b/assets/configuration/station_original.jpg new file mode 100644 index 0000000..c6f1fe9 Binary files /dev/null and b/assets/configuration/station_original.jpg differ diff --git a/assets/configuration/train_default.jpg b/assets/configuration/train_default.jpg new file mode 100644 index 0000000..95d2afe Binary files /dev/null and b/assets/configuration/train_default.jpg differ diff --git a/assets/configuration/train_original.jpg b/assets/configuration/train_original.jpg new file mode 100644 index 0000000..d9ec1eb Binary files /dev/null and b/assets/configuration/train_original.jpg differ diff --git a/assets/configuration/train_original_small.jpg b/assets/configuration/train_original_small.jpg new file mode 100644 index 0000000..6aacc9e Binary files /dev/null and b/assets/configuration/train_original_small.jpg differ diff --git a/components/ActionSheetComponents/EachTrainInfo/TrainDataView.js b/components/ActionSheetComponents/EachTrainInfo/TrainDataView.js index 05b2662..3595cda 100644 --- a/components/ActionSheetComponents/EachTrainInfo/TrainDataView.js +++ b/components/ActionSheetComponents/EachTrainInfo/TrainDataView.js @@ -52,7 +52,7 @@ export const TrainDataView = ({ }); if (!test.length) return; webview.current?.injectJavaScript( - `MoveDisplayStation('${test[0].line}_${test[0].station.MyStation}_${test[0].station.Station_JP}')` + `MoveDisplayStation('${test[0].line}_${test[0].station.MyStation}_${test[0].station.Station_JP}');setStrings();` ); navigate("Apps"); SheetManager.hide("EachTrainInfo"); diff --git a/components/ActionSheetComponents/StationDeteilView.js b/components/ActionSheetComponents/StationDeteilView.js index 497f2ca..686b0c4 100644 --- a/components/ActionSheetComponents/StationDeteilView.js +++ b/components/ActionSheetComponents/StationDeteilView.js @@ -115,13 +115,13 @@ export const StationDeteilView = (props) => { /> )} - {currentStation && + {/* {currentStation && currentStation.map((d) => ( - ))} + ))} */} {currentStation && currentStation[0].JrHpUrl && currentStation[0].StationNumber != "M12" && ( diff --git a/components/AndroidWidget/widget-task-handler.jsx b/components/AndroidWidget/widget-task-handler.jsx index 0acfb19..5b7ae14 100644 --- a/components/AndroidWidget/widget-task-handler.jsx +++ b/components/AndroidWidget/widget-task-handler.jsx @@ -3,19 +3,14 @@ import { TraInfoEXWidget } from "./TraInfoEXWidget"; import dayjs from "dayjs"; import { ToastAndroid } from "react-native"; -const nameToWidget = { +export const nameToWidget = { // Hello will be the **name** with which we will reference our widget. JR_shikoku_train_info: TraInfoEXWidget, }; -export async function widgetTaskHandler(props) { - const widgetInfo = props.widgetInfo; - const Widget = nameToWidget[widgetInfo.widgetName]; +export const getDelayData = async () => { + // Fetch data from the server const time = dayjs().format("HH:mm"); - ToastAndroid.show( - `Widget Action: ${props.widgetAction} ${time}`, - ToastAndroid.SHORT - ); const delayString = await fetch( "https://script.google.com/macros/s/AKfycbyKxch7z7l8e07LXulRHqxjVoIiB13kcgvoToLE-rqlxLmLSKdlmqz0FI1F2EuA7Zfg/exec" ) @@ -27,6 +22,16 @@ export async function widgetTaskHandler(props) { return null; }); ToastAndroid.show(`${delayString}`, ToastAndroid.SHORT); + return { time, delayString }; +}; +export async function widgetTaskHandler(props) { + const widgetInfo = props.widgetInfo; + const Widget = nameToWidget[widgetInfo.widgetName]; + ToastAndroid.show( + `Widget Action: ${JSON.stringify(props.widgetInfo.widgetId)}`, + ToastAndroid.SHORT + ); + const { time, delayString } = await getDelayData(); switch (props.widgetAction) { case "WIDGET_ADDED": case "WIDGET_UPDATE": diff --git a/components/DynamicHeaderScrollView.js b/components/DynamicHeaderScrollView.js index e6f652b..9fc6bd1 100644 --- a/components/DynamicHeaderScrollView.js +++ b/components/DynamicHeaderScrollView.js @@ -1,6 +1,7 @@ import { ScrollView, View, Animated, LayoutAnimation } from "react-native"; -import React, { useMemo, useState } from "react"; +import React, { useEffect, useMemo, useState, useLayoutEffect } from "react"; import { useScrollHandlers } from "react-native-actions-sheet"; +import { AS } from "../storageControl"; export const DynamicHeaderScrollView = (props) => { const { @@ -13,7 +14,30 @@ export const DynamicHeaderScrollView = (props) => { styles, from, } = props; - + const [headerSize, setHeaderSize] = useState("default"); + useLayoutEffect(() => { + AS.getItem("headerSize") + .then((res) => { + if (res) { + setHeaderSize(res); + } + }) + .catch((e) => { + AS.setItem("headerSize", "default"); + }); + }, []); + useEffect(() => { + switch (headerSize) { + case "small": + setHeaderVisible(true); + return; + case "big": + case "default": + default: + setHeaderVisible(false); + break; + } + }, [headerSize]); const viewHeader = useMemo(() => { switch (from) { case "AllTrainDiagramView": @@ -25,7 +49,7 @@ export const DynamicHeaderScrollView = (props) => { } }, [from]); - const Max_Header_Height = viewHeader ? 0 : 200; + const Max_Header_Height = headerSize == "small" ? 0 : viewHeader ? 0 : 200; const Min_Header_Height = viewHeader ? 0 : 80; const Scroll_Distance = Max_Header_Height - Min_Header_Height; @@ -87,13 +111,24 @@ export const DynamicHeaderScrollView = (props) => { const [headerVisible, setHeaderVisible] = useState(false); const onScroll = (event) => { - const scrollY = event.nativeEvent.contentOffset.y; - if (Scroll_Distance < scrollY == headerVisible) return; - LayoutAnimation.configureNext({ - duration: 100, - update: { type: "easeOut" }, - }); - setHeaderVisible(Scroll_Distance < scrollY); + switch (headerSize) { + case "big": + setHeaderVisible(false); + return; + case "small": + setHeaderVisible(true); + return; + case "default": + default: + const scrollY = event.nativeEvent.contentOffset.y; + if (Scroll_Distance < scrollY == headerVisible) return; + LayoutAnimation.configureNext({ + duration: 100, + update: { type: "easeOut" }, + }); + setHeaderVisible(Scroll_Distance < scrollY); + break; + } }; return ( diff --git a/components/FavoriteList.js b/components/FavoriteList.js index c2cb1aa..1d1a054 100644 --- a/components/FavoriteList.js +++ b/components/FavoriteList.js @@ -1,10 +1,11 @@ import React from "react"; import { View, Text, TouchableOpacity, ScrollView } from "react-native"; -import { ListItem } from "native-base"; + import Icon from "react-native-vector-icons/Entypo"; import { useFavoriteStation } from "../stateBox/useFavoriteStation"; import { useCurrentTrain } from "../stateBox/useCurrentTrain"; import { useNavigation } from "@react-navigation/native"; +import { FavoriteListItem } from "./atom/FavoriteListItem"; export default function FavoriteList({ stationData }) { const { favoriteStation } = useFavoriteStation(); const { webview } = useCurrentTrain(); @@ -15,7 +16,7 @@ export default function FavoriteList({ stationData }) { d[0].StationMap) .map((currentStation) => { return ( - { const getStationLine = (now) => { const returnData = Object.keys(stationData).filter((d) => { @@ -42,33 +44,26 @@ export default function FavoriteList({ stationData }) { const lineName = getStationLine(currentStation[0]); webview.current?.injectJavaScript( - `MoveDisplayStation('${lineName}_${currentStation[0].MyStation}_${currentStation[0].Station_JP}')` + `MoveDisplayStation('${lineName}_${currentStation[0].MyStation}_${currentStation[0].Station_JP}'); + setStrings();` ); navigate("Apps"); }} > - - {currentStation - .map((d) => d.StationNumber) - .filter((d) => d !== null) - .join("/")} - - - {currentStation[0].Station_JP} - 移動する - + ); })} diff --git a/components/Menu/FixedContentBottom.js b/components/Menu/FixedContentBottom.js index f7c2bc0..9b66a16 100644 --- a/components/Menu/FixedContentBottom.js +++ b/components/Menu/FixedContentBottom.js @@ -270,27 +270,7 @@ export const FixedContentBottom = (props) => { データベースに存在する全列車のダイヤを探索 - - このアプリについて - - - このアプリはXprocess(HARUKIN)が製作しているJR四国の完全非公式アシストアプリケーションです。このアプリに関することでのJR四国公式へ問合せすることはお控えください。以下のTwitterよりお願いします。 - - - - Linking.openURL("https://twitter.com/Xprocess_main") - } - > - - XprocessのTwitter - - - 制作運営のTwitterです。 - - + その他 { + const lineIDs = []; + const EachIDs = []; + console.log(currentStation); + currentStation.forEach((d) => { + if (!d.StationNumber) return; + const textArray = d.StationNumber.split(""); + lineIDs.push(textArray.filter((s) => "A" < s && s < "Z").join("")); + EachIDs.push(textArray.filter((s) => "0" <= s && s <= "9").join("")); + }); + const [head, setHead] = useState(false); + const [tail, setTail] = useState(false); + useEffect(() => { + switch (true) { + case array.length == 1: + setHead(true); + setTail(true); + break; + case index == 0: + setHead(true); + setTail(false); + break; + case index == array.length - 1: + setHead(false); + setTail(true); + break; + default: + setHead(false); + setTail(false); + } + }, [array]); + + return ( + + + {lineIDs.map((lineID, index) => ( + + + + {lineIDs[index]} + {"\n"} + {EachIDs[index]} + + + + ))} + + + + {currentStation[0].Station_JP} + + { + console.log("up"); + LayoutAnimation.configureNext( + LayoutAnimation.Presets.easeInEaseOut + ); + const removedStation = [...array].filter((d, i) => { + if (i == index) return false; + return true; + }); + removedStation.splice(index - 1, 0, currentStation); + setFavoriteStation(removedStation); + + AS.setItem("favoriteStation", JSON.stringify(removedStation)); + }} + > + {head ? null : } + + { + console.log("down"); + LayoutAnimation.configureNext( + LayoutAnimation.Presets.easeInEaseOut + ); + const removedStation = [...array].filter((d, i) => { + if (i == index) return false; + return true; + }); + removedStation.splice(index + 1, 0, currentStation); + setFavoriteStation(removedStation); + AS.setItem("favoriteStation", JSON.stringify(removedStation)); + }} + > + {tail ? null : } + + + + ); +}; diff --git a/components/Settings/FavoriteSettings.js b/components/Settings/FavoriteSettings.js new file mode 100644 index 0000000..ee05307 --- /dev/null +++ b/components/Settings/FavoriteSettings.js @@ -0,0 +1,90 @@ +import React from "react"; +import { View, Text, TouchableOpacity, ScrollView } from "react-native"; +import { useFavoriteStation } from "../../stateBox/useFavoriteStation"; +import { CheckBox } from "react-native-elements"; +import { FavoriteSettingsItem } from "./FavoliteSettings/FavoiliteSettingsItem"; + +export const FavoriteSettings = ({ navigate }) => { + const { favoriteStation, setFavoriteStation } = useFavoriteStation(); + return ( + + + + navigate("settingTopPage")} + style={{ + flexDirection: "column", + flex: 1, + }} + > + + + < 設定 + + + + + + + お気に入り設定 + + + + + {favoriteStation.map((currentStation, index, array) => ( + + ))} + + + お気に入り登録した駅を並び替えることができます。一番上に置いた駅が位置情報の起動時に表示されます。(移動不可能な駅の場合エラーが発生します。任意指定が可能になる機能を開発予定です。) + + + ); +}; + +const SimpleSwitch = ({ bool, setBool, str }) => ( + + setBool(bool == "true" ? "false" : "true")} + containerStyle={{ + flex: 1, + backgroundColor: "#00000000", + borderColor: "white", + alignContent: "center", + }} + textStyle={{ fontSize: 20, fontWeight: "normal" }} + title={str} + /> + +); diff --git a/components/Settings/LayoutSettings.js b/components/Settings/LayoutSettings.js new file mode 100644 index 0000000..44b36bb --- /dev/null +++ b/components/Settings/LayoutSettings.js @@ -0,0 +1,159 @@ +import React from "react"; +import { View, Text, TouchableOpacity, ScrollView } from "react-native"; +import { SwitchArea } from "../atom/SwitchArea"; +import { CheckBox } from "react-native-elements"; +import { TripleSwitchArea } from "../atom/TripleSwitchArea"; + +export const LayoutSettings = ({ + navigate, + iconSetting, + setIconSetting, + mapSwitch, + setMapSwitch, + stationMenu, + setStationMenu, + usePDFView, + setUsePDFView, + trainMenu, + setTrainMenu, + trainPosition, + setTrainPosition, + headerSize, + setHeaderSize, +}) => { + return ( + + + + navigate("settingTopPage")} + style={{ + flexDirection: "column", + flex: 1, + }} + > + + + < 設定 + + + + + + + レイアウト設定 + + + + + + + + + + + + + + + + + + ); +}; + +const SimpleSwitch = ({ bool, setBool, str }) => ( + + setBool(bool == "true" ? "false" : "true")} + containerStyle={{ + flex: 1, + backgroundColor: "#00000000", + borderColor: "white", + alignContent: "center", + }} + textStyle={{ fontSize: 20, fontWeight: "normal" }} + title={str} + /> + +); diff --git a/components/Settings/SettingTopPage.js b/components/Settings/SettingTopPage.js new file mode 100644 index 0000000..1f9ecf9 --- /dev/null +++ b/components/Settings/SettingTopPage.js @@ -0,0 +1,283 @@ +import React from "react"; +import { + View, + Text, + TouchableOpacity, + ScrollView, + Linking, + Image, + Platform, +} from "react-native"; +import * as Updates from "expo-updates"; +import { useWindowDimensions } from "react-native"; +import { ListItem } from "native-base"; + +const versionCode = 5.1; + +export const SettingTopPage = ({ navigate, testNFC, updateAndReload }) => { + const { width } = useWindowDimensions(); + return ( + + + + navigate("menu")} + style={{ + flexDirection: "column", + flex: 1, + }} + > + + + 閉じる + + + + + + + アプリの設定画面 + + + + + + + + + + 内部バージョン: {versionCode} + + + + + ReleaseChannel: {Updates.channel} + + + + + + このアプリは、四国旅客鉄道株式会社の提供する列車走行位置表示システムを利用し、HARUKIN/Xprocessにより一部の機能を拡張したものです。 + + + このアプリに関するお問い合わせは、HARUKIN/Xprocessにお願いします。くれぐれも四国旅客鉄道株式会社にはお問い合わせしないようにお願いします。 + + + + + navigate("FavoriteSettings")} + > + + お気に入り登録の並び替え + + + + {">"} + + + navigate("LayoutSettings")} + > + + レイアウト設定 + + + + {">"} + + + {Platform.OS === "android" ? ( + navigate("WidgetSettings")} + > + + ウィジェット設定 + + + + {">"} + + + ) : null} + + Linking.openURL( + "https://nexcloud.haruk.in/sites/press-harukin/JRShikokuApps/policy" + ) + } + > + + プライバシーポリシー + + + + + Linking.openURL("https://nexcloud.haruk.in/s/2WFEN5oLPGtrRqT") + } + > + + 開発情報 + + + + + Linking.openURL("https://twitter.com/Xprocess_main")} + > + + 運営Twitter + + + + {/* testNFC()}> + + testNFC + + + */} + + + + + + 設定を保存して再読み込み + + + + + ); +}; diff --git a/components/Settings/WidgetSettings.js b/components/Settings/WidgetSettings.js new file mode 100644 index 0000000..5b08b0c --- /dev/null +++ b/components/Settings/WidgetSettings.js @@ -0,0 +1,189 @@ +import React, { useEffect, useState } from "react"; +import { View, Text, TouchableOpacity, ScrollView } from "react-native"; +import { SwitchArea } from "../atom/SwitchArea"; +import { CheckBox } from "react-native-elements"; +import { TripleSwitchArea } from "../atom/TripleSwitchArea"; +import { getWidgetInfo, WidgetPreview } from "react-native-android-widget"; +import { TraInfoEXWidget } from "../AndroidWidget/TraInfoEXWidget"; +import { + getDelayData, + nameToWidget, +} from "../AndroidWidget/widget-task-handler"; +import { ListItem } from "native-base"; + +export const WidgetSettings = ({ navigate }) => { + const [widgetList, setWidgetList] = useState([]); + useEffect(() => { + const d = []; + Object.keys(nameToWidget).forEach((element) => { + const widgetInfo = getWidgetInfo(element); + widgetInfo.then((s) => { + if (s.length > 0) { + s.forEach((elem) => { + console.log(elem); + d.push(elem); + }); + } + }); + }); + setWidgetList(d); + }, []); + + const [time, setTime] = useState(time); + const [delayString, setDelayString] = useState(delayString); + useEffect(() => { + getDelayData().then(({ time, delayString }) => { + setTime(time); + setDelayString(delayString); + }); + }, []); + return ( + + + + navigate("settingTopPage")} + style={{ + flexDirection: "column", + flex: 1, + }} + > + + + < 設定 + + + + + + + ウィジェット設定 + + + + + + + {Object.keys(nameToWidget).map((Name) => { + const Data = nameToWidget[Name]; + return ( + ( + + )} + width={400} + height={250} + /> + ); + })} + + + + + ID + + + 名前 + + + {widgetList.map((widget) => ( + + + {widget.widgetId} + + + {widget.widgetName} + + + ))} + + + ホーム画面に追加したウィジェットをリストアップします。現状は数を表示するだけですが、ここに各種設定を追加していく予定です。 + + + ); +}; + +const SimpleSwitch = ({ bool, setBool, str }) => ( + + setBool(bool == "true" ? "false" : "true")} + containerStyle={{ + flex: 1, + backgroundColor: "#00000000", + borderColor: "white", + alignContent: "center", + }} + textStyle={{ fontSize: 20, fontWeight: "normal" }} + title={str} + /> + +); diff --git a/components/Settings/settings.js b/components/Settings/settings.js new file mode 100644 index 0000000..5d3be45 --- /dev/null +++ b/components/Settings/settings.js @@ -0,0 +1,154 @@ +import React, { useState, useEffect, useLayoutEffect } from "react"; +import { + View, + Text, + TouchableOpacity, + Linking, + ScrollView, + Image, + useWindowDimensions, + ToastAndroid, +} from "react-native"; +import { createStackNavigator } from "@react-navigation/stack"; +import { TransitionPresets } from "@react-navigation/stack"; +import * as ExpoFelicaReader from "../../modules/expo-felica-reader/src"; +import * as Updates from "expo-updates"; +import StatusbarDetect from "../../StatusbarDetect"; +import { AS } from "../../storageControl"; +var Status = StatusbarDetect(); +import { Switch } from "react-native-elements"; +import AutoHeightImage from "react-native-auto-height-image"; +import { SettingTopPage } from "./SettingTopPage"; +import { LayoutSettings } from "./LayoutSettings"; +import { FavoriteSettings } from "./FavoriteSettings"; +import { WidgetSettings } from "./WidgetSettings"; + +const Stack = createStackNavigator(); +export default function Setting(props) { + const { + navigation: { navigate }, + } = props; + const [iconSetting, setIconSetting] = useState(false); + const [mapSwitch, setMapSwitch] = useState(false); + const [stationMenu, setStationMenu] = useState(false); + const [usePDFView, setUsePDFView] = useState(false); + const [trainMenu, setTrainMenu] = useState(false); + const [trainPosition, setTrainPosition] = useState(false); + const [headerSize, setHeaderSize] = useState("default"); + useLayoutEffect(() => { + AS.getItem("iconSwitch").then(setIconSetting); + AS.getItem("mapSwitch").then(setMapSwitch); + AS.getItem("stationSwitch").then(setStationMenu); + AS.getItem("usePDFView").then(setUsePDFView); + AS.getItem("trainSwitch").then(setTrainMenu); + AS.getItem("trainPositionSwitch").then(setTrainPosition); + AS.getItem("headerSize").then(setHeaderSize); + }, []); + const testNFC = async () => { + const result = await ExpoFelicaReader.scan(); + alert(result); + }; + const updateAndReload = () => { + Promise.all([ + AS.setItem("iconSwitch", iconSetting.toString()), + AS.setItem("mapSwitch", mapSwitch.toString()), + AS.setItem("stationSwitch", stationMenu.toString()), + AS.setItem("usePDFView", usePDFView.toString()), + AS.setItem("trainSwitch", trainMenu.toString()), + AS.setItem("trainPositionSwitch", trainPosition.toString()), + AS.setItem("headerSize", headerSize), + ]).then(() => Updates.reloadAsync()); + }; + return ( + + + {(props) => ( + + )} + + + {(props) => ( + + )} + + + {(props) => } + + + {(props) => } + + + ); +} diff --git a/components/atom/FavoriteListItem.js b/components/atom/FavoriteListItem.js new file mode 100644 index 0000000..2d9aaa9 --- /dev/null +++ b/components/atom/FavoriteListItem.js @@ -0,0 +1,72 @@ +import React from "react"; +import { View, Text, TouchableOpacity } from "react-native"; +import lineColorList from "../../assets/originData/lineColorList"; + +export const FavoriteListItem = ({ currentStation, children, onPress }) => { + const lineIDs = []; + const EachIDs = []; + currentStation.forEach((d) => { + if (!d.StationNumber) return; + const textArray = d.StationNumber.split(""); + lineIDs.push(textArray.filter((s) => "A" < s && s < "Z").join("")); + EachIDs.push(textArray.filter((s) => "0" <= s && s <= "9").join("")); + }); + + return ( + + + {lineIDs.map((lineID, index) => ( + + + + {lineIDs[index]} + {"\n"} + {EachIDs[index]} + + + + ))} + + + + {currentStation[0].Station_JP} + + {children} + + + ); +}; diff --git a/components/atom/SimpleSwitch.js b/components/atom/SimpleSwitch.js new file mode 100644 index 0000000..536226a --- /dev/null +++ b/components/atom/SimpleSwitch.js @@ -0,0 +1,58 @@ +import { + useWindowDimensions, + View, + TouchableOpacity, + Text, + Image, + LayoutAnimation, +} from "react-native"; +export const SimpleSwitch = ({ + bool, + setBool, + color, + value, + image = require("../../assets/icons.png"), + subText = "", +}) => { + const { width } = useWindowDimensions(); + return ( + + { + LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); + setBool(value.toString()); + }} + > + + + + {subText} + + + ); +}; diff --git a/components/atom/SwitchArea.js b/components/atom/SwitchArea.js new file mode 100644 index 0000000..245a708 --- /dev/null +++ b/components/atom/SwitchArea.js @@ -0,0 +1,56 @@ +import { View, Text, Image, TouchableOpacity } from "react-native"; +import { SimpleSwitch } from "./SimpleSwitch"; +export const SwitchArea = ({ + str, + bool, + setBool, + falseImage, + trueImage, + falseText, + trueText, + children, +}) => { + return ( + + + {str} + + + + + + {bool == "true" && children} + + ); +}; diff --git a/components/atom/TripleSwitchArea.js b/components/atom/TripleSwitchArea.js new file mode 100644 index 0000000..5f8c99f --- /dev/null +++ b/components/atom/TripleSwitchArea.js @@ -0,0 +1,52 @@ +import { View, Text, Image, TouchableOpacity } from "react-native"; +import { SimpleSwitch } from "./SimpleSwitch"; +export const TripleSwitchArea = ({ + str, + bool, + setBool, + firstItem: { firstImage, firstText, firstValue }, + secondItem: { secondImage, secondText, secondValue }, + thirdItem: { thirdImage, thirdText, thirdValue }, +}) => { + return ( + + + {str} + + + + + + + + ); +}; diff --git a/components/settings.js b/components/settings.js deleted file mode 100644 index b82796b..0000000 --- a/components/settings.js +++ /dev/null @@ -1,245 +0,0 @@ -import React, { useState, useEffect, useLayoutEffect } from "react"; -import { View, Text, TouchableOpacity, Linking } from "react-native"; -import * as ExpoFelicaReader from "../modules/expo-felica-reader/src"; -import * as Updates from "expo-updates"; -import StatusbarDetect from "../StatusbarDetect"; -import { AS } from "../storageControl"; -var Status = StatusbarDetect(); -import { Switch } from "react-native-elements"; - -export default function Setting() { - const [iconSetting, setIconSetting] = useState(false); - const [mapSwitch, setMapSwitch] = useState(false); - const [stationMenu, setStationMenu] = useState(false); - const [usePDFView, setUsePDFView] = useState(false); - const [trainMenu, setTrainMenu] = useState(false); - const [trainPosition, setTrainPosition] = useState(false); - useLayoutEffect(() => { - AS.getItem("iconSwitch").then(setIconSetting); - AS.getItem("mapSwitch").then(setMapSwitch); - AS.getItem("stationSwitch").then(setStationMenu); - AS.getItem("usePDFView").then(setUsePDFView); - AS.getItem("trainSwitch").then(setTrainMenu); - AS.getItem("trainPositionSwitch").then(setTrainPosition); - }, []); - const testNFC = async () => { - const resulit = await ExpoFelicaReader.scan(); - alert(resulit); - }; - const updateAndReload = () => { - Promise.all([ - AS.setItem("iconSwitch", iconSetting.toString()), - AS.setItem("mapSwitch", mapSwitch.toString()), - AS.setItem("stationSwitch", stationMenu.toString()), - AS.setItem("usePDFView", usePDFView.toString()), - AS.setItem("trainSwitch", trainMenu.toString()), - AS.setItem("trainPositionSwitch", trainPosition.toString()), - ]).then(() => { - Updates.reloadAsync(); - }); - }; - return ( - - - - - 設定画面 - - - - - - 列車アイコンを表示する - - - - - - - マップを表示する(beta) - - - - - - - 駅メニューを表示 - - - - - - - 時刻表PDFをアプリ外で表示 - - - - - - - 列車メニュー - - - - - - - →列車現在位置表示(alpha) - - - - - - - 内部バージョン: 5.0.3.2 - - - - - - releaseChannel: {Updates.channel} - - - - - Linking.openURL( - "https://nexcloud.haruk.in/sites/press-harukin/JRShikokuApps/policy" - ) - } - > - - プライバシーポリシー - - - - - - - - - 設定を保存して再読み込み - - - - - ); -} -const SimpleSwitch = ({ bool, setBool, color }) => ( - setBool(value.toString())} - /> -); diff --git a/components/trainMenu.js b/components/trainMenu.js index 4fe042f..13876a0 100644 --- a/components/trainMenu.js +++ b/components/trainMenu.js @@ -1,4 +1,4 @@ -import React, { useRef } from "react"; +import React, { useRef, useMemo } from "react"; import { View, Text, TouchableOpacity, Linking } from "react-native"; import MapView, { Marker } from "react-native-maps"; import { MaterialCommunityIcons } from "@expo/vector-icons"; @@ -8,6 +8,36 @@ export default function TrainMenu({ stationData, style }) { const { webview } = useCurrentTrain(); const mapRef = useRef(); const { navigate } = useNavigation(); + const stationPin = useMemo( + () => + Object.keys(stationData).map((d, indexBase) => + stationData[d].map((D, index) => { + if (!D.StationMap) return null; + const latlng = D.StationMap.replace( + "https://www.google.co.jp/maps/place/", + "" + ).split(","); + if (latlng.length == 0) return null; + return ( + { + webview.current?.injectJavaScript( + `MoveDisplayStation('${d}_${D.MyStation}_${D.Station_JP}'); + setStrings();` + ); + if (navigate) navigate("Apps"); + }} + > + ); + }) + ), + [stationData] + ); return ( - {stationData && - Object.keys(stationData).map((d) => - stationData[d].map((D, index) => { - if (!D.StationMap) return null; - const latlng = D.StationMap.replace( - "https://www.google.co.jp/maps/place/", - "" - ).split(","); - if (latlng.length == 0) return null; - return ( - { - webview.current?.injectJavaScript( - `MoveDisplayStation('${d}_${D.MyStation}_${D.Station_JP}')` - ); - if (navigate) navigate("Apps"); - }} - > - ); - }) - )} + {stationPin} {navigate && ( diff --git a/components/駅名表/Sign.js b/components/駅名表/Sign.js index 852f9ec..38bc62f 100644 --- a/components/駅名表/Sign.js +++ b/components/駅名表/Sign.js @@ -28,6 +28,18 @@ export default function Sign(props) { }); setTestButtonStatus(isFavorite.length == 0 ? false : true); }, [favoriteStation, currentStation]); + useEffect(() => { + const isFavorite = favoriteStation.filter((d) => { + const compare = JSON.stringify(d); + const current = JSON.stringify(currentStation); + if (compare === current) { + return true; + } else { + return false; + } + }); + setTestButtonStatus(isFavorite.length == 0 ? false : true); + }, [favoriteStation, currentStation]); useInterval(() => { if (currentStation.length == 1) { diff --git a/config/newsUpdate.js b/config/newsUpdate.js index 2e96f85..5b873ec 100644 --- a/config/newsUpdate.js +++ b/config/newsUpdate.js @@ -1 +1 @@ -export const news = "2024-3-10"; +export const news = "2024-4-6"; diff --git a/stateBox/useDeviceOrientationChange.js b/stateBox/useDeviceOrientationChange.js index 79c305f..5efd975 100644 --- a/stateBox/useDeviceOrientationChange.js +++ b/stateBox/useDeviceOrientationChange.js @@ -22,14 +22,14 @@ export const DeviceOrientationChangeProvider = ({ children }) => { //ScreenOrientation.unlockAsync(); }, []); - useEffect(() => { - if (height / width > 1.5) { - setIsLandscape(false); - } - if (height / width < 1.5) { - //setIsLandscape(true); - } - }, [height, width]); + // useEffect(() => { + // if (height / width > 1.5) { + // setIsLandscape(false); + // } + // if (height / width < 1.5) { + // setIsLandscape(true); + // } + // }, [height, width]); return ( {children}