one 2.7.3 → 2.7.5
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.
- package/android/src/main/java/com/margelo/nitro/one/HybridOneFonts.kt +23 -8
- package/android/src/main/java/com/margelo/nitro/one/HybridOneNotifications.kt +5 -1
- package/android/src/main/java/com/margelo/nitro/one/HybridOneSpeechSynthesis.kt +8 -4
- package/android/src/main/java/dev/onejs/onenative/OneNativeComposeNodeView.kt +3 -2
- package/android/src/main/java/dev/onejs/onenative/OneNativePagerManager.kt +2 -0
- package/dist/cjs/platform/compose.android.cjs +1 -1
- package/dist/cjs/platform/compose.android.js +1 -1
- package/dist/cjs/platform/compose.android.js.map +1 -1
- package/dist/cjs/platform/generated/Controls.native.cjs +6 -6
- package/dist/cjs/platform/generated/Controls.native.js +6 -6
- package/dist/cjs/platform/generated/Controls.native.js.map +1 -1
- package/dist/cjs/vite/resolveResponse.cjs +15 -2
- package/dist/cjs/vite/resolveResponse.native.cjs +17 -2
- package/dist/cjs/vite/resolveResponse.native.js +17 -2
- package/dist/cjs/vite/resolveResponse.native.js.map +1 -1
- package/dist/esm/platform/compose.android.js +1 -1
- package/dist/esm/platform/compose.android.js.map +1 -1
- package/dist/esm/platform/generated/Controls.native.js +6 -6
- package/dist/esm/platform/generated/Controls.native.js.map +1 -1
- package/dist/esm/vite/resolveResponse.mjs +15 -2
- package/dist/esm/vite/resolveResponse.mjs.map +1 -1
- package/dist/esm/vite/resolveResponse.native.js +17 -2
- package/dist/esm/vite/resolveResponse.native.js.map +1 -1
- package/ios/ZoomTransition/ZoomTransition.swift +52 -15
- package/package.json +15 -15
- package/src/createHandleRequest.test.ts +98 -0
- package/src/platform/compose.android.tsx +5 -1
- package/src/platform/generated/Controls.native.tsx +6 -6
- package/src/vite/resolveResponse.ts +17 -2
- package/types/platform/compose.android.d.ts.map +1 -1
- package/types/vite/resolveResponse.d.ts.map +1 -1
|
@@ -126,11 +126,9 @@ class HybridOneFonts : HybridOneFontsSpec() {
|
|
|
126
126
|
}
|
|
127
127
|
// the resource name carries no extension; createFromFile sniffs
|
|
128
128
|
// the content, so the suffix is only a label.
|
|
129
|
-
val
|
|
130
|
-
val file = File(directory, "$resourceName.ttf")
|
|
129
|
+
val file = File(File(context.cacheDir, "one-fonts"), "$resourceName.ttf")
|
|
131
130
|
if (!file.isFile) {
|
|
132
|
-
|
|
133
|
-
file.writeBytes(bytes)
|
|
131
|
+
writeAtomically(file, bytes)
|
|
134
132
|
}
|
|
135
133
|
return file
|
|
136
134
|
}
|
|
@@ -139,8 +137,7 @@ class HybridOneFonts : HybridOneFontsSpec() {
|
|
|
139
137
|
val extension = url.path.substringAfterLast('.', "ttf").lowercase()
|
|
140
138
|
val digest = MessageDigest.getInstance("SHA-256").digest(url.toString().toByteArray())
|
|
141
139
|
val fileName = digest.joinToString("") { "%02x".format(it) } + "." + extension
|
|
142
|
-
val
|
|
143
|
-
val file = File(directory, fileName)
|
|
140
|
+
val file = File(File(context.cacheDir, "one-fonts"), fileName)
|
|
144
141
|
if (file.isFile) {
|
|
145
142
|
return file
|
|
146
143
|
}
|
|
@@ -148,8 +145,26 @@ class HybridOneFonts : HybridOneFontsSpec() {
|
|
|
148
145
|
if (bytes.isEmpty()) {
|
|
149
146
|
throw OneNativeError("E_FONTS_DOWNLOAD", "Fonts.load: \"$name\" downloaded zero bytes")
|
|
150
147
|
}
|
|
151
|
-
|
|
152
|
-
file.writeBytes(bytes)
|
|
148
|
+
writeAtomically(file, bytes)
|
|
153
149
|
return file
|
|
154
150
|
}
|
|
151
|
+
|
|
152
|
+
// concurrent loads of one font (a StrictMode double mount, or two
|
|
153
|
+
// screens) each write the cache file. writing in place truncates a file
|
|
154
|
+
// another load has already mapped for Typeface, which faults with
|
|
155
|
+
// SIGBUS, so each write goes to its own temp file and renames over the
|
|
156
|
+
// target, like the ios atomic write.
|
|
157
|
+
private fun writeAtomically(file: File, bytes: ByteArray) {
|
|
158
|
+
val directory = file.parentFile ?: throw IllegalStateException("Fonts: no cache directory")
|
|
159
|
+
directory.mkdirs()
|
|
160
|
+
val temp = File.createTempFile(file.name, ".part", directory)
|
|
161
|
+
try {
|
|
162
|
+
temp.writeBytes(bytes)
|
|
163
|
+
if (!temp.renameTo(file)) {
|
|
164
|
+
throw IllegalStateException("Fonts: could not move ${temp.name} into place")
|
|
165
|
+
}
|
|
166
|
+
} finally {
|
|
167
|
+
temp.delete()
|
|
168
|
+
}
|
|
169
|
+
}
|
|
155
170
|
}
|
|
@@ -1147,7 +1147,11 @@ class HybridOneNotifications :
|
|
|
1147
1147
|
context,
|
|
1148
1148
|
(schedule.identifier + ":" + action.identifier).hashCode(),
|
|
1149
1149
|
target,
|
|
1150
|
-
|
|
1150
|
+
// the system writes a typed reply into the intent, so a
|
|
1151
|
+
// text-input action needs a mutable one (refused otherwise).
|
|
1152
|
+
PendingIntent.FLAG_UPDATE_CURRENT or
|
|
1153
|
+
if (action.textInputPlaceholder != null) PendingIntent.FLAG_MUTABLE
|
|
1154
|
+
else PendingIntent.FLAG_IMMUTABLE
|
|
1151
1155
|
)
|
|
1152
1156
|
val builder =
|
|
1153
1157
|
androidx.core.app.NotificationCompat.Action.Builder(0, action.buttonTitle, pending)
|
|
@@ -190,10 +190,11 @@ class HybridOneSpeechSynthesis : HybridOneSpeechSynthesisSpec() {
|
|
|
190
190
|
override fun stop(): Promise<Unit> {
|
|
191
191
|
val promise = Promise<Unit>()
|
|
192
192
|
main.post {
|
|
193
|
-
//
|
|
194
|
-
//
|
|
195
|
-
val dropped =
|
|
193
|
+
// every utterance settles here, so isSpeaking is false once stop
|
|
194
|
+
// resolves; the engine's later onStop finds nothing live.
|
|
195
|
+
val dropped = live.values.toList() + waiting
|
|
196
196
|
waiting.clear()
|
|
197
|
+
live.clear()
|
|
197
198
|
engine?.stop()
|
|
198
199
|
dropped.forEach {
|
|
199
200
|
it.onEvent(SpeechSynthesisEvent(SpeechSynthesisEventType.STOPPED, null))
|
|
@@ -209,9 +210,12 @@ class HybridOneSpeechSynthesis : HybridOneSpeechSynthesisSpec() {
|
|
|
209
210
|
|
|
210
211
|
override fun resume(): Promise<Unit> = Promise.resolved(Unit)
|
|
211
212
|
|
|
213
|
+
// speaking or queued on this synthesizer, as AVSpeechSynthesizer reports
|
|
214
|
+
// on ios. the engine's own isSpeaking spans every app and stays true
|
|
215
|
+
// until its playback thread finishes the item that already sent onDone.
|
|
212
216
|
override fun isSpeaking(): Promise<Boolean> {
|
|
213
217
|
val promise = Promise<Boolean>()
|
|
214
|
-
main.post { promise.resolve(
|
|
218
|
+
main.post { promise.resolve(waiting.isNotEmpty() || live.isNotEmpty()) }
|
|
215
219
|
return promise
|
|
216
220
|
}
|
|
217
221
|
|
|
@@ -9,7 +9,6 @@ import android.graphics.PorterDuffColorFilter
|
|
|
9
9
|
import android.graphics.drawable.Animatable
|
|
10
10
|
import android.net.Uri
|
|
11
11
|
import android.os.Build
|
|
12
|
-
import android.view.View
|
|
13
12
|
import android.view.ViewGroup
|
|
14
13
|
import androidx.compose.foundation.BorderStroke
|
|
15
14
|
import androidx.compose.foundation.background
|
|
@@ -995,8 +994,10 @@ private class OneNativeControlledValue<T>(initial: T) {
|
|
|
995
994
|
|
|
996
995
|
class OneNativeComposeNodeView(context: Context) : ReactViewGroup(context) {
|
|
997
996
|
private val composeView =
|
|
997
|
+
// no view id: react native takes the nearest ancestor with a positive
|
|
998
|
+
// id as the react tag of a touch, so a generated id here sent taps on
|
|
999
|
+
// compose controls to whatever react view shared that number.
|
|
998
1000
|
ComposeView(context).apply {
|
|
999
|
-
id = View.generateViewId()
|
|
1000
1001
|
layoutParams =
|
|
1001
1002
|
ViewGroup.LayoutParams(
|
|
1002
1003
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
@@ -66,6 +66,8 @@ class OneNativePagerView(val reactContext: ThemedReactContext) : FrameLayout(rea
|
|
|
66
66
|
layoutParams = ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
|
|
67
67
|
isSaveEnabled = false
|
|
68
68
|
pager.isSaveEnabled = false
|
|
69
|
+
// the internal recycler is not a react view; a positive id becomes a touch target tag.
|
|
70
|
+
pager.getChildAt(0).id = View.NO_ID
|
|
69
71
|
pager.adapter = adapter
|
|
70
72
|
addView(pager, LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT))
|
|
71
73
|
pager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
|
@@ -1234,7 +1234,7 @@ function TextField(param) {
|
|
|
1234
1234
|
var syncHandle = (0, import_syncNativeState.syncHandleOf)(text);
|
|
1235
1235
|
var syncedText = (0, import_syncNativeState.useSyncValue)(text);
|
|
1236
1236
|
var controlled = (0, import_controlled.useControlled)(function(event) {
|
|
1237
|
-
syncHandle === null || syncHandle === void 0 ? void 0 : syncHandle.set(
|
|
1237
|
+
syncHandle === null || syncHandle === void 0 ? void 0 : syncHandle.set(syncHandle.get());
|
|
1238
1238
|
onTextChange(event.text);
|
|
1239
1239
|
}, revision);
|
|
1240
1240
|
var controlledFocus = (0, import_controlled.useControlled)(function(event) {
|
|
@@ -1234,7 +1234,7 @@ function TextField(param) {
|
|
|
1234
1234
|
var syncHandle = (0, import_syncNativeState.syncHandleOf)(text);
|
|
1235
1235
|
var syncedText = (0, import_syncNativeState.useSyncValue)(text);
|
|
1236
1236
|
var controlled = (0, import_controlled.useControlled)(function(event) {
|
|
1237
|
-
syncHandle === null || syncHandle === void 0 ? void 0 : syncHandle.set(
|
|
1237
|
+
syncHandle === null || syncHandle === void 0 ? void 0 : syncHandle.set(syncHandle.get());
|
|
1238
1238
|
onTextChange(event.text);
|
|
1239
1239
|
}, revision);
|
|
1240
1240
|
var controlledFocus = (0, import_controlled.useControlled)(function(event) {
|