Skip to content

Commit

Permalink
add outline component
Browse files Browse the repository at this point in the history
  • Loading branch information
sorax committed Aug 20, 2024
1 parent 775b1af commit 43ad6bf
Show file tree
Hide file tree
Showing 9 changed files with 225 additions and 161 deletions.
32 changes: 16 additions & 16 deletions assets/js/hooks/events/listener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export function keydown(event: KeyboardEvent) {
node.dirty = true;

changeItemContent(node);
this.pushEvent("update_node_content", node);
this.pushEventTo(this.el, "update_node_content", node);

const newNode: Node = {
uuid: self.crypto.randomUUID(),
Expand All @@ -57,7 +57,7 @@ export function keydown(event: KeyboardEvent) {
prev_id: node.uuid,
dirty: true,
};
this.pushEvent("create_node", newNode);
this.pushEventTo(this.el, "create_node", newNode);

const newItem = createItem(newNode);
item.after(newItem);
Expand All @@ -82,10 +82,10 @@ export function keydown(event: KeyboardEvent) {
prevNode.dirty = true;
changeItemContent(prevNode);
focusItem(prevItem);
this.pushEvent("update_node_content", prevNode);
this.pushEventTo(this.el, "update_node_content", prevNode);

deleteItem(node);
this.pushEvent("delete_node", node);
this.pushEventTo(this.el, "delete_node", node);
break;

case "Delete":
Expand All @@ -98,10 +98,10 @@ export function keydown(event: KeyboardEvent) {
node.dirty = true;
changeItemContent(node);
focusItem(item);
this.pushEvent("update_node_content", node);
this.pushEventTo(this.el, "update_node_content", node);

deleteItem(nextNode);
this.pushEvent("delete_node", nextNode);
this.pushEventTo(this.el, "delete_node", nextNode);
break;

case "Tab":
Expand All @@ -115,7 +115,7 @@ export function keydown(event: KeyboardEvent) {
moveItem(node, container);

focusItem(item);
this.pushEvent("move_node", node);
this.pushEventTo(this.el, "move_node", node);
}
} else {
// indent
Expand All @@ -125,7 +125,7 @@ export function keydown(event: KeyboardEvent) {
moveItem(node, container);

focusItem(item);
this.pushEvent("move_node", node);
this.pushEventTo(this.el, "move_node", node);
}
}
break;
Expand All @@ -147,7 +147,7 @@ function moveCursorUp(event: KeyboardEvent, outerThis: any) {
// TODO: if no prevItem exists, try to select the parent item

focusItem(prevItem);
outerThis.pushEvent("set_focus", prevNode.uuid);
outerThis.pushEventTo(this.el, "set_focus", prevNode.uuid);
}

function moveCursorDown(event: KeyboardEvent, outerThis: any) {
Expand All @@ -166,7 +166,7 @@ function moveCursorDown(event: KeyboardEvent, outerThis: any) {
// TODO: if no nextItem exists, try to select the first child

focusItem(nextItem);
outerThis.pushEvent("set_focus", nextNode.uuid);
outerThis.pushEventTo(this.el, "set_focus", nextNode.uuid);
}

function moveNodeUp(
Expand All @@ -189,12 +189,12 @@ function moveNodeUp(
if (nextNode) {
nextNode.prev_id = prevNode.uuid;
moveItem(nextNode, container);
outerThis.pushEvent("move_node", nextNode);
outerThis.pushEventTo(this.el, "move_node", nextNode);
}
moveItem(node, container);
outerThis.pushEvent("move_node", node);
outerThis.pushEventTo(this.el, "move_node", node);
moveItem(prevNode, container);
outerThis.pushEvent("move_node", prevNode);
outerThis.pushEventTo(this.el, "move_node", prevNode);

focusItem(item);
}
Expand Down Expand Up @@ -222,15 +222,15 @@ function moveNodeDown(
if (prevNode) {
nextNode.prev_id = prevNode.uuid;
moveItem(nextNode, container);
outerThis.pushEvent("move_node", nextNode);
outerThis.pushEventTo(this.el, "move_node", nextNode);
}
if (nextNextNode) {
nextNextNode.prev_id = node.uuid;
moveItem(nextNextNode, container);
outerThis.pushEvent("move_node", nextNextNode);
outerThis.pushEventTo(this.el, "move_node", nextNextNode);
}
moveItem(node, container);
outerThis.pushEvent("move_node", node);
outerThis.pushEventTo(this.el, "move_node", node);
focusItem(item);
}
}
4 changes: 2 additions & 2 deletions assets/js/hooks/events/listener/click.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ export function click(event: MouseEvent) {
upsertItem(node, container);

if (node.collapsed) {
this.pushEvent("set_expanded", node.uuid);
this.pushEventTo(this.el, "set_expanded", node.uuid);
} else {
this.pushEvent("set_collapsed", node.uuid);
this.pushEventTo(this.el, "set_collapsed", node.uuid);
}
}
4 changes: 2 additions & 2 deletions assets/js/hooks/events/listener/focus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import { getNodeByEvent } from "../../node";
export function focusin(event: FocusEvent) {
const { uuid } = getNodeByEvent(event);

this.pushEvent("set_focus", uuid);
this.pushEventTo(this.el, "set_focus", uuid);
}

export function focusout(event: FocusEvent) {
const { uuid } = getNodeByEvent(event);

this.pushEvent("remove_focus", uuid);
this.pushEventTo(this.el, "remove_focus", uuid);
}
2 changes: 1 addition & 1 deletion assets/js/hooks/events/listener/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ export function input(event: Event) {
const item = getItemByNode(node);
item && setItemDirty(item, true);

this.pushEvent("update_node_content", node);
this.pushEventTo(this.el, "update_node_content", node);
}
102 changes: 8 additions & 94 deletions lib/radiator_web/live/episode_live/index.ex
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
defmodule RadiatorWeb.EpisodeLive.Index do
use RadiatorWeb, :live_view

alias Radiator.Outline
alias Radiator.Outline.Dispatch

alias Radiator.Outline.Event.{
Expand Down Expand Up @@ -37,83 +36,17 @@ defmodule RadiatorWeb.EpisodeLive.Index do
@impl true
def handle_params(params, _uri, socket) do
episode = get_selected_episode(params)
nodes = get_nodes(episode)

if connected?(socket) and episode do
Dispatch.subscribe(episode.id)
end

socket
|> assign(:selected_episode, episode)
|> push_event("list", %{nodes: nodes})
|> reply(:noreply)
end

@impl true
def handle_event("set_focus", _node_id, socket) do
socket
|> reply(:noreply)
end

def handle_event("remove_focus", _node_id, socket) do
socket
|> reply(:noreply)
end

def handle_event("set_collapsed", _node_id, socket) do
socket
|> reply(:noreply)
end

def handle_event("set_expanded", _node_id, socket) do
socket
|> reply(:noreply)
end

def handle_event("create_node", params, socket) do
user = socket.assigns.current_user
episode = socket.assigns.selected_episode
attrs = Map.merge(params, %{"creator_id" => user.id, "episode_id" => episode.id})

Dispatch.insert_node(attrs, user.id, generate_event_id(socket.id))

socket
|> reply(:noreply)
end

def handle_event("update_node_content", %{"uuid" => uuid, "content" => content}, socket) do
user = socket.assigns.current_user

Dispatch.change_node_content(uuid, content, user.id, generate_event_id(socket.id))

socket
|> reply(:noreply)
end

def handle_event("move_node", %{"uuid" => uuid} = node, socket) do
user = socket.assigns.current_user

Dispatch.move_node(
uuid,
node["parent_id"],
node["prev_id"],
user.id,
generate_event_id(socket.id)
)

socket
|> reply(:noreply)
end

def handle_event("delete_node", %{"uuid" => uuid}, socket) do
user = socket.assigns.current_user

Dispatch.delete_node(uuid, user.id, generate_event_id(socket.id))

socket
|> reply(:noreply)
end

def handle_event("new_episode", _params, socket) do
show = socket.assigns.show
number = Podcast.get_next_episode_number(show.id)
Expand Down Expand Up @@ -159,48 +92,34 @@ defmodule RadiatorWeb.EpisodeLive.Index do
|> reply(:noreply)
end

def handle_info(
%NodeInsertedEvent{node: node, next_id: next_id} = event,
socket
) do
payload = %{node: node, next_id: next_id}
def handle_info(%NodeInsertedEvent{} = event, socket) do
send_update(RadiatorWeb.OutlineComponent, id: "outline", event: event)

socket
|> push_event("insert", payload)
|> stream_event(event)
|> reply(:noreply)
end

def handle_info(
%NodeContentChangedEvent{node_id: id, content: content} = event,
socket
) do
payload = %{node: %{uuid: id, content: content}}
def handle_info(%NodeContentChangedEvent{} = event, socket) do
send_update(RadiatorWeb.OutlineComponent, id: "outline", event: event)

socket
|> push_event("change_content", payload)
|> stream_event(event)
|> reply(:noreply)
end

def handle_info(
%NodeMovedEvent{node_id: id, parent_id: parent_id, prev_id: prev_id} =
event,
socket
) do
payload = %{node: %{uuid: id, parent_id: parent_id, prev_id: prev_id}}
def handle_info(%NodeMovedEvent{} = event, socket) do
send_update(RadiatorWeb.OutlineComponent, id: "outline", event: event)

socket
|> push_event("move", payload)
|> stream_event(event)
|> reply(:noreply)
end

def handle_info(%NodeDeletedEvent{node_id: id} = event, socket) do
payload = %{node: %{uuid: id}}
def handle_info(%NodeDeletedEvent{} = event, socket) do
send_update(RadiatorWeb.OutlineComponent, id: "outline", event: event)

socket
|> push_event("delete", payload)
|> stream_event(event)
|> reply(:noreply)
end
Expand All @@ -220,11 +139,6 @@ defmodule RadiatorWeb.EpisodeLive.Index do
[]
end

defp get_nodes(%{id: id}), do: Outline.list_nodes_by_episode_sorted(id)
defp get_nodes(_), do: []

defp generate_event_id(id), do: Ecto.UUID.generate() <> ":" <> id

defp stream_event(socket, event) do
socket
|> stream_insert(:event_logs, event, at: 0)
Expand Down
9 changes: 6 additions & 3 deletions lib/radiator_web/live/episode_live/index.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,12 @@
<section :if={@selected_episode}>
<h2 class="text-2xl"><%= @selected_episode.number %> <%= @selected_episode.title %></h2>
<img class="my-4" src={~p"/images/pic06.jpg"} alt="" />
<div id="outline" class="my-6" phx-hook="outline" phx-update="ignore">
<div class="children"></div>
</div>
<.live_component
id="outline"
module={RadiatorWeb.OutlineComponent}
episode_id={@selected_episode.id}
user_id={@current_user.id}
/>
</section>

<section>
Expand Down
Loading

0 comments on commit 43ad6bf

Please sign in to comment.