mirror of
https://github.com/ash-project/ash_hq.git
synced 2024-09-20 13:23:38 +12:00
242771dca9
The existing code was a bit convoluted, and did not work correctly when toggling the theme back to the system theme - neither theme was properly applied on page load (cookie was present, so no theming was added) This also fixes the edge case where changing the system theme would override the site theme, due to not reading/using the cookie value correctly
299 lines
9.4 KiB
Elixir
299 lines
9.4 KiB
Elixir
defmodule AshHqWeb.AppViewLive do
|
|
# credo:disable-for-this-file Credo.Check.Readability.MaxLineLength
|
|
use Surface.LiveView,
|
|
container: {:div, class: "h-full"}
|
|
|
|
alias AshHqWeb.Components.AppView.TopBar
|
|
|
|
alias AshHqWeb.Components.Search
|
|
alias AshHqWeb.Pages.{Ashley, Blog, Community, Docs, Home, Media, UserSettings}
|
|
|
|
alias Phoenix.LiveView.JS
|
|
alias Surface.Components.Context
|
|
require Ash.Query
|
|
|
|
import AshHqWeb.Tails
|
|
|
|
data(configured_theme, :string, default: :system)
|
|
data(libraries, :list, default: [])
|
|
data(selected_types, :map, default: %{})
|
|
data(current_user, :map)
|
|
|
|
data(library, :any, default: nil)
|
|
data(extension, :any, default: nil)
|
|
data(docs, :any, default: nil)
|
|
data(library_version, :any, default: nil)
|
|
data(guide, :any, default: nil)
|
|
data(doc_path, :list, default: [])
|
|
data(dsls, :list, default: [])
|
|
data(dsl, :any, default: nil)
|
|
data(options, :list, default: [])
|
|
data(module, :any, default: nil)
|
|
|
|
def render(%{platform: :ios} = assigns) do
|
|
~F"""
|
|
{#case @live_action}
|
|
{#match :home}
|
|
<Home id="home" />
|
|
{/case}
|
|
"""
|
|
end
|
|
|
|
def render(assigns) do
|
|
~F"""
|
|
<div
|
|
id="app"
|
|
class={classes(["h-full font-sans": true])}
|
|
phx-hook="ColorTheme"
|
|
>
|
|
<head>
|
|
<meta property="og:type" content="text/html">
|
|
<meta property="og:image" content="https://ash-hq.org/images/ash-logo-side.png">
|
|
<meta property="og:url" content={to_string(@uri)}>
|
|
<meta property="og:site_name" content="Ash HQ">
|
|
<meta property="twitter:card" content="summary_large_image">
|
|
<meta property="twitter:domain" content="ash-hq.org">
|
|
<meta property="twitter:site" content="@AshFramework">
|
|
<!-- Need to adjust this for future blog writers -->
|
|
<meta property="twitter:creator" content="@ZachSDaniel1">
|
|
|
|
{#if @live_action not in [:docs_dsl, :blog, :forum]}
|
|
<meta property="og:title" content="Ash Framework">
|
|
<meta
|
|
property="og:description"
|
|
content="A declarative foundation for ambitious Elixir applications. Model your domain, derive the rest."
|
|
/>
|
|
{/if}
|
|
</head>
|
|
<Search
|
|
id="search-box"
|
|
uri={@uri}
|
|
close={close_search()}
|
|
libraries={@libraries}
|
|
selected_types={@selected_types}
|
|
change_types="change-types"
|
|
change_versions="change-versions"
|
|
remove_version="remove_version"
|
|
/>
|
|
<button id="search-button" class="hidden" phx-click={AshHqWeb.AppViewLive.toggle_search()} />
|
|
<div
|
|
id="main-container"
|
|
class={
|
|
"w-full min-h-screen bg-white dark:bg-base-dark-850 dark:text-white flex flex-col items-stretch",
|
|
"h-screen overflow-y-auto": @live_action != :docs_dsl
|
|
}
|
|
>
|
|
<TopBar
|
|
live_action={@live_action}
|
|
toggle_theme="toggle_theme"
|
|
configured_theme={@configured_theme}
|
|
current_user={@current_user}
|
|
/>
|
|
{#for flash <- List.wrap(live_flash(@flash, :error))}
|
|
<p class="alert alert-warning" role="alert">{flash}</p>
|
|
{/for}
|
|
{#for flash <- List.wrap(live_flash(@flash, :info))}
|
|
<p class="alert alert-info max-h-min" role="alert">{flash}</p>
|
|
{/for}
|
|
{#case @live_action}
|
|
{#match :home}
|
|
<Home id="home" device_brand={@device_brand} />
|
|
{#match :blog}
|
|
<Blog id="blog" params={@params} />
|
|
{#match :community}
|
|
<Community id="community" />
|
|
{#match :docs_dsl}
|
|
<Docs
|
|
id="docs"
|
|
uri={@uri}
|
|
params={@params}
|
|
remove_version="remove_version"
|
|
change_versions="change-versions"
|
|
libraries={@libraries}
|
|
/>
|
|
{#match :user_settings}
|
|
<UserSettings id="user_settings" current_user={@current_user} />
|
|
{#match :media}
|
|
<Media id="media" />
|
|
{#match :ashley}
|
|
<Ashley id="ashley" current_user={@current_user} params={@params} />
|
|
{/case}
|
|
|
|
{#if @live_action not in [:docs_dsl, :ashley]}
|
|
<footer class="p-8 sm:p-6 bg-base-light-200 dark:bg-base-dark-850 sm:justify-center sticky">
|
|
<div class="md:flex md:justify-around">
|
|
<div class="flex justify-center mb-6 md:mb-0">
|
|
<a href="/" class="flex items-center">
|
|
<img src="/images/ash-logo-side.svg" class="mr-3 h-32" alt="Ash Framework Logo">
|
|
</a>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-3 gap-8 sm:gap-6">
|
|
<div>
|
|
<h2 class="mb-6 text-sm font-semibold text-gray-900 uppercase dark:text-white">Resources</h2>
|
|
<ul class="text-gray-600 dark:text-gray-400">
|
|
<li class="mb-4">
|
|
<a href="https://github.com/ash-project" class="hover:underline">Source</a>
|
|
</li>
|
|
<li class="mb-4">
|
|
<a href="/docs/guides/ash/latest/tutorials/get-started" class="hover:underline">Get Started</a>
|
|
</li>
|
|
<li class="mb-4">
|
|
<a href="/blog" class="hover:underline">Blog</a>
|
|
</li>
|
|
<li>
|
|
<a href="/media" class="hover:underline">Media</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div>
|
|
<h2 class="mb-6 text-sm font-semibold text-gray-900 uppercase dark:text-white">Community</h2>
|
|
<ul class="text-gray-600 dark:text-gray-400">
|
|
<li class="mb-4">
|
|
<a href="https://twitter.com/AshFramework" class="hover:underline">Twitter</a>
|
|
</li>
|
|
<li>
|
|
<a href="https://discord.gg/D7FNG2q" class="hover:underline">Discord</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div>
|
|
<h2 class="mb-6 text-sm font-semibold text-gray-900 uppercase dark:text-white">Help Us</h2>
|
|
<ul class="text-gray-600 dark:text-gray-400">
|
|
<li class="mb-4">
|
|
<a href="https://github.com/ash-project/ash_hq/issues/new/choose" class="hover:underline">Report an issue</a>
|
|
</li>
|
|
<li class="mb-4">
|
|
<a href="https://ash-hq.appsignal-status.com" class="hover:underline">Status Page</a>
|
|
</li>
|
|
<li>
|
|
<a href="/docs/guides/ash/latest/how_to/contribute" class="hover:underline">Contribute</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
{/if}
|
|
</div>
|
|
</div>
|
|
"""
|
|
end
|
|
|
|
def handle_params(params, uri, socket) do
|
|
{:noreply,
|
|
socket
|
|
|> assign(params: params, uri: uri)}
|
|
end
|
|
|
|
def handle_info({:page_title, title}, socket) do
|
|
{:noreply, assign(socket, :page_title, "Ash Framework - #{title}")}
|
|
end
|
|
|
|
def handle_event("change-types", %{"types" => types}, socket) do
|
|
types =
|
|
types
|
|
|> Enum.filter(fn {_, value} ->
|
|
value == "true"
|
|
end)
|
|
|> Enum.map(&elem(&1, 0))
|
|
|
|
{:noreply,
|
|
socket
|
|
|> assign(
|
|
:selected_types,
|
|
types
|
|
)
|
|
|> push_event("selected-types", %{types: types})}
|
|
end
|
|
|
|
def handle_event("toggle_theme", _, socket) do
|
|
theme =
|
|
case socket.assigns.configured_theme do
|
|
"light" ->
|
|
"dark"
|
|
|
|
"dark" ->
|
|
"system"
|
|
|
|
"system" ->
|
|
"light"
|
|
end
|
|
|
|
{:noreply,
|
|
socket
|
|
|> assign(:configured_theme, theme)
|
|
|> push_event("set_theme", %{theme: theme})}
|
|
end
|
|
|
|
def mount(_params, session, socket) do
|
|
socket = assign(socket, :page_title, "Ash Framework")
|
|
|
|
socket =
|
|
assign_new(socket, :user_agent, fn _assigns ->
|
|
get_connect_params(socket)["user_agent"]
|
|
end)
|
|
|
|
socket = assign(socket, :device_brand, "Apple")
|
|
|
|
socket = Context.put(socket, platform: socket.assigns.platform)
|
|
configured_theme = session["theme"] || "system"
|
|
|
|
all_types = AshHq.Docs.Extensions.Search.Types.types()
|
|
|
|
selected_types =
|
|
case session["selected_types"] do
|
|
nil ->
|
|
AshHq.Docs.Extensions.Search.Types.types()
|
|
|
|
types ->
|
|
types
|
|
|> String.split(",")
|
|
|> Enum.filter(&(&1 in all_types))
|
|
end
|
|
|
|
versions_query =
|
|
AshHq.Docs.LibraryVersion
|
|
|> Ash.Query.sort(version: :desc)
|
|
|
|
libraries = AshHq.Docs.Library.read!(load: [versions: versions_query])
|
|
|
|
{:ok,
|
|
socket
|
|
|> assign(:libraries, libraries)
|
|
|> assign(
|
|
:selected_types,
|
|
selected_types
|
|
)
|
|
|> assign(configured_theme: configured_theme)
|
|
|> push_event("selected_types", %{types: selected_types})}
|
|
end
|
|
|
|
def toggle_search(js \\ %JS{}) do
|
|
js
|
|
|> JS.toggle(
|
|
to: "#search-box",
|
|
in: {
|
|
"transition ease-in duration-100",
|
|
"opacity-0",
|
|
"opacity-100"
|
|
},
|
|
out: {
|
|
"transition ease-out duration-75",
|
|
"opacity-100",
|
|
"opacity-0"
|
|
}
|
|
)
|
|
|> JS.dispatch("js:focus", to: "#search-input")
|
|
end
|
|
|
|
def close_search(js \\ %JS{}) do
|
|
js
|
|
|> JS.hide(
|
|
transition: "fade-out",
|
|
to: "#search-box"
|
|
)
|
|
|> JS.hide(transition: "fade-out", to: "#search-versions")
|
|
|> JS.show(transition: "fade-in", to: "#search-body")
|
|
end
|
|
end
|