reflex 0.8.12a1__py3-none-any.whl → 0.8.13__py3-none-any.whl
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.
Potentially problematic release.
This version of reflex might be problematic. Click here for more details.
- reflex/.templates/web/utils/state.js +48 -17
- reflex/app.py +17 -12
- reflex/app_mixins/lifespan.py +11 -0
- reflex/compiler/compiler.py +4 -1
- reflex/components/core/upload.py +53 -14
- reflex/components/core/upload.pyi +8 -0
- reflex/components/react_player/audio.pyi +23 -46
- reflex/components/react_player/react_player.py +159 -19
- reflex/components/react_player/react_player.pyi +40 -45
- reflex/components/react_player/video.pyi +23 -46
- reflex/components/recharts/recharts.py +2 -2
- reflex/constants/colors.py +3 -1
- reflex/constants/installer.py +2 -2
- reflex/environment.py +3 -0
- reflex/istate/proxy.py +36 -36
- reflex/plugins/shared_tailwind.py +1 -1
- reflex/reflex.py +54 -3
- reflex/state.py +15 -5
- reflex/testing.py +14 -0
- reflex/utils/build.py +77 -57
- reflex/utils/exec.py +12 -0
- reflex/utils/export.py +7 -2
- reflex/utils/prerequisites.py +82 -7
- reflex/utils/serializers.py +8 -4
- reflex/utils/token_manager.py +10 -0
- reflex/utils/types.py +2 -0
- reflex/vars/__init__.py +56 -26
- reflex/vars/base.py +20 -113
- reflex/vars/color.py +214 -0
- reflex/vars/number.py +2 -2
- reflex/vars/sequence.py +0 -136
- {reflex-0.8.12a1.dist-info → reflex-0.8.13.dist-info}/METADATA +1 -1
- {reflex-0.8.12a1.dist-info → reflex-0.8.13.dist-info}/RECORD +36 -35
- {reflex-0.8.12a1.dist-info → reflex-0.8.13.dist-info}/WHEEL +0 -0
- {reflex-0.8.12a1.dist-info → reflex-0.8.13.dist-info}/entry_points.txt +0 -0
- {reflex-0.8.12a1.dist-info → reflex-0.8.13.dist-info}/licenses/LICENSE +0 -0
|
@@ -4,9 +4,14 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from typing import Any, TypedDict
|
|
6
6
|
|
|
7
|
-
from reflex.components.component import
|
|
8
|
-
from reflex.
|
|
7
|
+
from reflex.components.component import Component
|
|
8
|
+
from reflex.components.core.cond import cond
|
|
9
|
+
from reflex.event import EventHandler, no_args_event_spec
|
|
10
|
+
from reflex.utils import console
|
|
9
11
|
from reflex.vars.base import Var
|
|
12
|
+
from reflex.vars.object import ObjectVar
|
|
13
|
+
|
|
14
|
+
ReactPlayerEvent = ObjectVar[dict[str, dict[str, dict[str, Any]]]]
|
|
10
15
|
|
|
11
16
|
|
|
12
17
|
class Progress(TypedDict):
|
|
@@ -16,21 +21,123 @@ class Progress(TypedDict):
|
|
|
16
21
|
playedSeconds: float
|
|
17
22
|
loaded: float
|
|
18
23
|
loadedSeconds: float
|
|
24
|
+
duration: float
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _on_progress_signature(event: ReactPlayerEvent) -> list[Var[Progress]]:
|
|
28
|
+
"""Type signature for on_progress event.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
event: The event variable.
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
The progress information extracted from the event.
|
|
35
|
+
"""
|
|
36
|
+
player_info = event["target"]["api"]["playerInfo"].to(dict)
|
|
37
|
+
progress_state = player_info["progressState"].to(dict)
|
|
38
|
+
current = progress_state["current"].to(float)
|
|
39
|
+
loaded = progress_state["loaded"].to(float)
|
|
40
|
+
duration = progress_state["duration"].to(float)
|
|
41
|
+
return [
|
|
42
|
+
cond(
|
|
43
|
+
progress_state,
|
|
44
|
+
{
|
|
45
|
+
"played": cond(duration, current / duration, 0.0),
|
|
46
|
+
"playedSeconds": current,
|
|
47
|
+
"loaded": cond(duration, loaded / duration, 0.0),
|
|
48
|
+
"loadedSeconds": loaded,
|
|
49
|
+
"duration": duration,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"played": 0.0,
|
|
53
|
+
"playedSeconds": 0.0,
|
|
54
|
+
"loaded": 0.0,
|
|
55
|
+
"loadedSeconds": 0.0,
|
|
56
|
+
"duration": 0.0,
|
|
57
|
+
},
|
|
58
|
+
).to(Progress)
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _player_info_key_or_zero(event: ReactPlayerEvent, key: str) -> Var[float]:
|
|
63
|
+
"""Helper to extract a value from playerInfo or return 0.0 if not available.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
event: The event variable.
|
|
67
|
+
key: The key to extract from playerInfo.
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
The extracted value or 0.0 if not available.
|
|
71
|
+
"""
|
|
72
|
+
player_info = event["target"]["api"]["playerInfo"].to(dict)
|
|
73
|
+
return cond(
|
|
74
|
+
player_info[key],
|
|
75
|
+
player_info[key],
|
|
76
|
+
0.0,
|
|
77
|
+
).to(float)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _on_time_update_signature(event: ReactPlayerEvent) -> list[Var[float]]:
|
|
81
|
+
"""Type signature for on_time_update event.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
event: The event variable.
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
The current timestamp in seconds.
|
|
88
|
+
"""
|
|
89
|
+
return [_player_info_key_or_zero(event, "currentTime")]
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _on_duration_change_signature(event: ReactPlayerEvent) -> list[Var[float]]:
|
|
93
|
+
"""Type signature for on_duration_change event.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
event: The event variable.
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
The active media's duration in seconds.
|
|
100
|
+
"""
|
|
101
|
+
return [_player_info_key_or_zero(event, "duration")]
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def _on_rate_change_signature(event: ReactPlayerEvent) -> list[Var[float]]:
|
|
105
|
+
"""Type signature for on_rate_change event.
|
|
19
106
|
|
|
107
|
+
Args:
|
|
108
|
+
event: The event variable.
|
|
20
109
|
|
|
21
|
-
|
|
110
|
+
Returns:
|
|
111
|
+
The current playback rate.
|
|
112
|
+
"""
|
|
113
|
+
return [_player_info_key_or_zero(event, "playbackRate")]
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
_DEPRECATED_PROP_MAP = {
|
|
117
|
+
"url": "src",
|
|
118
|
+
"on_duration": "on_duration_change",
|
|
119
|
+
"on_playback_rate_change": "on_rate_change",
|
|
120
|
+
"on_seek": "on_seeked",
|
|
121
|
+
"on_buffer": "on_waiting",
|
|
122
|
+
"on_buffer_end": "on_playing",
|
|
123
|
+
"on_enable_pip": "on_enter_picture_in_picture",
|
|
124
|
+
"on_disable_pip": "on_leave_picture_in_picture",
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class ReactPlayer(Component):
|
|
22
129
|
"""Using react-player and not implement all props and callback yet.
|
|
23
130
|
reference: https://github.com/cookpete/react-player.
|
|
24
131
|
"""
|
|
25
132
|
|
|
26
|
-
library = "react-player@
|
|
133
|
+
library = "react-player@3.3.3"
|
|
27
134
|
|
|
28
135
|
tag = "ReactPlayer"
|
|
29
136
|
|
|
30
137
|
is_default = True
|
|
31
138
|
|
|
32
139
|
# The url of a video or song to play
|
|
33
|
-
|
|
140
|
+
src: Var[str | list[str] | list[dict[str, str]]]
|
|
34
141
|
|
|
35
142
|
# Set to true or false to pause or play the media
|
|
36
143
|
playing: Var[bool]
|
|
@@ -50,38 +157,44 @@ class ReactPlayer(NoSSRComponent):
|
|
|
50
157
|
# Mutes the player
|
|
51
158
|
muted: Var[bool]
|
|
52
159
|
|
|
160
|
+
# Player-specific configuration parameters.
|
|
161
|
+
config: Var[dict[str, Any]]
|
|
162
|
+
|
|
53
163
|
# Called when media is loaded and ready to play. If playing is set to true, media will play immediately.
|
|
54
164
|
on_ready: EventHandler[no_args_event_spec]
|
|
55
165
|
|
|
56
166
|
# Called when media starts playing.
|
|
57
167
|
on_start: EventHandler[no_args_event_spec]
|
|
58
168
|
|
|
59
|
-
# Called when
|
|
169
|
+
# Called when playing is set to true.
|
|
60
170
|
on_play: EventHandler[no_args_event_spec]
|
|
61
171
|
|
|
62
|
-
#
|
|
63
|
-
|
|
172
|
+
# Called when media starts or resumes playing after pausing or buffering.
|
|
173
|
+
on_playing: EventHandler[no_args_event_spec]
|
|
174
|
+
|
|
175
|
+
# Called while the video is loading only. Contains played and loaded progress as a fraction, and playedSeconds and loadedSeconds in seconds. eg { played: 0.12, playedSeconds: 11.3, loaded: 0.34, loadedSeconds: 16.7 }
|
|
176
|
+
on_progress: EventHandler[_on_progress_signature]
|
|
177
|
+
|
|
178
|
+
# Called when the media's current time changes (~4Hz, use .throttle to limit calls to backend).
|
|
179
|
+
on_time_update: EventHandler[_on_time_update_signature]
|
|
64
180
|
|
|
65
181
|
# Callback containing duration of the media, in seconds.
|
|
66
|
-
|
|
182
|
+
on_duration_change: EventHandler[_on_duration_change_signature]
|
|
67
183
|
|
|
68
184
|
# Called when media is paused.
|
|
69
185
|
on_pause: EventHandler[no_args_event_spec]
|
|
70
186
|
|
|
71
187
|
# Called when media starts buffering.
|
|
72
|
-
|
|
188
|
+
on_waiting: EventHandler[no_args_event_spec]
|
|
73
189
|
|
|
74
|
-
# Called when media
|
|
75
|
-
|
|
190
|
+
# Called when the media is seeking.
|
|
191
|
+
on_seeking: EventHandler[no_args_event_spec]
|
|
76
192
|
|
|
77
193
|
# Called when media seeks with seconds parameter.
|
|
78
|
-
|
|
194
|
+
on_seeked: EventHandler[_on_time_update_signature]
|
|
79
195
|
|
|
80
196
|
# Called when playback rate of the player changed. Only supported by YouTube, Vimeo (if enabled), Wistia, and file paths.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
# Called when playback quality of the player changed. Only supported by YouTube (if enabled).
|
|
84
|
-
on_playback_quality_change: EventHandler[no_args_event_spec]
|
|
197
|
+
on_rate_change: EventHandler[_on_rate_change_signature]
|
|
85
198
|
|
|
86
199
|
# Called when media finishes playing. Does not fire when loop is set to true.
|
|
87
200
|
on_ended: EventHandler[no_args_event_spec]
|
|
@@ -93,10 +206,37 @@ class ReactPlayer(NoSSRComponent):
|
|
|
93
206
|
on_click_preview: EventHandler[no_args_event_spec]
|
|
94
207
|
|
|
95
208
|
# Called when picture-in-picture mode is enabled.
|
|
96
|
-
|
|
209
|
+
on_enter_picture_in_picture: EventHandler[no_args_event_spec]
|
|
97
210
|
|
|
98
211
|
# Called when picture-in-picture mode is disabled.
|
|
99
|
-
|
|
212
|
+
on_leave_picture_in_picture: EventHandler[no_args_event_spec]
|
|
213
|
+
|
|
214
|
+
@classmethod
|
|
215
|
+
def create(cls, *children, **props) -> ReactPlayer:
|
|
216
|
+
"""Create a component.
|
|
217
|
+
|
|
218
|
+
Args:
|
|
219
|
+
children: The children of the component.
|
|
220
|
+
props: The props of the component.
|
|
221
|
+
|
|
222
|
+
Returns:
|
|
223
|
+
The created component.
|
|
224
|
+
|
|
225
|
+
Raises:
|
|
226
|
+
ValueError: If both a deprecated prop and its replacement are both passed.
|
|
227
|
+
"""
|
|
228
|
+
for prop, new_prop in _DEPRECATED_PROP_MAP.items():
|
|
229
|
+
if prop in props:
|
|
230
|
+
if new_prop in props:
|
|
231
|
+
msg = (
|
|
232
|
+
f"The prop {prop!r} is deprecated, but the replacement {new_prop!r} is also passed. Please remove {prop!r}.",
|
|
233
|
+
)
|
|
234
|
+
raise ValueError(msg)
|
|
235
|
+
console.warn(
|
|
236
|
+
f"The prop {prop!r} has been replaced by {new_prop!r}, please update your code.",
|
|
237
|
+
)
|
|
238
|
+
props[new_prop] = props.pop(prop)
|
|
239
|
+
return super().create(*children, **props) # type: ignore[return-value]
|
|
100
240
|
|
|
101
241
|
def _render(self, props: dict[str, Any] | None = None):
|
|
102
242
|
"""Render the component. Adds width and height set to None because
|
|
@@ -6,29 +6,49 @@
|
|
|
6
6
|
from collections.abc import Mapping, Sequence
|
|
7
7
|
from typing import Any, TypedDict
|
|
8
8
|
|
|
9
|
-
from reflex.components.component import
|
|
9
|
+
from reflex.components.component import Component
|
|
10
10
|
from reflex.components.core.breakpoints import Breakpoints
|
|
11
11
|
from reflex.event import EventType, PointerEventInfo
|
|
12
12
|
from reflex.vars.base import Var
|
|
13
|
+
from reflex.vars.object import ObjectVar
|
|
14
|
+
|
|
15
|
+
ReactPlayerEvent = ObjectVar[dict[str, dict[str, dict[str, Any]]]]
|
|
13
16
|
|
|
14
17
|
class Progress(TypedDict):
|
|
15
18
|
played: float
|
|
16
19
|
playedSeconds: float
|
|
17
20
|
loaded: float
|
|
18
21
|
loadedSeconds: float
|
|
22
|
+
duration: float
|
|
23
|
+
|
|
24
|
+
_DEPRECATED_PROP_MAP = {
|
|
25
|
+
"url": "src",
|
|
26
|
+
"on_duration": "on_duration_change",
|
|
27
|
+
"on_playback_rate_change": "on_rate_change",
|
|
28
|
+
"on_seek": "on_seeked",
|
|
29
|
+
"on_buffer": "on_waiting",
|
|
30
|
+
"on_buffer_end": "on_playing",
|
|
31
|
+
"on_enable_pip": "on_enter_picture_in_picture",
|
|
32
|
+
"on_disable_pip": "on_leave_picture_in_picture",
|
|
33
|
+
}
|
|
19
34
|
|
|
20
|
-
class ReactPlayer(
|
|
35
|
+
class ReactPlayer(Component):
|
|
21
36
|
@classmethod
|
|
22
37
|
def create(
|
|
23
38
|
cls,
|
|
24
39
|
*children,
|
|
25
|
-
|
|
40
|
+
src: Var[list[dict[str, str]] | list[str] | str]
|
|
41
|
+
| list[dict[str, str]]
|
|
42
|
+
| list[str]
|
|
43
|
+
| str
|
|
44
|
+
| None = None,
|
|
26
45
|
playing: Var[bool] | bool | None = None,
|
|
27
46
|
loop: Var[bool] | bool | None = None,
|
|
28
47
|
controls: Var[bool] | bool | None = None,
|
|
29
48
|
light: Var[bool] | bool | None = None,
|
|
30
49
|
volume: Var[float] | float | None = None,
|
|
31
50
|
muted: Var[bool] | bool | None = None,
|
|
51
|
+
config: Var[dict[str, Any]] | dict[str, Any] | None = None,
|
|
32
52
|
style: Sequence[Mapping[str, Any]]
|
|
33
53
|
| Mapping[str, Any]
|
|
34
54
|
| Var[Mapping[str, Any]]
|
|
@@ -40,18 +60,16 @@ class ReactPlayer(NoSSRComponent):
|
|
|
40
60
|
class_name: Any | None = None,
|
|
41
61
|
custom_attrs: dict[str, Var | Any] | None = None,
|
|
42
62
|
on_blur: EventType[()] | None = None,
|
|
43
|
-
on_buffer: EventType[()] | None = None,
|
|
44
|
-
on_buffer_end: EventType[()] | None = None,
|
|
45
63
|
on_click: EventType[()] | EventType[PointerEventInfo] | None = None,
|
|
46
64
|
on_click_preview: EventType[()] | None = None,
|
|
47
65
|
on_context_menu: EventType[()] | EventType[PointerEventInfo] | None = None,
|
|
48
|
-
on_disable_pip: EventType[()] | None = None,
|
|
49
66
|
on_double_click: EventType[()] | EventType[PointerEventInfo] | None = None,
|
|
50
|
-
|
|
51
|
-
on_enable_pip: EventType[()] | None = None,
|
|
67
|
+
on_duration_change: EventType[Any] | None = None,
|
|
52
68
|
on_ended: EventType[()] | None = None,
|
|
69
|
+
on_enter_picture_in_picture: EventType[()] | None = None,
|
|
53
70
|
on_error: EventType[()] | None = None,
|
|
54
71
|
on_focus: EventType[()] | None = None,
|
|
72
|
+
on_leave_picture_in_picture: EventType[()] | None = None,
|
|
55
73
|
on_mount: EventType[()] | None = None,
|
|
56
74
|
on_mouse_down: EventType[()] | None = None,
|
|
57
75
|
on_mouse_enter: EventType[()] | None = None,
|
|
@@ -62,52 +80,29 @@ class ReactPlayer(NoSSRComponent):
|
|
|
62
80
|
on_mouse_up: EventType[()] | None = None,
|
|
63
81
|
on_pause: EventType[()] | None = None,
|
|
64
82
|
on_play: EventType[()] | None = None,
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
83
|
+
on_playing: EventType[()] | None = None,
|
|
84
|
+
on_progress: EventType[Any] | None = None,
|
|
85
|
+
on_rate_change: EventType[Any] | None = None,
|
|
68
86
|
on_ready: EventType[()] | None = None,
|
|
69
87
|
on_scroll: EventType[()] | None = None,
|
|
70
88
|
on_scroll_end: EventType[()] | None = None,
|
|
71
|
-
|
|
89
|
+
on_seeked: EventType[Any] | None = None,
|
|
90
|
+
on_seeking: EventType[()] | None = None,
|
|
72
91
|
on_start: EventType[()] | None = None,
|
|
92
|
+
on_time_update: EventType[Any] | None = None,
|
|
73
93
|
on_unmount: EventType[()] | None = None,
|
|
94
|
+
on_waiting: EventType[()] | None = None,
|
|
74
95
|
**props,
|
|
75
96
|
) -> ReactPlayer:
|
|
76
|
-
"""Create
|
|
97
|
+
"""Create a component.
|
|
77
98
|
|
|
78
99
|
Args:
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
playing: Set to true or false to pause or play the media
|
|
82
|
-
loop: Set to true or false to loop the media
|
|
83
|
-
controls: Set to true or false to display native player controls.
|
|
84
|
-
light: Set to true to show just the video thumbnail, which loads the full player on click
|
|
85
|
-
volume: Set the volume of the player, between 0 and 1
|
|
86
|
-
muted: Mutes the player
|
|
87
|
-
on_ready: Called when media is loaded and ready to play. If playing is set to true, media will play immediately.
|
|
88
|
-
on_start: Called when media starts playing.
|
|
89
|
-
on_play: Called when media starts or resumes playing after pausing or buffering.
|
|
90
|
-
on_progress: Callback containing played and loaded progress as a fraction, and playedSeconds and loadedSeconds in seconds. eg { played: 0.12, playedSeconds: 11.3, loaded: 0.34, loadedSeconds: 16.7 }
|
|
91
|
-
on_duration: Callback containing duration of the media, in seconds.
|
|
92
|
-
on_pause: Called when media is paused.
|
|
93
|
-
on_buffer: Called when media starts buffering.
|
|
94
|
-
on_buffer_end: Called when media has finished buffering. Works for files, YouTube and Facebook.
|
|
95
|
-
on_seek: Called when media seeks with seconds parameter.
|
|
96
|
-
on_playback_rate_change: Called when playback rate of the player changed. Only supported by YouTube, Vimeo (if enabled), Wistia, and file paths.
|
|
97
|
-
on_playback_quality_change: Called when playback quality of the player changed. Only supported by YouTube (if enabled).
|
|
98
|
-
on_ended: Called when media finishes playing. Does not fire when loop is set to true.
|
|
99
|
-
on_error: Called when an error occurs whilst attempting to play media.
|
|
100
|
-
on_click_preview: Called when user clicks the light mode preview.
|
|
101
|
-
on_enable_pip: Called when picture-in-picture mode is enabled.
|
|
102
|
-
on_disable_pip: Called when picture-in-picture mode is disabled.
|
|
103
|
-
style: The style of the component.
|
|
104
|
-
key: A unique key for the component.
|
|
105
|
-
id: The id for the component.
|
|
106
|
-
ref: The Var to pass as the ref to the component.
|
|
107
|
-
class_name: The class name for the component.
|
|
108
|
-
custom_attrs: custom attribute
|
|
109
|
-
**props: The props of the component.
|
|
100
|
+
children: The children of the component.
|
|
101
|
+
props: The props of the component.
|
|
110
102
|
|
|
111
103
|
Returns:
|
|
112
|
-
The component.
|
|
104
|
+
The created component.
|
|
105
|
+
|
|
106
|
+
Raises:
|
|
107
|
+
ValueError: If both a deprecated prop and its replacement are both passed.
|
|
113
108
|
"""
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
from collections.abc import Mapping, Sequence
|
|
7
7
|
from typing import Any
|
|
8
8
|
|
|
9
|
-
import reflex
|
|
10
9
|
from reflex.components.core.breakpoints import Breakpoints
|
|
11
10
|
from reflex.components.react_player.react_player import ReactPlayer
|
|
12
11
|
from reflex.event import EventType, PointerEventInfo
|
|
@@ -17,13 +16,18 @@ class Video(ReactPlayer):
|
|
|
17
16
|
def create(
|
|
18
17
|
cls,
|
|
19
18
|
*children,
|
|
20
|
-
|
|
19
|
+
src: Var[list[dict[str, str]] | list[str] | str]
|
|
20
|
+
| list[dict[str, str]]
|
|
21
|
+
| list[str]
|
|
22
|
+
| str
|
|
23
|
+
| None = None,
|
|
21
24
|
playing: Var[bool] | bool | None = None,
|
|
22
25
|
loop: Var[bool] | bool | None = None,
|
|
23
26
|
controls: Var[bool] | bool | None = None,
|
|
24
27
|
light: Var[bool] | bool | None = None,
|
|
25
28
|
volume: Var[float] | float | None = None,
|
|
26
29
|
muted: Var[bool] | bool | None = None,
|
|
30
|
+
config: Var[dict[str, Any]] | dict[str, Any] | None = None,
|
|
27
31
|
style: Sequence[Mapping[str, Any]]
|
|
28
32
|
| Mapping[str, Any]
|
|
29
33
|
| Var[Mapping[str, Any]]
|
|
@@ -35,18 +39,16 @@ class Video(ReactPlayer):
|
|
|
35
39
|
class_name: Any | None = None,
|
|
36
40
|
custom_attrs: dict[str, Var | Any] | None = None,
|
|
37
41
|
on_blur: EventType[()] | None = None,
|
|
38
|
-
on_buffer: EventType[()] | None = None,
|
|
39
|
-
on_buffer_end: EventType[()] | None = None,
|
|
40
42
|
on_click: EventType[()] | EventType[PointerEventInfo] | None = None,
|
|
41
43
|
on_click_preview: EventType[()] | None = None,
|
|
42
44
|
on_context_menu: EventType[()] | EventType[PointerEventInfo] | None = None,
|
|
43
|
-
on_disable_pip: EventType[()] | None = None,
|
|
44
45
|
on_double_click: EventType[()] | EventType[PointerEventInfo] | None = None,
|
|
45
|
-
|
|
46
|
-
on_enable_pip: EventType[()] | None = None,
|
|
46
|
+
on_duration_change: EventType[Any] | None = None,
|
|
47
47
|
on_ended: EventType[()] | None = None,
|
|
48
|
+
on_enter_picture_in_picture: EventType[()] | None = None,
|
|
48
49
|
on_error: EventType[()] | None = None,
|
|
49
50
|
on_focus: EventType[()] | None = None,
|
|
51
|
+
on_leave_picture_in_picture: EventType[()] | None = None,
|
|
50
52
|
on_mount: EventType[()] | None = None,
|
|
51
53
|
on_mouse_down: EventType[()] | None = None,
|
|
52
54
|
on_mouse_enter: EventType[()] | None = None,
|
|
@@ -57,54 +59,29 @@ class Video(ReactPlayer):
|
|
|
57
59
|
on_mouse_up: EventType[()] | None = None,
|
|
58
60
|
on_pause: EventType[()] | None = None,
|
|
59
61
|
on_play: EventType[()] | None = None,
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
| EventType[reflex.components.react_player.react_player.Progress]
|
|
64
|
-
| None = None,
|
|
62
|
+
on_playing: EventType[()] | None = None,
|
|
63
|
+
on_progress: EventType[Any] | None = None,
|
|
64
|
+
on_rate_change: EventType[Any] | None = None,
|
|
65
65
|
on_ready: EventType[()] | None = None,
|
|
66
66
|
on_scroll: EventType[()] | None = None,
|
|
67
67
|
on_scroll_end: EventType[()] | None = None,
|
|
68
|
-
|
|
68
|
+
on_seeked: EventType[Any] | None = None,
|
|
69
|
+
on_seeking: EventType[()] | None = None,
|
|
69
70
|
on_start: EventType[()] | None = None,
|
|
71
|
+
on_time_update: EventType[Any] | None = None,
|
|
70
72
|
on_unmount: EventType[()] | None = None,
|
|
73
|
+
on_waiting: EventType[()] | None = None,
|
|
71
74
|
**props,
|
|
72
75
|
) -> Video:
|
|
73
|
-
"""Create
|
|
76
|
+
"""Create a component.
|
|
74
77
|
|
|
75
78
|
Args:
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
playing: Set to true or false to pause or play the media
|
|
79
|
-
loop: Set to true or false to loop the media
|
|
80
|
-
controls: Set to true or false to display native player controls.
|
|
81
|
-
light: Set to true to show just the video thumbnail, which loads the full player on click
|
|
82
|
-
volume: Set the volume of the player, between 0 and 1
|
|
83
|
-
muted: Mutes the player
|
|
84
|
-
on_ready: Called when media is loaded and ready to play. If playing is set to true, media will play immediately.
|
|
85
|
-
on_start: Called when media starts playing.
|
|
86
|
-
on_play: Called when media starts or resumes playing after pausing or buffering.
|
|
87
|
-
on_progress: Callback containing played and loaded progress as a fraction, and playedSeconds and loadedSeconds in seconds. eg { played: 0.12, playedSeconds: 11.3, loaded: 0.34, loadedSeconds: 16.7 }
|
|
88
|
-
on_duration: Callback containing duration of the media, in seconds.
|
|
89
|
-
on_pause: Called when media is paused.
|
|
90
|
-
on_buffer: Called when media starts buffering.
|
|
91
|
-
on_buffer_end: Called when media has finished buffering. Works for files, YouTube and Facebook.
|
|
92
|
-
on_seek: Called when media seeks with seconds parameter.
|
|
93
|
-
on_playback_rate_change: Called when playback rate of the player changed. Only supported by YouTube, Vimeo (if enabled), Wistia, and file paths.
|
|
94
|
-
on_playback_quality_change: Called when playback quality of the player changed. Only supported by YouTube (if enabled).
|
|
95
|
-
on_ended: Called when media finishes playing. Does not fire when loop is set to true.
|
|
96
|
-
on_error: Called when an error occurs whilst attempting to play media.
|
|
97
|
-
on_click_preview: Called when user clicks the light mode preview.
|
|
98
|
-
on_enable_pip: Called when picture-in-picture mode is enabled.
|
|
99
|
-
on_disable_pip: Called when picture-in-picture mode is disabled.
|
|
100
|
-
style: The style of the component.
|
|
101
|
-
key: A unique key for the component.
|
|
102
|
-
id: The id for the component.
|
|
103
|
-
ref: The Var to pass as the ref to the component.
|
|
104
|
-
class_name: The class name for the component.
|
|
105
|
-
custom_attrs: custom attribute
|
|
106
|
-
**props: The props of the component.
|
|
79
|
+
children: The children of the component.
|
|
80
|
+
props: The props of the component.
|
|
107
81
|
|
|
108
82
|
Returns:
|
|
109
|
-
The component.
|
|
83
|
+
The created component.
|
|
84
|
+
|
|
85
|
+
Raises:
|
|
86
|
+
ValueError: If both a deprecated prop and its replacement are both passed.
|
|
110
87
|
"""
|
|
@@ -8,7 +8,7 @@ from reflex.components.component import Component, MemoizationLeaf, NoSSRCompone
|
|
|
8
8
|
class Recharts(Component):
|
|
9
9
|
"""A component that wraps a recharts lib."""
|
|
10
10
|
|
|
11
|
-
library = "recharts@3.2.
|
|
11
|
+
library = "recharts@3.2.1"
|
|
12
12
|
|
|
13
13
|
def _get_style(self) -> dict:
|
|
14
14
|
return {"wrapperStyle": self.style}
|
|
@@ -17,7 +17,7 @@ class Recharts(Component):
|
|
|
17
17
|
class RechartsCharts(NoSSRComponent, MemoizationLeaf):
|
|
18
18
|
"""A component that wraps a recharts lib."""
|
|
19
19
|
|
|
20
|
-
library = "recharts@3.2.
|
|
20
|
+
library = "recharts@3.2.1"
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
LiteralAnimationEasing = Literal["ease", "ease-in", "ease-out", "ease-in-out", "linear"]
|
reflex/constants/colors.py
CHANGED
reflex/constants/installer.py
CHANGED
|
@@ -143,11 +143,11 @@ class PackageJson(SimpleNamespace):
|
|
|
143
143
|
"postcss-import": "16.1.1",
|
|
144
144
|
"@react-router/dev": _react_router_version,
|
|
145
145
|
"@react-router/fs-routes": _react_router_version,
|
|
146
|
-
"vite": "npm:rolldown-vite@7.1.
|
|
146
|
+
"vite": "npm:rolldown-vite@7.1.12",
|
|
147
147
|
}
|
|
148
148
|
OVERRIDES = {
|
|
149
149
|
# This should always match the `react` version in DEPENDENCIES for recharts compatibility.
|
|
150
150
|
"react-is": _react_version,
|
|
151
151
|
"cookie": "1.0.2",
|
|
152
|
-
"vite": "npm:rolldown-vite@7.1.
|
|
152
|
+
"vite": "npm:rolldown-vite@7.1.12",
|
|
153
153
|
}
|
reflex/environment.py
CHANGED
|
@@ -657,6 +657,9 @@ class EnvironmentVariables:
|
|
|
657
657
|
# Whether to force a full reload on changes.
|
|
658
658
|
VITE_FORCE_FULL_RELOAD: EnvVar[bool] = env_var(False)
|
|
659
659
|
|
|
660
|
+
# Whether to enable SSR for the frontend.
|
|
661
|
+
REFLEX_SSR: EnvVar[bool] = env_var(True)
|
|
662
|
+
|
|
660
663
|
|
|
661
664
|
environment = EnvironmentVariables()
|
|
662
665
|
|
reflex/istate/proxy.py
CHANGED
|
@@ -71,10 +71,15 @@ class StateProxy(wrapt.ObjectProxy):
|
|
|
71
71
|
state_instance: The state instance to proxy.
|
|
72
72
|
parent_state_proxy: The parent state proxy, for linked mutability and context tracking.
|
|
73
73
|
"""
|
|
74
|
+
from reflex.state import _substate_key
|
|
75
|
+
|
|
74
76
|
super().__init__(state_instance)
|
|
75
|
-
# compile is not relevant to backend logic
|
|
76
77
|
self._self_app = prerequisites.get_and_validate_app().app
|
|
77
78
|
self._self_substate_path = tuple(state_instance.get_full_name().split("."))
|
|
79
|
+
self._self_substate_token = _substate_key(
|
|
80
|
+
state_instance.router.session.client_token,
|
|
81
|
+
self._self_substate_path,
|
|
82
|
+
)
|
|
78
83
|
self._self_actx = None
|
|
79
84
|
self._self_mutable = False
|
|
80
85
|
self._self_actx_lock = asyncio.Lock()
|
|
@@ -127,16 +132,9 @@ class StateProxy(wrapt.ObjectProxy):
|
|
|
127
132
|
msg = "The state is already mutable. Do not nest `async with self` blocks."
|
|
128
133
|
raise ImmutableStateError(msg)
|
|
129
134
|
|
|
130
|
-
from reflex.state import _substate_key
|
|
131
|
-
|
|
132
135
|
await self._self_actx_lock.acquire()
|
|
133
136
|
self._self_actx_lock_holder = current_task
|
|
134
|
-
self._self_actx = self._self_app.modify_state(
|
|
135
|
-
token=_substate_key(
|
|
136
|
-
self.__wrapped__.router.session.client_token,
|
|
137
|
-
self._self_substate_path,
|
|
138
|
-
)
|
|
139
|
-
)
|
|
137
|
+
self._self_actx = self._self_app.modify_state(token=self._self_substate_token)
|
|
140
138
|
mutable_state = await self._self_actx.__aenter__()
|
|
141
139
|
super().__setattr__(
|
|
142
140
|
"__wrapped__", mutable_state.get_substate(self._self_substate_path)
|
|
@@ -378,17 +376,6 @@ class MutableProxy(wrapt.ObjectProxy):
|
|
|
378
376
|
pydantic.BaseModel.__dict__
|
|
379
377
|
)
|
|
380
378
|
|
|
381
|
-
# These types will be wrapped in MutableProxy
|
|
382
|
-
__mutable_types__ = (
|
|
383
|
-
list,
|
|
384
|
-
dict,
|
|
385
|
-
set,
|
|
386
|
-
Base,
|
|
387
|
-
DeclarativeBase,
|
|
388
|
-
BaseModelV2,
|
|
389
|
-
BaseModelV1,
|
|
390
|
-
)
|
|
391
|
-
|
|
392
379
|
# Dynamically generated classes for tracking dataclass mutations.
|
|
393
380
|
__dataclass_proxies__: dict[type, type] = {}
|
|
394
381
|
|
|
@@ -469,20 +456,6 @@ class MutableProxy(wrapt.ObjectProxy):
|
|
|
469
456
|
return wrapped(*args, **(kwargs or {}))
|
|
470
457
|
return None
|
|
471
458
|
|
|
472
|
-
@classmethod
|
|
473
|
-
def _is_mutable_type(cls, value: Any) -> bool:
|
|
474
|
-
"""Check if a value is of a mutable type and should be wrapped.
|
|
475
|
-
|
|
476
|
-
Args:
|
|
477
|
-
value: The value to check.
|
|
478
|
-
|
|
479
|
-
Returns:
|
|
480
|
-
Whether the value is of a mutable type.
|
|
481
|
-
"""
|
|
482
|
-
return isinstance(value, cls.__mutable_types__) or (
|
|
483
|
-
dataclasses.is_dataclass(value) and not isinstance(value, Var)
|
|
484
|
-
)
|
|
485
|
-
|
|
486
459
|
@staticmethod
|
|
487
460
|
def _is_called_from_dataclasses_internal() -> bool:
|
|
488
461
|
"""Check if the current function is called from dataclasses helper.
|
|
@@ -514,7 +487,7 @@ class MutableProxy(wrapt.ObjectProxy):
|
|
|
514
487
|
if self._is_called_from_dataclasses_internal():
|
|
515
488
|
return value
|
|
516
489
|
# Recursively wrap mutable types, but do not re-wrap MutableProxy instances.
|
|
517
|
-
if
|
|
490
|
+
if is_mutable_type(type(value)) and not isinstance(value, MutableProxy):
|
|
518
491
|
base_cls = globals()[self.__base_proxy__]
|
|
519
492
|
return base_cls(
|
|
520
493
|
wrapped=value,
|
|
@@ -575,7 +548,7 @@ class MutableProxy(wrapt.ObjectProxy):
|
|
|
575
548
|
self._wrap_recursive_decorator,
|
|
576
549
|
)
|
|
577
550
|
|
|
578
|
-
if
|
|
551
|
+
if is_mutable_type(type(value)) and __name not in (
|
|
579
552
|
"__wrapped__",
|
|
580
553
|
"_self_state",
|
|
581
554
|
"__dict__",
|
|
@@ -764,3 +737,30 @@ class ImmutableMutableProxy(MutableProxy):
|
|
|
764
737
|
return super()._mark_dirty(
|
|
765
738
|
wrapped=wrapped, instance=instance, args=args, kwargs=kwargs
|
|
766
739
|
)
|
|
740
|
+
|
|
741
|
+
|
|
742
|
+
# These types will be wrapped in MutableProxy
|
|
743
|
+
MUTABLE_TYPES = (
|
|
744
|
+
list,
|
|
745
|
+
dict,
|
|
746
|
+
set,
|
|
747
|
+
Base,
|
|
748
|
+
DeclarativeBase,
|
|
749
|
+
BaseModelV2,
|
|
750
|
+
BaseModelV1,
|
|
751
|
+
)
|
|
752
|
+
|
|
753
|
+
|
|
754
|
+
@functools.lru_cache(maxsize=1024)
|
|
755
|
+
def is_mutable_type(type_: type) -> bool:
|
|
756
|
+
"""Check if a type is mutable and should be wrapped.
|
|
757
|
+
|
|
758
|
+
Args:
|
|
759
|
+
type_: The type to check.
|
|
760
|
+
|
|
761
|
+
Returns:
|
|
762
|
+
Whether the type is mutable and should be wrapped.
|
|
763
|
+
"""
|
|
764
|
+
return issubclass(type_, MUTABLE_TYPES) or (
|
|
765
|
+
dataclasses.is_dataclass(type_) and not issubclass(type_, Var)
|
|
766
|
+
)
|