observerを利用した新型のトレインビューボタン化改造機能

This commit is contained in:
harukin-DeskMini 2022-09-28 03:17:22 +09:00
parent b234b056c3
commit 560649004c
4 changed files with 186 additions and 56 deletions

181
App.js
View File

@ -1,59 +1,158 @@
import React, { useEffect, useRef } from 'react'; import React, { useEffect, useRef } from "react";
import { NavigationContainer } from '@react-navigation/native'; import { NavigationContainer } from "@react-navigation/native";
import { createStackNavigator,TransitionPresets ,} from '@react-navigation/stack'; import {
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; createStackNavigator,
import { AntDesign, Ionicons } from '@expo/vector-icons'; TransitionPresets,
import {ToastAndroid, Platform, UIManager,} from 'react-native'; } from "@react-navigation/stack";
import { UpdateAsync } from './UpdateAsync.js'; import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import Apps from './Apps'; import { AntDesign, Ionicons } from "@expo/vector-icons";
import tndView from './ndView'; import { ToastAndroid, Platform, UIManager } from "react-native";
import trainbase from './trainbaseview'; import { UpdateAsync } from "./UpdateAsync.js";
import howto from './howto'; import Apps from "./Apps";
import menu from './menu'; import tndView from "./ndView";
import News from './components/news.js'; import trainbase from "./trainbaseview";
import TestArea from './TestArea.js'; import howto from "./howto";
import Setting from './components/settings.js'; import menu from "./menu";
import trainMenu from './components/trainMenu.js'; import News from "./components/news.js";
import TestArea from "./TestArea.js";
import Setting from "./components/settings.js";
import trainMenu from "./components/trainMenu.js";
const Stack = createStackNavigator(); const Stack = createStackNavigator();
const Tab = createBottomTabNavigator(); const Tab = createBottomTabNavigator();
if (Platform.OS === 'android') { if (Platform.OS === "android") {
if (UIManager.setLayoutAnimationEnabledExperimental) { if (UIManager.setLayoutAnimationEnabledExperimental) {
UIManager.setLayoutAnimationEnabledExperimental(true); UIManager.setLayoutAnimationEnabledExperimental(true);
} }
} }
export default function App(){ export default function App() {
const navigationRef = useRef(); const navigationRef = useRef();
var platform = Platform.OS === "android" ? 70 : 50; var platform = Platform.OS === "android" ? 70 : 50;
useEffect(()=>UpdateAsync(),[]) useEffect(() => UpdateAsync(), []);
return( return (
<NavigationContainer name= "Root" ref={navigationRef} style={{flex:1}}> <NavigationContainer name="Root" ref={navigationRef} style={{ flex: 1 }}>
<Tab.Navigator> <Tab.Navigator>
<Stack.Screen name="login" component={top} options={{ tabBarLabel: '位置情報',headerTransparent:true,gestureEnabled:true,tabBarIcon: ({ color, size }) => (<AntDesign name="barchart" size={32} />),}}/> <Stack.Screen
<Stack.Screen name="menuPage" component={menuPage} options={{ tabBarLabel: 'リンク',headerTransparent:true,gestureEnabled:true,tabBarIcon: ({ color, size }) => (<Ionicons name="ios-radio" size={32}/>),}}/> name="login"
<Stack.Screen name="home" component={tndView} options={{ tabBarLabel: '運行情報',headerTransparent:true,gestureEnabled:true,tabBarIcon: ({ color, size }) => (<Ionicons name="md-train" size={32}/>),}}/> component={top}
options={{
tabBarLabel: "位置情報",
headerTransparent: true,
gestureEnabled: true,
tabBarIcon: ({ color, size }) => (
<AntDesign name="barchart" size={32} />
),
}}
/>
<Stack.Screen
name="menuPage"
component={menuPage}
options={{
tabBarLabel: "リンク",
headerTransparent: true,
gestureEnabled: true,
tabBarIcon: ({ color, size }) => (
<Ionicons name="ios-radio" size={32} />
),
}}
/>
<Stack.Screen
name="home"
component={tndView}
options={{
tabBarLabel: "運行情報",
headerTransparent: true,
gestureEnabled: true,
tabBarIcon: ({ color, size }) => (
<Ionicons name="md-train" size={32} />
),
}}
/>
</Tab.Navigator> </Tab.Navigator>
</NavigationContainer> </NavigationContainer>
);
)
} }
function top(){ function top() {
return( return (
<Stack.Navigator> <Stack.Navigator>
<Stack.Screen name="Apps" component={Apps} options={{headerShown: false,gestureEnabled:true,headerTransparent:true,}}/> <Stack.Screen
<Stack.Screen name="trainbase" component={trainbase} options={{ title: 'トレインビジョン',gestureEnabled:true,...TransitionPresets.SlideFromRightIOS}}/> name="Apps"
<Stack.Screen name="howto" component={howto} options={{ title: '使い方',gestureEnabled:true,...TransitionPresets.ModalPresentationIOS,cardOverlayEnabled:true,headerTransparent:true,headerShown:false}}/> component={Apps}
<Stack.Screen name="test" component={TestArea} options={{}}/> options={{
<Stack.Screen name="news" component={News} options={{gestureEnabled:true,...TransitionPresets.ModalPresentationIOS,cardOverlayEnabled:true,headerTransparent:true,headerShown:false}} /> headerShown: false,
<Stack.Screen name="trainMenu" component={trainMenu} options={{gestureEnabled:true,...TransitionPresets.ModalPresentationIOS,cardOverlayEnabled:true,headerTransparent:true,headerShown:false}} /> gestureEnabled: true,
headerTransparent: true,
}}
/>
<Stack.Screen
name="trainbase"
component={trainbase}
options={{
title: "トレインビジョン",
gestureEnabled: true,
...TransitionPresets.SlideFromRightIOS,
}}
/>
<Stack.Screen
name="howto"
component={howto}
options={{
title: "使い方",
gestureEnabled: true,
...TransitionPresets.ModalPresentationIOS,
cardOverlayEnabled: true,
headerTransparent: true,
headerShown: false,
}}
/>
<Stack.Screen name="test" component={TestArea} options={{}} />
<Stack.Screen
name="news"
component={News}
options={{
gestureEnabled: true,
...TransitionPresets.ModalPresentationIOS,
cardOverlayEnabled: true,
headerTransparent: true,
headerShown: false,
}}
/>
<Stack.Screen
name="trainMenu"
component={trainMenu}
options={{
gestureEnabled: true,
...TransitionPresets.ModalPresentationIOS,
cardOverlayEnabled: true,
headerTransparent: true,
headerShown: false,
}}
/>
</Stack.Navigator> </Stack.Navigator>
) );
} }
function menuPage(){ function menuPage() {
return( return (
<Stack.Navigator> <Stack.Navigator>
<Stack.Screen name="menu" component={menu} options={{headerShown: false,gestureEnabled:true,headerTransparent:true,}}/> <Stack.Screen
<Stack.Screen name="setting" component={Setting} options={{gestureEnabled:true,...TransitionPresets.ModalPresentationIOS,cardOverlayEnabled:true,headerTransparent:true,headerShown:false}} /> name="menu"
component={menu}
options={{
headerShown: false,
gestureEnabled: true,
headerTransparent: true,
}}
/>
<Stack.Screen
name="setting"
component={Setting}
options={{
gestureEnabled: true,
...TransitionPresets.ModalPresentationIOS,
cardOverlayEnabled: true,
headerTransparent: true,
headerShown: false,
}}
/>
</Stack.Navigator> </Stack.Navigator>
) );
} }

30
Apps.js
View File

@ -773,7 +773,30 @@ observer.observe(target, {
}); });
`; `;
const injectJavascriptData = bootData + trainIconMaker + textInsert; const modal_content = `
const modal_content = document.getElementById('modal_content'); // body要素を監視
const modal_observer = new MutationObserver( (mutations) => {
// observer.disconnect(); // 監視を終了
for(let d of modal_content.getElementsByTagName("button") ){
const data = d.onclick.toString().split("\\"")[1];
d.onclick = () => window.ReactNativeWebView.postMessage(data)
}
});
// 監視を開始
modal_observer.observe(modal_content, {
//attributes: true, // 属性変化の監視
//attributeOldValue: true, // 変化前の属性値を matation.oldValue に格納する
//characterData: true, // テキストノードの変化を監視
//characterDataOldValue: true, // 変化前のテキストを matation.oldValue に格納する
childList: true, // 子ノードの変化を監視
//subtree: true // 子孫ノードも監視対象に含める
});
`;
const injectJavascriptData =
bootData + modal_content + trainIconMaker + textInsert;
useEffect(() => { useEffect(() => {
AsyncStorage.getItem("status") AsyncStorage.getItem("status")
@ -862,7 +885,10 @@ observer.observe(target, {
} }
} }
}} }}
onMessage={(event) => {}} onMessage={(event) => {
console.log(event.nativeEvent.data);
navigate("trainbase", { info: event.nativeEvent.data });
}}
injectedJavaScript={injectJavascriptData} injectedJavaScript={injectJavascriptData}
/> />
<TouchableOpacity <TouchableOpacity

View File

@ -67,7 +67,7 @@ export default function Setting(props) {
textAlignVertical: "center", textAlignVertical: "center",
}} }}
> >
内部バージョン: 4.3.1 内部バージョン: 4.3.2
</Text> </Text>
<View style={{ flex: 1 }} /> <View style={{ flex: 1 }} />
</View> </View>

View File

@ -1,14 +1,19 @@
const WEBVIEW = "WEBVIEW"; const WEBVIEW = "WEBVIEW";
import React, { Component } from 'react'; import React, { Component } from "react";
import { StatusBar,View} from 'react-native'; import { StatusBar, View } from "react-native";
import {WebView} from 'react-native-webview'; import { WebView } from "react-native-webview";
export default function trainbase({route, navigation}) { const jss = `document.getElementById('Footer').style.display = 'none';`;
export default function trainbase({ route, navigation }) {
const { info } = route.params; const { info } = route.params;
console.log(info);
return ( return (
<View style={{height:"100%"}}> <View style={{ height: "100%" }}>
<WebView source={{uri: info}} useWebKit={true} originWhitelist={['https://train.jr-shikoku.co.jp']}injectedJavaScript={jss}/> <WebView
source={{ uri: "https://train.jr-shikoku.co.jp/" + info }}
useWebKit={true}
originWhitelist={["https://train.jr-shikoku.co.jp"]}
injectedJavaScript={jss}
/>
</View> </View>
); );
} }
const jss = `document.getElementById('Footer').style.display = 'none';`;