Skip to content

Instantly share code, notes, and snippets.

@zachdaniel
Created September 16, 2022 03:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zachdaniel/9d94489d72863768962f8f973fa7326b to your computer and use it in GitHub Desktop.
Save zachdaniel/9d94489d72863768962f8f973fa7326b to your computer and use it in GitHub Desktop.
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