Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/eval_in_wasm_build_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ jobs:
cache-dependency-path: pnpm-lock.yaml

- name: Install JS dependencies
env:
CXXFLAGS: "-std=c++20"
run: pnpm install
working-directory: .

Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/hello_popcorn_build_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ jobs:
cache-dependency-path: pnpm-lock.yaml

- name: Install JS dependencies
env:
CXXFLAGS: "-std=c++20"
run: pnpm install
working-directory: .

Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/langtour_e2e_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ jobs:
working-directory: language-tour/elixir_tour

- name: Install pnpm dependencies
env:
CXXFLAGS: "-std=c++20"
run: pnpm install --frozen-lockfile

- name: Build popcorn JS package
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/local_live_view_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ jobs:
cache-dependency-path: pnpm-lock.yaml

- name: Install JS dependencies
env:
CXXFLAGS: "-std=c++20"
run: pnpm install
working-directory: .

Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/otp_js_e2e_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ jobs:
cache-dependency-path: pnpm-lock.yaml

- name: Install JS dependencies
env:
CXXFLAGS: "-std=c++20"
run: pnpm install

- name: Setup Playwright
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/popcorn_build_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ jobs:

- name: Install JS dependencies
working-directory: .
env:
CXXFLAGS: "-std=c++20"
run: pnpm install

- name: Setup Playwright
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/popcorn_js_e2e_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ jobs:
cache-dependency-path: pnpm-lock.yaml

- name: Install JS dependencies
env:
CXXFLAGS: "-std=c++20"
run: pnpm install

- name: Build popcorn JS package
Expand Down
2 changes: 1 addition & 1 deletion examples/local-lv-forms/assets/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
font-size: 15px;
}

.title {
h1 {
padding: 30px 25px;
font-size: 30px;
font-weight: bold;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div class="page">
<p class="title centered">LocalLiveView & Phoenix Integration: Forms Demo</p>
<h1 class="centered">LocalLiveView & Phoenix Integration: Forms Demo</h1>
<div class="centered-div description">
<p>Explore seamless form handling and LocalLiveView integration.</p>
<p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ defmodule FormDemoWeb.FormDemoLive do
<div class="centered-div">
<.local_live_view id={"form-demo-local-#{@socket.id}"} view="FormDemoLocal" />
<div class="bordered">
<h1>[Server Runtime] User List:</h1>
<h2>[Server Runtime] User List:</h2>
<ul>
<%= for user <- @users do %>
<li>Username: {user["username"]}, Email: {user["email"]}</li>
Expand Down
30 changes: 18 additions & 12 deletions examples/local-lv-forms/local/lib/form_demo_local.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,31 @@ defmodule FormDemoLocal do
@impl true
def render(assigns) do
~H"""
<h2 class="header">Add new user</h2>
<div class="bordered">
<.form for={@form} id="my-form" phx-change="validate" phx-submit="save">
<label>USERNAME</label>
<.input type="text" field={@form[:username]} />
<.input type="text" field={@form[:username]} placeholder="at least 4 characters" />
<label>EMAIL</label>
<.input type="text" field={@form[:email]} />
<div class="centered">
<button class="ghost-button" disabled={@disabled}>SAVE</button>
<.input type="text" field={@form[:email]} placeholder="name@domain.com" />
<div class="buttons">
<button type="submit" class="ghost-button" disabled={@disabled}>SAVE</button>
<button type="button" class="ghost-button" phx-click="generate_random">
GENERATE RANDOM
</button>
</div>
</.form>
<div class="centered">
<button class="ghost-button" phx-click="generate_random">GENERATE RANDOM</button>
</div>
</div>
<%= for error <- @errors do %>
<p style="color:red;">{error}</p>
<% end %>
<div class="bordered">
<h1>[Local Runtime] User List:</h1>
<div data-value="errors-list">
<%= for error <- @errors do %>
<p style="color:red;">{error}</p>
<% end %>
</div>
<div class="bordered" data-value="users-list">
<h2 class="title">[Local Runtime] User List:</h2>
<%= if @users == [] do %>
<p>No users yet - save one above</p>
<% end %>
<ul>
<%= for user <- @users do %>
<li>Username: {user["username"]}, Email: {user["email"]}</li>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
defmodule FormDemoLocalPresentation do
use LocalLiveView

defdelegate render(assigns), to: FormDemoLocal

def mount(params, session, socket) do
result = FormDemoLocal.mount(params, session, socket)
{:ok, new_socket} = result

Popcorn.Wasm.send_event("llv_presentation", %{
block: nil,
event: "mount",
assigns: presentation_assigns(new_socket)
})

result
end

def handle_event(event, params, socket)
when event in ["validate", "save", "generate_random"] do
effective_socket =
case socket.assigns[:_pending_cur] do
nil -> socket
pending -> assign(socket, Map.to_list(pending))
end

{:noreply, updated} = FormDemoLocal.handle_event(event, params, effective_socket)

Popcorn.Wasm.send_event("llv_presentation", %{
block: event,
event: event,
assigns: presentation_assigns(updated)
})

new_pending = %{
form: updated.assigns.form,
errors: updated.assigns.errors,
disabled: updated.assigns.disabled,
users: updated.assigns.users
}

{:noreply,
socket
|> assign(:_pending_prev, socket.assigns[:_pending_cur])
|> assign(:_pending_cur, new_pending)}
end

def handle_info({:js_push, "llv_ack", _}, socket) do
case {socket.assigns[:_pending_prev], socket.assigns[:_pending_cur]} do
{%{form: form, errors: errors, disabled: disabled, users: users}, _} ->
{:noreply,
socket
|> assign(:form, form)
|> assign(:errors, errors)
|> assign(:disabled, disabled)
|> assign(:users, users)
|> assign(:_pending_prev, nil)}

{nil, %{form: form, errors: errors, disabled: disabled, users: users}} ->
{:noreply,
socket
|> assign(:form, form)
|> assign(:errors, errors)
|> assign(:disabled, disabled)
|> assign(:users, users)
|> assign(:_pending_cur, nil)}

_ ->
{:noreply, socket}
end
end

def handle_event(event, params, socket) do
FormDemoLocal.handle_event(event, params, socket)
end

defp presentation_assigns(socket) do
assigns = socket.assigns
form_params = assigns.form.params

%{
username: Map.get(form_params, "username", ""),
email: Map.get(form_params, "email", ""),
errors: length(assigns.errors),
disabled: assigns.disabled,
users: length(assigns.users)
}
end
end
9 changes: 9 additions & 0 deletions examples/local-lv-forms/local/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ defmodule Local.MixProject do
version: "0.1.0",
elixir: "~> 1.17",
start_permanent: Mix.env() == :prod,
elixirc_paths: elixirc_paths(),
deps: deps(),
compilers: Mix.compilers(),
aliases: aliases()
Expand All @@ -17,6 +18,14 @@ defmodule Local.MixProject do
[default_target: :wasm]
end

defp elixirc_paths do
if System.get_env("LLV_LANDING_PATCH") == "true" do
["lib", "lib_landing"]
else
["lib"]
end
end

def application do
[
extra_applications: [:logger],
Expand Down
24 changes: 10 additions & 14 deletions examples/local-lv-thermostat/local/lib/thermostat_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,20 @@ defmodule ThermostatLive do

def render(assigns) do
~H"""
<p>Current temperature: {@temperature}°C</p>
<div class="thermostat-controls">
<button phx-click="inc_temperature" class="ghost-button">+</button>
<button phx-click="dec_temperature" class="ghost-button">-</button>
<div class="thermostat-wrapper">
<p class="thermostat-temp-label">Current temperature</p>
<p class="thermostat-temp-value" data-value="temperature">{@temperature}°C</p>
<div class="thermostat-controls">
<button phx-click="inc_temperature" class="ghost-button">+</button>
<button phx-click="dec_temperature" class="ghost-button">-</button>
</div>
<p class="thermostat-country">Country: {@country}</p>
</div>
<p>Country: {@country}</p>
"""
end

def mount(_params, _session, socket) do
temperature = 25
country = "Poland"

socket =
socket
|> assign(:temperature, temperature)
|> assign(:country, country)

{:ok, socket}
{:ok, socket |> assign(:temperature, 25) |> assign(:country, "Poland")}
end

def handle_event("inc_temperature", _params, socket) do
Expand All @@ -31,4 +26,5 @@ defmodule ThermostatLive do
def handle_event("dec_temperature", _params, socket) do
{:noreply, update(socket, :temperature, &(&1 - 1))}
end

end
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
defmodule ThermostatLivePresentation do
use LocalLiveView

defdelegate render(assigns), to: ThermostatLive

def mount(params, session, socket) do
result = ThermostatLive.mount(params, session, socket)
{:ok, new_socket} = result

Popcorn.Wasm.send_event("llv_presentation", %{
block: nil,
event: "mount",
assigns: presentation_assigns(new_socket)
})

result
end

def handle_event(event, params, socket)
when event in ["inc_temperature", "dec_temperature"] do

effective_socket =
case socket.assigns[:_pending_cur] do
nil -> socket
pending -> assign(socket, Map.to_list(pending))
end

{:noreply, updated} = ThermostatLive.handle_event(event, params, effective_socket)

Popcorn.Wasm.send_event("llv_presentation", %{
block: event,
event: event,
assigns: presentation_assigns(updated)
})

new_pending = %{
temperature: updated.assigns.temperature,
country: updated.assigns.country
}

{:noreply,
socket
|> assign(:_pending_prev, socket.assigns[:_pending_cur])
|> assign(:_pending_cur, new_pending)}
end

def handle_info({:js_push, "llv_ack", _}, socket) do
case {socket.assigns[:_pending_prev], socket.assigns[:_pending_cur]} do
{%{temperature: t, country: c}, _} ->
{:noreply,
socket
|> assign(:temperature, t)
|> assign(:country, c)
|> assign(:_pending_prev, nil)}

{nil, %{temperature: t, country: c}} ->
{:noreply,
socket
|> assign(:temperature, t)
|> assign(:country, c)
|> assign(:_pending_cur, nil)}

_ ->
{:noreply, socket}
end
end

def handle_event(event, params, socket) do
ThermostatLive.handle_event(event, params, socket)
end

defp presentation_assigns(socket) do
%{
temperature: socket.assigns.temperature,
country: socket.assigns.country
}
end
end
9 changes: 9 additions & 0 deletions examples/local-lv-thermostat/local/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ defmodule Local.MixProject do
version: "0.1.0",
elixir: "~> 1.17",
start_permanent: Mix.env() == :prod,
elixirc_paths: elixirc_paths(),
deps: deps(),
compilers: Mix.compilers(),
aliases: aliases()
Expand All @@ -24,6 +25,14 @@ defmodule Local.MixProject do
]
end

defp elixirc_paths do
if System.get_env("LLV_LANDING_PATCH") == "true" do
["lib", "lib_landing"]
else
["lib"]
end
end

defp deps do
[
{:local_live_view, path: "../../../local-live-view"}
Expand Down
Loading
Loading