add download event (#1797)
This commit is contained in:
parent
f2b0915aff
commit
b378827b83
@ -73,7 +73,7 @@ export const getToken = () => {
|
|||||||
* @param delta The delta to apply.
|
* @param delta The delta to apply.
|
||||||
*/
|
*/
|
||||||
export const applyDelta = (state, delta) => {
|
export const applyDelta = (state, delta) => {
|
||||||
const new_state = {...state}
|
const new_state = { ...state }
|
||||||
for (const substate in delta) {
|
for (const substate in delta) {
|
||||||
let s = new_state;
|
let s = new_state;
|
||||||
const path = substate.split(".").slice(1);
|
const path = substate.split(".").slice(1);
|
||||||
@ -153,6 +153,15 @@ export const applyEvent = async (event, socket) => {
|
|||||||
navigator.clipboard.writeText(content);
|
navigator.clipboard.writeText(content);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (event.name == "_download") {
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.hidden = true;
|
||||||
|
a.href = event.payload.url;
|
||||||
|
a.download = event.payload.filename;
|
||||||
|
a.click();
|
||||||
|
a.remove();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (event.name == "_alert") {
|
if (event.name == "_alert") {
|
||||||
alert(event.payload.message);
|
alert(event.payload.message);
|
||||||
@ -413,7 +422,7 @@ const applyClientStorageDelta = (client_storage, delta) => {
|
|||||||
for (const key in delta[substate]) {
|
for (const key in delta[substate]) {
|
||||||
const state_key = `${substate}.${key}`
|
const state_key = `${substate}.${key}`
|
||||||
if (client_storage.cookies && state_key in client_storage.cookies) {
|
if (client_storage.cookies && state_key in client_storage.cookies) {
|
||||||
const cookie_options = {...client_storage.cookies[state_key]}
|
const cookie_options = { ...client_storage.cookies[state_key] }
|
||||||
const cookie_name = cookie_options.name || state_key
|
const cookie_name = cookie_options.name || state_key
|
||||||
delete cookie_options.name // name is not a valid cookie option
|
delete cookie_options.name // name is not a valid cookie option
|
||||||
cookies.set(cookie_name, delta[substate][key], cookie_options);
|
cookies.set(cookie_name, delta[substate][key], cookie_options);
|
||||||
@ -445,18 +454,18 @@ export const useEventLoop = (
|
|||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const [state, dispatch] = useReducer(applyDelta, initial_state)
|
const [state, dispatch] = useReducer(applyDelta, initial_state)
|
||||||
const [connectError, setConnectError] = useState(null)
|
const [connectError, setConnectError] = useState(null)
|
||||||
|
|
||||||
// Function to add new events to the event queue.
|
// Function to add new events to the event queue.
|
||||||
const Event = (events, _e) => {
|
const Event = (events, _e) => {
|
||||||
preventDefault(_e);
|
preventDefault(_e);
|
||||||
queueEvents(events, socket)
|
queueEvents(events, socket)
|
||||||
}
|
}
|
||||||
|
|
||||||
const sentHydrate = useRef(false); // Avoid double-hydrate due to React strict-mode
|
const sentHydrate = useRef(false); // Avoid double-hydrate due to React strict-mode
|
||||||
// initial state hydrate
|
// initial state hydrate
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (router.isReady && !sentHydrate.current) {
|
if (router.isReady && !sentHydrate.current) {
|
||||||
Event(initial_events.map((e) => ({...e})))
|
Event(initial_events.map((e) => ({ ...e })))
|
||||||
sentHydrate.current = true
|
sentHydrate.current = true
|
||||||
}
|
}
|
||||||
}, [router.isReady])
|
}, [router.isReady])
|
||||||
|
@ -23,6 +23,7 @@ from .event import EventChain as EventChain
|
|||||||
from .event import FileUpload as upload_files
|
from .event import FileUpload as upload_files
|
||||||
from .event import clear_local_storage as clear_local_storage
|
from .event import clear_local_storage as clear_local_storage
|
||||||
from .event import console_log as console_log
|
from .event import console_log as console_log
|
||||||
|
from .event import download as download
|
||||||
from .event import redirect as redirect
|
from .event import redirect as redirect
|
||||||
from .event import remove_cookie as remove_cookie
|
from .event import remove_cookie as remove_cookie
|
||||||
from .event import remove_local_storage as remove_local_storage
|
from .event import remove_local_storage as remove_local_storage
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import inspect
|
import inspect
|
||||||
from typing import Any, Callable, Dict, List, Tuple
|
from typing import Any, Callable, Dict, List, Optional, Tuple
|
||||||
|
|
||||||
from reflex import constants
|
from reflex import constants
|
||||||
from reflex.base import Base
|
from reflex.base import Base
|
||||||
@ -330,6 +330,34 @@ def set_clipboard(content: str) -> EventSpec:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def download(url: str, filename: Optional[str] = None) -> EventSpec:
|
||||||
|
"""Download the file at a given path.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
url : The URL to the file to download.
|
||||||
|
filename : The name that the file should be saved as after download.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValueError: If the URL provided is invalid.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
EventSpec: An event to download the associated file.
|
||||||
|
"""
|
||||||
|
if not url.startswith("/"):
|
||||||
|
raise ValueError("The URL argument should start with a /")
|
||||||
|
|
||||||
|
# if filename is not provided, infer it from url
|
||||||
|
if filename is None:
|
||||||
|
filename = url.rpartition("/")[-1]
|
||||||
|
|
||||||
|
return server_side(
|
||||||
|
"_download",
|
||||||
|
get_fn_signature(download),
|
||||||
|
url=url,
|
||||||
|
filename=filename,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_event(state, event):
|
def get_event(state, event):
|
||||||
"""Get the event from the given state.
|
"""Get the event from the given state.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user