Skip to content

Commit

Permalink
Merge pull request #31 from mym0404/ground-overlay
Browse files Browse the repository at this point in the history
Ground Overlay
  • Loading branch information
mym0404 authored May 1, 2024
2 parents fb0edeb + d918293 commit 345ffce
Show file tree
Hide file tree
Showing 20 changed files with 735 additions and 57 deletions.
27 changes: 9 additions & 18 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,6 @@ jobs:
- name: Setup
uses: ./.github/actions/setup

- name: Convert Arch
run: yarn ${{matrix.arch}}

- name: Cache turborepo for Android
uses: actions/cache@v4
with:
Expand All @@ -92,7 +89,7 @@ jobs:
- name: Check turborepo cache for Android
run: |
TURBO_CACHE_STATUS=$(node -p "($(yarn turbo run ci:android --single-package --cache-dir="${{ env.TURBO_CACHE_DIR }}" --dry=json)).tasks.find(t => t.task === 'ci:android').cache.status")
TURBO_CACHE_STATUS=$(node -p "($(yarn turbo run ci:android:${{matrix.arch}} --single-package --cache-dir="${{ env.TURBO_CACHE_DIR }}" --dry=json)).tasks.find(t => t.task === 'ci:android:${{matrix.arch}}').cache.status")
if [[ $TURBO_CACHE_STATUS == "HIT" ]]; then
echo "turbo_cache_hit=1" >> $GITHUB_ENV
Expand Down Expand Up @@ -121,19 +118,16 @@ jobs:
restore-keys: |
${{ runner.os }}-gradle-${{matrix.arch}}-
- name: Build example for Android
env:
JAVA_OPTS: "-XX:MaxHeapSize=6g"
run: |
yarn turbo run ci:android --single-package --cache-dir="${{ env.TURBO_CACHE_DIR }}"
run: yarn turbo:android:${{matrix.arch}}

build-ios:
runs-on: macos-latest
strategy:
matrix:
arch: [ new ]
arch: [ old, new ]
env:
TURBO_CACHE_DIR: .turbo/ios-${{matrix.arch}}
steps:
Expand All @@ -153,7 +147,7 @@ jobs:
- name: Check turborepo cache for iOS
run: |
TURBO_CACHE_STATUS=$(node -p "($(yarn turbo run ci:ios --single-package --cache-dir="${{ env.TURBO_CACHE_DIR }}" --dry=json)).tasks.find(t => t.task === 'ci:ios').cache.status")
TURBO_CACHE_STATUS=$(node -p "($(yarn turbo run ci:ios:${{matrix.arch}} --single-package --cache-dir="${{ env.TURBO_CACHE_DIR }}" --dry=json)).tasks.find(t => t.task === 'ci:ios:${{matrix.arch}}').cache.status")
if [[ $TURBO_CACHE_STATUS == "HIT" ]]; then
echo "turbo_cache_hit=1" >> $GITHUB_ENV
Expand All @@ -166,16 +160,13 @@ jobs:
with:
path: |
**/ios/Pods
example/ios/build/generated/ios
key: ${{ runner.os }}-cocoapods-${{ hashFiles('example/ios/Podfile.lock') }}-${{matrix.arch}}-noop
restore-keys: |
${{ runner.os }}-cocoapods-${{matrix.arch}}-
- name: Install cocoapods
# if: env.turbo_cache_hit != 1 && steps.cocoapods-cache.outputs.cache-hit != 'true'
run: yarn ${{matrix.arch}}:pod
env:
NO_FLIPPER: 1

- name: Install pod for codegen stuffs
run: yarn pod:${{matrix.arch}}
- name: Build example for iOS
run: |
yarn turbo run ci:ios --single-package --cache-dir="${{ env.TURBO_CACHE_DIR }}"
run: yarn turbo:ios:${{matrix.arch}}

6 changes: 2 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,8 @@ The `package.json` file contains various scripts for common tasks:

**Architecture Convert**

- `new`: convert example project to new architecture
- `old`: convert example project to old architecture
- `new:pod`: convert example project to new architecture with pod install
- `old:pod`: convert example project to old architecture with pod install
- `new`: convert example project to new architecture if needed (gradlew clean, install pod)
- `old`: convert example project to old architecture if needed (gradlew clean, install pod)

**Util**

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package com.mjstudio.reactnativenavermap.overlay.ground

import android.annotation.SuppressLint
import android.graphics.Bitmap
import com.facebook.drawee.generic.GenericDraweeHierarchy
import com.facebook.drawee.view.DraweeHolder
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.uimanager.ThemedReactContext
import com.mjstudio.reactnativenavermap.event.NaverMapOverlayTapEvent
import com.mjstudio.reactnativenavermap.overlay.RNCNaverMapOverlay
import com.mjstudio.reactnativenavermap.util.ImageRequestCanceller
import com.mjstudio.reactnativenavermap.util.createDraweeHierarchy
import com.mjstudio.reactnativenavermap.util.emitEvent
import com.mjstudio.reactnativenavermap.util.getOverlayImage
import com.naver.maps.map.NaverMap
import com.naver.maps.map.overlay.GroundOverlay
import com.naver.maps.map.overlay.OverlayImage
import com.naver.maps.map.util.MarkerIcons

@SuppressLint("ViewConstructor")
class RNCNaverMapGround(private val reactContext: ThemedReactContext) :
RNCNaverMapOverlay<GroundOverlay>(reactContext) {
private val imageHolder: DraweeHolder<GenericDraweeHierarchy>? by lazy {
DraweeHolder.create(createDraweeHierarchy(resources), reactContext)?.apply {
onAttach()
}
}
private var lastImage: ReadableMap? = null
private var imageRequestCanceller: ImageRequestCanceller? = null
private var isImageSet = false

override val overlay: GroundOverlay by lazy {
GroundOverlay().apply {
setOnClickListener {
reactContext.emitEvent(id) { surfaceId, reactTag ->
NaverMapOverlayTapEvent(
surfaceId,
reactTag,
)
}
true
}
}
}

override fun addToMap(map: NaverMap) {
if (!isImageSet) {
overlay.image = MarkerIcons.GREEN
overlay.alpha = 0f
}
overlay.map = map
}

override fun removeFromMap(map: NaverMap) {
overlay.map = null
}

override fun onDropViewInstance() {
overlay.map = null
overlay.onClickListener = null
imageHolder?.onDetach()
imageRequestCanceller?.invoke()
}

fun setImage(image: ReadableMap?) {
lastImage = image
overlay.alpha = 0f
imageRequestCanceller?.invoke()
imageRequestCanceller =
getOverlayImage(imageHolder!!, context, image?.toHashMap()) {
setOverlayImage(it)
isImageSet = true
overlay.alpha = 1f
}
}

private fun setOverlayImage(image: OverlayImage?) {
overlay.image =
image ?: OverlayImage.fromBitmap(Bitmap.createBitmap(0, 0, Bitmap.Config.ARGB_8888))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package com.mjstudio.reactnativenavermap.overlay.ground

import com.facebook.react.bridge.ReadableMap
import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.uimanager.annotations.ReactProp
import com.mjstudio.reactnativenavermap.RNCNaverMapGroundManagerSpec
import com.mjstudio.reactnativenavermap.event.NaverMapOverlayTapEvent
import com.mjstudio.reactnativenavermap.util.getLatLngBoundsOrNull
import com.mjstudio.reactnativenavermap.util.registerDirectEvent
import com.naver.maps.map.overlay.GroundOverlay

class RNCNaverMapGroundManager : RNCNaverMapGroundManagerSpec<RNCNaverMapGround>() {
override fun getName(): String {
return NAME
}

override fun createViewInstance(context: ThemedReactContext): RNCNaverMapGround {
return RNCNaverMapGround(context)
}

override fun onDropViewInstance(view: RNCNaverMapGround) {
super.onDropViewInstance(view)
view.onDropViewInstance()
}

override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> =
(super.getExportedCustomDirectEventTypeConstants() ?: mutableMapOf()).apply {
registerDirectEvent(this, NaverMapOverlayTapEvent.EVENT_NAME)
}

private fun RNCNaverMapGround?.withOverlay(fn: (GroundOverlay) -> Unit) {
this?.overlay?.run(fn)
}

@ReactProp(name = "zIndexValue")
override fun setZIndexValue(
view: RNCNaverMapGround?,
value: Int,
) = view.withOverlay {
it.zIndex = value
}

@ReactProp(name = "isHidden")
override fun setIsHidden(
view: RNCNaverMapGround?,
value: Boolean,
) = view.withOverlay {
it.isVisible = !value
}

@ReactProp(name = "minZoom")
override fun setMinZoom(
view: RNCNaverMapGround?,
value: Double,
) = view.withOverlay {
it.minZoom = value
}

@ReactProp(name = "maxZoom")
override fun setMaxZoom(
view: RNCNaverMapGround?,
value: Double,
) = view.withOverlay {
it.maxZoom = value
}

@ReactProp(name = "isMinZoomInclusive")
override fun setIsMinZoomInclusive(
view: RNCNaverMapGround?,
value: Boolean,
) = view.withOverlay {
it.isMinZoomInclusive = value
}

@ReactProp(name = "isMaxZoomInclusive")
override fun setIsMaxZoomInclusive(
view: RNCNaverMapGround?,
value: Boolean,
) = view.withOverlay {
it.isMaxZoomInclusive = value
}

@ReactProp(name = "image")
override fun setImage(
view: RNCNaverMapGround?,
value: ReadableMap?,
) {
view?.setImage(value)
}

@ReactProp(name = "region")
override fun setRegion(
view: RNCNaverMapGround?,
value: ReadableMap?,
) = view.withOverlay {
value?.getLatLngBoundsOrNull()?. run {
it.bounds = this
}
}

// region PROPS

companion object {
const val NAME = "RNCNaverMapGround"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,6 @@ class RNCNaverMapMarker(val reactContext: ThemedReactContext) :
private var imageRequestCanceller: ImageRequestCanceller? = null
private var isImageSetFromSubview = false

override fun onDetachedFromWindow() {
imageRequestCanceller?.invoke()
super.onDetachedFromWindow()
}

override val overlay: Marker by lazy {
Marker().apply {
setOnClickListener {
Expand All @@ -68,6 +63,7 @@ class RNCNaverMapMarker(val reactContext: ThemedReactContext) :
overlay.map = null
overlay.onClickListener = null
imageHolder?.onDetach()
imageRequestCanceller?.invoke()
}

fun setCustomView(
Expand Down
21 changes: 21 additions & 0 deletions android/src/newarch/RNCNaverMapGroundManagerSpec.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.mjstudio.reactnativenavermap

import android.view.View
import com.facebook.react.uimanager.SimpleViewManager
import com.facebook.react.uimanager.ViewManagerDelegate
import com.facebook.react.viewmanagers.RNCNaverMapGroundManagerDelegate
import com.facebook.react.viewmanagers.RNCNaverMapGroundManagerInterface

abstract class RNCNaverMapGroundManagerSpec<T : View> :
SimpleViewManager<T>(),
RNCNaverMapGroundManagerInterface<T?> {
private val mDelegate: ViewManagerDelegate<T>

init {
mDelegate = RNCNaverMapGroundManagerDelegate(this)
}

override fun getDelegate(): ViewManagerDelegate<T>? {
return mDelegate
}
}
51 changes: 51 additions & 0 deletions android/src/oldarch/RNCNaverMapGroundManagerSpec.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.mjstudio.reactnativenavermap

import android.view.View
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.uimanager.SimpleViewManager

internal interface RNCNaverMapGroundManagerInterface<T : View?> {
fun setZIndexValue(
view: T,
value: Int,
)

fun setIsHidden(
view: T,
value: Boolean,
)

fun setMinZoom(
view: T,
value: Double,
)

fun setMaxZoom(
view: T,
value: Double,
)

fun setIsMinZoomInclusive(
view: T,
value: Boolean,
)

fun setIsMaxZoomInclusive(
view: T,
value: Boolean,
)

fun setImage(
view: T,
value: ReadableMap?,
)

fun setRegion(
view: T,
value: ReadableMap?,
)
}

abstract class RNCNaverMapGroundManagerSpec<T : View> :
SimpleViewManager<T>(),
RNCNaverMapGroundManagerInterface<T?>
Loading

0 comments on commit 345ffce

Please sign in to comment.