@momo-kits/native-kits 0.160.1-scrolltotop.12-debug → 0.160.1-scrolltotop.13-debug

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -40,7 +40,7 @@ kotlin {
40
40
  }
41
41
 
42
42
  cocoapods {
43
- version = "0.160.1-scrolltotop.12-debug"
43
+ version = "0.160.1-scrolltotop.13-debug"
44
44
  summary = "IOS Shared module"
45
45
  homepage = "https://momo.vn"
46
46
  ios.deploymentTarget = "15.0"
@@ -3,12 +3,33 @@ package vn.momo.kits.navigation
3
3
  import androidx.compose.runtime.Composable
4
4
  import androidx.compose.runtime.DisposableEffect
5
5
  import androidx.compose.runtime.remember
6
+ import kotlin.time.Clock
7
+ import kotlin.time.ExperimentalTime
8
+
9
+ private const val TAG = "[ScrollToTop]"
10
+
11
+ private fun Any.tag(): String = "${this::class.simpleName ?: "Any"}@${hashCode().toString(16)}"
12
+
13
+ @OptIn(ExperimentalTime::class)
14
+ private fun ts(): String {
15
+ val ms = Clock.System.now().toEpochMilliseconds()
16
+ val s = ms / 1000
17
+ val hh = ((s / 3600) % 24).toString().padStart(2, '0')
18
+ val mm = ((s / 60) % 60).toString().padStart(2, '0')
19
+ val ss = (s % 60).toString().padStart(2, '0')
20
+ val mmm = (ms % 1000).toString().padStart(3, '0')
21
+ return "$hh:$mm:$ss.$mmm"
22
+ }
23
+
24
+ private fun log(msg: String) = println("${ts()} $TAG $msg")
6
25
 
7
26
  actual fun onNavigatorEntered(navigator: Navigator) {
27
+ log("onNavigatorEntered owner=${navigator.tag()}")
8
28
  ScrollToTopRegistry.pushOwner(navigator)
9
29
  }
10
30
 
11
31
  actual fun onNavigatorExited(navigator: Navigator) {
32
+ log("onNavigatorExited owner=${navigator.tag()}")
12
33
  ScrollToTopRegistry.removeOwner(navigator)
13
34
  }
14
35
 
@@ -17,11 +38,16 @@ internal actual fun RegisterScrollToTop(navigator: Navigator, callback: (() -> U
17
38
  val token = remember { Any() }
18
39
  DisposableEffect(navigator, callback) {
19
40
  if (callback != null) {
41
+ log("RegisterScrollToTop push owner=${navigator.tag()} token=${token.tag()}")
20
42
  ScrollToTopRegistry.push(navigator, token, callback)
21
43
  } else {
44
+ log("RegisterScrollToTop remove(callback=null) owner=${navigator.tag()} token=${token.tag()}")
45
+ ScrollToTopRegistry.remove(navigator, token)
46
+ }
47
+ onDispose {
48
+ log("RegisterScrollToTop dispose owner=${navigator.tag()} token=${token.tag()}")
22
49
  ScrollToTopRegistry.remove(navigator, token)
23
50
  }
24
- onDispose { ScrollToTopRegistry.remove(navigator, token) }
25
51
  }
26
52
  }
27
53
 
@@ -42,39 +68,57 @@ object ScrollToTopRegistry {
42
68
  private val ownerStack = mutableListOf<Any>()
43
69
 
44
70
  fun pushOwner(owner: Any) {
45
- ownerStack.remove(owner)
71
+ val existed = ownerStack.remove(owner)
46
72
  ownerStack.add(owner)
73
+ log("pushOwner owner=${owner.tag()} reorder=$existed ownerStack=${ownerStack.size} state=${dump()}")
47
74
  }
48
75
 
49
76
  fun removeOwner(owner: Any) {
50
- ownerStack.remove(owner)
51
- stacksByOwner.remove(owner)
77
+ val removedFromStack = ownerStack.remove(owner)
78
+ val removedScreens = stacksByOwner.remove(owner)?.size ?: 0
79
+ log("removeOwner owner=${owner.tag()} removedFromStack=$removedFromStack droppedScreens=$removedScreens state=${dump()}")
52
80
  }
53
81
 
54
82
  internal fun push(owner: Any, token: Any, callback: () -> Unit) {
55
83
  val stack = stacksByOwner.getOrPut(owner) { mutableListOf() }
56
84
  val idx = stack.indexOfFirst { it.token === token }
57
85
  if (idx >= 0) {
58
- // Same screen, callback changed (e.g. via setOptions) — replace in place
59
- // so we don't reorder the per-owner stack.
60
86
  stack[idx] = Entry(token, callback)
87
+ log("push(update) owner=${owner.tag()} token=${token.tag()} idx=$idx size=${stack.size} state=${dump()}")
61
88
  } else {
62
89
  stack.add(Entry(token, callback))
90
+ log("push(new) owner=${owner.tag()} token=${token.tag()} size=${stack.size} state=${dump()}")
63
91
  }
64
92
  }
65
93
 
66
94
  internal fun remove(owner: Any, token: Any) {
67
- stacksByOwner[owner]?.removeAll { it.token === token }
95
+ val stack = stacksByOwner[owner]
96
+ val before = stack?.size ?: 0
97
+ val removed = stack?.removeAll { it.token === token } ?: false
98
+ log("remove owner=${owner.tag()} token=${token.tag()} removed=$removed size=${before}->${stack?.size ?: 0} state=${dump()}")
68
99
  }
69
100
 
70
101
  fun trigger() {
71
- val owner = ownerStack.lastOrNull() ?: run {
72
- // Fallback: no owner registered yet — fire the only owner if there's exactly one.
102
+ val owner = ownerStack.lastOrNull()
103
+ if (owner == null) {
73
104
  if (stacksByOwner.size == 1) {
74
- stacksByOwner.values.first().lastOrNull()?.callback?.invoke()
105
+ val only = stacksByOwner.entries.first()
106
+ val cb = only.value.lastOrNull()?.callback
107
+ log("trigger(fallback singleOwner) owner=${only.key.tag()} hasCallback=${cb != null}")
108
+ cb?.invoke()
109
+ } else {
110
+ log("trigger NO-OP (no owner, owners=${stacksByOwner.size}) state=${dump()}")
75
111
  }
76
112
  return
77
113
  }
78
- stacksByOwner[owner]?.lastOrNull()?.callback?.invoke()
114
+ val cb = stacksByOwner[owner]?.lastOrNull()?.callback
115
+ log("trigger owner=${owner.tag()} hasCallback=${cb != null} state=${dump()}")
116
+ cb?.invoke()
117
+ }
118
+
119
+ private fun dump(): String {
120
+ val owners = ownerStack.joinToString(",") { it.tag() }
121
+ val stacks = stacksByOwner.entries.joinToString(",") { (o, s) -> "${o.tag()}:${s.size}" }
122
+ return "ownerStack=[$owners] stacks={$stacks}"
79
123
  }
80
124
  }
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict />
5
+ </plist>
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict />
5
+ </plist>
package/gradle.properties CHANGED
@@ -18,7 +18,7 @@ kotlin.apple.xcodeCompatibility.nowarn=true
18
18
  name="ComposeKits"
19
19
  group=vn.momo.kits
20
20
  artifact.id=kits
21
- version=0.159.1-beta.16
21
+ version=0.160.1-scrolltotop.13
22
22
 
23
23
  repo=GitLab
24
24
  url=https://gitlab.mservice.com.vn/api/v4/projects/5400/packages/maven
@@ -0,0 +1,8 @@
1
+ ## This file must *NOT* be checked into Version Control Systems,
2
+ # as it contains information specific to your local configuration.
3
+ #
4
+ # Location of the SDK. This is only used by Gradle.
5
+ # For customization when using a Version Control System, please read the
6
+ # header note.
7
+ #Tue Jun 17 09:25:26 ICT 2025
8
+ sdk.dir=/Users/thanhle/Library/Android/sdk
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/native-kits",
3
- "version": "0.160.1-scrolltotop.12-debug",
3
+ "version": "0.160.1-scrolltotop.13-debug",
4
4
  "private": false,
5
5
  "dependencies": {},
6
6
  "devDependencies": {},
package/publish.sh CHANGED
File without changes