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
34 changes: 20 additions & 14 deletions lib/cookbook_web/live/cookbook_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule CookbookWeb.CookbookLive do

@featured_recipes ["search", "card-row", "sectioned-grid", "gesture"]

def handle_params(params, uri, socket) do
def handle_params(_params, uri, socket) do
uri = URI.parse(uri) |> Map.put(:query, nil) |> URI.to_string()

{:ok, qr} =
Expand All @@ -21,46 +21,52 @@ defmodule CookbookWeb.CookbookLive do
end

def mount(_params, _session, socket) do
all_recipes = recipes(nil)
all_recipes = recipes("All", "")
categorized_recipes = Enum.group_by(all_recipes, & &1.metadata.category)

categories =
categorized_recipes
categories = categorized_recipes
|> Map.keys()
|> Enum.sort()
categories = ["All" | categories]

{:ok,
socket
|> assign(:recipes, all_recipes)
|> assign(:selected_category, nil)
|> assign(:selected_category, "All")
|> assign(:query, "")
|> assign(:scope, "")
|> assign(:categories, categories)
|> assign(
:featured_recipes,
Enum.filter(all_recipes, &Enum.member?(@featured_recipes, Path.basename(&1.path)))
)}
end

def handle_event("clear-filter", _params, socket) do
handle_event("filter", %{"category" => nil}, socket)
end
# def handle_event("clear-filter", _params, socket) do
# handle_event("filter", %{"category" => nil}, socket)
# end

def handle_event("filter", %{"category" => category}, socket) do
{:noreply,
socket
|> assign(:selected_category, category)
|> assign(:recipes, recipes(category))}
|> assign(:recipes, recipes(category, socket.assigns.query))}
end

def recipes(nil) do
Phoenix.Router.routes(CookbookWeb.Router)
|> Enum.filter(&String.starts_with?(&1.path, "/recipes/"))
def handle_event("query-changed", %{ "query" => query }, socket) do
{:noreply,
socket
|> assign(:query, query)
|> assign(:recipes, recipes(socket.assigns.selected_category, query))}
end

def recipes(category) do
def recipes(category, query) do
query = String.downcase(query)
Phoenix.Router.routes(CookbookWeb.Router)
|> Enum.filter(
&(String.starts_with?(&1.path, "/recipes/") and &1.metadata.category == category)
&(String.starts_with?(&1.path, "/recipes/") and (&1.metadata.category == category or category == "All"))
)
|> Enum.filter(&(String.contains?(String.downcase(&1.metadata.title), query) or String.contains?(String.downcase(&1.metadata.description), query)))
end

def render(assigns) do
Expand Down
156 changes: 84 additions & 72 deletions lib/cookbook_web/live/cookbook_live.swiftui.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,81 +5,93 @@ defmodule CookbookWeb.CookbookLive.SwiftUI do
target = Map.get(interface, "target", "ios")
assigns = assign(assigns, :target, target)
~LVN"""
<List
id="cookbook"
style={[
"listStyle(.plain)",
~s[navigationTitle("Cookbook")],
"toolbar(content: :toolbar)"
]}
<Group
style={[~s[searchScopes(attr("category"), activation: .automatic, scopes: :scopes)]]}
category={@selected_category}
phx-change="filter"
>
<ToolbarItem template="toolbar">
<.link href="https://github.com/liveview-native/cookbook" style="buttonStyle(.automatic);">
<.icon name="info.circle" />
</.link>
</ToolbarItem>
<Section style="listSectionSeparator(.hidden); listSectionSpacing(0);">
<ScrollView
axes="horizontal"
style={[
"scrollTargetBehavior(.viewAligned)",
"scrollIndicators(.hidden)",
"safeAreaPadding(.horizontal, 16)",
"listRowInsets(EdgeInsets())",
"listRowSpacing(0)",
"listRowBackground(:none)",
"padding(.vertical, 8)"
]}
>
<HStack style="scrollTargetLayout();">
<Group
style={[
~s[containerRelativeFrame(.horizontal, count: attr("count"), span: 1, spacing: 16)]
]}
count={if @target == "ios", do: 1, else: 3}
>
<.featured_recipe
:for={{recipe, index} <- Enum.with_index(@featured_recipes)}
recipe={recipe}
hue={index / length(@featured_recipes)}
/>
</Group>
<Text template="scopes" :for={category <- @categories} id={category}><%= category %></Text>
<List
id="cookbook"
style={[
"listStyle(.plain)",
~s[navigationTitle("Cookbook")],
"toolbar(content: :toolbar)",
~s[searchable(text: attr("query"))]
]}
query={@query}
scope={@scope}
phx-change="query-changed"
phx-debounce={100}
>
<ToolbarItem template="toolbar">
<.link href="https://github.com/liveview-native/cookbook" style="buttonStyle(.automatic);">
<.icon name="info.circle" />
</.link>
</ToolbarItem>
<Section style="listSectionSeparator(.hidden); listSectionSpacing(0);">
<ScrollView
axes="horizontal"
style={[
"scrollTargetBehavior(.viewAligned)",
"scrollIndicators(.hidden)",
"safeAreaPadding(.horizontal, 16)",
"listRowInsets(EdgeInsets())",
"listRowSpacing(0)",
"listRowBackground(:none)",
"padding(.vertical, 8)"
]}
>
<HStack style="scrollTargetLayout();">
<Group
style={[
~s[containerRelativeFrame(.horizontal, count: attr("count"), span: 1, spacing: 16)]
]}
count={if @target == "ios", do: 1, else: 3}
>
<.featured_recipe
:for={{recipe, index} <- Enum.with_index(@featured_recipes)}
recipe={recipe}
hue={index / length(@featured_recipes)}
/>
</Group>
</HStack>
</ScrollView>
</Section>
<Section>
<HStack template="header">
<Text>Recipes</Text>
<Spacer />
<Menu>
<Label template="label" systemImage={if @selected_category == nil, do: "line.3.horizontal.decrease.circle", else: "line.3.horizontal.decrease.circle.fill"}>
<%= @selected_category || "All" %>
</Label>

<%!-- <Button phx-click="clear-filter">All</Button> --%>
<Button
:for={category <- @categories}
phx-click="filter"
phx-value-category={category}
>
<%= category %>
</Button>
</Menu>
</HStack>
</ScrollView>
</Section>
<Section>
<HStack template="header">
<Text>Recipes</Text>
<Spacer />
<Menu>
<Label template="label" systemImage={if @selected_category == nil, do: "line.3.horizontal.decrease.circle", else: "line.3.horizontal.decrease.circle.fill"}>
<%= @selected_category || "All" %>
<.link
:for={recipe <- @recipes}
navigate={recipe.path}
>
<Label>
<VStack alignment="leading" template="title">
<Text><%= recipe.metadata.title %></Text>
<Text style="foregroundStyle(.secondary);"><%= recipe.metadata.description %></Text>
</VStack>
<Image template="icon" systemName={recipe.metadata.icon} />
</Label>

<Button phx-click="clear-filter">All</Button>
<Button
:for={category <- @categories}
phx-click="filter"
phx-value-category={category}
>
<%= category %>
</Button>
</Menu>
</HStack>
<.link
:for={recipe <- @recipes}
navigate={recipe.path}
>
<Label>
<VStack alignment="leading" template="title">
<Text><%= recipe.metadata.title %></Text>
<Text style="foregroundStyle(.secondary);"><%= recipe.metadata.description %></Text>
</VStack>
<Image template="icon" systemName={recipe.metadata.icon} />
</Label>
</.link>
</Section>
</List>
</.link>
</Section>
</List>
</Group>
"""
end

Expand Down