Created
September 16, 2022 03:42
-
-
Save zachdaniel/9d94489d72863768962f8f973fa7326b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule BetterComponent do | |
defmodule Live do | |
defmacro __using__(opts) do | |
quote do | |
import BetterComponent | |
use Surface.LiveComponent | |
def update(assigns, socket) do | |
case assigns[:__event__] do | |
event when is_binary(event) -> | |
case handle_event(event, assigns[:__event_payload__] || %{}, socket) do | |
{:noreply, socket} -> | |
{:ok, socket} | |
{:reply, _map, _socket} -> | |
raise "Can't return `{:reply, socket}` from event handler for \"#{event}\" because it is being called synthetically" | |
end | |
_ -> | |
better_update(assigns, socket) | |
end | |
end | |
def handle_event(_event, _payload, socket) do | |
{:noreply, socket} | |
end | |
def better_update(assigns, socket) do | |
{:ok, assign(socket, assigns)} | |
end | |
defoverridable handle_event: 3, better_update: 2 | |
end | |
end | |
end | |
defmodule LiveView do | |
defmacro __using__(opts) do | |
quote generated: true do | |
import BetterComponent | |
use Surface.LiveView | |
def handle_event(_event, _payload, socket) do | |
{:noreply, socket} | |
end | |
def handle_info({:__event__, event_name, payload}, socket) do | |
case handle_event(event, payload || %{}, socket) do | |
{:noreply, socket} -> | |
{:noreply, socket} | |
{:reply, _map, _socket} -> | |
raise "Can't return `{:reply, socket}` from event handler for \"#{event_name}\" because it is being called synthetically" | |
end | |
end | |
defoverridable handle_event: 3, better_update: 2 | |
end | |
end | |
end | |
defmodule Catalogue do | |
defmacro __using__(opts) do | |
quote generated: true do | |
import BetterComponent | |
def handle_event(_event, _payload, socket) do | |
{:noreply, socket} | |
end | |
def handle_info({:__event__, event_name, payload}, socket) do | |
case handle_event(event_name, paylaod, socket) do | |
{:noreply, socket} -> | |
{:noreply, socket} | |
{:reply, _map, _socket} -> | |
raise "Can't return `{:reply, socket}` from event handler for \"#{event_name}\" because it is being called synthetically" | |
end | |
end | |
defoverridable handle_event: 3 | |
end | |
end | |
end | |
defmacro __using__(_) do | |
quote do | |
use Surface.Component | |
import BetterComponent | |
end | |
end | |
defmacro my_event(myself, name, id \\ nil) do | |
quote do | |
{unquote(myself), unquote(name), __MODULE__, unquote(id)} | |
end | |
end | |
defmacro html_event(data) do | |
quote do | |
case unquote(data) do | |
nil -> | |
nil | |
{target, event, _, _} -> | |
%{name: event, target: target} | |
end | |
end | |
end | |
def call_event(nil, _), do: :ok | |
def call_event({target, event, module, id}, payload \\ %{}) do | |
if target == :live_view do | |
send(self(), {:__event__, event, payload}) | |
else | |
if is_nil(id) do | |
raise "Can't call an event when a nil id is provided, make this a better message?" | |
end | |
Phoenix.LiveView.send_update(module, id: id, __event__: event, __event_payload__: payload) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment