Rendering a webpage located on device with react native - webview

I have researched quite a lot and tried to no avail to render a locally located webpage (with dynamic content based off of get vars in the url) to render in a webpage on android and ios with react native.
Firstly is this even possible?
and if its not possible is there any other cross platform mobile development technologies out there that can achieve this?
Thank you

Yes it's possible to load local html into the webview. You can pass the html via require to the webview's source property. There's an example in the docs:
render(): ReactElement<any> {
return (
<WebView
style={{
backgroundColor: BGWASH,
height: 100,
}}
source={require('./helloworld.html')}
scalesPageToFit={true}
/>
);
}
You can use the injectedJavaScript property to inject javascript containing your arguments in order to make the content dynamic.
render(): ReactElement<any> {
return (
<WebView
style={{
backgroundColor: BGWASH,
height: 100,
}}
source={require('./helloworld.html')}
scalesPageToFit={true}
injectedJavaScript="var a = 1;"
/>
);
}

Related

React Native Paper Dark Theme on IOS

I want to use react-native-paper dark theme on my apps, however, all my <View> are still had a white background and causing all the Text component unreadable because the text turns white in dark mode. I didn't use custom theming since the docs mention that:
If you don't use a custom theme, Paper will automatically turn animations on/off, depending on device settings.
This is my code in App.js:
import React from 'react';
import {Provider as PaperProvider} from 'react-native-paper';
import Home from './src/Home';
const App = () => {
return (
<PaperProvider>
<Home />
</PaperProvider>
);
};
export default App;
This is in my Home.js:
import React from 'react';
import {View} from 'react-native';
import {Appbar, Card, Title} from 'react-native-paper';
const Home = () => {
return (
<View style={{flex: 1}}>
<Appbar.Header>
<Appbar.BackAction onPress={() => console.log('back')} />
<Appbar.Content title="Title" subtitle={'Subtitle'} />
</Appbar.Header>
<View>
<Title>Hello World</Title>
<Card
style={{margin: 15, padding: 15}}
onPress={() => console.log('press card')}>
<Title>This is Card</Title>
</Card>
</View>
</View>
);
};
export default Home;
and this is the result:
The view still white and the Title also white due to dark mode
It working fine on android
The text turns white because it is the behavior of dark mode, but why my <View> is still white? This is only happening on iOS, it works fine on android.
This is a new react native project, and based on documentation in react-native-paper it will turn the dark theme automatically. So, I need help if I missed something in setting up this project on iOS. Any help would be appreciated.
react: 16.13.1
react-native: 0.63.4
react-native-paper: ^4.7.1
react-native-vector-icons: ^8.0.0
If you do not specify a custom theme, Paper will use the DefaultTheme which is essentially a light theme. To employ a dark theme in your app, Paper provides a Material based DarkTheme. You can specify which theme to use within the Paper provider.
Complete example from the docs for DefaultTheme including customization:
import * as React from 'react';
import { DefaultTheme, Provider as PaperProvider } from 'react-native-paper';
import App from './src/App';
const theme = {
...DefaultTheme,
roundness: 2,
colors: {
...DefaultTheme.colors,
primary: '#3498db',
accent: '#f1c40f',
},
};
export default function Main() {
return (
<PaperProvider theme={theme}>
<App />
</PaperProvider>
);
}
PaperProvider uses React Context. Theme can be accessed within components with the withTheme HOC or useTheme hook.

setNativeProps for TextInput in React Native

How do I know what native props are available for a component to use setNativeProps. In this example, the <TextInput> component doesn't have text as a prop but apparently setNativeProps use text instead of value as a prop. Thank you!
clearText = () => {
this._textInput.setNativeProps({text: ''});
}
render() {
return (
<View style={{flex: 1}}>
<TextInput
ref={component => this._textInput = component}
/>
<TouchableOpacity onPress={this.clearText}>
<Text>Clear text</Text>
</TouchableOpacity>
</View>
);
}
}
This is pretty common in react-native, due to limited documentation. Whenever looking for any information regarding react-native components, it is a good idea to simply look at the .js file you are using. In this case, TextInput, can be found...
Project/node_modules/react-native/Libraries/Components/TextInput/TextInput.js
Hope you can find what you're looking for - with a bit of digging. If you want to look further, looking into the RCT files is a good idea also.
Project/node_modules/react-native/Libraries/Text/RCTTextField.h
Project/node_modules/react-native/Libraries/Text/RCTTextView.h

How i set position text on Listview with React-Native in Android and iOS

I am a newbie developer. I'm currently developing apps using React-Native on two platforms, Android and iOS.
I have several constraints when designing this app on the two platforms I use. This app is similar to chat. For the wrapping compiler I use Listview. But there are constraints when running on the iOS platform.
My code is as follows:
<View style={Styles.container}>
<View style={Styles.conversation}>
{this.messages.length > 0
? <ListView
enableEmptySections
style={Styles.messageList}
ref={ref => (this.listView = ref)}
onContentSizeChange={(contentWidth, contentHeight) => {
this.listView.scrollTo({
y: contentHeight,
});
}
}}
dataSource={ds.cloneWithRows(this.messages)}
renderRow={item => <Message data={item} key={item.key} />}
/>
: <Text style={Styles.welcome_message}>Welcome to Kelle</Text>}
</View>
The code above on Android goes well. But when it runs on iOS, the chat text position in the Listview becomes random. Like the picture below:
Has anyone ever experienced anything like this? How should I solve this problem?

ReactNative 0.28: Resizing WebView based on content height

I'm basically asking the same question as this one, but for RN 0.28+. The solutions presented in the various answers do not seem to work in RN 0.28, so I'm hoping there are other configurations or hacks...
Is there any way to resize a WebView based on the height of its content? I've tried injecting the document height into the title and reading that back with onNavigationStateChange, but it always returns 568 (similar to the comments to this gist).
return <TouchableHighlight onPress={() => console.log('touched ' + this.props.choice.id)}
style={styles.choiceRowWrapper} >
<View style={styles.choiceWebViewWrapper}>
<WebView automaticallyAdjustContentInsets={false}
javascriptEnabled={true}
onNavigationStateChange={(navState) => this._updateWebViewNavState(navState)}
scrollEnabled={false}
source={{html: WrapHTML(this.props.choice.text)}}
style={[styles.choiceWebView, {height: this.state.height}]} />
</View>
</TouchableHighlight>
}
_updateWebViewNavState = (navState) => {
console.log(navState);
if (navState.title) {
this.setState({ height: parseInt(navState.title) });
}
}
function WrapHTML (markup) {
return `<!DOCTYPE html>
<html>
<head>
</head>
<body class="content">
${markup}
</body>
<script>window.location.hash = 1;document.title = document.height;</script>
</html>`;
};
I have also tried various things inside of the WebView document, like:
document.scrollHeight.contentSize.height
document.body.height
But all of them are undefined. The closest I got was something like this (from this iOS SO question):
document.getElementById("content").offsetHeight;
But for short text content that returns 20, and for a longer text content (one full sentence) it returns 40...neither of which seems accurate.
I also started trying this RN component, but the repo indicates that it is not being actively maintained -- the latest version on npm doesn't support RN 0.28 because of the change they made for importing React by itself (instead of from ReactNative).
Has anyone gotten WebViews to resize properly with RN 0.28?
After a lot of research and tinkering, I found this approach which is a slightly more involved version of setting the document title to the screen height value. In my tests, this has worked on both Android and iOS with react native 0.47.
https://gist.github.com/xyos/dcaa43fa561760b9d6194d78e5fb7721

(Rails) Need some javascript assistance

I currently have an application that calls creates and displays charts from various objects' data using JS. However, I'm having some severe issues. Can someone please explain why the following code works just fine when statically inserted into a page, but when used via rjs "page.replace_html my_div_id" it removes EVERYTHING ELSE on the page:
<script language="JavaScript" type="text/javascript">
<!--
if (AC_FL_RunContent == 0 || DetectFlashVer == 0) {
alert("This page requires AC_RunActiveContent.js.");
} else {
var hasRightVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision);
if(hasRightVersion) {
AC_FL_RunContent(
'codebase', 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,45,0',
'width', '800',
'height', '500',
'scale', 'noscale',
'salign', 'TL',
'bgcolor', '#777788',
'wmode', 'opaque',
'movie', 'charts',
'src', 'charts',
'FlashVars', 'library_path=xmlswfitems/charts_library&xml_source=xmlcharts/M1 Building One',
'id', 'my_chart',
'name', 'M1 Building One',
'menu', 'true',
'allowFullScreen', 'true',
'allowScriptAccess','sameDomain',
'quality', 'high',
'align', 'middle',
'pluginspage', 'http://www.macromedia.com/go/getflashplayer',
'play', 'true',
'devicefont', 'false'
);
} else {
var alternateContent = 'This content requires the Adobe Flash Player. '
+ '<u><a href=http://www.macromedia.com/go/getflash/>Get Flash</a></u>.';
document.write(alternateContent);
}
}
// -->
</script>
...also, it completely fails with IE. My only leads are from Safari ("unmatched embed tag"), Firefox (browser pretends chart never loads even though it has), IE (non-specific prototype.js error). FYI, I'm using XML/SWF Charts. I'm writing this code from scratch as I have needs not met by the existing/outdated SWFCharts library so please don't suggest solutions involving that particular library.
Best.
Use a standard library like SWFObject to embed your flash. It takes care of all the crossbrowser quirks for you and let's you do both static and dynamic publishing with regular html to fall back on if the user does not have flash.
AC_FL_RunContent uses document.write to generate the <object>/<embed> tags, which, if called after the page is completely loaded, replaces the entire contents of the page.
You will probably need to use SWFObject; as far as I know, it doesn't use document.write so it should work anytime.

Resources