2
0
mirror of synced 2025-02-23 11:38:49 +00:00

[admob][android] Implement shared event emitter @Salakar

This commit is contained in:
Elliot Hesp 2017-05-26 17:55:22 +01:00
parent d0e1ae3dec
commit 1b8a2826ac
3 changed files with 97 additions and 56 deletions

View File

@ -1,18 +1,29 @@
import React, { PropTypes } from 'react';
import { requireNativeComponent, View } from 'react-native';
import { statics } from './';
import { nativeToJSError } from '../../utils';
class Banner extends React.Component {
static propTypes = {
...View.propTypes,
// TODO ehesp: cant init this outside of the component; statics isn't defined
...(() => {
const eventProps = {};
Object.keys(statics.EventTypes).forEach((key) => {
eventProps[key] = PropTypes.func;
});
return eventProps;
}),
size: PropTypes.string,
unitId: PropTypes.string,
onAdLoaded: PropTypes.func,
testing: PropTypes.bool,
};
static defaultProps = {
size: 'SMART_BANNER',
unitId: 'ca-app-pub-3940256099942544/6300978111', // Testing
testing: true,
};
constructor() {
@ -23,12 +34,16 @@ class Banner extends React.Component {
};
}
/**
* Handle a single banner event and pass to
* any props watching it
* @param nativeEvent
*/
onBannerEvent = ({ nativeEvent }) => {
if (this.props[nativeEvent.type]) {
if (nativeEvent.type === 'onAdFailedToLoad') {
const error = new Error(nativeEvent.payload.message);
error.code = nativeEvent.payload.code;
this.props[nativeEvent.type](error);
const { code, message } = nativeEvent.payload;
this.props[nativeEvent.type](nativeToJSError(code, message));
} else {
this.props[nativeEvent.type](nativeEvent.payload || {});
}
@ -37,10 +52,19 @@ class Banner extends React.Component {
if (nativeEvent.type === 'onSizeChange') this.updateSize(nativeEvent.payload);
};
/**
* Handle a native onSizeChange event
* @param width
* @param height
*/
updateSize = ({ width, height }) => {
this.setState({ width, height });
};
/**
* Render the native component
* @returns {XML}
*/
render() {
return (
<RNFirebaseAdMobBanner

View File

@ -1,20 +1,47 @@
import { NativeModules, NativeEventEmitter } from 'react-native';
import Interstitial from './Interstitial';
import AdRequest from './AdRequest';
import Banner from './Banner';
import Base from './../base';
import { Base } from './../base';
const FirebaseAdMob = NativeModules.RNFirebaseAdMob;
const FirebaseAdMobEvt = new NativeEventEmitter(FirebaseAdMob);
export default class Admob extends Base {
interstitial(adUnit: string) {
return new Interstitial(this, FirebaseAdMobEvt, adUnit);
constructor() {
super();
FirebaseAdMobEvt.addListener('interstitial_event', this._onInterstitialEvent.bind(this));
}
_onInterstitialEvent(event) {
const { adunit } = event;
const jsEventType = `interstitial_${adunit}`;
if (!this.hasListeners(jsEventType)) {
// TODO
}
this.emit(jsEventType, event);
}
interstitial(adUnit: string) {
return new Interstitial(this, adUnit);
}
static get statics() {
return statics;
}
}
export const statics = {
Banner,
AdRequest,
EventTypes: {
onAdLoaded: 'onAdLoaded',
onAdOpened: 'onAdOpened',
onAdLeftApplication: 'onAdLeftApplication',
onAdClosed: 'onAdClosed',
onAdFailedToLoad: 'onAdFailedToLoad',
},
};

View File

@ -1,25 +1,14 @@
/**
* @flow
*/
import { NativeModules, NativeEventEmitter } from 'react-native';
import EventEmitter from 'EventEmitter';
import Log from '../utils/log';
import EventEmitter from './../utils/eventEmitter';
const FirebaseModule = NativeModules.RNFirebase;
const FirebaseModuleEvt = new NativeEventEmitter(FirebaseModule);
const logs = {};
const SharedEventEmitter = new EventEmitter();
type FirebaseOptions = {};
export class Base extends EventEmitter {
constructor(firebase: Object, options: FirebaseOptions = {}) {
super();
this.firebase = firebase;
this.eventHandlers = {};
this.options = Object.assign({}, firebase.options, options);
}
export class Base {
/**
* Return a namespaced instance of Log
@ -27,52 +16,53 @@ export class Base extends EventEmitter {
*/
get log(): Log {
if (logs[this.namespace]) return logs[this.namespace];
return logs[this.namespace] = new Log(this.namespace, this.firebase._debug);
// todo grab log level from global config provider (still todo);
return logs[this.namespace] = new Log(this.namespace, '*');
}
/**
* app instance
**/
get app(): Object {
return this.firebase.app;
}
/**
* Add a native module event subscription
* @param name
* @param handler
* @param nativeModule
* @returns {*}
* @private
/*
* Proxy functions to shared event emitter instance
* https://github.com/facebook/react-native/blob/master/Libraries/EventEmitter/EventEmitter.js
*/
_on(name, handler, nativeModule) {
let _nativeModule = nativeModule;
if (!_nativeModule) {
_nativeModule = FirebaseModuleEvt;
}
return this.eventHandlers[name] = _nativeModule.addListener(name, handler);
get sharedEventEmitter () {
return SharedEventEmitter;
}
/**
* Remove a native module event subscription
* @param name
* @private
*/
_off(name): void {
const subscription = this.eventHandlers[name];
if (!subscription) return;
get addListener() {
return SharedEventEmitter.addListener.bind(SharedEventEmitter);
}
subscription.remove();
delete this.eventHandlers[name];
get on() {
return SharedEventEmitter.addListener.bind(SharedEventEmitter);
}
get emit() {
return SharedEventEmitter.emit.bind(SharedEventEmitter);
}
get listeners() {
return SharedEventEmitter.listeners.bind(SharedEventEmitter);
}
hasListeners(eventType: string): Boolean {
const subscriptions = SharedEventEmitter._subscriber.getSubscriptionsForType(eventType);
return subscriptions && subscriptions.length;
}
get removeListener() {
return SharedEventEmitter.removeListener.bind(SharedEventEmitter);
}
get removeAllListeners() {
return SharedEventEmitter.removeAllListeners.bind(SharedEventEmitter);
}
}
export class ReferenceBase extends Base {
constructor(firebase: Object, path: string) {
super(firebase);
constructor(path: string) {
super();
this.path = path || '/';
}