From 8947c26c7e5b44b710a0777dfd5d4db87752c755 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Brand=C3=A9ho?= Date: Fri, 16 Jun 2023 22:40:25 +0200 Subject: [PATCH] add server_side event for cookie and local storage (#1206) --- pynecone/.templates/web/package.json | 1 + pynecone/.templates/web/utils/state.js | 14 ++++++++++ pynecone/__init__.py | 2 ++ pynecone/event.py | 36 ++++++++++++++++++++++++++ tests/test_event.py | 30 +++++++++++++++++++++ 5 files changed, 83 insertions(+) diff --git a/pynecone/.templates/web/package.json b/pynecone/.templates/web/package.json index 1e7c14d7b..03a569a65 100644 --- a/pynecone/.templates/web/package.json +++ b/pynecone/.templates/web/package.json @@ -16,6 +16,7 @@ "focus-visible": "^5.2.0", "framer-motion": "^10.12.4", "gridjs": "^6.0.6", + "universal-cookie": "^4.0.4", "gridjs-react": "^6.0.1", "json5": "^2.2.3", "next": "^13.3.1", diff --git a/pynecone/.templates/web/utils/state.js b/pynecone/.templates/web/utils/state.js index 3f51689a2..ec6ebe8f3 100644 --- a/pynecone/.templates/web/utils/state.js +++ b/pynecone/.templates/web/utils/state.js @@ -3,6 +3,8 @@ import axios from "axios"; import io from "socket.io-client"; import JSON5 from "json5"; import env from "env.json"; +import Cookies from "universal-cookie"; + // Endpoint URLs. const PINGURL = env.pingUrl @@ -94,6 +96,18 @@ export const applyEvent = async (event, router, socket) => { return false; } + if (event.name == "_set_cookie") { + const cookies = new Cookies(); + cookies.set(event.payload.key, event.payload.value); + localStorage.setItem(event.payload.key, event.payload.value); + return false; + } + + if (event.name == "_set_local_storage") { + localStorage.setItem(event.payload.key, event.payload.value); + return false; + } + if (event.name == "_alert") { alert(event.payload.message); return false; diff --git a/pynecone/__init__.py b/pynecone/__init__.py index 0341a890c..e4ebf698a 100644 --- a/pynecone/__init__.py +++ b/pynecone/__init__.py @@ -23,7 +23,9 @@ from .event import EventChain as EventChain from .event import FileUpload as upload_files from .event import console_log as console_log from .event import redirect as redirect +from .event import set_cookie as set_cookie from .event import set_focus as set_focus +from .event import set_local_storage as set_local_storage from .event import set_value as set_value from .event import window_alert as window_alert from .middleware import Middleware as Middleware diff --git a/pynecone/event.py b/pynecone/event.py index d9d3d0de7..86400ddec 100644 --- a/pynecone/event.py +++ b/pynecone/event.py @@ -236,6 +236,42 @@ def set_value(ref: str, value: Any) -> EventSpec: ) +def set_cookie(key: str, value: str) -> EventSpec: + """Set a cookie on the frontend. + + Args: + key (str): The key identifying the cookie. + value (str): The value contained in the cookie. + + Returns: + EventSpec: An event to set a cookie. + """ + return server_side( + "_set_cookie", + get_fn_signature(set_cookie), + key=key, + value=value, + ) + + +def set_local_storage(key: str, value: str) -> EventSpec: + """Set a value in the local storage on the frontend. + + Args: + key (str): The key identifying the variable in the local storage. + value (str): The value contained in the local storage. + + Returns: + EventSpec: An event to set a key-value in local storage. + """ + return server_side( + "_set_local_storage", + get_fn_signature(set_local_storage), + key=key, + value=value, + ) + + def get_event(state, event): """Get the event from the given state. diff --git a/tests/test_event.py b/tests/test_event.py index 9e29a64ce..88e7e3626 100644 --- a/tests/test_event.py +++ b/tests/test_event.py @@ -143,3 +143,33 @@ def test_set_value(): assert ( format.format_event(spec) == 'E("_set_value", {ref:ref_input1,value:message})' ) + + +def test_set_cookie(): + """Test the event set_cookie.""" + spec = event.set_cookie("testkey", "testvalue") + assert isinstance(spec, EventSpec) + assert spec.handler.fn.__qualname__ == "_set_cookie" + assert spec.args == ( + ("key", "testkey"), + ("value", "testvalue"), + ) + assert ( + format.format_event(spec) + == 'E("_set_cookie", {key:"testkey",value:"testvalue"})' + ) + + +def test_set_local_storage(): + """Test the event set_local_storage.""" + spec = event.set_local_storage("testkey", "testvalue") + assert isinstance(spec, EventSpec) + assert spec.handler.fn.__qualname__ == "_set_local_storage" + assert spec.args == ( + ("key", "testkey"), + ("value", "testvalue"), + ) + assert ( + format.format_event(spec) + == 'E("_set_local_storage", {key:"testkey",value:"testvalue"})' + )