react-native-nitro-player 1.5.0-alpha.0 → 1.5.0-alpha.1

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/README.md CHANGED
@@ -677,7 +677,9 @@ Cast requires native configuration in your **app** (not just the library).
677
677
  <key>NSBonjourServices</key>
678
678
  <array>
679
679
  <string>_googlecast._tcp</string>
680
- <!-- If using a custom receiver, also add _<RECEIVER_APP_ID>._googlecast._tcp -->
680
+ <!-- Receiver-specific service. Use _CC1AD845._googlecast._tcp for the Default
681
+ Media Receiver, or _<YOUR_RECEIVER_APP_ID>._googlecast._tcp for a custom one. -->
682
+ <string>_CC1AD845._googlecast._tcp</string>
681
683
  </array>
682
684
  <!-- Only if you use Cast guest mode (full SDK): -->
683
685
  <key>NSBluetoothAlwaysUsageDescription</key>
@@ -41,9 +41,15 @@ final class CastSessionManager: NSObject {
41
41
  let criteria = GCKDiscoveryCriteria(applicationID: appId)
42
42
  let options = GCKCastOptions(discoveryCriteria: criteria)
43
43
  options.suspendSessionsWhenBackgrounded = false
44
+ // We expose a custom Cast button (not GCKUICastButton), so device discovery
45
+ // must begin immediately instead of waiting for a tap on a GCKUICastButton —
46
+ // otherwise no devices are ever found.
47
+ options.startDiscoveryAfterFirstTapOnCastButton = false
44
48
  GCKCastContext.setSharedInstanceWith(options)
45
49
 
46
50
  let context = GCKCastContext.sharedInstance()
51
+ // Begin scanning right away so devices are available before the picker opens.
52
+ context.discoveryManager.startDiscovery()
47
53
  context.sessionManager.add(self)
48
54
  NotificationCenter.default.addObserver(
49
55
  self,
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { Pressable, StyleSheet, View, } from 'react-native';
2
+ import { Pressable, View, } from 'react-native';
3
3
  import { Cast } from '../index';
4
4
  import { useCastState } from '../hooks/useCastState';
5
5
  /**
@@ -40,61 +40,86 @@ export function CastButton({ size = 24, color = '#000000', activeColor = '#1E88E
40
40
  }
41
41
  /**
42
42
  * Dependency-free rendition of the standard Cast glyph: a rounded "screen"
43
- * rectangle with a broadcast signal (dot + two arcs) in the bottom-left corner.
44
- * Drawn purely with `View`s so the library stays dependency-free.
43
+ * rectangle (with its bottom-left corner open) and a broadcast signal — a dot
44
+ * and two concentric arcs — radiating from the bottom-left. Drawn purely with
45
+ * `View`s so the library stays dependency-free.
45
46
  */
46
47
  function CastGlyph({ size, color, }) {
47
- const stroke = Math.max(1.5, Math.round(size * 0.083));
48
- const inset = stroke;
49
- const dotSize = stroke * 1.7;
50
- const r1 = size * 0.28; // inner arc radius
51
- const r2 = size * 0.46; // outer arc radius
48
+ const stroke = Math.max(1.5, Math.round(size / 13));
49
+ const inset = Math.round(size * 0.14);
50
+ const dotSize = stroke * 1.5;
51
+ // Origin of the broadcast signal — the screen's bottom-left corner.
52
+ const cx = inset + stroke / 2;
53
+ const cy = size - inset - stroke / 2;
54
+ // Leave the screen's bottom-left corner open so the signal reads clearly.
55
+ const gap = size * 0.46;
52
56
  return (React.createElement(View, { style: { width: size, height: size } },
53
- React.createElement(View, { style: [
54
- StyleSheet.absoluteFill,
55
- {
56
- borderWidth: stroke,
57
- borderColor: color,
58
- borderRadius: Math.max(2, size * 0.12),
59
- },
60
- ] }),
61
57
  React.createElement(View, { style: {
62
58
  position: 'absolute',
63
59
  left: inset,
60
+ top: inset,
61
+ right: inset,
62
+ height: stroke,
63
+ backgroundColor: color,
64
+ borderRadius: stroke,
65
+ } }),
66
+ React.createElement(View, { style: {
67
+ position: 'absolute',
68
+ top: inset,
69
+ bottom: inset,
70
+ right: inset,
71
+ width: stroke,
72
+ backgroundColor: color,
73
+ borderRadius: stroke,
74
+ } }),
75
+ React.createElement(View, { style: {
76
+ position: 'absolute',
77
+ left: inset + gap,
64
78
  bottom: inset,
79
+ right: inset,
80
+ height: stroke,
81
+ backgroundColor: color,
82
+ borderRadius: stroke,
83
+ } }),
84
+ React.createElement(View, { style: {
85
+ position: 'absolute',
86
+ left: inset,
87
+ top: inset,
88
+ height: size - 2 * inset - gap,
89
+ width: stroke,
90
+ backgroundColor: color,
91
+ borderRadius: stroke,
92
+ } }),
93
+ React.createElement(RippleArc, { cx: cx, cy: cy, radius: size * 0.2, stroke: stroke, color: color }),
94
+ React.createElement(RippleArc, { cx: cx, cy: cy, radius: size * 0.34, stroke: stroke, color: color }),
95
+ React.createElement(View, { style: {
96
+ position: 'absolute',
97
+ left: cx - dotSize / 2,
98
+ top: cy - dotSize / 2,
65
99
  width: dotSize,
66
100
  height: dotSize,
67
101
  borderRadius: dotSize / 2,
68
102
  backgroundColor: color,
69
- } }),
70
- React.createElement(Arc, { origin: inset + dotSize / 2, radius: r1, stroke: stroke, color: color }),
71
- React.createElement(Arc, { origin: inset + dotSize / 2, radius: r2, stroke: stroke, color: color })));
103
+ } })));
72
104
  }
73
105
  /**
74
- * A quarter-circle arc (the top-right quadrant) centered at the bottom-left
75
- * `origin` point. Produced by clipping a full bordered circle to one quadrant.
106
+ * A quarter-circle arc (the up-right quadrant) centered at (cx, cy). Rendered as
107
+ * a circle with only its top border colored, rotated 45° so the visible cap
108
+ * faces up-and-to-the-right — i.e. radiating from the bottom-left dot.
76
109
  */
77
- function Arc({ origin, radius, stroke, color, }) {
78
- return (React.createElement(View
79
- // Clip box reveals only the quadrant facing up-and-right from the origin.
80
- , {
81
- // Clip box reveals only the quadrant facing up-and-right from the origin.
82
- style: {
110
+ function RippleArc({ cx, cy, radius, stroke, color, }) {
111
+ return (React.createElement(View, { style: {
83
112
  position: 'absolute',
84
- left: origin,
85
- bottom: origin - radius,
86
- width: radius,
87
- height: radius,
88
- overflow: 'hidden',
89
- } },
90
- React.createElement(View, { style: {
91
- position: 'absolute',
92
- left: -radius,
93
- top: 0,
94
- width: radius * 2,
95
- height: radius * 2,
96
- borderRadius: radius,
97
- borderWidth: stroke,
98
- borderColor: color,
99
- } })));
113
+ left: cx - radius,
114
+ top: cy - radius,
115
+ width: radius * 2,
116
+ height: radius * 2,
117
+ borderRadius: radius,
118
+ borderWidth: stroke,
119
+ borderTopColor: color,
120
+ borderRightColor: 'transparent',
121
+ borderBottomColor: 'transparent',
122
+ borderLeftColor: 'transparent',
123
+ transform: [{ rotate: '45deg' }],
124
+ } }));
100
125
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-nitro-player",
3
- "version": "1.5.0-alpha.0",
3
+ "version": "1.5.0-alpha.1",
4
4
  "description": "A powerful audio player library for React Native with playlist management, playback controls, and support for Android Auto and CarPlay",
5
5
  "main": "lib/index",
6
6
  "module": "lib/index",
@@ -1,7 +1,6 @@
1
1
  import React from 'react'
2
2
  import {
3
3
  Pressable,
4
- StyleSheet,
5
4
  View,
6
5
  type PressableProps,
7
6
  type StyleProp,
@@ -104,8 +103,9 @@ export function CastButton({
104
103
 
105
104
  /**
106
105
  * Dependency-free rendition of the standard Cast glyph: a rounded "screen"
107
- * rectangle with a broadcast signal (dot + two arcs) in the bottom-left corner.
108
- * Drawn purely with `View`s so the library stays dependency-free.
106
+ * rectangle (with its bottom-left corner open) and a broadcast signal — a dot
107
+ * and two concentric arcs — radiating from the bottom-left. Drawn purely with
108
+ * `View`s so the library stays dependency-free.
109
109
  */
110
110
  function CastGlyph({
111
111
  size,
@@ -114,83 +114,120 @@ function CastGlyph({
114
114
  size: number
115
115
  color: string
116
116
  }): React.ReactElement {
117
- const stroke = Math.max(1.5, Math.round(size * 0.083))
118
- const inset = stroke
119
- const dotSize = stroke * 1.7
120
- const r1 = size * 0.28 // inner arc radius
121
- const r2 = size * 0.46 // outer arc radius
117
+ const stroke = Math.max(1.5, Math.round(size / 13))
118
+ const inset = Math.round(size * 0.14)
119
+ const dotSize = stroke * 1.5
120
+ // Origin of the broadcast signal — the screen's bottom-left corner.
121
+ const cx = inset + stroke / 2
122
+ const cy = size - inset - stroke / 2
123
+ // Leave the screen's bottom-left corner open so the signal reads clearly.
124
+ const gap = size * 0.46
122
125
 
123
126
  return (
124
127
  <View style={{ width: size, height: size }}>
125
- {/* Screen outline */}
128
+ {/* Screen: top + right + most of bottom + most of left, leaving the
129
+ bottom-left corner open (composed from edges for a clean cast look). */}
130
+ {/* Top edge */}
126
131
  <View
127
- style={[
128
- StyleSheet.absoluteFill,
129
- {
130
- borderWidth: stroke,
131
- borderColor: color,
132
- borderRadius: Math.max(2, size * 0.12),
133
- },
134
- ]}
132
+ style={{
133
+ position: 'absolute',
134
+ left: inset,
135
+ top: inset,
136
+ right: inset,
137
+ height: stroke,
138
+ backgroundColor: color,
139
+ borderRadius: stroke,
140
+ }}
135
141
  />
136
- {/* Broadcast dot */}
142
+ {/* Right edge */}
137
143
  <View
138
144
  style={{
139
145
  position: 'absolute',
140
- left: inset,
146
+ top: inset,
147
+ bottom: inset,
148
+ right: inset,
149
+ width: stroke,
150
+ backgroundColor: color,
151
+ borderRadius: stroke,
152
+ }}
153
+ />
154
+ {/* Bottom edge (stops short of the bottom-left corner) */}
155
+ <View
156
+ style={{
157
+ position: 'absolute',
158
+ left: inset + gap,
141
159
  bottom: inset,
160
+ right: inset,
161
+ height: stroke,
162
+ backgroundColor: color,
163
+ borderRadius: stroke,
164
+ }}
165
+ />
166
+ {/* Left edge (stops short of the bottom-left corner) */}
167
+ <View
168
+ style={{
169
+ position: 'absolute',
170
+ left: inset,
171
+ top: inset,
172
+ height: size - 2 * inset - gap,
173
+ width: stroke,
174
+ backgroundColor: color,
175
+ borderRadius: stroke,
176
+ }}
177
+ />
178
+ {/* Two concentric broadcast arcs radiating from the corner dot */}
179
+ <RippleArc cx={cx} cy={cy} radius={size * 0.2} stroke={stroke} color={color} />
180
+ <RippleArc cx={cx} cy={cy} radius={size * 0.34} stroke={stroke} color={color} />
181
+ {/* Broadcast dot */}
182
+ <View
183
+ style={{
184
+ position: 'absolute',
185
+ left: cx - dotSize / 2,
186
+ top: cy - dotSize / 2,
142
187
  width: dotSize,
143
188
  height: dotSize,
144
189
  borderRadius: dotSize / 2,
145
190
  backgroundColor: color,
146
191
  }}
147
192
  />
148
- {/* Two concentric quarter arcs radiating from the dot */}
149
- <Arc origin={inset + dotSize / 2} radius={r1} stroke={stroke} color={color} />
150
- <Arc origin={inset + dotSize / 2} radius={r2} stroke={stroke} color={color} />
151
193
  </View>
152
194
  )
153
195
  }
154
196
 
155
197
  /**
156
- * A quarter-circle arc (the top-right quadrant) centered at the bottom-left
157
- * `origin` point. Produced by clipping a full bordered circle to one quadrant.
198
+ * A quarter-circle arc (the up-right quadrant) centered at (cx, cy). Rendered as
199
+ * a circle with only its top border colored, rotated 45° so the visible cap
200
+ * faces up-and-to-the-right — i.e. radiating from the bottom-left dot.
158
201
  */
159
- function Arc({
160
- origin,
202
+ function RippleArc({
203
+ cx,
204
+ cy,
161
205
  radius,
162
206
  stroke,
163
207
  color,
164
208
  }: {
165
- origin: number
209
+ cx: number
210
+ cy: number
166
211
  radius: number
167
212
  stroke: number
168
213
  color: string
169
214
  }): React.ReactElement {
170
215
  return (
171
216
  <View
172
- // Clip box reveals only the quadrant facing up-and-right from the origin.
173
217
  style={{
174
218
  position: 'absolute',
175
- left: origin,
176
- bottom: origin - radius,
177
- width: radius,
178
- height: radius,
179
- overflow: 'hidden',
219
+ left: cx - radius,
220
+ top: cy - radius,
221
+ width: radius * 2,
222
+ height: radius * 2,
223
+ borderRadius: radius,
224
+ borderWidth: stroke,
225
+ borderTopColor: color,
226
+ borderRightColor: 'transparent',
227
+ borderBottomColor: 'transparent',
228
+ borderLeftColor: 'transparent',
229
+ transform: [{ rotate: '45deg' }],
180
230
  }}
181
- >
182
- <View
183
- style={{
184
- position: 'absolute',
185
- left: -radius,
186
- top: 0,
187
- width: radius * 2,
188
- height: radius * 2,
189
- borderRadius: radius,
190
- borderWidth: stroke,
191
- borderColor: color,
192
- }}
193
- />
194
- </View>
231
+ />
195
232
  )
196
233
  }