chore(android): add ktlint
This commit is contained in:
parent
3393f76165
commit
6f286f5f67
15
android/.editorconfig
Normal file
15
android/.editorconfig
Normal file
@ -0,0 +1,15 @@
|
||||
[*.{kt,kts}]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
continuation_indent_size=4
|
||||
insert_final_newline=true
|
||||
max_line_length=140
|
||||
ktlint_code_style=android_studio
|
||||
ktlint_standard=enabled
|
||||
ktlint_experimental=enabled
|
||||
ktlint_standard_filename=disabled # dont require PascalCase filenames
|
||||
ktlint_standard_no-wildcard-imports=disabled # allow .* imports
|
||||
ktlint_function_signature_rule_force_multiline_when_parameter_count_greater_or_equal_than=5
|
||||
ktlint_function_signature_body_expression_wrapping=multiline
|
||||
ij_kotlin_allow_trailing_comma_on_call_site=false
|
||||
ij_kotlin_allow_trailing_comma=false
|
||||
@ -6,11 +6,7 @@ import com.facebook.react.bridge.ReactApplicationContext
|
||||
import com.facebook.react.uimanager.ViewManager
|
||||
|
||||
class TrueSheetPackage : ReactPackage {
|
||||
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
||||
return listOf(TrueSheetViewModule(reactContext))
|
||||
}
|
||||
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> = listOf(TrueSheetViewModule(reactContext))
|
||||
|
||||
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
||||
return listOf(TrueSheetViewManager())
|
||||
}
|
||||
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> = listOf(TrueSheetViewManager())
|
||||
}
|
||||
|
||||
@ -21,7 +21,9 @@ import com.lodev09.truesheet.core.SheetBehavior
|
||||
import com.lodev09.truesheet.core.SizeChangeEvent
|
||||
import com.lodev09.truesheet.utils.maxSize
|
||||
|
||||
class TrueSheetView(context: Context) : ViewGroup(context), LifecycleEventListener {
|
||||
class TrueSheetView(context: Context) :
|
||||
ViewGroup(context),
|
||||
LifecycleEventListener {
|
||||
private var eventDispatcher: EventDispatcher? = null
|
||||
|
||||
private val reactContext: ThemedReactContext
|
||||
@ -62,33 +64,31 @@ class TrueSheetView(context: Context) : ViewGroup(context), LifecycleEventListen
|
||||
// Configure Sheet events
|
||||
sheetBehavior.apply {
|
||||
maxSize = maxSize(context)
|
||||
addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
|
||||
override fun onSlide(sheetView: View, slideOffset: Float) {
|
||||
footerView?.let {
|
||||
it.y = (sheetView.height - sheetView.top - it.height).toFloat()
|
||||
}
|
||||
}
|
||||
override fun onStateChanged(view: View, newState: Int) {
|
||||
val sizeInfo = getSizeInfoForState(sizes.size, newState)
|
||||
if (sizeInfo != null && sizeInfo.index != sizeIndex) {
|
||||
sizeIndex = sizeInfo.index
|
||||
|
||||
// dispatch onSizeChange event
|
||||
eventDispatcher?.dispatchEvent(SizeChangeEvent(surfaceId, id, sizeInfo))
|
||||
}
|
||||
|
||||
when (newState) {
|
||||
BottomSheetBehavior.STATE_HIDDEN -> {
|
||||
sheetDialog.dismiss()
|
||||
addBottomSheetCallback(
|
||||
object : BottomSheetBehavior.BottomSheetCallback() {
|
||||
override fun onSlide(sheetView: View, slideOffset: Float) {
|
||||
footerView?.let {
|
||||
it.y = (sheetView.height - sheetView.top - it.height).toFloat()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStateChanged(view: View, newState: Int) {
|
||||
val sizeInfo = getSizeInfoForState(sizes.size, newState)
|
||||
if (sizeInfo != null && sizeInfo.index != sizeIndex) {
|
||||
sizeIndex = sizeInfo.index
|
||||
|
||||
// dispatch onSizeChange event
|
||||
eventDispatcher?.dispatchEvent(SizeChangeEvent(surfaceId, id, sizeInfo))
|
||||
}
|
||||
|
||||
when (newState) {
|
||||
BottomSheetBehavior.STATE_HIDDEN -> sheetDialog.dismiss()
|
||||
else -> {}
|
||||
}
|
||||
BottomSheetBehavior.STATE_COLLAPSED -> {}
|
||||
BottomSheetBehavior.STATE_DRAGGING -> {}
|
||||
BottomSheetBehavior.STATE_EXPANDED -> {}
|
||||
BottomSheetBehavior.STATE_HALF_EXPANDED -> {}
|
||||
BottomSheetBehavior.STATE_SETTLING -> {}
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
// Configure the sheet layout
|
||||
@ -131,7 +131,13 @@ class TrueSheetView(context: Context) : ViewGroup(context), LifecycleEventListen
|
||||
sheetRootView.dispatchProvideStructure(structure)
|
||||
}
|
||||
|
||||
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
|
||||
override fun onLayout(
|
||||
changed: Boolean,
|
||||
l: Int,
|
||||
t: Int,
|
||||
r: Int,
|
||||
b: Int
|
||||
) {
|
||||
// Do nothing as we are laid out by UIManager
|
||||
}
|
||||
|
||||
@ -163,9 +169,7 @@ class TrueSheetView(context: Context) : ViewGroup(context), LifecycleEventListen
|
||||
return sheetRootView.childCount
|
||||
}
|
||||
|
||||
override fun getChildAt(index: Int): View {
|
||||
return sheetRootView.getChildAt(index)
|
||||
}
|
||||
override fun getChildAt(index: Int): View = sheetRootView.getChildAt(index)
|
||||
|
||||
override fun removeView(child: View) {
|
||||
sheetRootView.removeView(child)
|
||||
@ -227,4 +231,3 @@ class TrueSheetView(context: Context) : ViewGroup(context), LifecycleEventListen
|
||||
const val TAG = "TrueSheetView"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -14,9 +14,7 @@ import com.lodev09.truesheet.core.SizeChangeEvent
|
||||
class TrueSheetViewManager : ViewGroupManager<TrueSheetView>() {
|
||||
override fun getName() = TAG
|
||||
|
||||
override fun createViewInstance(reactContext: ThemedReactContext): TrueSheetView {
|
||||
return TrueSheetView(reactContext)
|
||||
}
|
||||
override fun createViewInstance(reactContext: ThemedReactContext): TrueSheetView = TrueSheetView(reactContext)
|
||||
|
||||
override fun onDropViewInstance(view: TrueSheetView) {
|
||||
super.onDropViewInstance(view)
|
||||
|
||||
@ -5,8 +5,9 @@ import com.facebook.react.bridge.WritableMap
|
||||
import com.facebook.react.uimanager.events.Event
|
||||
|
||||
// onPresent
|
||||
class PresentEvent(surfaceId: Int, viewId: Int): Event<PresentEvent>(surfaceId, viewId) {
|
||||
class PresentEvent(surfaceId: Int, viewId: Int) : Event<PresentEvent>(surfaceId, viewId) {
|
||||
override fun getEventName() = EVENT_NAME
|
||||
|
||||
override fun getEventData(): WritableMap = Arguments.createMap()
|
||||
|
||||
companion object {
|
||||
@ -15,8 +16,9 @@ class PresentEvent(surfaceId: Int, viewId: Int): Event<PresentEvent>(surfaceId,
|
||||
}
|
||||
|
||||
// onDismiss
|
||||
class DismissEvent(surfaceId: Int, viewId: Int): Event<PresentEvent>(surfaceId, viewId) {
|
||||
class DismissEvent(surfaceId: Int, viewId: Int) : Event<PresentEvent>(surfaceId, viewId) {
|
||||
override fun getEventName() = EVENT_NAME
|
||||
|
||||
override fun getEventData(): WritableMap = Arguments.createMap()
|
||||
|
||||
companion object {
|
||||
@ -24,8 +26,9 @@ class DismissEvent(surfaceId: Int, viewId: Int): Event<PresentEvent>(surfaceId,
|
||||
}
|
||||
}
|
||||
|
||||
class SizeChangeEvent(surfaceId: Int, viewId: Int, private val sizeInfo: SizeInfo): Event<SizeChangeEvent>(surfaceId, viewId) {
|
||||
class SizeChangeEvent(surfaceId: Int, viewId: Int, private val sizeInfo: SizeInfo) : Event<SizeChangeEvent>(surfaceId, viewId) {
|
||||
override fun getEventName() = EVENT_NAME
|
||||
|
||||
override fun getEventData(): WritableMap {
|
||||
val data = Arguments.createMap()
|
||||
data.putInt("index", sizeInfo.index)
|
||||
|
||||
@ -26,7 +26,8 @@ import com.facebook.react.views.view.ReactViewGroup
|
||||
* styleHeight on the LayoutShadowNode to be the window size. This is done through the
|
||||
* UIManagerModule, and will then cause the children to layout as if they can fill the window.
|
||||
*/
|
||||
internal class RootViewGroup(context: Context?) : ReactViewGroup(context),
|
||||
internal class RootViewGroup(context: Context?) :
|
||||
ReactViewGroup(context),
|
||||
RootView {
|
||||
private var hasAdjustedSize = false
|
||||
private var viewWidth = 0
|
||||
@ -59,13 +60,15 @@ internal class RootViewGroup(context: Context?) : ReactViewGroup(context),
|
||||
reactContext.runOnNativeModulesQueueThread(
|
||||
object : GuardedRunnable(reactContext) {
|
||||
override fun runGuarded() {
|
||||
val uiManager: UIManagerModule = reactContext
|
||||
.reactApplicationContext
|
||||
.getNativeModule(UIManagerModule::class.java) ?: return
|
||||
val uiManager: UIManagerModule =
|
||||
reactContext
|
||||
.reactApplicationContext
|
||||
.getNativeModule(UIManagerModule::class.java) ?: return
|
||||
|
||||
uiManager.updateNodeSize(viewTag, viewWidth, viewHeight)
|
||||
}
|
||||
})
|
||||
}
|
||||
)
|
||||
} else {
|
||||
hasAdjustedSize = true
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ import com.lodev09.truesheet.utils.toDIP
|
||||
|
||||
data class SizeInfo(val index: Int, val value: Float)
|
||||
|
||||
class SheetBehavior<T: ViewGroup> : BottomSheetBehavior<T>() {
|
||||
class SheetBehavior<T : ViewGroup> : BottomSheetBehavior<T>() {
|
||||
var maxSize: Point = Point()
|
||||
|
||||
var contentView: ViewGroup? = null
|
||||
@ -23,7 +23,7 @@ class SheetBehavior<T: ViewGroup> : BottomSheetBehavior<T>() {
|
||||
val expanded = state == STATE_EXPANDED
|
||||
|
||||
if (isDownEvent && expanded) {
|
||||
for(i in 0 until it.childCount) {
|
||||
for (i in 0 until it.childCount) {
|
||||
val contentChild = it.getChildAt(i)
|
||||
val scrolled = (contentChild is ScrollView && contentChild.scrollY > 0)
|
||||
|
||||
@ -58,30 +58,44 @@ class SheetBehavior<T: ViewGroup> : BottomSheetBehavior<T>() {
|
||||
private fun getSizeHeight(size: Any, contentHeight: Int): Int {
|
||||
val maxHeight = maxSize.y
|
||||
|
||||
val height = when (size) {
|
||||
is Double -> PixelUtil.toPixelFromDIP(size).toInt()
|
||||
is Int -> PixelUtil.toPixelFromDIP(size.toDouble()).toInt()
|
||||
is String -> {
|
||||
return when (size) {
|
||||
"auto" -> contentHeight
|
||||
"large" -> maxHeight
|
||||
"medium" -> (maxHeight * 0.50).toInt()
|
||||
"small" -> (maxHeight * 0.25).toInt()
|
||||
else -> {
|
||||
if (size.endsWith('%')) {
|
||||
val percent = size.trim('%').toDoubleOrNull()
|
||||
return if (percent == null) 0
|
||||
else ((percent / 100) * maxHeight).toInt()
|
||||
} else {
|
||||
val fixedHeight = size.toDoubleOrNull()
|
||||
return if (fixedHeight == null) 0
|
||||
else PixelUtil.toPixelFromDIP(fixedHeight).toInt()
|
||||
val height =
|
||||
when (size) {
|
||||
is Double -> PixelUtil.toPixelFromDIP(size).toInt()
|
||||
|
||||
is Int -> PixelUtil.toPixelFromDIP(size.toDouble()).toInt()
|
||||
|
||||
is String -> {
|
||||
return when (size) {
|
||||
"auto" -> contentHeight
|
||||
|
||||
"large" -> maxHeight
|
||||
|
||||
"medium" -> (maxHeight * 0.50).toInt()
|
||||
|
||||
"small" -> (maxHeight * 0.25).toInt()
|
||||
|
||||
else -> {
|
||||
if (size.endsWith('%')) {
|
||||
val percent = size.trim('%').toDoubleOrNull()
|
||||
return if (percent == null) {
|
||||
0
|
||||
} else {
|
||||
((percent / 100) * maxHeight).toInt()
|
||||
}
|
||||
} else {
|
||||
val fixedHeight = size.toDoubleOrNull()
|
||||
return if (fixedHeight == null) {
|
||||
0
|
||||
} else {
|
||||
PixelUtil.toPixelFromDIP(fixedHeight).toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else -> (maxHeight * 0.5).toInt()
|
||||
}
|
||||
else -> (maxHeight * 0.5).toInt()
|
||||
}
|
||||
|
||||
return minOf(height, maxHeight)
|
||||
}
|
||||
@ -103,10 +117,12 @@ class SheetBehavior<T: ViewGroup> : BottomSheetBehavior<T>() {
|
||||
maxHeight = getSizeHeight(sizes[0], contentHeight)
|
||||
skipCollapsed = true
|
||||
}
|
||||
|
||||
2 -> {
|
||||
peekHeight = getSizeHeight(sizes[0], contentHeight)
|
||||
maxHeight = getSizeHeight(sizes[1], contentHeight)
|
||||
}
|
||||
|
||||
3 -> {
|
||||
// Enables half expanded
|
||||
isFitToContents = false
|
||||
@ -119,14 +135,15 @@ class SheetBehavior<T: ViewGroup> : BottomSheetBehavior<T>() {
|
||||
}
|
||||
}
|
||||
|
||||
fun getSizeInfoForState(sizeCount: Int, state: Int): SizeInfo? {
|
||||
return when (sizeCount) {
|
||||
fun getSizeInfoForState(sizeCount: Int, state: Int): SizeInfo? =
|
||||
when (sizeCount) {
|
||||
1 -> {
|
||||
when (state) {
|
||||
STATE_EXPANDED -> SizeInfo(0, PixelUtil.toDIPFromPixel(maxHeight.toFloat()))
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
2 -> {
|
||||
when (state) {
|
||||
STATE_COLLAPSED -> SizeInfo(0, toDIP(peekHeight))
|
||||
@ -134,40 +151,48 @@ class SheetBehavior<T: ViewGroup> : BottomSheetBehavior<T>() {
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
3 -> {
|
||||
when (state) {
|
||||
STATE_COLLAPSED -> SizeInfo(0, toDIP(peekHeight))
|
||||
|
||||
STATE_HALF_EXPANDED -> {
|
||||
val height = halfExpandedRatio * maxSize.y
|
||||
SizeInfo(1, toDIP(height.toInt()))
|
||||
}
|
||||
|
||||
STATE_EXPANDED -> SizeInfo(2, toDIP(maxHeight))
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun setStateForSizeIndex(sizeCount: Int, index: Int) {
|
||||
state = when (sizeCount) {
|
||||
1 -> STATE_EXPANDED
|
||||
2 -> {
|
||||
when (index) {
|
||||
0 -> STATE_COLLAPSED
|
||||
1 -> STATE_EXPANDED
|
||||
else -> STATE_HIDDEN
|
||||
state =
|
||||
when (sizeCount) {
|
||||
1 -> STATE_EXPANDED
|
||||
|
||||
2 -> {
|
||||
when (index) {
|
||||
0 -> STATE_COLLAPSED
|
||||
1 -> STATE_EXPANDED
|
||||
else -> STATE_HIDDEN
|
||||
}
|
||||
}
|
||||
}
|
||||
3 -> {
|
||||
when(index) {
|
||||
0 -> STATE_COLLAPSED
|
||||
1 -> STATE_HALF_EXPANDED
|
||||
2 -> STATE_EXPANDED
|
||||
else -> STATE_HIDDEN
|
||||
|
||||
3 -> {
|
||||
when (index) {
|
||||
0 -> STATE_COLLAPSED
|
||||
1 -> STATE_HALF_EXPANDED
|
||||
2 -> STATE_EXPANDED
|
||||
else -> STATE_HIDDEN
|
||||
}
|
||||
}
|
||||
|
||||
else -> STATE_HIDDEN
|
||||
}
|
||||
else -> STATE_HIDDEN
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,18 +1,20 @@
|
||||
package com.lodev09.truesheet.utils
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.graphics.Point
|
||||
import android.view.WindowManager
|
||||
import com.facebook.infer.annotation.Assertions
|
||||
|
||||
/**
|
||||
* To get the size of the screen, we use information from the WindowManager and default Display.
|
||||
* We don't use DisplayMetricsHolder, or Display#getSize() because they return values that include
|
||||
* the status bar. We only want the values of what will actually be shown on screen. We use
|
||||
* Display#getSize() to determine if the screen is in portrait or landscape. We don't use
|
||||
* getRotation because the 'natural' rotation will be portrait on phones and landscape on tablets.
|
||||
* This should only be called on the native modules/shadow nodes thread.
|
||||
*/
|
||||
* To get the size of the screen, we use information from the WindowManager and default Display.
|
||||
* We don't use DisplayMetricsHolder, or Display#getSize() because they return values that include
|
||||
* the status bar. We only want the values of what will actually be shown on screen. We use
|
||||
* Display#getSize() to determine if the screen is in portrait or landscape. We don't use
|
||||
* getRotation because the 'natural' rotation will be portrait on phones and landscape on tablets.
|
||||
* This should only be called on the native modules/shadow nodes thread.
|
||||
*/
|
||||
@SuppressLint("DiscouragedApi", "InternalInsetResource")
|
||||
fun maxSize(context: Context): Point {
|
||||
val minPoint = Point()
|
||||
val maxPoint = Point()
|
||||
|
||||
@ -2,6 +2,4 @@ package com.lodev09.truesheet.utils
|
||||
|
||||
import com.facebook.react.uimanager.PixelUtil
|
||||
|
||||
fun toDIP(value: Int): Float {
|
||||
return PixelUtil.toDIPFromPixel(value.toFloat())
|
||||
}
|
||||
fun toDIP(value: Int): Float = PixelUtil.toDIPFromPixel(value.toFloat())
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
"typecheck": "tsc --noEmit",
|
||||
"lint": "eslint --fix \"**/*.{js,ts,tsx}\"",
|
||||
"format": "prettier --write \"**/*.{js,ts,tsx}\"",
|
||||
"tidy": "yarn typecheck && yarn lint && yarn format && scripts/swiftlint.sh && scripts/swiftformat.sh",
|
||||
"tidy": "yarn typecheck && yarn lint && yarn format && scripts/swiftlint.sh && scripts/ktlint.sh",
|
||||
"clean": "del-cli android/build lib && yarn workspace true-sheet-example clean",
|
||||
"prepare": "bob build",
|
||||
"release": "release-it"
|
||||
|
||||
8
scripts/ktlint.sh
Executable file
8
scripts/ktlint.sh
Executable file
@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
if which ktlint >/dev/null; then
|
||||
cd android && ktlint --color --relative --editorconfig=./.editorconfig -F ./**/*.kt*
|
||||
else
|
||||
echo "error: KTLint not installed, install with 'brew install ktlint' (or manually from https://github.com/pinterest/ktlint)"
|
||||
exit 1
|
||||
fi
|
||||
@ -1,8 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
if which swiftformat >/dev/null; then
|
||||
cd ios && swiftformat --quiet .
|
||||
else
|
||||
echo "error: SwiftFormat not installed, install with 'brew install swiftformat' (or manually from https://github.com/nicklockwood/SwiftFormat)"
|
||||
exit 1
|
||||
fi
|
||||
@ -1,8 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
if which swiftlint >/dev/null; then
|
||||
cd ios && swiftlint --quiet --fix && swiftlint --quiet
|
||||
cd ios && swiftlint --quiet --fix && swiftlint --quiet && swiftformat --quiet .
|
||||
else
|
||||
echo "error: SwiftLint not installed, install with 'brew install swiftlint' (or manually from https://github.com/realm/SwiftLint)"
|
||||
echo "error: SwiftLint or SwiftFormat not installed, install with 'brew install swiftlint' (or manually from https://github.com/realm/SwiftLint)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
Loading…
Reference in New Issue
Block a user