diff --git a/.gitignore b/.gitignore index 5d64756..562c430 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,4 @@ buck-out/ # Bundle artifact *.jsbundle +/yarn.lock diff --git a/App.js b/App.js index 3644216..4618b33 100644 --- a/App.js +++ b/App.js @@ -1,256 +1,833 @@ import React, { Component } from 'react'; - import { +import { Platform, StyleSheet, Text, View, Image, - Dimensions, - TouchableOpacity, + ImageBackground, + PixelRatio, + NativeModules } from 'react-native'; + //引用插件 -import Swiper from 'react-native-swiper'; +import Package from './package.json' import HttpUtils from './HttpUtils.js'; import CodePush from "react-native-code-push"; +import DeviceInfo from "react-native-device-info"; + +import * as Animatable from 'react-native-animatable'; + +var testMac = 'FF:FF:FF:FF:FF:FF' + +var contentItemDefault = { + type:0, + subType:0, + qrcode:[], + target:{ + coverImg:'', + title:'', + subTitle:'', + priceStr:'', + salePriceStr:'', + remark:'', + } +} -// 取得屏幕的宽高Dimensions -const { width, height } = Dimensions.get('window'); - -export default class MyPage extends Component { +var baseInfoDefault = { + imgUrlH:'', + imgQrcodeWeapp:'', + imgQrcodeWemp:'' +} - constructor(props) { - super(props); - this.state = { - swiperShow: false, - text:'', - qrcode:[], - restartAllowed: true , - syncMessage: "我是小更新" , - progress: false - }; +var curAdIndex = 0; +var errorMsg = { + ERR_MAC_GET:'设备编号获取错误', + ERR_START_AD:'广告播放系统错误', + ERR_DATA_GET:'广告数据获取错误', + ERR_HEARTBEAT:'设备心跳数据错误' } +var animationThemes = [ + // 滑入 + { + first:"slideInDown", + second:"slideInLeft", + third:"slideInRight" + }, + // 放大 + { + first:"zoomInDown", + second:"zoomInLeft", + third:"zoomInRight" + }, + // 翻转 + { + first:"flipInX", + second:"flipInY", + third:"flipInX" + }, + // 弹出 + { + first:"bounceInDown", + second:"bounceInLeft", + third:"bounceInRight" + } +] +var hbRequestCount +var getAdDataCount +var pageChangeCount + +export default class MyPage extends Component { + constructor(props) { + super(props); + this.state = { + baseInfo: baseInfoDefault, + adDataList:[], + contentItem0:null, + contentItem1:null, + contentItem2:null, + animationTheme:{}, + heartConfig:{ + heartbeatInterval:1000*10, + dataRefreshInterval:1000*60*60, + pageChangeInterval:1000*10, + }, + contentDisplayStatus:false, + syncMessage: "初始化..." , + errorMessage: '加载中...', + progress: { + receivedBytes:0, + totalBytes:0 + }, + macAddress: '', + versionInfo:'未知' + }; + } // 监听更新状态 codePushStatusDidChange(syncStatus) { switch(syncStatus) { case CodePush.SyncStatus.CHECKING_FOR_UPDATE: - this.setState({ syncMessage: "Checking for update." }); + this.setState({ syncMessage: "检查更新" }); break; case CodePush.SyncStatus.DOWNLOADING_PACKAGE: - this.setState({ syncMessage: "Downloading package." }); + this.setState({ syncMessage: "下载更新" }); break; case CodePush.SyncStatus.AWAITING_USER_ACTION: - this.setState({ syncMessage: "Awaiting user action." }); + this.setState({ syncMessage: "等待用户操作" }); break; case CodePush.SyncStatus.INSTALLING_UPDATE: - this.setState({ syncMessage: "Installing update." }); + this.setState({ syncMessage: "安装更新" }); break; case CodePush.SyncStatus.UP_TO_DATE: - this.setState({ syncMessage: "App up to date.", progress: false }); + this.setState({ syncMessage: "已更新到最新程序", progress: false }); break; case CodePush.SyncStatus.UPDATE_IGNORED: - this.setState({ syncMessage: "Update cancelled by user.", progress: false }); + this.setState({ syncMessage: "更新被取消", progress: false }); break; case CodePush.SyncStatus.UPDATE_INSTALLED: - this.setState({ syncMessage: "Update installed and will be applied on restart.", progress: false }); + this.setState({ syncMessage: "更新已安装,重启应用后生效", progress: false }); break; case CodePush.SyncStatus.UNKNOWN_ERROR: - this.setState({ syncMessage: "An unknown error occurred.", progress: false }); + this.setState({ syncMessage: "未知错误", progress: false }); break; } } - - codePushDownloadDidProgress(progress) { this.setState({ progress }); } + // 列表滚动 + updateContent() { + if (this.state.adDataList.length <=0) + return false; + + if (curAdIndex >= this.state.adDataList.length) { + curAdIndex = 0 + } - // 允许重启后更新 - toggleAllowRestart() { - this.state.restartAllowed - ? CodePush.disallowRestart() - : CodePush.allowRestart(); + this.setState({contentItem0:this.state.adDataList[curAdIndex]}); - this.setState({ restartAllowed: !this.state.restartAllowed }); + if (curAdIndex + 1 < this.state.adDataList.length) + this.setState({contentItem1:this.state.adDataList[curAdIndex+1]}); + else + this.setState({contentItem1:null}); + + if (curAdIndex + 2 < this.state.adDataList.length) + this.setState({contentItem2:this.state.adDataList[curAdIndex+2]}); + else + this.setState({contentItem2:null}); + + curAdIndex+=3 + return true; } + + hbRequest() { + HttpUtils.post(NativeModules.BuildConfig.apiHost + 'api/wxDeviceScreenAd/heartbeat?deviceId=' + +encodeURIComponent(this.state.macAddress), + {version:this.state.versionInfo}) + .then(result => { + let config = JSON.parse(result.data.config); + this.setState({ + heartConfig:{ + heartbeatInterval:config.heartbeatInterval, + dataRefreshInterval:config.dataRefreshInterval, + pageChangeInterval:config.pageChangeInterval + } + }) + // 动画划入 + if(config.animationTheme == 0){ + this.setState({ + animationTheme:animationThemes[0] + }) + }else if(config.animationTheme == 1){ + // 放大 + this.setState({ + animationTheme:animationThemes[1] + }) + }else if(config.animationTheme == 2){ + // 淡入 + this.setState({ + animationTheme:animationThemes[2] + }) + }else if(config.animationTheme == 3){ + // 弹入 + this.setState({ + animationTheme:animationThemes[3] + }) + } + + }) + .catch(error => { + console.warn(error) + this.setState({ errorMessage : error}); + }) + } + + getAdDataList() { + HttpUtils.get(NativeModules.BuildConfig.apiHost + 'api/wxDeviceScreenAd/list?deviceId='+encodeURIComponent(this.state.macAddress)+'&pageNum=1&pageSize=1000') + .then((result) => { + if (result.code != 200) { + this.setState({contentDisplayStatus: false}) + this.setState({errorMessage : result.message+'\n'+this.state.macAddress}); + } else if (result.data.list) { + this.setState({adDataList : result.data.list}); + if (this.updateContent()) { + this.setState({contentDisplayStatus: true}) + } + } else { + this.setState({contentDisplayStatus: false}) + this.setState({errorMessage : errorMsg.ERR_DATA_GET}); + } + }) + .catch(error => { + this.setState({contentDisplayStatus: false}) + this.setState({errorMessage : error.message}); + }) + } + getBaseInfo() { + HttpUtils.get(NativeModules.BuildConfig.apiHost + 'api/wxDeviceScreenAd/info?deviceId='+encodeURIComponent(this.state.macAddress)) + .then(result => { + if (result.code != 200) { + this.setState({contentDisplayStatus: false}) + this.setState({errorMessage : result.message+'\n'+this.state.macAddress}); + } else if (result.data) { + this.setState({baseInfo:result.data}); + } else { + this.setState({contentDisplayStatus: false}) + this.setState({errorMessage : errorMsg.ERR_DATA_GET}); + } + }) + .catch(error => { + this.setState({contentDisplayStatus: false}) + this.setState({errorMessage : error.message}); + }) + + } + +componentDidMount() { + CodePush.allowRestart(); + CodePush.sync( + { installMode: CodePush.InstallMode.IMMEDIATE}, + this.codePushStatusDidChange.bind(this), + this.codePushDownloadDidProgress.bind(this) + ); - // 获取更新数据 - getUpdateMetadata() { - CodePush.getUpdateMetadata(CodePush.UpdateState.RUNNING) + CodePush.getUpdateMetadata(CodePush.UpdateState.RUNNING) .then((metadata: LocalPackage) => { - this.setState({ syncMessage: metadata ? JSON.stringify(metadata) : "Running binary version", progress: false }); + this.setState({ versionInfo: metadata ? metadata.appVersion +'b'+NativeModules.BuildConfig.versionCode+"-" + metadata.label : "Unknown"}); }, (error: any) => { - this.setState({ syncMessage: "Error: " + error, progress: false }); - }); - } + this.setState({ versionInfo: "Unknown"}); + }); + DeviceInfo.getMACAddress().then((mac)=>{ + if (mac=='' || mac==null ) { + if (NativeModules.BuildConfig.buildType == 'debug') { + this.setState({macAddress : this.testMac}) + this.startAd() + } else { + this.setState({ contentDisplayStatus: false}) + this.setState({ errorMessage : errorMsg.ERR_MAC_GET}); + } + } else { + this.setState({macAddress : mac}) + this.startAd() + } + }).catch(e => { + this.setState({ contentDisplayStatus: false}) + this.setState({ errorMessage : errorMsg.ERR_START_AD}); + }) +} - /** Update is downloaded silently, and applied on restart (recommended) 自动更新,一键操作 */ - sync() { - CodePush.sync( - {}, - this.codePushStatusDidChange.bind(this), - this.codePushDownloadDidProgress.bind(this) - ); - } - /** Update pops a confirmation dialog, and then immediately reboots the app 一键更新,加入的配置项 */ - syncImmediate() { - CodePush.sync( - { installMode: CodePush.InstallMode.IMMEDIATE, updateDialog: true }, - this.codePushStatusDidChange.bind(this), - this.codePushDownloadDidProgress.bind(this) - ); - } - // 轮播图 -renderBanner() { - if (this.state.swiperShow) { - console.log ('返回值' + this.state.swiperShow); - return ( - - - - - - - ); +startAd() { + this.getBaseInfo() + this.getAdDataList() + this.hbRequest() + + hbRequestCount =this.state.heartConfig.heartbeatInterval; + getAdDataCount =this.state.heartConfig.dataRefreshInterval; + pageChangeCount =this.state.heartConfig.pageChangeInterval; + + setInterval(()=>{ + hbRequestCount -=1000; + getAdDataCount -=1000; + pageChangeCount -=1000; + if (pageChangeCount <= 0) { //页面切换间隔 + if (this.state.contentDisplayStatus) { + this.setState({ contentDisplayStatus: false}) + if (this.updateContent()) { + this.setState({ contentDisplayStatus: true}) + } + } else { + this.getBaseInfo() + this.getAdDataList() + } + pageChangeCount = this.state.heartConfig.pageChangeInterval + } + + if (getAdDataCount<=0) { + this.getAdDataList() + getAdDataCount = this.state.heartConfig.dataRefreshInterval + } + + if (hbRequestCount<=0) { + this.hbRequest() + hbRequestCount = this.state.heartConfig.heartbeatInterval + } + },1000) +} -} else { - return ( - - - {this.state.text} - - ); +getContentViewItemUplayer(contentItem) { + if (contentItem.type == 0) { + if (contentItem.subType == 2) + return ( ) + if (contentItem.subType == 6) + return ( ) + if (contentItem.subType == 7) + return ( ) + return null; } } -get() { - HttpUtils.get('https://mall.youlane.cn/api/wxDeviceScreenAd/list?deviceId=11%3AAA%3A33%3ABB%3A44&pageNum=1&pageSize=5') - .then(result => { - this.setState({ - text: JSON.stringify, - qrcode: result.data.list[0].qrcode}); - }) - .catch(error => console.error(error)) +getContentViewItemActionStr(contentItem) { + if (contentItem.type == 0) { + if (contentItem.subType == 2) + return '扫码秒杀'; + else if (contentItem.subType == 6) + return '扫码砍价'; + else if (contentItem.subType == 7) + return '扫码拼团'; + else + return '扫码领取'; + } } +getContentViewItemMerchantName(contentItem) { + if (contentItem.type == 0) { + if (contentItem.target.merchantVoList.length > 1) + return '多商户通用'; + else + return contentItem.target.merchantVoList[0].merchantName; + } +} -componentDidMount() { - - this.get() - setTimeout(() => { - this.setState({ - swiperShow: true, - }); - }, 10000) +getContentViewItem(contentItem, annomation) { + if (!contentItem) + return ( + + + ) + + actionText = this.getContentViewItemActionStr(contentItem); + merchantName = this.getContentViewItemMerchantName(contentItem); + // console.warn(annomation) + return ( + + + + {/* 列表 */} + + + + {/* 券的title */} + {contentItem.target.title} + + {/* 售价 */} + + + {contentItem.target.salePriceStr} + + {/* 面额 */} + + ¥{contentItem.target.priceStr} + + + + + + {/* 优惠券底部商户名称 */} + + {merchantName} + {contentItem.target.merchantVoList[0].buildingName}{contentItem.target.merchantVoList[0].floorName} + {actionText} + + + {this.getContentViewItemUplayer(contentItem)} + + ) } +getContentView() { + if (this.state.contentDisplayStatus) { + return ( + {this.getContentViewItem(this.state.contentItem0,this.state.animationTheme.first)} + {this.getContentViewItem(this.state.contentItem1,this.state.animationTheme.second)} + {this.getContentViewItem(this.state.contentItem2,this.state.animationTheme.third)} + ) + }else{ + return ( + + {this.state.errorMessage} + ) + } +} render() { - let progressView; if (this.state.progress) { - progressView = ( - {this.state.progress.receivedBytes} of {this.state.progress.totalBytes} bytes received + if (this.state.progress.totalBytes > 0) + return ( + {this.state.syncMessage}{'\n'} + {this.state.progress.receivedBytes} of {this.state.progress.totalBytes} bytes received{'\n'} + + ); + return ( + {this.state.syncMessage} + ); - } + } + return ( - + + {/* 头部title二维码开始 */} + + + + + + + + + + + {/* 券列表展示列表开始 */} + {this.getContentView()} + {/* 底部商场信息展示开始 */} + + + + + + + 小程序 + + + + 公众号 + + {this.state.versionInfo} + + + ); + } + } - - 可以修改此处文字,查看是否更新成功! - + const styles = StyleSheet.create({ + updatePage:{ + flex: 2, + width:'100%', + height:'100%', + backgroundColor:'transparent', + textAlign :'center', + textAlignVertical:'center', + fontSize: 63/PixelRatio.get(), + color: 'darkblue' + }, - - Press for background sync - + //layer background + background:{ + flex: 1, + width:'100%', + height:'100%' + }, - - Press for dialog-driven sync - + //layer top + title:{ + flex: 6, + flexDirection: 'row', + alignItems: 'center', + paddingLeft:42/PixelRatio.get(), + paddingRight:42/PixelRatio.get(), + backgroundColor:'transparent' + }, - {progressView} - - - Restart { this.state.restartAllowed ? "allowed" : "forbidden"} - + content:{ + flex: 18, + flexDirection: 'column', + alignItems: 'center', + backgroundColor:'transparent' + }, - - Press for Update Metadata - + bottom:{ + flex: 2, + flexDirection: 'row', + alignItems: 'center', + paddingLeft:42/PixelRatio.get(), + paddingRight:42/PixelRatio.get(), + backgroundColor:'transparent' + }, - - {this.state.syncMessage || ""} + //layer title + titleImagePlace: { + flex: 2, + paddingTop: '20%', + paddingLeft: '15%', + alignItems: 'center', + backgroundColor:'transparent' + }, + titleImage: { + width:'100%', + height:'100%', + flex: 1, + backgroundColor:'transparent' + }, - - ); + titleQrcodeBonder: { + width:'100%', + height:'100%', + alignItems: 'center', + flexDirection: 'column', + flex: 1, + backgroundColor:'transparent' + }, -/* -return ( - - {this.renderBanner()} - + titleQrcodePlacehold: { + flex: 5, + backgroundColor:'transparent' + }, - ); -*/ - } - } + titleQrcode: { + flex: 6, + width:'100%', + height:'100%', + backgroundColor:'transparent' + }, + + //layer bottom + bottomLogoBackground: { + flex: 3, + borderRadius:16/PixelRatio.get(), + marginTop: 26/PixelRatio.get(), + marginBottom: 26/PixelRatio.get(), + backgroundColor:'transparent',//'rgba(255,255,255,0.5)', + }, + bottomLogo: { + width:'100%', + height:'100%', + backgroundColor:'transparent' + }, + bottomQrcode1Background : { + flex: 1, + width:'100%', + height:'100%', + marginLeft: 21/PixelRatio.get(), + paddingTop: 27/PixelRatio.get(), + paddingBottom: 11/PixelRatio.get(), + flexDirection: 'column', + backgroundColor:'transparent' + }, + + bottomQrcode2Background : { + flex: 1, + width:'100%', + height:'100%', + marginLeft: 21/PixelRatio.get(), + paddingTop: 26/PixelRatio.get(), + paddingBottom: 11/PixelRatio.get(), + flexDirection: 'column', + backgroundColor:'transparent' + }, + + bottomQrcode1: { + flex: 2, + width:'100%', + height:'100%', + backgroundColor:'transparent' + }, + + bottomQrcode2: { + flex: 2, + width:'100%', + height:'100%', + backgroundColor:'transparent' + }, + + bottomQrcode1Str: { + flex: 1, + textAlign :'center', + textAlignVertical:'center', + fontSize: 16/PixelRatio.get(), + color : 'white', + backgroundColor:'transparent' + }, + + bottomQrcode2Str: { + flex: 1, + textAlign :'center', + textAlignVertical:'center', + fontSize: 16/PixelRatio.get(), + color : 'white', + backgroundColor:'transparent' + }, + + bottomPlacehold: { + flex: 8, + width:'100%', + height:'100%', + backgroundColor:'transparent', + textAlign :'right', + textAlignVertical:'bottom', + fontSize: 27/PixelRatio.get(), + color : 'gray' + }, + + //layer content item + contentItem:{ + flex: 1, + width:'100%', + height:'100%', + flexDirection: 'column', + backgroundColor:'transparent' + }, + + contentItemDownLayer:{ + position:'absolute', + width:'100%', + height:'100%', + flexDirection: 'column', + alignItems: 'center', + backgroundColor:'transparent' + }, + + contentItemUpLayer:{ + width:210/PixelRatio.get(), + height:153/PixelRatio.get(), + position:'absolute', + backgroundColor:'transparent' + }, + + contentItemTop:{ + flex: 3, + width:'100%', + height:'100%', + paddingLeft: 66/PixelRatio.get(), + paddingRight: 53/PixelRatio.get(), + paddingTop: 40/PixelRatio.get(), + flexDirection: 'row', + alignItems: 'center', + backgroundColor:'transparent' + }, + + contentItemBottom:{ + flex: 1, + width:'100%', + height:'100%', + paddingLeft: 66/PixelRatio.get(), + paddingRight: 53/PixelRatio.get(), + paddingBottom: 40/PixelRatio.get(), + flexDirection: 'row', + alignItems: 'center', + backgroundColor:'transparent' + }, + + //layer content item top + contentItemTopCoverImg:{ + flex: 5, + width:'100%', + height:'100%', + borderRadius:27/PixelRatio.get(), + backgroundColor:'transparent' + }, + + contentItemTopDetail:{ + flex: 6, + width:'100%', + height:'100%', + paddingLeft: 20/PixelRatio.get(), + paddingRight: 20/PixelRatio.get(), + alignItems: 'center', + backgroundColor:'transparent' + }, + + contentItemTopQrcode:{ + flex: 5, + width:'100%', + height:'100%', + // borderStyle:"solid", + // borderWidth:1, + // borderColor:"red", + marginLeft:18/PixelRatio.get(), + backgroundColor:'transparent' + }, + + //layer content item bottom + contentItemBottomMerchantName:{ + flex: 5, + width:'100%', + height:'100%', + alignItems: 'center', + color:"black", + backgroundColor:'transparent', + textAlign :'center', + textAlignVertical:'center', + fontSize: 27/PixelRatio.get(), + fontWeight : 'bold' + }, + + contentItemBottomPlacehold:{ + flex: 6, + fontSize: 27/PixelRatio.get(), + paddingLeft: 27/PixelRatio.get(), + paddingRight: 79/PixelRatio.get(), + width:'100%', + height:'100%', + color:"black", + textAlignVertical:'center', + backgroundColor:'transparent', + }, + + contentItemBottomAction:{ + flex: 5, + width:'100%', + height:'100%', + backgroundColor:'transparent', + textAlign :'center', + textAlignVertical:'center', + fontSize: 36/PixelRatio.get(), + color: 'black', + // borderStyle:"solid", + // borderWidth:1, + // borderColor:"red" + }, + + // 券的title + contentItemTopDetailTitle:{ + flex: 2, + // height:'100%', + width:'100%', + marginTop:"2%", + // borderStyle:"solid", + // borderWidth:1, + // borderColor:"red", + backgroundColor:'transparent', + textAlign :'left', + color:"black", + textAlignVertical:'center', + fontSize: 53/PixelRatio.get(), + }, + /* + contentItemTopDetailRemark:{ + flex: 1, + width:'100%', + height:'100%', + backgroundColor:'transparent', + textAlign :'left', + textAlignVertical:'center', + fontSize: 27/PixelRatio.get(), + color : 'gray' + }, + */ + contentItemTopDetailPrice:{ + flex: 2, + width:'100%', + height:'100%', + backgroundColor:'transparent', + flexDirection: 'row', + }, + + // 售价的样式 + contentItemTopDetailCurPrice:{ + position:"absolute", + bottom:10, + left:0, + width:'100%', + height:'100%', + flexDirection: 'row', + backgroundColor:'transparent', + }, + + contentItemTopDetailCurPriceStr:{ + backgroundColor:'transparent', + fontSize:96/PixelRatio.get(), + fontFamily:"PingFangSC-Bold", + fontWeight: "bold", + textAlign :'left', + textAlignVertical:'bottom', + color : 'red' + }, + + contentItemTopDetailCurPriceStrUnit:{ + backgroundColor:'transparent', + textAlign :'left', + textAlignVertical:'bottom', + paddingBottom: 16/PixelRatio.get(), + fontSize: 48/PixelRatio.get(), + color : 'red' + }, + // 面额的样式 + contentItemTopDetailSalePrice:{ + position:"absolute", + bottom:2, + left:0, + // flex: 1, + paddingTop:50, + width:'100%', + // height:'100%', + backgroundColor:'transparent', + }, + + contentItemTopDetailSalePriceStr:{ + width:'100%', + height:'100%', + backgroundColor:'transparent', + textAlign :'left', + textAlignVertical:'bottom', + fontSize: 27/PixelRatio.get(), + textDecorationLine: 'line-through', + color : 'gray' + }, - const styles = StyleSheet.create({ - container: { - width:width, - height:height, - flex:1 - }, - wrapper: { - width:width, - height:height, - flex:1 - }, - bannerImg: { - width:width, - height:height, - flex:1 - }, - container: { - flex: 1, - alignItems: "center", - backgroundColor: "#F5FCFF", - paddingTop: 50 - }, - image: { - margin: 30, - width: Dimensions.get("window").width - 100, - height: 365 * (Dimensions.get("window").width - 100) / 651, - }, - messages: { - marginTop: 30, - textAlign: "center", - }, - restartToggleButton: { - color: "blue", - fontSize: 17 - }, - syncButton: { - color: "green", - fontSize: 17 - }, - welcome: { - fontSize: 20, - textAlign: "center", - margin: 20 - }, }); diff --git a/HttpUtils.js b/HttpUtils.js index c6828ac..5c8ac5b 100644 --- a/HttpUtils.js +++ b/HttpUtils.js @@ -10,7 +10,6 @@ export default class HttpUtil { fetch(url) .then(response => response.json()) .then(result => resolve(result)) - .catch(error => reject(error)) }) } @@ -32,7 +31,6 @@ export default class HttpUtil { }) .then(response => response.json()) .then(result => resolve(result)) - .catch(error => reject(error)) }) } } diff --git a/android/app/build.gradle b/android/app/build.gradle index 12293d1..2b56ef0 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -116,7 +116,7 @@ android { android.applicationVariants.all { variant -> variant.outputs.all { - outputFileName = "screenad_" + variant.buildType.name + "_v" + defaultConfig.versionName + ".apk" + outputFileName = "screenad_" + variant.buildType.name + "_" + defaultConfig.versionCode + ".apk" } } @@ -131,16 +131,24 @@ android { buildTypes { debug { buildConfigField "String", "API_HOST", "\"https://mall.youlane.cn/\"" - buildConfigField "String", "CODEPUSH_HOST", "\"http://202.165.179.86:3333/\"" + buildConfigField "String", "CODEPUSH_HOST", "\"http://mall.youlane.cn:3333/\"" buildConfigField "String", "CODEPUSH_KEY", "\"8snO1yoHlvhEtBjr02zTr3g1comw4ksvOXqog\"" } release { - buildConfigField "String", "API_HOST", "\"https://admin.malls.iformall.com/\"" - buildConfigField "String", "CODEPUSH_HOST", "\"http://202.165.179.86:3333/\"" + buildConfigField "String", "API_HOST", "\"https://admintest.malls.iformall.com/\"" + buildConfigField "String", "CODEPUSH_HOST", "\"http://mall.youlane.cn:3333/\"" buildConfigField "String", "CODEPUSH_KEY", "\"9rYZYySFD0ryN5wCD9YmjJkT55Kf4ksvOXqog\"" minifyEnabled enableProguardInReleaseBuilds proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" } + product.initWith(release) + product { + buildConfigField "String", "API_HOST", "\"https://admin.malls.iformall.com/\"" + buildConfigField "String", "CODEPUSH_HOST", "\"http://admin.malls.iformall.com:3333/\"" + buildConfigField "String", "CODEPUSH_KEY", "\"9rYZYySFD0ryN5wCD9YmjJkT55Kf4ksvOXqog\"" + matchingFallbacks = ['product', 'release'] + } + } // applicationVariants are e.g. debug, release applicationVariants.all { variant -> @@ -158,6 +166,8 @@ android { } dependencies { + implementation project(':react-native-camera') + implementation project(':react-native-device-info') implementation project(':react-native-code-push') implementation fileTree(dir: "libs", include: ["*.jar"]) implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}" diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 354036e..fe1cc5f 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -3,6 +3,8 @@ + + + + + + + + diff --git a/android/app/src/main/java/com/screenad/AutoStartBroadcastReceiver.java b/android/app/src/main/java/com/screenad/AutoStartBroadcastReceiver.java new file mode 100644 index 0000000..bba55d5 --- /dev/null +++ b/android/app/src/main/java/com/screenad/AutoStartBroadcastReceiver.java @@ -0,0 +1,22 @@ +package com.screenad; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + + +//开机自启动广播接受 +public class AutoStartBroadcastReceiver extends BroadcastReceiver { + static final String action_boot ="android.intent.action.BOOT_COMPLETED"; + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction().equals(action_boot) && !BuildConfig.BUILD_TYPE.equals("debug")){ + Intent sayHelloIntent=new Intent(context,MainActivity.class); + + sayHelloIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + context.startActivity(sayHelloIntent); + } + } + +} \ No newline at end of file diff --git a/android/app/src/main/java/com/screenad/MainActivity.java b/android/app/src/main/java/com/screenad/MainActivity.java index 7cbb030..4fadcf0 100644 --- a/android/app/src/main/java/com/screenad/MainActivity.java +++ b/android/app/src/main/java/com/screenad/MainActivity.java @@ -1,5 +1,10 @@ package com.screenad; +import android.graphics.Color; +import android.os.Build; +import android.os.Bundle; +import android.view.View; + import com.facebook.react.ReactActivity; public class MainActivity extends ReactActivity { @@ -8,6 +13,22 @@ public class MainActivity extends ReactActivity { * Returns the name of the main component registered from JavaScript. * This is used to schedule rendering of the component. */ + + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + View decorView = getWindow().getDecorView(); + int option = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_FULLSCREEN; + decorView.setSystemUiVisibility(option); + getWindow().setNavigationBarColor(Color.TRANSPARENT); + getWindow().setStatusBarColor(Color.TRANSPARENT); + + } + @Override protected String getMainComponentName() { return "screenAd"; diff --git a/android/app/src/main/java/com/screenad/MainApplication.java b/android/app/src/main/java/com/screenad/MainApplication.java index 2253e13..2664dc1 100644 --- a/android/app/src/main/java/com/screenad/MainApplication.java +++ b/android/app/src/main/java/com/screenad/MainApplication.java @@ -3,6 +3,11 @@ package com.screenad; import android.app.Application; import com.facebook.react.ReactApplication; +import org.reactnative.camera.RNCameraPackage; + +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.learnium.RNDeviceInfo.RNDeviceInfo; import com.microsoft.codepush.react.CodePush; import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; @@ -12,14 +17,16 @@ import com.facebook.soloader.SoLoader; import java.util.Arrays; import java.util.List; + + public class MainApplication extends Application implements ReactApplication { private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { - @Override - protected String getJSBundleFile() { - return CodePush.getJSBundleFile(); - } + @Override + protected String getJSBundleFile() { + return CodePush.getJSBundleFile(); + } @Override public boolean getUseDeveloperSupport() { @@ -29,13 +36,16 @@ public class MainApplication extends Application implements ReactApplication { @Override protected List getPackages() { return Arrays.asList( - new MainReactPackage(), - new CodePush( - BuildConfig.CODEPUSH_KEY, - getApplicationContext(), - BuildConfig.DEBUG, - BuildConfig.CODEPUSH_HOST - ) + new MainReactPackage(), + new RNCameraPackage(), + new RNBuildConfigPackage(), + new RNDeviceInfo(), + new CodePush( + BuildConfig.CODEPUSH_KEY, + getApplicationContext(), + BuildConfig.DEBUG, + BuildConfig.CODEPUSH_HOST + ) ); } diff --git a/android/app/src/main/java/com/screenad/RNBuildConfig.java b/android/app/src/main/java/com/screenad/RNBuildConfig.java new file mode 100644 index 0000000..ee2981f --- /dev/null +++ b/android/app/src/main/java/com/screenad/RNBuildConfig.java @@ -0,0 +1,36 @@ +package com.screenad; + +import android.content.pm.PackageManager; + +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReactMethod; + +import java.util.HashMap; +import java.util.Map; + +import javax.annotation.Nullable; + +public class RNBuildConfig extends ReactContextBaseJavaModule { + + public RNBuildConfig(ReactApplicationContext reactContext) { + super(reactContext); + } + + @Override + public String getName() { + return "BuildConfig"; + } + + @Override + public @Nullable + Map getConstants() { + HashMap constants = new HashMap(); + constants.put("apiHost", BuildConfig.API_HOST); + constants.put("buildType", BuildConfig.BUILD_TYPE); + constants.put("versionCode", BuildConfig.VERSION_CODE); + constants.put("versionName", BuildConfig.VERSION_NAME); + + return constants; + } +} \ No newline at end of file diff --git a/android/app/src/main/java/com/screenad/RNBuildConfigPackage.java b/android/app/src/main/java/com/screenad/RNBuildConfigPackage.java new file mode 100644 index 0000000..82a0699 --- /dev/null +++ b/android/app/src/main/java/com/screenad/RNBuildConfigPackage.java @@ -0,0 +1,31 @@ +package com.screenad; + +import com.facebook.react.ReactPackage; +import com.facebook.react.bridge.JavaScriptModule; +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.uimanager.ViewManager; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class RNBuildConfigPackage implements ReactPackage { + + @Override + public List createViewManagers(ReactApplicationContext reactContext) { + return Collections.emptyList(); + } + @Override + public List createNativeModules( + ReactApplicationContext reactContext) { + List modules = new ArrayList<>(); + modules.add(new RNBuildConfig(reactContext)); + return modules; + } + // Deprecated RN 0.47 + public List> createJSModules() { + return Collections.emptyList(); + } + +} diff --git a/android/settings.gradle b/android/settings.gradle index ec77d91..080e5f7 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -1,4 +1,8 @@ rootProject.name = 'screenAd' +include ':react-native-camera' +project(':react-native-camera').projectDir = new File(rootProject.projectDir, '..\\node_modules\\react-native-camera\\android') +include ':react-native-device-info' +project(':react-native-device-info').projectDir = new File(rootProject.projectDir, '..\\node_modules\\react-native-device-info\\android') include ':react-native-code-push' project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '..\\node_modules\\react-native-code-push\\android\\app') diff --git a/image/background.png b/image/background.png new file mode 100644 index 0000000..1eb28ab Binary files /dev/null and b/image/background.png differ diff --git a/image/discount.png b/image/discount.png new file mode 100644 index 0000000..96b4125 Binary files /dev/null and b/image/discount.png differ diff --git a/image/groupbuy.png b/image/groupbuy.png new file mode 100644 index 0000000..5807f8b Binary files /dev/null and b/image/groupbuy.png differ diff --git a/image/item-background.png b/image/item-background.png new file mode 100644 index 0000000..f8c0944 Binary files /dev/null and b/image/item-background.png differ diff --git a/image/logo.png b/image/logo.png new file mode 100644 index 0000000..d703fc0 Binary files /dev/null and b/image/logo.png differ diff --git a/image/page1.jpg b/image/page1.jpg deleted file mode 100644 index 3211bd8..0000000 Binary files a/image/page1.jpg and /dev/null differ diff --git a/image/page2.jpg b/image/page2.jpg deleted file mode 100644 index 3211bd8..0000000 Binary files a/image/page2.jpg and /dev/null differ diff --git a/image/page3.jpg b/image/page3.jpg deleted file mode 100644 index 3211bd8..0000000 Binary files a/image/page3.jpg and /dev/null differ diff --git a/image/page4.jpg b/image/page4.jpg deleted file mode 100644 index 3211bd8..0000000 Binary files a/image/page4.jpg and /dev/null differ diff --git a/image/test-l.png b/image/test-l.png new file mode 100644 index 0000000..b0523f4 Binary files /dev/null and b/image/test-l.png differ diff --git a/image/timed.png b/image/timed.png new file mode 100644 index 0000000..b359dc3 Binary files /dev/null and b/image/timed.png differ diff --git a/image/title-qrcode.png b/image/title-qrcode.png new file mode 100644 index 0000000..b441a18 Binary files /dev/null and b/image/title-qrcode.png differ diff --git a/image/title.png b/image/title.png new file mode 100644 index 0000000..96134ec Binary files /dev/null and b/image/title.png differ diff --git a/ios/screenAd.xcodeproj/project.pbxproj b/ios/screenAd.xcodeproj/project.pbxproj index c2764c9..6de6d06 100644 --- a/ios/screenAd.xcodeproj/project.pbxproj +++ b/ios/screenAd.xcodeproj/project.pbxproj @@ -41,6 +41,9 @@ ED2971652150620600B7C4FE /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED2971642150620600B7C4FE /* JavaScriptCore.framework */; }; 84325BCA939E4E4E8090435C /* libCodePush.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 928B0784CE244B05BADC60D9 /* libCodePush.a */; }; 1D9B977EF02A4A4889A3DB8D /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 66D0C7202A274329A44896AF /* libz.tbd */; }; + 87AC1C7FBD2D486A8496775D /* libRNDeviceInfo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DEA1E60B1E4C4CF08017D6C7 /* libRNDeviceInfo.a */; }; + 603338A972BC497CB13A8E7E /* libRNDeviceInfo-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 145DB45C59D944B7BC067032 /* libRNDeviceInfo-tvOS.a */; }; + 34AFC50E88444884839918E1 /* libRNCamera.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7847EE6DABE74D92BBD93F0A /* libRNCamera.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -351,6 +354,11 @@ 0CB64B19BE27429888B0F5FA /* CodePush.xcodeproj */ = {isa = PBXFileReference; name = "CodePush.xcodeproj"; path = "../node_modules/react-native-code-push/ios/CodePush.xcodeproj"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; }; 928B0784CE244B05BADC60D9 /* libCodePush.a */ = {isa = PBXFileReference; name = "libCodePush.a"; path = "libCodePush.a"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; }; 66D0C7202A274329A44896AF /* libz.tbd */ = {isa = PBXFileReference; name = "libz.tbd"; path = "usr/lib/libz.tbd"; sourceTree = SDKROOT; fileEncoding = undefined; lastKnownFileType = sourcecode.text-based-dylib-definition; explicitFileType = undefined; includeInIndex = 0; }; + D7C737D4F5674419B8D2A7F0 /* RNDeviceInfo.xcodeproj */ = {isa = PBXFileReference; name = "RNDeviceInfo.xcodeproj"; path = "../node_modules/react-native-device-info/ios/RNDeviceInfo.xcodeproj"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; }; + DEA1E60B1E4C4CF08017D6C7 /* libRNDeviceInfo.a */ = {isa = PBXFileReference; name = "libRNDeviceInfo.a"; path = "libRNDeviceInfo.a"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; }; + 145DB45C59D944B7BC067032 /* libRNDeviceInfo-tvOS.a */ = {isa = PBXFileReference; name = "libRNDeviceInfo-tvOS.a"; path = "libRNDeviceInfo-tvOS.a"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; }; + 00A674D206BA447C9B2B9CBA /* RNCamera.xcodeproj */ = {isa = PBXFileReference; name = "RNCamera.xcodeproj"; path = "../node_modules/react-native-camera/ios/RNCamera.xcodeproj"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; }; + 7847EE6DABE74D92BBD93F0A /* libRNCamera.a */ = {isa = PBXFileReference; name = "libRNCamera.a"; path = "libRNCamera.a"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -381,6 +389,8 @@ 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */, 84325BCA939E4E4E8090435C /* libCodePush.a in Frameworks */, 1D9B977EF02A4A4889A3DB8D /* libz.tbd in Frameworks */, + 87AC1C7FBD2D486A8496775D /* libRNDeviceInfo.a in Frameworks */, + 34AFC50E88444884839918E1 /* libRNCamera.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -397,6 +407,7 @@ 2D02E4C61E0B4AEC006451C7 /* libRCTSettings-tvOS.a in Frameworks */, 2D02E4C71E0B4AEC006451C7 /* libRCTText-tvOS.a in Frameworks */, 2D02E4C81E0B4AEC006451C7 /* libRCTWebSocket-tvOS.a in Frameworks */, + 603338A972BC497CB13A8E7E /* libRNDeviceInfo-tvOS.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -572,6 +583,8 @@ 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */, 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */, 0CB64B19BE27429888B0F5FA /* CodePush.xcodeproj */, + D7C737D4F5674419B8D2A7F0 /* RNDeviceInfo.xcodeproj */, + 00A674D206BA447C9B2B9CBA /* RNCamera.xcodeproj */, ); name = Libraries; sourceTree = ""; @@ -1200,10 +1213,15 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); HEADER_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)\..\node_modules\react-native-code-push\ios\CodePush/**", + "$(SRCROOT)\..\node_modules\react-native-device-info\ios\RNDeviceInfo", + "$(SRCROOT)\..\node_modules\react-native-camera\ios/**", ); }; name = Debug; @@ -1226,10 +1244,15 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); HEADER_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)\..\node_modules\react-native-code-push\ios\CodePush/**", + "$(SRCROOT)\..\node_modules\react-native-device-info\ios\RNDeviceInfo", + "$(SRCROOT)\..\node_modules\react-native-camera\ios/**", ); }; name = Release; @@ -1253,6 +1276,8 @@ HEADER_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)\..\node_modules\react-native-code-push\ios\CodePush/**", + "$(SRCROOT)\..\node_modules\react-native-device-info\ios\RNDeviceInfo", + "$(SRCROOT)\..\node_modules\react-native-camera\ios/**", ); }; name = Debug; @@ -1275,6 +1300,8 @@ HEADER_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)\..\node_modules\react-native-code-push\ios\CodePush/**", + "$(SRCROOT)\..\node_modules\react-native-device-info\ios\RNDeviceInfo", + "$(SRCROOT)\..\node_modules\react-native-camera\ios/**", ); }; name = Release; @@ -1305,10 +1332,15 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); HEADER_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)\..\node_modules\react-native-code-push\ios\CodePush/**", + "$(SRCROOT)\..\node_modules\react-native-device-info\ios\RNDeviceInfo", + "$(SRCROOT)\..\node_modules\react-native-camera\ios/**", ); }; name = Debug; @@ -1339,10 +1371,15 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); HEADER_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)\..\node_modules\react-native-code-push\ios\CodePush/**", + "$(SRCROOT)\..\node_modules\react-native-device-info\ios\RNDeviceInfo", + "$(SRCROOT)\..\node_modules\react-native-camera\ios/**", ); }; name = Release; @@ -1372,10 +1409,15 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); HEADER_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)\..\node_modules\react-native-code-push\ios\CodePush/**", + "$(SRCROOT)\..\node_modules\react-native-device-info\ios\RNDeviceInfo", + "$(SRCROOT)\..\node_modules\react-native-camera\ios/**", ); }; name = Debug; @@ -1405,10 +1447,15 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); HEADER_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)\..\node_modules\react-native-code-push\ios\CodePush/**", + "$(SRCROOT)\..\node_modules\react-native-device-info\ios\RNDeviceInfo", + "$(SRCROOT)\..\node_modules\react-native-camera\ios/**", ); }; name = Release; diff --git a/package.json b/package.json index 6b80a89..4ae85b4 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,10 @@ "dependencies": { "react": "16.6.3", "react-native": "0.58.4", + "react-native-animatable": "^1.3.1", + "react-native-camera": "^1.12.0", "react-native-code-push": "^5.5.2", + "react-native-device-info": "^0.26.4", "react-native-swiper": "^1.5.14" }, "devDependencies": {