diff --git a/assets/js/app.js b/assets/js/app.js index 592dfa7..678868b 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -263,21 +263,6 @@ let Focus = { }, } -// Accessible focus wrapping -Hooks.FocusWrap = { - mounted(){ - this.content = document.querySelector(this.el.getAttribute("data-content")) - this.focusStart = this.el.querySelector(`#${this.el.id}-start`) - this.focusEnd = this.el.querySelector(`#${this.el.id}-end`) - this.focusStart.addEventListener("focus", () => Focus.focusLastDescendant(this.content)) - this.focusEnd.addEventListener("focus", () => Focus.focusFirstDescendant(this.content)) - this.content.addEventListener("phx:show-end", () => this.content.focus()) - if(window.getComputedStyle(this.content).display !== "none"){ - Focus.focusFirstDescendant(this.content) - } - }, -} - let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content") let liveSocket = new LiveSocket("/live", Socket, { hooks: Hooks, @@ -297,7 +282,7 @@ let routeUpdated = () => { // Show progress bar on live navigation and form submits topbar.config({barColors: {0: "rgba(147, 51, 234, 1)"}, shadowColor: "rgba(0, 0, 0, .3)"}) -window.addEventListener("phx:page-loading-start", info => topbar.show()) +window.addEventListener("phx:page-loading-start", info => topbar.delayedShow(200)) window.addEventListener("phx:page-loading-stop", info => topbar.hide()) // Accessible routing @@ -333,5 +318,4 @@ liveSocket.connect() // >> liveSocket.enableDebug() // >> liveSocket.enableLatencySim(1000) // enabled for duration of browser session // >> liveSocket.disableLatencySim() -window.liveSocket = liveSocket - +window.liveSocket = liveSocket \ No newline at end of file diff --git a/assets/js/phoenix b/assets/js/phoenix new file mode 120000 index 0000000..bb89e2c --- /dev/null +++ b/assets/js/phoenix @@ -0,0 +1 @@ +/Users/chris/oss/phoenix/assets/js/phoenix \ No newline at end of file diff --git a/assets/js/phoenix_live_view b/assets/js/phoenix_live_view new file mode 120000 index 0000000..41aeefb --- /dev/null +++ b/assets/js/phoenix_live_view @@ -0,0 +1 @@ +/Users/chris/oss/phoenix_live_view/assets/js/phoenix_live_view \ No newline at end of file diff --git a/assets/vendor/topbar.js b/assets/vendor/topbar.js index ff7fbb6..40c3b7a 100644 --- a/assets/vendor/topbar.js +++ b/assets/vendor/topbar.js @@ -4,7 +4,7 @@ * http://buunguyen.github.io/topbar * Copyright (c) 2021 Buu Nguyen */ -(function (window, document) { + (function (window, document) { "use strict"; // https://gist.github.com/paulirish/1579671 @@ -35,10 +35,11 @@ })(); var canvas, - progressTimerId, - fadeTimerId, currentProgress, showing, + progressTimerId = null, + fadeTimerId = null, + delayTimerId = null, addEvent = function (elem, type, handler) { if (elem.addEventListener) elem.addEventListener(type, handler, false); else if (elem.attachEvent) elem.attachEvent("on" + type, handler); @@ -95,6 +96,11 @@ for (var key in opts) if (options.hasOwnProperty(key)) options[key] = opts[key]; }, + delayedShow: function(time) { + if (showing) return; + if (delayTimerId) return; + delayTimerId = setTimeout(() => topbar.show(), time); + }, show: function () { if (showing) return; showing = true; @@ -125,6 +131,8 @@ return currentProgress; }, hide: function () { + clearTimeout(delayTimerId); + delayTimerId = null; if (!showing) return; showing = false; if (progressTimerId != null) { diff --git a/config/config.exs b/config/config.exs index f47e5d3..0358d99 100644 --- a/config/config.exs +++ b/config/config.exs @@ -11,9 +11,7 @@ config :live_beats, replica: LiveBeats.ReplicaRepo, ecto_repos: [LiveBeats.Repo] - -config :live_beats, :files, - admin_usernames: [] +config :live_beats, :files, admin_usernames: [] # Configures the endpoint config :live_beats, LiveBeatsWeb.Endpoint, diff --git a/config/runtime.exs b/config/runtime.exs index ce760a4..dd3a5f9 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -19,8 +19,7 @@ if config_env() == :prod do For example: ecto://USER:PASS@HOST/DATABASE """ - replica_database_url = - System.get_env("REPLICA_DATABASE_URL") || database_url + replica_database_url = System.get_env("REPLICA_DATABASE_URL") || database_url host = System.get_env("PHX_HOST") || "example.com" ecto_ipv6? = System.get_env("ECTO_IPV6") == "true" @@ -69,7 +68,6 @@ if config_env() == :prod do hostname: "livebeats.local", transport_opts: [inet6: true] - config :live_beats, :github, client_id: System.fetch_env!("LIVE_BEATS_GITHUB_CLIENT_ID"), client_secret: System.fetch_env!("LIVE_BEATS_GITHUB_CLIENT_SECRET") diff --git a/config/test.exs b/config/test.exs index 9583d5b..fba318d 100644 --- a/config/test.exs +++ b/config/test.exs @@ -30,7 +30,6 @@ config :live_beats, LiveBeats.ReplicaRepo, pool_size: 10, priv: "priv/repo" - # We don't run a server during test. If one is required, # you can enable the server option below. config :live_beats, LiveBeatsWeb.Endpoint, diff --git a/lib/live_beats.ex b/lib/live_beats.ex index a71ffc5..ff0abe0 100644 --- a/lib/live_beats.ex +++ b/lib/live_beats.ex @@ -19,6 +19,7 @@ defmodule LiveBeats do """ def config([main_key | rest] = keyspace) when is_list(keyspace) do main = Application.fetch_env!(:live_beats, main_key) + Enum.reduce(rest, main, fn next_key, current -> case Keyword.fetch(current, next_key) do {:ok, val} -> val @@ -85,11 +86,11 @@ defmodule LiveBeats do target.handle_execute({src_mod, event_struct}) catch kind, err -> - Logger.error """ + Logger.error(""" executing {#{inspect(src_mod)}, #{inspect(event_mod)}} failed with #{inspect(kind)} #{inspect(err)} - """ + """) end end end diff --git a/lib/live_beats/accounts/identity.ex b/lib/live_beats/accounts/identity.ex index 31004a3..3cd287c 100644 --- a/lib/live_beats/accounts/identity.ex +++ b/lib/live_beats/accounts/identity.ex @@ -31,11 +31,17 @@ defmodule LiveBeats.Accounts.Identity do "provider_id" => to_string(info["id"]), "provider_login" => info["login"], "provider_name" => info["name"] || info["login"], - "provider_email" => primary_email, + "provider_email" => primary_email } %Identity{provider: @github, provider_meta: %{"user" => info, "emails" => emails}} - |> cast(params, [:provider_token, :provider_email, :provider_login, :provider_name, :provider_id]) + |> cast(params, [ + :provider_token, + :provider_email, + :provider_login, + :provider_name, + :provider_id + ]) |> validate_required([:provider_token, :provider_email, :provider_name, :provider_id]) |> validate_length(:provider_meta, max: 10_000) end diff --git a/lib/live_beats/accounts/user.ex b/lib/live_beats/accounts/user.ex index 82dc55f..c97b6a7 100644 --- a/lib/live_beats/accounts/user.ex +++ b/lib/live_beats/accounts/user.ex @@ -4,7 +4,6 @@ defmodule LiveBeats.Accounts.User do alias LiveBeats.Accounts.{User, Identity} - schema "users" do field :email, :string field :name, :string @@ -61,7 +60,6 @@ defmodule LiveBeats.Accounts.User do |> validate_username() end - defp validate_email(changeset) do changeset |> validate_required([:email]) diff --git a/lib/live_beats/github.ex b/lib/live_beats/github.ex index 85a9a26..0365e32 100644 --- a/lib/live_beats/github.ex +++ b/lib/live_beats/github.ex @@ -1,6 +1,7 @@ defmodule LiveBeats.Github do def authorize_url() do state = random_string() + "https://github.com/login/oauth/authorize?client_id=#{client_id()}&state=#{state}&scope=user:email" end @@ -34,6 +35,7 @@ defmodule LiveBeats.Github do end defp fetch_user_info({:error, _reason} = error), do: error + defp fetch_user_info({:ok, token}) do resp = http( @@ -43,6 +45,7 @@ defmodule LiveBeats.Github do [], [{"accept", "application/vnd.github.v3+json"}, {"Authorization", "token #{token}"}] ) + case resp do {:ok, info} -> {:ok, %{info: Jason.decode!(info), token: token}} {:error, _reason} = err -> err @@ -50,6 +53,7 @@ defmodule LiveBeats.Github do end defp fetch_emails({:error, _} = err), do: err + defp fetch_emails({:ok, user}) do resp = http( @@ -59,6 +63,7 @@ defmodule LiveBeats.Github do [], [{"accept", "application/vnd.github.v3+json"}, {"Authorization", "token #{user.token}"}] ) + case resp do {:ok, info} -> emails = Jason.decode!(info) diff --git a/lib/live_beats/media_library/genre.ex b/lib/live_beats/media_library/genre.ex index bb15a61..3b7f3c0 100644 --- a/lib/live_beats/media_library/genre.ex +++ b/lib/live_beats/media_library/genre.ex @@ -16,6 +16,7 @@ defmodule LiveBeats.MediaLibrary.Genre do end defp put_slug(%Ecto.Changeset{valid?: false} = changeset), do: changeset + defp put_slug(%Ecto.Changeset{valid?: true} = changeset) do if title = get_change(changeset, :title) do put_change(changeset, :slug, Phoenix.Naming.underscore(title)) diff --git a/lib/live_beats_web/channels/presence.ex b/lib/live_beats_web/channels/presence.ex index cdafae9..6b02faa 100644 --- a/lib/live_beats_web/channels/presence.ex +++ b/lib/live_beats_web/channels/presence.ex @@ -90,8 +90,11 @@ defmodule LiveBeatsWeb.Presence do |> assign_new(:total_count, fn -> count end) ~H""" -
-

Listening now (<%= @count %>)

+
+ +

+ Listening now (<%= @count %>) +

<%= if @total_count > @count do %> @@ -125,7 +124,7 @@ end defmodule LiveBeatsWeb.Presence.BadgeComponent do use LiveBeatsWeb, :live_component - # https://fly.io/docs/reference/regions/ + #  https://fly.io/docs/reference/regions/ @region_names %{ "ams" => "Amsterdam, Netherlands", "atl" => "Atlanta, Georgia (US)", @@ -152,14 +151,27 @@ defmodule LiveBeatsWeb.Presence.BadgeComponent do def render(assigns) do ~H"""
  • - <.link navigate={profile_path(@presence)} class="flex-1 flex items-center justify-between border-t border-r border-b border-gray-200 bg-white rounded-r-md truncate"> - + <.link + navigate={profile_path(@presence)} + class="flex-1 flex items-center justify-between border-t border-r border-b border-gray-200 bg-white rounded-r-md truncate" + > +
    <%= @presence.username %> <%= if @ping do %>

    ping: <%= @ping %>ms

    - <%= if @region do %><% end %> + <%= if @region do %> + + <% end %> <% end %>
    diff --git a/lib/live_beats_web/controllers/oauth_callback_controller.ex b/lib/live_beats_web/controllers/oauth_callback_controller.ex index 4105084..d4ebc54 100644 --- a/lib/live_beats_web/controllers/oauth_callback_controller.ex +++ b/lib/live_beats_web/controllers/oauth_callback_controller.ex @@ -10,7 +10,6 @@ defmodule LiveBeatsWeb.OAuthCallbackController do with {:ok, info} <- client.exchange_access_token(code: code, state: state), %{info: info, primary_email: primary, emails: emails, token: token} = info, {:ok, user} <- Accounts.register_github_user(primary, info, emails, token) do - conn |> put_flash(:info, "Welcome #{user.email}") |> LiveBeatsWeb.UserAuth.log_in_user(user) @@ -19,7 +18,10 @@ defmodule LiveBeatsWeb.OAuthCallbackController do Logger.debug("failed GitHub insert #{inspect(changeset.errors)}") conn - |> put_flash(:error, "We were unable to fetch the necessary information from your GithHub account") + |> put_flash( + :error, + "We were unable to fetch the necessary information from your GithHub account" + ) |> redirect(to: "/") {:error, reason} -> @@ -40,6 +42,6 @@ defmodule LiveBeatsWeb.OAuthCallbackController do end defp github_client(conn) do - conn.assigns[:github_client] || LiveBeats.Github + conn.assigns[:github_client] || LiveBeats.Github end end diff --git a/lib/live_beats_web/controllers/user_auth.ex b/lib/live_beats_web/controllers/user_auth.ex index eb48ad3..e352c43 100644 --- a/lib/live_beats_web/controllers/user_auth.ex +++ b/lib/live_beats_web/controllers/user_auth.ex @@ -19,7 +19,9 @@ defmodule LiveBeatsWeb.UserAuth do def on_mount(:ensure_authenticated, _params, session, socket) do case session do %{"user_id" => user_id} -> - new_socket = LiveView.assign_new(socket, :current_user, fn -> Accounts.get_user!(user_id) end) + new_socket = + LiveView.assign_new(socket, :current_user, fn -> Accounts.get_user!(user_id) end) + %Accounts.User{} = new_socket.assigns.current_user {:cont, new_socket} diff --git a/lib/live_beats_web/live/live_helpers.ex b/lib/live_beats_web/live/live_helpers.ex index 0a9cdf4..0c71ea1 100644 --- a/lib/live_beats_web/live/live_helpers.ex +++ b/lib/live_beats_web/live/live_helpers.ex @@ -158,42 +158,6 @@ defmodule LiveBeatsWeb.LiveHelpers do """ end - attr :navigate, :string - attr :patch, :string - attr :href, :string, default: nil - attr :replace, :string, default: false - attr :rest, :global - def link(%{navigate: _to} = assigns) do - assigns = assign_new(assigns, :class, fn -> nil end) - - ~H""" - - <%= render_slot(@inner_block) %> - - """ - end - - def link(%{patch: _to} = assigns) do - ~H""" - - <%= render_slot(@inner_block) %> - - """ - end - - def link(%{} = assigns) do - ~H""" - - <%= render_slot(@inner_block) %> - - """ - end - @doc """ Returns a button triggered dropdown with aria keyboard and focus supporrt. @@ -487,19 +451,6 @@ defmodule LiveBeatsWeb.LiveHelpers do """ end - attr :id, :string, required: true - attr :content, :string - - def focus_wrap(assigns) do - ~H""" -
    - - <%= render_slot(@inner_block) %> - -
    - """ - end - attr :id, :string, required: true attr :min, :integer, default: 0 attr :max, :integer, default: 100 diff --git a/lib/live_beats_web/live/player_live.ex b/lib/live_beats_web/live/player_live.ex index fb235e8..a26b661 100644 --- a/lib/live_beats_web/live/player_live.ex +++ b/lib/live_beats_web/live/player_live.ex @@ -29,9 +29,11 @@ defmodule LiveBeatsWeb.PlayerLive do <.progress_bar id="player-progress" /> -
    + phx-update="ignore" + >
    @@ -43,7 +45,7 @@ defmodule LiveBeatsWeb.PlayerLive do navigate={profile_path(@profile)} class="mx-auto flex border-2 border-white border-opacity-20 rounded-md p-1 pr-2" > - <.icon name={:user_circle} class="w-4 h-4 block"/> + <.icon name={:user_circle} class="w-4 h-4 block" />

    <%= @profile.username %>

    <% else %> @@ -52,7 +54,12 @@ defmodule LiveBeatsWeb.PlayerLive do <%= if is_nil(@profile) or @own_profile? do %> - -
  • - +
    - <.error input_name={"songs[#{@ref}][title]"} field={:title} errors={@errors} class="-mt-1"/> - <.error input_name={"songs[#{@ref}][artist]"} field={:artist} errors={@errors} class="-mt-1"/> + <.error input_name={"songs[#{@ref}][title]"} field={:title} errors={@errors} class="-mt-1" /> + <.error input_name={"songs[#{@ref}][artist]"} field={:artist} errors={@errors} class="-mt-1" />
    - <.error input_name={"songs[#{@ref}][attribution]"} field={:attribution} errors={@errors} class="-mt-1"/> + <.error + input_name={"songs[#{@ref}][attribution]"} + field={:attribution} + errors={@errors} + class="-mt-1" + />
    + > +
    """ end diff --git a/lib/live_beats_web/live/profile_live/song_row_component.ex b/lib/live_beats_web/live/profile_live/song_row_component.ex index 33d3884..61b64da 100644 --- a/lib/live_beats_web/live/profile_live/song_row_component.ex +++ b/lib/live_beats_web/live/profile_live/song_row_component.ex @@ -10,27 +10,39 @@ defmodule LiveBeatsWeb.ProfileLive.SongRowComponent do <%= for {col, i} <- Enum.with_index(@col) do %> + >
    <%= if i == 0 do %> <%= if @status == :playing do %> - <.icon name={:volume_up} class="h-5 w-5 -mt-1 -ml-1" aria-label="Playing" role="button"/> + <.icon + name={:volume_up} + class="h-5 w-5 -mt-1 -ml-1" + aria-label="Playing" + role="button" + /> <% end %> <%= if @status == :paused do %> - <.icon name={:volume_up} class="h-5 w-5 -mt-1 -ml-1 text-gray-400" aria-label="Paused" role="button"/> + <.icon + name={:volume_up} + class="h-5 w-5 -mt-1 -ml-1 text-gray-400" + aria-label="Paused" + role="button" + /> <% end %> <%= if @status == :stopped do %> - <%= if @owns_profile? do %> - <.icon name={:play} class="h-5 w-5 text-gray-400" aria-label="Play" role="button"/> - <% end %> + <%= if @owns_profile? do %> + <.icon name={:play} class="h-5 w-5 text-gray-400" aria-label="Play" role="button" /> + <% end %> <% end %> <% end %> @@ -42,7 +54,8 @@ defmodule LiveBeatsWeb.ProfileLive.SongRowComponent do """ end - def update(%{action: :send, status: status}, socket) when status in [:playing, :paused, :stopped] do + def update(%{action: :send, status: status}, socket) + when status in [:playing, :paused, :stopped] do {:ok, assign(socket, status: status)} end diff --git a/lib/live_beats_web/live/profile_live/upload_form_component.ex b/lib/live_beats_web/live/profile_live/upload_form_component.ex index 0740bd3..29fc864 100644 --- a/lib/live_beats_web/live/profile_live/upload_form_component.ex +++ b/lib/live_beats_web/live/profile_live/upload_form_component.ex @@ -169,7 +169,7 @@ defmodule LiveBeatsWeb.ProfileLive.UploadFormComponent do do: ~H|Something went wrong| defp file_error(%{kind: %Ecto.Changeset{}} = assigns), - do: ~H|<%= @label %>: <%= LiveBeatsWeb.ErrorHelpers.translate_changeset_errors(@kind) %>| + do: ~H|<%= @label %>: <%= LiveBeatsWeb.ErrorHelpers.translate_changeset_errors(@kind) %>| defp file_error(%{kind: {msg, opts}} = assigns) when is_binary(msg) and is_list(opts), do: ~H|<%= @label %>: <%= LiveBeatsWeb.ErrorHelpers.translate_error(@kind) %>| diff --git a/lib/live_beats_web/live/profile_live/upload_form_component.html.heex b/lib/live_beats_web/live/profile_live/upload_form_component.html.heex index a791a27..258f9d1 100644 --- a/lib/live_beats_web/live/profile_live/upload_form_component.html.heex +++ b/lib/live_beats_web/live/profile_live/upload_form_component.html.heex @@ -7,14 +7,13 @@ class="space-y-8" phx-target={@myself} phx-change="validate" - phx-submit="save"> - + phx-submit="save" + >
    <%= for {{ref, changeset}, i} <- Enum.with_index(@changesets) do %> <.live_component id={ref} module={SongEntryComponent} changeset={changeset} index={i} /> <% end %> -
    @@ -22,7 +21,7 @@
    - <.icon name={:x_circle} class="h-5 w-5 text-red-400"/> + <.icon name={:x_circle} class="h-5 w-5 text-red-400" />

    @@ -42,13 +41,30 @@
    -
    -
    diff --git a/lib/live_beats_web/live/settings_live.ex b/lib/live_beats_web/live/settings_live.ex index d912df4..643b99b 100644 --- a/lib/live_beats_web/live/settings_live.ex +++ b/lib/live_beats_web/live/settings_live.ex @@ -10,7 +10,13 @@ defmodule LiveBeatsWeb.SettingsLive do
    - <.form let={f} for={@changeset} phx-change="validate" phx-submit="save" class="space-y-8 divide-y divide-gray-200"> + <.form + :let={f} + for={@changeset} + phx-change="validate" + phx-submit="save" + class="space-y-8 divide-y divide-gray-200" + >
    @@ -28,8 +34,16 @@ defmodule LiveBeatsWeb.SettingsLive do <%= URI.parse(LiveBeatsWeb.Endpoint.url()).host %>/ - <%= text_input f, :username, class: "flex-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full min-w-0 rounded-none rounded-r-md sm:text-sm border-gray-300" %> - <.error field={:username} input_name="user[username]" errors={@changeset.errors} class="pt-2 pl-4 pr-4 ml-2 text-center" /> + <%= text_input(f, :username, + class: + "flex-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full min-w-0 rounded-none rounded-r-md sm:text-sm border-gray-300" + ) %> + <.error + field={:username} + input_name="user[username]" + errors={@changeset.errors} + class="pt-2 pl-4 pr-4 ml-2 text-center" + />
    @@ -38,7 +52,11 @@ defmodule LiveBeatsWeb.SettingsLive do Email (from GitHub)
    - <%= text_input f, :email, disabled: true, class: "flex-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full min-w-0 rounded-md sm:text-sm border-gray-300 bg-gray-50" %> + <%= text_input(f, :email, + disabled: true, + class: + "flex-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full min-w-0 rounded-md sm:text-sm border-gray-300 bg-gray-50" + ) %>
    @@ -47,8 +65,16 @@ defmodule LiveBeatsWeb.SettingsLive do Profile Tagline
    - <%= text_input f, :profile_tagline, class: "flex-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full min-w-0 rounded-md sm:text-sm border-gray-300" %> - <.error field={:profile_tagline} input_name="user[profile_tagline]" errors={@changeset.errors} class="pt-2 pl-4 pr-4 ml-2 text-center" /> + <%= text_input(f, :profile_tagline, + class: + "flex-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full min-w-0 rounded-md sm:text-sm border-gray-300" + ) %> + <.error + field={:profile_tagline} + input_name="user[profile_tagline]" + errors={@changeset.errors} + class="pt-2 pl-4 pr-4 ml-2 text-center" + />

    Write a short tagline for your beats page.

    @@ -58,7 +84,10 @@ defmodule LiveBeatsWeb.SettingsLive do
    -
    diff --git a/lib/live_beats_web/live/sign_in_live.ex b/lib/live_beats_web/live/sign_in_live.ex index 146d1d7..c86ce91 100644 --- a/lib/live_beats_web/live/sign_in_live.ex +++ b/lib/live_beats_web/live/sign_in_live.ex @@ -5,7 +5,11 @@ defmodule LiveBeatsWeb.SignInLive do ~H"""
    - Workflow + Workflow

    Sign in to your account

    @@ -20,7 +24,10 @@ defmodule LiveBeatsWeb.SignInLive do
    diff --git a/lib/live_beats_web/templates/layout/live.html.heex b/lib/live_beats_web/templates/layout/live.html.heex index b45e9ae..b6b9f53 100644 --- a/lib/live_beats_web/templates/layout/live.html.heex +++ b/lib/live_beats_web/templates/layout/live.html.heex @@ -1,28 +1,48 @@ -

    <%= for user <- @users do %> - <.link navigate={profile_path(user)} + <.link + navigate={profile_path(user)} class="group flex items-center px-3 py-2 text-base leading-5 font-medium text-gray-600 rounded-md hover:text-gray-900 hover:bg-gray-50" > @@ -36,30 +37,51 @@ defmodule LiveBeatsWeb.LayoutView do <%= if @current_user do %> <.link navigate={profile_path(@current_user)} - class={"text-gray-700 hover:text-gray-900 group flex items-center px-2 py-2 text-sm font-medium rounded-md #{if @active_tab == :profile, do: "bg-gray-200", else: "hover:bg-gray-50"}"} + class={ + "text-gray-700 hover:text-gray-900 group flex items-center px-2 py-2 text-sm font-medium rounded-md #{if @active_tab == :profile, do: "bg-gray-200", else: "hover:bg-gray-50"}" + } aria-current={if @active_tab == :profile, do: "true", else: "false"} > - <.icon name={:music_note} outlined class="text-gray-400 group-hover:text-gray-500 mr-3 flex-shrink-0 h-6 w-6"/> - My Songs + <.icon + name={:music_note} + outlined + class="text-gray-400 group-hover:text-gray-500 mr-3 flex-shrink-0 h-6 w-6" + /> My Songs <.link navigate={Routes.settings_path(Endpoint, :edit)} - class={"text-gray-700 hover:text-gray-900 group flex items-center px-2 py-2 text-sm font-medium rounded-md #{if @active_tab == :settings, do: "bg-gray-200", else: "hover:bg-gray-50"}"} + class={ + "text-gray-700 hover:text-gray-900 group flex items-center px-2 py-2 text-sm font-medium rounded-md #{if @active_tab == :settings, do: "bg-gray-200", else: "hover:bg-gray-50"}" + } aria-current={if @active_tab == :settings, do: "true", else: "false"} > - <.icon name={:adjustments} outlined class="text-gray-400 group-hover:text-gray-500 mr-3 flex-shrink-0 h-6 w-6"/> - Settings + <.icon + name={:adjustments} + outlined + class="text-gray-400 group-hover:text-gray-500 mr-3 flex-shrink-0 h-6 w-6" + /> Settings <% else %> - <.link navigate={Routes.sign_in_path(Endpoint, :index)} + <.link + navigate={Routes.sign_in_path(Endpoint, :index)} class="text-gray-700 hover:text-gray-900 hover:bg-gray-50 group flex items-center px-2 py-2 text-sm font-medium rounded-md" > -