Dore is a WebView container implemented using React Native. Help you migrate Cordova application to React Native WebView.
Dore 是一个使用 React Native 实现的 WebView 容器,可以让你在 WebView 调用 React Native 组件。
设计初衷:作为迁移 Cordova 的 WebView 应用到 React Native 的 WebView 的基础设施。
Feel free to give a pull request or issues, questions.
欢迎使用 Dore,如果你在过程中遇到问题,可以与我们联系。
Demo (Ionic v1 + Angular + React Native + Dore) : see in examples
Screenshots:
Workflow:
微信群:
- AppAvailability (react-native-check-app-install)
- AppState
- AsyncStorage
- BackHandler (Android)
- Badge (by react-native-icon-badge
- Brightness (by react-native-device-brightness)
- Console
- Calender (by react-native-calendar-events)
- Clipboard
- DatePicker (iOS by react-native-notag-datepicker)
- DeviceInfo (by react-native-device-info)
- Flashlight (react-native-torch)
- Geolocation
- Keyboard
- NetInfo
- Orientation
- Permissions (by react-native-permissions)
- ScreenShot (by react-native-view-shot)
- Shake (by react-native-shake-event)
- SMS (by react-native-sms)
- SQLite (Test Only,react-native-sqlite-storage
- StatusBar
- Toast (by dore-toast)
- Vibration
Those plugins just list, don't plan to implement in Dore.
- ActionSheet (https://github.com/EddyVerbruggen/cordova-plugin-actionsheet)
- Camera
- Dialog (https://github.com/apache/cordova-plugin-dialogs)
- Feedback (https://github.com/EddyVerbruggen/nativescript-feedback)
- QRCode
- Share (https://github.com/EddyVerbruggen/SocialSharing-PhoneGap-Plugin)
- BluetoothSerial (https://github.com/don/BluetoothSerial)
- BLE (https://github.com/don/cordova-plugin-ble-central)
- fs
- NFC
- Push Notifications (https://github.com/zo0r/react-native-push-notification)
- TTS (https://github.com/naoufal/react-native-speech)
- Wechat (RN)
- Weibo (RN)
see in examples
1.Import to your React-Native WebView
...
import Toast from 'dore-toast';
import Orientation from 'react-native-orientation';
import RNIconBadge from 'dore-icon-badge'
import RNDeviceInfo from "react-native-device-info";
import Dore from 'dore';
export default class ExampleWebView extends Component {
...
constructor() {
super()
...
Dore.inject([{
name: 'Toast',
class: Toast
}, {
name: 'Orientation',
class: Orientation
}, {
name: 'Badge',
class: RNIconBadge
}, {
name: 'DeviceInfo',
class: RNDeviceInfo
}])
}
onMessage = evt => {
Dore.handleMessage(evt, this.webView)
};
onWebViewLoadStart = () => {
if (this.state.isLoading) {
this.webView.injectJavaScript('window.isPhone = true;');
}
};
render() {
...
return (
<View>
<WebView
...
onMessage={this.onMessage}
/>
</View>
)
}
}
2.import DoreClient, e.x:
<script src="js/promise.js"></script>
<script src="js/DoreClient.js"></script>
3.use in WebView
DoreClient.showToast('Hello, world!')
function | return type | return |
---|---|---|
isAppInstalled | promise | string |
isAppInstalledAndroid | promise | string |
checkURLScheme | promise | string |
install:
yarn add react-native-check-app-install
react-native link
inject:
import { AppInstalledChecker } from "react-native-check-app-install";
Dore.inject([{
name: 'AppInstalledChecker',
class: AppInstalledChecker
}]);
examples:
DoreClient.checkURLScheme('whatsapp').then(function(response){
$scope.isAppInstalled = response;
})
state value: active
, background
, inactive
DoreClient.addStateListener();
$ionicPlatform.on('STATE', function(event) {
DoreClient.showToast(event.detail.data);
});
function | return type | return |
---|---|---|
setAsyncStorage | - | - |
getAsyncStorage | promise | string |
$scope.setAsyncStorage = function (key, data) {
DoreClient.setAsyncStorage(key, data);
};
$scope.getAsyncStorage = function (key) {
DoreClient.getAsyncStorage(key).then(function(response){
$scope.storage = response.data;
})
};
example:
$ionicPlatform.on('ANDROID_BACK', function (event) {
DoreClient.showToast('ANDROID_BACK');
});
function | return type | return |
---|---|---|
setBadge | - | - |
getBadge | promise | { badge: 'xx' } |
clearBadge | - | - |
$scope.getBadge = function () {
DoreClient.getBadge().then(function (data) {
$scope.badge = data.badge;
$scope.$apply();
})
};
$scope.setBadge = function() {
DoreClient.setBadge(19);
};
$scope.clearBadge = function() {
DoreClient.clearBadge();
};
function | return type | return |
---|---|---|
getBrightnessLevel | promise | float |
setBrightnessLevel | - | - |
$scope.getBrightness = function () {
DoreClient.getBrightnessLevel().then(function(brightness) {
$scope.brightness = brightness;
$scope.$apply();
})
};
$scope.setBrightness = function () {
DoreClient.setBrightnessLevel(0.2);
};
function | return type | return |
---|---|---|
calendarAuthorizationStatus | promise | String |
requestCalendarAuthorize | - | - |
findEventById | promise | json |
fetchAllCalendar | promise | json |
saveCalendar | promise | json |
removeCalendar | promise | json |
findCalendars | promise | json |
install
yarn add react-native-calendar-events
react-native link react-native-calendar-events
inject
import RNCalendarEvents from 'react-native-calendar-events';
Dore.inject([{
name: 'Calendar',
class: RNCalendarEvents
}]);
examples:
permissions action:
DoreClient.calendarAuthorizationStatus().then(function (response) {
$scope.authStatus = response;
$scope.$apply();
});
DoreClient.requestCalendarAuthorize();
calendar actions:
$scope.saveCalendar = function () {
DoreClient.saveCalendar("title",
{
location: 'location',
notes: 'notes',
startDate: new Date().toISOString(),
endDate: new Date().toISOString()
}).then(function(response){
console.log(response);
})
};
$scope.findCalendars = function () {
DoreClient.findCalendars().then(function(response){
console.log(response);
$scope.calendars = response;
$scope.$apply();
})
};
$scope.fetchAllCalendar = function () {
DoreClient.fetchAllCalendar('2017-12-26T19:26:00.000Z',
'2018-01-1T19:26:00.000Z', ['1', '2']).then(function(response){
console.log(response);
$scope.fetchCalendars = response;
$scope.$apply();
})
};
$scope.removeFirstCalendar = function () {
DoreClient.fetchAllCalendar('2017-12-26T19:26:00.000Z',
'2018-01-1T19:26:00.000Z', ['1', '2']).then(function(response){
console.log(response);
if (response.length < 1) {
return DoreClient.showToast("请先创建日历");
}
var lastCalendar = response[0];
DoreClient.removeCalendar(lastCalendar.id)
})
};
$scope.findEventById = function () {
DoreClient.findEventById("297D3B27-4070-49A4-8BF9-1E7631727B4A").then(function(response){
console.log(response);
$scope.savedCalendar = response;
$scope.$apply();
})
};
function | return type | return |
---|---|---|
copy | - | |
paste | event | window.event |
copy:
DoreClient.copy($scope.text);
paste:
$ionicPlatform.on('PASTE', function(event) {
$scope.copyText = event.detail.data;
$scope.$apply();
});
DoreClient.paste();
Console (MDN Console)
send WebView console to React Native
$scope.console = console; // can use inline console function after register
$scope.outputSingleObject = function () {
var someObject = {str: "Some text", id: 5};
console.log(someObject);
};
$scope.outputMultipleObjects = function () {
var car = "Dodge Charger";
var someObject = {str: "Some text", id: 5};
var optionalParams = [car, ". The object is:", someObject];
console.info("My first car was a", optionalParams);
};
$scope.stringSubstitutions = function () {
for (var i = 0; i < 5; i++) {
var optionalParams = [ "Bob", i + 1];
console.log("Hello, %s. You've called me %d times.", optionalParams);
}
};
$scope.stylingConsoleOutput = function () {
var optionalParams = ["color: yellow; font-style: italic; background-color: blue;padding: 2px"];
console.log("This is %cMy stylish message", optionalParams);
};
$scope.groupInTheConsole = function () {
console.log("This is the outer level");
console.group();
console.log("Level 2");
console.group();
console.log("Level 3");
console.warn("More of level 3");
console.groupEnd();
console.log("Back to level 2");
console.groupEnd();
console.debug("Back to the outer level");
};
$scope.timers = function () {
console.time("answer time");
alert("Click to continue");
console.timeEnd("answer time");
};
$scope.stackTraces = function () {
function foo() {
function bar() {
console.trace();
}
bar();
}
foo();
};
function | return type | return |
---|---|---|
showDatePicker | promise | { date: 'xx' } |
var options = {
date: '2017-10-22 12:12:12',
maxDate: '2022-10-22 12:12:12'
};
DoreClient.showDatePicker(options).then(function(data) {
$scope.date = data.date;
$scope.$apply();
});
function | return type | return |
---|---|---|
getAppVersion | promise | { version: 'xx' } |
getUniqueID | promise | { uniqueID: 'xx' } |
getBrand | promise | { brand: 'xx' } |
getModel | promise | { model: 'xx' } |
getSystemName | promise | { systemName: 'xx' } |
isEmulator | promise | boolean |
isTablet | promise | boolean |
examples:
$scope.getAppVersion = function() {
DoreClient.getAppVersion().then(function(data) {
$scope.version = data.version;
$scope.$apply();
});
};
$scope.isTablet = function() {
DoreClient.isTablet().then(function(data) {
$scope.isTablet = data;
$scope.$apply();
});
};
function | return type | return |
---|---|---|
onFlashlight | - | - |
offFlashlight | - | - |
inject
import Torch from 'react-native-torch';
Dore.inject([{
name: 'Flashlight',
class: Torch
}]);
usage
$scope.onFlashlight = function () {
DoreClient.onFlashlight();
};
$scope.offFlashlight = function () {
DoreClient.offFlashlight();
}
function | return type | return |
---|---|---|
getCurrentPosition | promise | json |
watchPosition | event | event |
clearWatch | - | - |
stopObserving | - | - |
$scope.getCurrentPosition = function() {
DoreClient.getCurrentPosition().then(function(data) {
$scope.location = data;
$scope.$apply();
});
};
$scope.watchPosition = function() {
$ionicPlatform.on('WATCH_POSITION', function(event) {
$scope.wPosition = event.detail.data;
$scope.$apply();
});
DoreClient.watchPosition();
};
$scope.clearWatch = function() {
DoreClient.clearWatch();
};
$scope.stopObserving = function() {
DoreClient.stopObserving();
};
function | return type | return |
---|---|---|
hideKeyboard | - | - |
DoreClient.hideKeyboard();
function | return type | return |
---|---|---|
getConnectionInfo | promise | json |
addNetInfoEventListener | event | event |
removeNetInfoEventListener | - | - |
$scope.getConnectionInfo = function() {
DoreClient.getConnectionInfo().then(function(data) {
$scope.connectionInfo = data;
$scope.$apply();
});
};
$scope.addEventListener = function() {
$ionicPlatform.on('CONNECTION_CHANGE', function(event) {
$scope.wConnectionInfo = event.detail.data;
$scope.$apply();
});
DoreClient.addNetInfoEventListener();
};
$scope.removeEventListener = function() {
DoreClient.removeNetInfoEventListener();
};
function | return type | return |
---|---|---|
getOrientation | promise | string |
lockToLandscape | - | - |
lockToPortrait | - | - |
$scope.lockToLandscape = function() {
DoreClient.lockToLandscape();
};
$scope.lockToPortrait = function() {
DoreClient.lockToPortrait();
};
$scope.getConnectionInfo = function() {
DoreClient.getConnectionInfo().then(function(data) {
$scope.connectionInfo = data;
$scope.$apply();
});
};
function | return type | return |
---|---|---|
checkPermissions | promise | JSON |
requestPermissions | promise | JSON |
checkMultiple | promise | JSON |
$scope.checkPermissions = function () {
DoreClient.checkPermissions('camera').then(function(response) {
DoreClient.showToast(JSON.stringify(response));
})
};
$scope.requestPermissions = function () {
DoreClient.requestPermissions('camera').then(function(response) {
DoreClient.showToast(JSON.stringify(response));
})
};
$scope.checkMultiple = function () {
DoreClient.checkMultiple(['camera', 'photo']).then(function(response) {
DoreClient.showToast(JSON.stringify(response));
})
};
function | return type | return |
---|---|---|
captureScreen | string | URI |
install:
yarn add react-native-view-shot
react-native link react-native-view-shot
inject:
import { captureScreen } from "react-native-view-shot";
Dore.inject([{
name: 'Capture',
class: captureScreen
}]);
Usage
DoreClient.captureScreen().then(function(response) {
})
function | return type | return |
---|---|---|
sendSMS | event | event |
Install:
yarn add react-native-sms
react-native link react-native-sms
Inject
import SendSMS from 'react-native-sms';
Dore.inject([{
name: 'SMS',
class: SendSMS
}]);
Examples:
$scope.sendSMS = function () {
DoreClient.sendSMS({
body: 'Hello, world',
recipients: ['10086']
});
}
function | return type | return |
---|---|---|
hideStatusBar | - | - |
showStatusBar | - | - |
DoreClient.hideStatusBar();
DoreClient.showStatusBar();
function | return type | return |
---|---|---|
addShakeListener | event | - |
removeShakeListener | - | - |
$ionicPlatform.on('SHAKE', function (response) {
$scope.shake = response.detail.data;
$scope.$apply();
});
DoreClient.addShakeListener();
Done:
DoreClient.removeShakeListener();
function | return type | return |
---|---|---|
show | - | - |
DoreClient.showToast(String, duration: short | long , position: 'center' | 'top')
DoreClient.showToast('this is a toast');
DoreClient.showToast('this is a toast', 'long', 'center');
function | return type | return |
---|---|---|
vibrate | - | - |
show | - | - |
DoreClient.vibrationVibrate(1000);
DoreClient.vibrationCancel();
function operationDataBase(webview, db) {}
function errorCB(error) {}
var SQLite = DoreClient.SQLite;
SQLite.open(
'test.db',
'1.0',
'SQLite test databases',
200000,
operationDataBase,
errorCB)
.then(function (payload) {
console.log('open then');
console.log(payload);
alert(JSON.stringify(payload))
})
.catch(function (err) {
console.log(err)
})
};
Workflow: DoreClient:Browser -> vibrationVibrate -> DoreClient -> window.postMessage -> RN
DoreClient, handle message in WebView
Browser
$scope.vibrationVibrate = function () {
DoreClient.vibrationVibrate([1000, 2000, 3000]);
};
DoreClient
function invoke(action, payload) {
function postMessage(action, payload) {
var message = JSON.stringify({
action: action,
payload: payload
});
window.postMessage(message, '');
}
}
DoreClient = {
vibrationVibrate: function (duration) {
return invoke('VIBRATION', {type: 'VIBRATE', duration: duration});
}
}
Workflow: Dore: WebView -> onMessage -> Dore -> xxxBridge -> Native
Dore, handle message in React Native
WebView
onMessage = evt => {
Dore.handleMessage(evt, this.webView)
};
Dore
Dore.handleMessage = (event, webView) => {
const action = eventData.action;
switch (action) {
case 'VIBRATION': {
return VibrationBridge(payload)
}
}
}
Bridge
import { Vibration } from 'react-native';
let VibrationBridge = (payload) => {
if (payload.type === 'VIBRATE') {
if (!payload.options) {
return Vibration.vibrate(500) // is duration is fixed time (about 500ms)
}
if (Number.isInteger(payload.duration) || payload.duration.length > 0) {
return Vibration.vibrate(payload.duration)
}
} else if (payload.type === 'CANCEL') {
Vibration.cancel();
}
};
© 2017 A Phodal Huang's Idea. This code is distributed under the MIT license. See LICENSE
in this directory.