Created
September 16, 2022 02:59
-
-
Save zachdaniel/cb4a97d31198a94d9eec4774ceb8a1fc to your computer and use it in GitHub Desktop.
This file contains hidden or 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, 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 | |
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, 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 | |
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