diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/EventReqEntity.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/EventReqEntity.kt new file mode 100644 index 0000000000..584890c8c4 --- /dev/null +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/EventReqEntity.kt @@ -0,0 +1,7 @@ +package com.mogo.eagle.core.function.business.travelreality + +data class EventReqEntity( + var points: List, + var cityCode: String = "0734", + var adCode: String = "" +) diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/TravelRealityModel.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/TravelRealityModel.kt index d42452e123..c8395575df 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/TravelRealityModel.kt +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/TravelRealityModel.kt @@ -1,5 +1,14 @@ package com.mogo.eagle.core.function.business.travelreality +import android.content.Context +import android.graphics.Bitmap +import android.graphics.drawable.Drawable +import com.amap.api.maps.model.LatLng +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.GranularRoundedCorners +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition import com.mogo.commons.constants.HostConst import com.mogo.eagle.core.data.BaseResponse import com.mogo.eagle.core.data.Response @@ -9,9 +18,8 @@ import com.mogo.eagle.core.network.MoGoRetrofitFactory import com.mogo.eagle.core.network.apiCall import com.mogo.eagle.core.network.apiResponseCall import com.mogo.eagle.core.network.request -import com.mogo.eagle.core.utilcode.util.GsonUtils import com.mogo.eagle.core.utilcode.util.Md5Util -import retrofit2.http.Query +import me.jessyan.autosize.utils.AutoSizeUtils import java.util.Locale class TravelRealityModel private constructor() { @@ -30,7 +38,7 @@ class TravelRealityModel private constructor() { /** * 查询道路事件 */ - fun getEventsWithTrajRequest(reqData: List, + fun getEventsWithTrajRequest(reqData: EventReqEntity, onSuccess: ((List) -> Unit), onError: ((String) -> Unit)){ request?>>{ loader { @@ -60,7 +68,7 @@ class TravelRealityModel private constructor() { val md5String = "${CROSS_DEVICE.uppercase(Locale.getDefault())}$time" val loc = CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84() val cityCode = CallerMapUIServiceManager.getCityCode() ?: "0734" - getNetWorkApi(HostConst.getNDEHost()).getCrossDevice(Md5Util.getMD5Result(md5String), time, "", loc.longitude, loc.latitude, "0734") + getNetWorkApi(HostConst.getNDEHost()).getCrossDevice(Md5Util.getMD5Result(md5String), time, "", loc.longitude, loc.latitude, cityCode) } } onSuccess { @@ -83,7 +91,7 @@ class TravelRealityModel private constructor() { val md5String = "${CITY_ROAD_RANGE.uppercase(Locale.getDefault())}$time" val loc = CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84() val cityCode = CallerMapUIServiceManager.getCityCode() ?: "0734" - getNetWorkApi(HostConst.getNDEHost()).getCityRoadRange(Md5Util.getMD5Result(md5String), time, loc.longitude, loc.latitude, "0734") + getNetWorkApi(HostConst.getNDEHost()).getCityRoadRange(Md5Util.getMD5Result(md5String), time, loc.longitude, loc.latitude, cityCode) } } onSuccess { @@ -106,7 +114,7 @@ class TravelRealityModel private constructor() { val md5String = "${CITY_ROAD_TRACK.uppercase(Locale.getDefault())}$time" val loc = CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84() val cityCode = CallerMapUIServiceManager.getCityCode() ?: "0734" - getNetWorkApi(HostConst.getNDEHost()).getCityRoadTrack(Md5Util.getMD5Result(md5String), time, loc.longitude, loc.latitude, "0734") + getNetWorkApi(HostConst.getNDEHost()).getCityRoadTrack(Md5Util.getMD5Result(md5String), time, loc.longitude, loc.latitude, cityCode) } } onSuccess { @@ -117,4 +125,32 @@ class TravelRealityModel private constructor() { } } } + + fun downloadImage(context: Context, url: String?, + latLng: LatLng, + onSuccess: ((Bitmap, LatLng) -> Unit), + onFailed: ((LatLng) -> Unit) + ) { + if (url.isNullOrEmpty()) return + val radiusPx = AutoSizeUtils.dp2px(context, 15f).toFloat() + val options = RequestOptions().transform( + GranularRoundedCorners(radiusPx, radiusPx,0f,0f) + ) + Glide.with(context) + .asBitmap() + .apply(options) + .load(url) + .into(object : CustomTarget() { + override fun onResourceReady(resource: Bitmap, transition: Transition?) { + onSuccess(resource, latLng) + } + + override fun onLoadCleared(placeholder: Drawable?) {} + + override fun onLoadFailed(errorDrawable: Drawable?) { + super.onLoadFailed(errorDrawable) + onFailed(latLng) + } + }) + } } \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/TravelRealityService.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/TravelRealityService.kt index 55b30de4bb..afa7315222 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/TravelRealityService.kt +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/TravelRealityService.kt @@ -24,7 +24,7 @@ interface TravelRealityService { suspend fun getEventsWithTrajRequest( @Header("MogoAuthKey") authKey: String, @Header("MogoReqTime") time: String, - @Body reqData: List + @Body reqData: EventReqEntity ): Response> /** diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/view/EventVideoView.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/view/EventVideoView.kt new file mode 100644 index 0000000000..7c545d9bb3 --- /dev/null +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/view/EventVideoView.kt @@ -0,0 +1,48 @@ +package com.mogo.eagle.core.function.business.travelreality.view + +import android.annotation.SuppressLint +import android.content.Context +import android.graphics.Bitmap +import android.util.AttributeSet +import android.view.LayoutInflater +import android.widget.ImageView +import android.widget.TextView +import androidx.constraintlayout.widget.ConstraintLayout +import com.mogo.eagle.core.function.map.R + +@SuppressLint("ViewConstructor") +class EventVideoView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0, + private val title: String? = "全息路口" +) : ConstraintLayout ( + context, + attrs, + defStyleAttr +) { + + init { + LayoutInflater.from(context).inflate(R.layout.layout_event_video_maker, this, true) + initView() + } + + private lateinit var videoImgView: ImageView + + private fun initView() { + videoImgView = findViewById(R.id.videoImg) + val titleView = findViewById(R.id.tvTitle) + + title?.let { + titleView.text = it + } + } + + fun setBitmap(bitmap: Bitmap) { + videoImgView.setImageBitmap(bitmap) + } + + fun setPlaceHolder() { + videoImgView.setImageResource(R.drawable.video_marker_place_holder) + } +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/view/TravelRealityView.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/view/TravelRealityView.kt index 911edc3f90..4d8a5fa0b9 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/view/TravelRealityView.kt +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/view/TravelRealityView.kt @@ -32,13 +32,16 @@ import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Liste import com.mogo.eagle.core.function.api.autopilot.IMoGoPlanningRottingListener import com.mogo.eagle.core.function.business.roadcross.net.NDERoadCameraNetWorkModel.Companion.ndeRoadCameraNetWorkModel import com.mogo.eagle.core.function.business.travelreality.CrossDeviceBean +import com.mogo.eagle.core.function.business.travelreality.DeviceInfoBean import com.mogo.eagle.core.function.business.travelreality.EventBean +import com.mogo.eagle.core.function.business.travelreality.EventReqEntity import com.mogo.eagle.core.function.business.travelreality.Point import com.mogo.eagle.core.function.business.travelreality.TravelRealityModel.Companion.travelNetWorkModel +import com.mogo.eagle.core.function.business.travelreality.view.EventVideoView import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager import com.mogo.eagle.core.function.call.autopilot.CallerPlanningRottingListenerManager +import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager import com.mogo.eagle.core.function.map.R -import com.mogo.eagle.core.function.smp.V2XMarkerView import com.mogo.eagle.core.utilcode.mogo.MapAssetStyleUtils import com.mogo.eagle.core.utilcode.util.LocationUtils import com.mogo.eagle.core.utilcode.util.ThreadUtils @@ -57,6 +60,29 @@ class TravelRealityView @JvmOverloads constructor( ) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoChassisLocationGCJ02Listener, IMoGoPlanningRottingListener { + companion object { + private const val TAG = "TravelRealityView" + + private const val DRAW_POLY_LINE = 1 + private const val DRAW_CAR_LOCATION = 2 + private const val DRAW_ROAD_EVENT = 3 + private const val DRAW_CROSS_DEVICE = 4 + private const val DRAW_ROAD_RANGE = 5 + private const val DRAW_ROAD_TRAJECTORY = 6 + private const val DRAW_GLOBAL_TRAJECTORY = 7 + private const val MOVE_MAP_CAMERA = 8 + private const val DRAW_LIVE_DETAIL = 9 + private const val DRAW_END_MARKER = 10 + private const val UPDATE_VIDEO_MARKER = 11 + + private const val maxRoadRange = 68f + private const val minRoadRange = 52f + private const val maxRoadWidth = 32f + private const val minRoadWidth = 14f + private const val maxGlobalWidth = 20f + private const val minGlobalWidth = 13f + } + private var mContext: Context? = null private var mMapView: TextureMapView? = null @@ -109,6 +135,14 @@ class TravelRealityView @JvmOverloads constructor( private val roadTrajectoryBitmap by lazy { BitmapDescriptorFactory.fromResource(R.drawable.mogo_road_over) } + @Volatile + private var roadRange = minRoadRange + @Volatile + private var roadWidth = minRoadWidth + @Volatile + private var globalWidth = minGlobalWidth + + // // 测试时使用 // private val pointBitmap1 by lazy { @@ -141,6 +175,8 @@ class TravelRealityView @JvmOverloads constructor( @Volatile private var deviceList: List? = null + @Volatile + private var deviceInPathList: List? = null @Volatile private var roadTrackList: List?>?>? = null @@ -157,21 +193,6 @@ class TravelRealityView @JvmOverloads constructor( private var testTime = 0L - companion object { - private const val TAG = "TravelRealityView" - - private const val DRAW_POLY_LINE = 1 - private const val DRAW_CAR_LOCATION = 2 - private const val DRAW_ROAD_EVENT = 3 - private const val DRAW_CROSS_DEVICE = 4 - private const val DRAW_ROAD_RANGE = 5 - private const val DRAW_ROAD_TRAJECTORY = 6 - private const val DRAW_GLOBAL_TRAJECTORY = 7 - private const val MOVE_MAP_CAMERA = 8 - private const val DRAW_LIVE_DETAIL = 9 - private const val DRAW_END_MARKER = 10 - } - init { try { val typedArray = context.obtainStyledAttributes(attrs, R.styleable.TravelRealityView) @@ -334,7 +355,7 @@ class TravelRealityView @JvmOverloads constructor( val boundsBuilder = LatLngBounds.Builder() val globalOptions = PolylineOptions() - globalOptions.width(AutoSizeUtils.dp2px(context, 20f).toFloat()) + globalOptions.width(AutoSizeUtils.dp2px(context, globalWidth).toFloat()) globalOptions.lineJoinType(PolylineOptions.LineJoinType.LineJoinRound) globalOptions.lineCapType(PolylineOptions.LineCapType.LineCapRound) globalOptions.color(globalPathColor) @@ -371,6 +392,23 @@ class TravelRealityView @JvmOverloads constructor( // mAMap?.addMarkers(markerOptionsList1, false) + val distance = LocationUtils.getDistance( + globalData[globalData.size - 1].lat, + globalData[globalData.size - 1].lon, + globalData[0].lat, + globalData[0].lon + ) + Log.w(TAG, "起终点距离为:$distance") + if (distance < 2000) { + roadRange = maxRoadRange + roadWidth = maxRoadWidth + globalWidth = maxGlobalWidth + } else { + roadRange = minRoadRange + roadWidth = minRoadWidth + globalWidth = minGlobalWidth + } + val endOption = MarkerOptions() endOption.icon(BitmapDescriptorFactory.fromResource(endPointDrawable)) endOption.position( @@ -450,6 +488,7 @@ class TravelRealityView @JvmOverloads constructor( eventOptionsList.add(MarkerOptions().apply { position(coordinateConverterWgsToGcj(eventBean.lat, eventBean.lon)) anchor(0.5f, 0.5f) + zIndex(0.8f) icon(BitmapDescriptorFactory.fromResource(R.drawable.mogo_shigu_nor)) }) roadEventList.add(eventBean) @@ -459,6 +498,7 @@ class TravelRealityView @JvmOverloads constructor( eventOptionsList.add(MarkerOptions().apply { position(coordinateConverterWgsToGcj(eventBean.lat, eventBean.lon)) anchor(0.5f, 0.5f) + zIndex(0.8f) icon(BitmapDescriptorFactory.fromResource(R.drawable.mogo_shigong_image)) }) roadEventList.add(eventBean) @@ -468,6 +508,7 @@ class TravelRealityView @JvmOverloads constructor( eventOptionsList.add(MarkerOptions().apply { position(coordinateConverterWgsToGcj(eventBean.lat, eventBean.lon)) anchor(0.5f, 0.5f) + zIndex(0.8f) icon(BitmapDescriptorFactory.fromResource(R.drawable.mogo_yongdu_nor)) }) } @@ -476,6 +517,7 @@ class TravelRealityView @JvmOverloads constructor( eventOptionsList.add(MarkerOptions().apply { position(coordinateConverterWgsToGcj(eventBean.lat, eventBean.lon)) anchor(0.5f, 0.5f) + zIndex(0.8f) icon(BitmapDescriptorFactory.fromResource(R.drawable.mogo_jingzhi_nor)) }) roadEventList.add(eventBean) @@ -485,6 +527,7 @@ class TravelRealityView @JvmOverloads constructor( eventOptionsList.add(MarkerOptions().apply { position(coordinateConverterWgsToGcj(eventBean.lat, eventBean.lon)) anchor(0.5f, 0.5f) + zIndex(0.8f) icon(BitmapDescriptorFactory.fromResource(R.drawable.mogo_jingzhi_nor)) }) roadEventList.add(eventBean) @@ -493,7 +536,7 @@ class TravelRealityView @JvmOverloads constructor( } private fun retryGetCrossDevice() { - val crossDeviceListTmp = deviceList + val crossDeviceListTmp = deviceInPathList if (crossDeviceListTmp.isNullOrEmpty()) { if (retryCount >= 5) return retryCount++ @@ -507,6 +550,7 @@ class TravelRealityView @JvmOverloads constructor( roadEventList.forEach { ipList.add(it.ip ?: "") } + // 轨迹线附近的路口设备取几个进行卡片展示 for (i in crossDeviceListTmp.indices) { if (maxSize > 0 && !crossDeviceListTmp[i].deviceInfoList.isNullOrEmpty()) { crossDeviceListTmp[i].deviceInfoList!![0].deviceIp?.let { @@ -523,16 +567,36 @@ class TravelRealityView @JvmOverloads constructor( } } + /** + * 先下载图片,然后设置给View, + * 再转换成BitmapDescriptor,最后进行渲染 + */ + private fun downloadImage(url: String, latLng: LatLng?) { + if (latLng == null) return + travelNetWorkModel.downloadImage(context, url, latLng, onSuccess = { bitmap, latLng -> + val view = EventVideoView(context) + view.setBitmap(bitmap) + updateVideoMarker(view, latLng) + }, onFailed = { + val view = EventVideoView(context) + view.setPlaceHolder() + updateVideoMarker(view, latLng) + }) + } + private fun reqCrossLive(ipList: MutableList) { ndeRoadCameraNetWorkModel.batchRequestCrossLive(ipList, onSuccess = { val liveOptionsList = ArrayList() var markerOption: MarkerOptions it.forEach { roadCamera -> roadCamera.ip?.let { ip -> + roadCamera.imageUrl?.let { url -> + downloadImage(url, ipPointMap[ip]) + } markerOption = MarkerOptions() markerOption.position(ipPointMap[ip]) markerOption.anchor(0.5f, 0.5f) - markerOption.icon(BitmapDescriptorFactory.fromView(V2XMarkerView(context))) + markerOption.zIndex(0.9f) liveOptionsList.add(markerOption) } } @@ -548,6 +612,7 @@ class TravelRealityView @JvmOverloads constructor( if (crossDeviceList.isEmpty()) return val crossOptionsList = ArrayList() val globalList = reqData + val deviceInPaths = ArrayList() globalList?.forEachIndexed { index, globalPoint -> if (index >= 0 && index < globalList.size - 1) { crossDeviceList.forEach { @@ -563,7 +628,7 @@ class TravelRealityView @JvmOverloads constructor( ) { return@loop } - + deviceInPaths.add(deviceBean) crossOptionsList.add(MarkerOptions().apply { position( coordinateConverterWgsToGcj( @@ -578,6 +643,7 @@ class TravelRealityView @JvmOverloads constructor( } } } + deviceInPathList = arrayListOf(CrossDeviceBean("", 0.0, "", 0.0, deviceInPaths)) // 绘制路口设备 drawMarkers(DRAW_CROSS_DEVICE, crossOptionsList) } @@ -616,7 +682,7 @@ class TravelRealityView @JvmOverloads constructor( val options = PolylineOptions() trajectoryList?.forEach loop@{ trajPointList -> if (trajPointList.isNullOrEmpty() || trajPointList.size < 2) return@loop - options.width(AutoSizeUtils.dp2px(context, 52f).toFloat()) + options.width(AutoSizeUtils.dp2px(context, minRoadRange).toFloat()) options.isUseTexture = true options.lineJoinType(PolylineOptions.LineJoinType.LineJoinRound) options.lineCapType(PolylineOptions.LineCapType.LineCapSquare) @@ -684,7 +750,11 @@ class TravelRealityView @JvmOverloads constructor( // 绘制新的智慧路段轨迹 polylineOptionTmp = PolylineOptions() polylineOptionTmp?.let { optionTmp -> - buildPolylineOption(optionTmp, 52f, roadTrajectoryBitmap) + buildPolylineOption( + optionTmp, + roadRange, + roadTrajectoryBitmap + ) optionTmp.add( coordinateConverterWgsToGcj( trajPointList[1], @@ -737,7 +807,8 @@ class TravelRealityView @JvmOverloads constructor( if (lastIndex < 0 || index - lastIndex > 1) { globalOptionList.add(PolylineOptions().also { optionTmp = it - buildPolylineOptionWithColor(it, 30f, roadTrajectoryColor) + buildPolylineOptionWithColor(it, roadWidth, roadTrajectoryColor) + it.add(coordinateConverterWgsToGcj(point.lat, point.lon)) }) } else { optionTmp?.add(coordinateConverterWgsToGcj(point.lat, point.lon)) @@ -792,6 +863,18 @@ class TravelRealityView @JvmOverloads constructor( } } + private fun updateVideoMarker(view: EventVideoView, latLng: LatLng?) { + if (latLng == null) return + val options = MarkerOptions() + options.position(latLng) + options.icon(BitmapDescriptorFactory.fromView(view)) + Message.obtain().apply { + what = UPDATE_VIDEO_MARKER + obj = options + nonFrequentHandler?.sendMessage(this) + } + } + private fun drawMarkers(type: Int, optionList: ArrayList) { Message.obtain().apply { what = type @@ -869,7 +952,8 @@ class TravelRealityView @JvmOverloads constructor( Log.d(TAG, "Cross device error is:$it") }) // 获取道路事件 - travelNetWorkModel.getEventsWithTrajRequest(reqData!!, onSuccess = { + val cityCode = CallerMapUIServiceManager.getCityCode() ?: "0734" + travelNetWorkModel.getEventsWithTrajRequest(EventReqEntity(pointList, cityCode), onSuccess = { Log.d(TAG, "Events result is:$it") handleRoadEvent(it) }, onError = { @@ -943,7 +1027,7 @@ class TravelRealityView @JvmOverloads constructor( DRAW_LIVE_DETAIL -> { removeMessages(DRAW_LIVE_DETAIL) (msg.obj as ArrayList).apply { -// realDrawLiveMarkers(this) + realDrawLiveMarkers(this) } } @@ -951,6 +1035,10 @@ class TravelRealityView @JvmOverloads constructor( removeMessages(DRAW_END_MARKER) realDrawEndMarker(msg.obj as MarkerOptions) } + + UPDATE_VIDEO_MARKER -> { + realUpdateVideoMarker(msg.obj as MarkerOptions) + } } } catch (e: Exception) { e.printStackTrace() @@ -1077,6 +1165,14 @@ class TravelRealityView @JvmOverloads constructor( } } + private fun realUpdateVideoMarker(options: MarkerOptions) { + liveMarkerList.forEach { + if (it.position == options.position) { + it.setIcon(options.icon) + } + } + } + private fun realDrawEndMarker(options: MarkerOptions) { mEndMarker?.destroy() if (endPointDrawable != -1) { diff --git a/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/event_logo_icon.png b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/event_logo_icon.png new file mode 100644 index 0000000000..37382e6ec9 Binary files /dev/null and b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/event_logo_icon.png differ diff --git a/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/event_video_bg.png b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/event_video_bg.png new file mode 100644 index 0000000000..91a52d3150 Binary files /dev/null and b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/event_video_bg.png differ diff --git a/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/video_marker_place_holder.png b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/video_marker_place_holder.png new file mode 100644 index 0000000000..17ac3e6ce8 Binary files /dev/null and b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/video_marker_place_holder.png differ diff --git a/core/function-impl/mogo-core-function-map/src/main/res/layout/layout_event_video_maker.xml b/core/function-impl/mogo-core-function-map/src/main/res/layout/layout_event_video_maker.xml new file mode 100644 index 0000000000..8e24de19c3 --- /dev/null +++ b/core/function-impl/mogo-core-function-map/src/main/res/layout/layout_event_video_maker.xml @@ -0,0 +1,44 @@ + + + + + + + + + + \ No newline at end of file