|
|
Line 1: |
Line 1: |
| 1. Create notes field with a data type of text via migration | | 1. Create notes field with a data type of text via migration |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
| ________________________________________
| |
|
| |
|
| |
| https://fly.io/phoenix-files/sdeb-toggling-element/
| |
| https://www.youtube.com/watch?v=vBgZvQapqhs
| |
|
| |
| https://blog.testdouble.com/posts/2022-11-28-how-to-use-javascript-with-phoenix-liveview/
| |
|
| |
|
|
| |
|
|
| |
|
| <source> | | <source> |
| | import {HfInference} from "@huggingface/inference"; |
| | import dotenv from "dotenv"; |
| | dotenv.config() |
|
| |
|
| defmodule AppWeb.PageLive do
| | const HF_ACCESS_TOKEN = process.env.HF_ACCESS_TOKEN |
| use AppWeb, :live_view
| |
|
| |
|
| def mount(_params, _session, socket) do
| | const hf = new HfInference(HF_ACCESS_TOKEN); |
| {:ok, socket}
| |
| end
| |
|
| |
|
| def button_event("invoke_writing") do
| |
| %JS{}
| |
| |> JS.remove_class("active", to: "#writing_button")
| |
| |> JS.add_class("hidden", to: "#writing_button")
| |
| |> JS.remove_class("hidden", to: "#preview_button")
| |
| |> JS.add_class("active", to: "#preview_button")
| |
| |> JS.remove_class("active", to: "#preview")
| |
| |> JS.add_class("hidden", to: "#preview")
| |
| |> JS.remove_class("hidden", to: "#writing")
| |
| |> JS.add_class("active", to: "#writing")
| |
| end
| |
|
| |
|
| def button_event("invoke_preview") do
| | /*______Uncomment for this example______________________ |
| %JS{}
| |
| |> JS.remove_class("active", to: "#preview_button")
| |
| |> JS.add_class("hidden", to: "#preview_button")
| |
| |> JS.remove_class("hidden", to: "#writing_button")
| |
| |> JS.add_class("active", to: "#writing_button")
| |
| |> JS.remove_class("active", to: "#writing")
| |
| |> JS.add_class("hidden", to: "#writing")
| |
| |> JS.remove_class("hidden", to: "#preview")
| |
| |> JS.add_class("active", to: "#preview")
| |
| end
| |
|
| |
|
| def render(assigns) do
| | const model = "nlpconnect/vit-gpt2-image-captioning"; |
| ~H"""
| | const imageURL = "https://i.imgur.com/lTvb7Et.png"; |
| <button phx-click={button_event("invoke_writing")} id="writing_button" class="hidden">
| |
| Preview
| |
| </button>
| |
|
| |
|
| <button phx-click={button_event("invoke_preview")} id="preview_button">
| | const response = await fetch(imageURL); |
| Writing
| | const imageBlob = await response.blob(); |
| </button>
| |
|
| |
|
| <div id="writing"> Writing Editing </div>
| | const result = await hf.imageToText({ |
| | data: imageBlob, |
| | model: model, |
| | }); |
|
| |
|
| <div id="preview" class="hidden"> PREVIEW THE WORK </div>
| | _______________________________________________________*/ |
|
| |
|
|
| |
|
| """
| |
| end
| |
| end
| |
| </source>
| |
|
| |
|
| | /*________Another example ___________________*/ |
|
| |
|
| <%= for id <- 1..5 do %>
| | const result = await hf.summarization({ |
| <.modal id={"notes-modal-#{id}"}>
| | model: 'facebook/bart-large-cnn', |
| <div phx-hook="TrixEditor" id="xyz">
| | inputs: "The role of a dumb man is to get smarter oogy bookie boo", |
| <div id="richtext" phx-update="ignore">
| | parameters:{ |
| <trix-editor class="trix-content"></trix-editor>
| | max_length: 100 |
| </div>
| | } |
| </div>
| | }); |
| </.modal>
| |
| <div phx-click={show_modal("notes-modal-#{id}")}>Click item <%= id %></div>
| |
| <% end %>
| |
|
| |
|
|
| |
|
| <ul class="nav nav-tabs mb-2" id="myTabs" role="tablist">
| |
| <li class="nav-item"><btn id="tab1Label" data-toggle="tab" class="nav-link active" role="tab" aria-controls="tab1" aria-selected="true">#tab1|ROUTES</btn></li>
| |
|
| |
|
| <li><btn id="btn2Label" data-toggle="tab" class="nav-link" role="tab" aria-controls="tab2" aria-selected="false">#tab2|CREATE LIVEVIEWS</btn></li>
| |
|
| |
|
| <li><btn id="btn3Label" data-toggle="tab" class="nav-link" role="tab" aria-controls="tab3" aria-selected="false">#tab3|EDIT LIVEVIEWS</btn></li>
| |
| <li><btn id="btn4Label" data-toggle="tab" class="nav-link" role="tab" aria-controls="tab4" aria-selected="false">#tab4|SUBSCRIBE</btn></li>
| |
| <li><btn id="btn5Label" data-toggle="tab" class="nav-link" role="tab" aria-controls="tab5" aria-selected="false">#tab5|HANDLE_INFO</btn></li>
| |
|
| |
|
| | | console.log(result); |
| </ul>
| |
| | |
| <div class="tab-content">
| |
| <div id="tab1" class="tab-pane fade show active" role="tabpanel" aria-labelledby="tab1Label">
| |
| '''Tab 1''': Lorem ipsum...
| |
| </div>
| |
| | |
| | |
| | |
| <div id="tab2" class="tab-pane fade" role="tabpanel" aria-labelledby="tab2Label">
| |
| tab 2
| |
| </div>
| |
| | |
| | |
| <div id="tab3" class="tab-pane fade" role="tabpanel" aria-labelledby="tab3Label">
| |
| tab 3
| |
| </div>
| |
| | |
| | |
| | |
| <div id="tab4" class="tab-pane fade" role="tabpanel" aria-labelledby="tab4Label">
| |
| tab 4
| |
| </div>
| |
| | |
| <div id="tab5" class="tab-pane fade" role="tabpanel" aria-labelledby="tab5Label">
| |
| tab 5
| |
| </div>
| |
| </div>
| |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| Create two working minimalistic LiveViews.
| |
| | |
| One is named '''SendView''' and the other is '''ReceiveView''' .
| |
| | |
| The '''SendView''' consist of a single form field to send data to RecieveView. ReceiveView contains code to renders SendView data to its page.
| |
| | |
| To understand web socket configuration we will:
| |
| | |
| 1. Create a '''one way data connection''' between the two LiveViews and explain clearly the relationship between the code pieces with a focus on data flow.
| |
| | |
| 2. Edit the code to '''create a two-way''' connection between both live views.
| |
| | |
| 3. Combine both LiveViews into one live view to send and receive.
| |
| | |
| 4. Write code to store real time chat content to a database.
| |
| | |
| | |
| This may seem like pointless overkill and maybe it is. However, this is what has worked for me.
| |
| | |
| == PUB SUB ==
| |
| | |
| Before we begin, I will share three small pieces of code with you. These are the main characters, or main components for what we will build.
| |
| | |
| <source>
| |
| AppWeb.Endpoint.subscribe()
| |
| </source> | | </source> |
|
| |
|
| <source>
| |
| AppWeb.Endpoint.broadcast()
| |
| </source>
| |
|
| |
|
| <source>
| |
| def handle_info(msg, socket) do
| |
| {:noreply, assign(socket)}
| |
| end
| |
| </source>
| |
|
| |
|
|
| |
|
| <source>
| |
| def handle_event(msg, params, socket) do
| |
| {:noreply, socket}
| |
| end
| |
| </source>
| |
|
| |
|
| We will ultimately weave these little pieces of code into a LiveView and create a chat application.
| |
|
| |
|
| == Create Two Minimalistic Vanilla LiveViews ==
| |
|
| |
|
| In router.ex create the following routes:
| |
|
| |
|
|
| |
|
| <source>
| |
| scope "/", AppWeb do
| |
| pipe_through :browser
| |
| live "/send", SendLive, :home
| |
| live "/receive", ReceiveLive, :home
| |
| end
| |
| </source>
| |
|
| |
|
| | ________________________________________ |
|
| |
|
|
| |
|
| | https://fly.io/phoenix-files/sdeb-toggling-element/ |
| | https://www.youtube.com/watch?v=vBgZvQapqhs |
|
| |
|
| In app_web create a folder named live. In the live folder create a file named send_live.ex.
| | https://blog.testdouble.com/posts/2022-11-28-how-to-use-javascript-with-phoenix-liveview/ |
| | |
| Copy this code into it:
| |
| <source>
| |
| defmodule AppWeb.SendLive do
| |
| use AppWeb, :live_view
| |
| | |
| def mount(_params, _session, socket) do
| |
| {:ok, assign(socket, data: " ")}
| |
| end
| |
| | |
| def handle_event("send", params, socket) do
| |
| {:noreply, socket}
| |
| end
| |
| | |
| def render(assigns) do
| |
| ~H"""
| |
| <div>
| |
| <h1>connection Send</h1>
| |
| | |
| <form phx-submit="send">
| |
| <input type="text" name="text" />
| |
| <button type="submit">Send</button>
| |
| </form>
| |
| </div>
| |
| """
| |
| end
| |
| end
| |
| </source>
| |
| <source>
| |
| | |
| defmodule AppWeb.SendLive do
| |
| use AppWeb, :live_view
| |
| | |
| def mount(_params, _session, socket) do
| |
| if connected?(socket) do
| |
| end
| |
| | |
| {:ok, assign(socket, username: username, messages: [])}
| |
| end
| |
| | |
| # def handle_info(%{event: "message", payload: message}, socket) do
| |
| # {:noreply, assign(socket, messages: socket.assigns.messages ++ [message])}
| |
| # end
| |
| | |
| def handle_event("send", %{"text" => text}, socket) do
| |
| AppWeb.Endpoint.broadcast("connection input-1", "SOUND", %{
| |
| text: text,
| |
| name: socket.assigns.username
| |
| })
| |
| | |
| {:noreply, socket}
| |
| end
| |
| | |
| defp username do
| |
| "User #{:rand.uniform(100)}"
| |
| end
| |
| | |
| def render(assigns) do
| |
| ~H"""
| |
| <div>
| |
| <h1>connection Send</h1>
| |
| <div
| |
| class="messages"
| |
| style="border: 1px solid #eee; height: 400px; overflow: scroll; margin-bottom: 8px;"
| |
| >
| |
| </div>
| |
| <form phx-submit="send">
| |
| <input type="text" name="text" />
| |
| <button type="submit">Send</button>
| |
| </form>
| |
| </div>
| |
| """
| |
| end
| |
| end
| |
| | |
| </source>
| |
| | |
| <source>
| |
| defmodule AppWeb.ReceiveLive do
| |
| use AppWeb, :live_view
| |
| | |
| def mount(_params, _session, socket) do
| |
| {:ok, assign(socket, messages: " ")}
| |
| end
| |
| | |
| def handle_info(msg, socket) do
| |
| {:noreply, assign(socket, data: "")}
| |
| end
| |
| | |
| def render(assigns) do
| |
| ~H"""
| |
| <div>
| |
| <h1>ReceiveLive Connection</h1>
| |
| | |
| <%= for m <- [1,2,3,4,5] do %>
| |
| <%= m %>
| |
| <% end %>
| |
| </div>
| |
| """
| |
| end
| |
| end
| |
| | |
| | |
| </source>
| |
| | |
| <source>
| |
| | |
| defmodule AppWeb.RecieveLive do
| |
| use AppWeb, :live_view
| |
| | |
| def mount(_params, _session, socket) do
| |
| if connected?(socket) do
| |
| AppWeb.Endpoint.subscribe("connection input-1")
| |
| end
| |
| | |
| {:ok, assign(socket, username: username, messages: [])}
| |
| end
| |
| | |
| def handle_info(%{event: "SOUND", payload: message}, socket) do
| |
| {:noreply, assign(socket, messages: socket.assigns.messages ++ [message])}
| |
| end
| |
| | |
| # def handle_event("send", %{"text" => text}, socket) do
| |
| # AppWeb.Endpoint.broadcast("connection input-1", "message", %{
| |
| # text: text,
| |
| # name: "X"
| |
| # })
| |
| | |
| # {:noreply, socket}
| |
| # end
| |
| | |
| defp username do
| |
| "User #{:rand.uniform(100)}"
| |
| end
| |
| | |
| def render(assigns) do
| |
| ~H"""
| |
| <div>
| |
| <h1>connection Recieve Live</h1>
| |
| | |
| <div
| |
| class="messages"
| |
| style="border: 1px solid #eee; height: 400px; overflow: scroll; margin-bottom: 8px;"
| |
| >
| |
| <%= for m <- @messages do %>
| |
| <p style="margin: 2px;"><b><%= m.name %></b>: <%= m.text %></p>
| |
| <% end %>
| |
| </div>
| |
| </div>
| |
| """
| |
| end
| |
| end
| |
| | |
| </source>
| |
| | |
| | |
| Open the /send route and the /receive route each in their own tab. You will now write code so the form in send sends data to the page in receive.
| |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| * How to Create Database Seed Data.
| |
| * How to Use Generators in a Real World Project
| |
| * How to Work with Database Data via Basic Commands and Custom Change sets.
| |
| * How to Render Database Data to LiveView (via Context Commands).
| |
| * How to Create a Chat using PubSub.
| |
| * How to Create Event Handlers in LiveView
| |
| * How to Create a Dynamic Route from Scratch.
| |
| * How to Use Elixirs Template language
| |
| * How to Work with Modal
| |
| * How to Use CSS From Scratch (Without bundler)
| |
| * How to use JS hooks
| |
| | |
| _________________________________________________
| |
| | |
| https://elixirschool.com/blog/live-view-live-component | |
| | |
| | |
| | |
| | |
| | |
| Note:
| |
| | |
| mix phx.gen.html Alerts Alert alerts title:string content:text enabled:boolean
| |
| | |
| | |
| <pre>
| |
| defmodule AppWeb.PageLive do
| |
| use AppWeb, :live_view
| |
| alias App.Alerts
| |
| def mount(_params, _session, socket) do
| |
| {:ok, assign(socket, alerts: Alerts.list_alerts())}
| |
| end
| |
| | |
| def render(assigns) do
| |
| ~H"""
| |
| <%= for alert <- @alerts do %>
| |
| <%= if alert.enabled do %>
| |
| <div><%= alert.content%></div>
| |
| <% end %>
| |
| | |
| <% end %>
| |
| | |
| """
| |
| end
| |
| | |
| end
| |
| | |
| #_____________________________
| |
| | |
| def check_for_single_selection(data) do
| |
| | |
| list = App.Alerts.list_alerts()
| |
| | |
| IO.inspect list
| |
| | |
| result = Enum.filter(list, fn x -> x.enabled == true end)
| |
| IO.inspect "WORK_____________________________"
| |
| IO.inspect result
| |
| IO.inspect "WORK_____________________________"
| |
| | |
| data
| |
| | |
| end
| |
| </pre>
| |
| __________________________________________________
| |
| | |
| Complex pattern matching
| |
| https://www.youtube.com/watch?v=gCVWrM5BNVE
| |
| | |
| Genservers (and related, agent,task etc)
| |
| | |
| | |
| __________________________________________________
| |
| | |
| ECTO
| |
| | |
| query = from "artists", select:[:name]
| |
| | |
| '''Verbose:'''
| |
| | |
| Ecto.Query.from("artists", select[:name])
| |
| | |
| | |
| Repo.all(query)
| |
| | |
| #=> [%{name: "Miles Davis"}, %{name: "Bill Evans"}]
| |
| | |
| | |
| | |
| | |
| | |
| Repo.to_sql(:all, query)
| |
| | |
| ____________________________________________
| |
| | |
| | |
| defmodule AppWeb.PageLive do
| |
| use AppWeb, :live_view
| |
| | |
| def mount(_params, _session, socket) do
| |
| {:ok,
| |
| assign(socket,
| |
| notes: "We are the world"
| |
| )}
| |
| end
| |
| | |
| def handle_event("submit-modal-form", params, socket) do
| |
| IO.inspect("_______________SUBMITTED")
| |
| IO.inspect(params)
| |
| | |
| {:noreply, redirect(socket, to: "/")}
| |
| end
| |
| | |
| def handle_event("show", params, socket) do
| |
| end
| |
| | |
| def render(assigns) do
| |
| ~H"""
| |
| <%= for id <- 1..5 do %>
| |
| <.modal id={"notes-modal-#{id}"} class="bg-red-500">
| |
| <div phx-hook="TrixEditor" id={"notes-modal-trix#{id}"}>
| |
| <div id={"richtext-#{id}"} phx-update="ignore">
| |
| <form phx-submit="submit-modal-form">
| |
| <input
| |
| id={"notes-connection-modal-#{id}"}
| |
| value={"notes-modal-#{id}"}
| |
| type="hidden"
| |
| name="content"
| |
| />
| |
| <trix-editor class="trix-content" input={"notes-connection-modal-#{id}"}></trix-editor>
| |
| <.button>Save Changes</.button>
| |
| </form>
| |
| </div>
| |
| </div>
| |
| </.modal>
| |
| <div phx-click={show_modal("notes-modal-#{id}")}>Click item <%= id %></div>
| |
| <% end %>
| |
| """
| |
| end
| |
| end
| |