- <.link navigate={~p"/media_profiles"}>
+ <.link :if={!Plug.Conn.get_session(@conn, :onboarding)} navigate={~p"/media_profiles"}>
<.icon name="hero-arrow-left" class="w-10 h-10 hover:dark:text-white" />
diff --git a/lib/pinchflat_web/controllers/media_sources/source_controller.ex b/lib/pinchflat_web/controllers/media_sources/source_controller.ex
index e4b28ad..58aaf90 100644
--- a/lib/pinchflat_web/controllers/media_sources/source_controller.ex
+++ b/lib/pinchflat_web/controllers/media_sources/source_controller.ex
@@ -16,18 +16,37 @@ defmodule PinchflatWeb.MediaSources.SourceController do
def new(conn, _params) do
changeset = MediaSource.change_source(%Source{})
- render(conn, :new, changeset: changeset, media_profiles: media_profiles())
+ if get_session(conn, :onboarding) do
+ render(conn, :new,
+ changeset: changeset,
+ media_profiles: media_profiles(),
+ layout: {Layouts, :onboarding}
+ )
+ else
+ render(conn, :new, changeset: changeset, media_profiles: media_profiles())
+ end
end
def create(conn, %{"source" => source_params}) do
case MediaSource.create_source(source_params) do
{:ok, source} ->
+ redirect_location =
+ if get_session(conn, :onboarding), do: ~p"/?onboarding=1", else: ~p"/sources/#{source}"
+
conn
|> put_flash(:info, "Source created successfully.")
- |> redirect(to: ~p"/sources/#{source}")
+ |> redirect(to: redirect_location)
{:error, %Ecto.Changeset{} = changeset} ->
- render(conn, :new, changeset: changeset, media_profiles: media_profiles())
+ if get_session(conn, :onboarding) do
+ render(conn, :new,
+ changeset: changeset,
+ media_profiles: media_profiles(),
+ layout: {Layouts, :onboarding}
+ )
+ else
+ render(conn, :new, changeset: changeset, media_profiles: media_profiles())
+ end
end
end
diff --git a/lib/pinchflat_web/controllers/media_sources/source_html/new.html.heex b/lib/pinchflat_web/controllers/media_sources/source_html/new.html.heex
index 6bd86c1..5914e03 100644
--- a/lib/pinchflat_web/controllers/media_sources/source_html/new.html.heex
+++ b/lib/pinchflat_web/controllers/media_sources/source_html/new.html.heex
@@ -1,5 +1,5 @@
- <.link navigate={~p"/sources"}>
+ <.link :if={!Plug.Conn.get_session(@conn, :onboarding)} navigate={~p"/sources"}>
<.icon name="hero-arrow-left" class="w-10 h-10 hover:dark:text-white" />
New Source
diff --git a/lib/pinchflat_web/controllers/media_sources/source_html/source_form.html.heex b/lib/pinchflat_web/controllers/media_sources/source_html/source_form.html.heex
index 4244d5d..28c5747 100644
--- a/lib/pinchflat_web/controllers/media_sources/source_html/source_form.html.heex
+++ b/lib/pinchflat_web/controllers/media_sources/source_html/source_form.html.heex
@@ -3,9 +3,9 @@
Oops, something went wrong! Please check the errors below.
- <.input field={f[:original_url]} type="text" label="Source URL" help="URL of a channel or playlist (required)" />
+ <.input field={f[:friendly_name]} type="text" label="Custom Name" />
- <.input field={f[:friendly_name]} type="text" label="Friendly Name" />
+ <.input field={f[:original_url]} type="text" label="Source URL" help="URL of a channel or playlist (required)" />
<.input
field={f[:media_profile_id]}
@@ -21,14 +21,14 @@
options={friendly_index_frequencies()}
type="select"
label="Index Frequency"
- help="Roughly how often to check for media to download"
+ help="The time between one index of this source finishing and the next one starting"
/>
<.input
field={f[:download_media]}
type="toggle"
label="Download Media?"
- help="Unchecking still indexes media but it won't be downloaded"
+ help="Unchecking still indexes media but it won't be downloaded until you enable this option"
/>
<:actions>
diff --git a/lib/pinchflat_web/controllers/page_controller.ex b/lib/pinchflat_web/controllers/page_controller.ex
deleted file mode 100644
index 816b6cf..0000000
--- a/lib/pinchflat_web/controllers/page_controller.ex
+++ /dev/null
@@ -1,9 +0,0 @@
-defmodule PinchflatWeb.PageController do
- use PinchflatWeb, :controller
-
- def home(conn, _params) do
- # The home page is often custom made,
- # so skip the default app layout.
- render(conn, :home)
- end
-end
diff --git a/lib/pinchflat_web/controllers/page_html/home.html.heex b/lib/pinchflat_web/controllers/page_html/home.html.heex
deleted file mode 100644
index 5aa726d..0000000
--- a/lib/pinchflat_web/controllers/page_html/home.html.heex
+++ /dev/null
@@ -1,202 +0,0 @@
-<.flash_group flash={@flash} />
-
-
-
-
-
-
-
- Phoenix Framework
-
- v<%= Application.spec(:phoenix, :vsn) %>
-
-
-
- Peace of mind from prototype to production.
-
-
- Build rich, interactive web applications quickly, with less code and fewer moving parts. Join our growing community of developers using Phoenix to craft APIs, HTML5 apps and more, for fun or at scale.
-
-
-
-
diff --git a/lib/pinchflat_web/controllers/pages/page_controller.ex b/lib/pinchflat_web/controllers/pages/page_controller.ex
new file mode 100644
index 0000000..7c26cdf
--- /dev/null
+++ b/lib/pinchflat_web/controllers/pages/page_controller.ex
@@ -0,0 +1,35 @@
+defmodule PinchflatWeb.Pages.PageController do
+ use PinchflatWeb, :controller
+
+ alias Pinchflat.Repo
+ alias Pinchflat.MediaSource.Source
+ alias Pinchflat.Profiles.MediaProfile
+
+ def home(conn, params) do
+ force_onboarding = params["onboarding"]
+ media_profiles_exist = Repo.exists?(MediaProfile)
+ sources_exist = Repo.exists?(Source)
+
+ if !force_onboarding && media_profiles_exist && sources_exist do
+ render_home_page(conn)
+ else
+ render_onboarding_page(conn, media_profiles_exist, sources_exist)
+ end
+ end
+
+ defp render_home_page(conn) do
+ conn
+ |> put_session(:onboarding, false)
+ |> render(:home)
+ end
+
+ defp render_onboarding_page(conn, media_profiles_exist, sources_exist) do
+ conn
+ |> put_session(:onboarding, true)
+ |> render(:onboarding_checklist,
+ media_profiles_exist: media_profiles_exist,
+ sources_exist: sources_exist,
+ layout: {Layouts, :onboarding}
+ )
+ end
+end
diff --git a/lib/pinchflat_web/controllers/page_html.ex b/lib/pinchflat_web/controllers/pages/page_html.ex
similarity index 60%
rename from lib/pinchflat_web/controllers/page_html.ex
rename to lib/pinchflat_web/controllers/pages/page_html.ex
index de29b52..16f7731 100644
--- a/lib/pinchflat_web/controllers/page_html.ex
+++ b/lib/pinchflat_web/controllers/pages/page_html.ex
@@ -1,4 +1,4 @@
-defmodule PinchflatWeb.PageHTML do
+defmodule PinchflatWeb.Pages.PageHTML do
use PinchflatWeb, :html
embed_templates "page_html/*"
diff --git a/lib/pinchflat_web/controllers/pages/page_html/home.html.heex b/lib/pinchflat_web/controllers/pages/page_html/home.html.heex
new file mode 100644
index 0000000..cecaf9e
--- /dev/null
+++ b/lib/pinchflat_web/controllers/pages/page_html/home.html.heex
@@ -0,0 +1,8 @@
+
+
+
+
TODO: Put some useful info or analytics here
+
For now, the options in the sidebar have what you need
+
+
+
diff --git a/lib/pinchflat_web/controllers/pages/page_html/onboarding_checklist.html.heex b/lib/pinchflat_web/controllers/pages/page_html/onboarding_checklist.html.heex
new file mode 100644
index 0000000..8a387b3
--- /dev/null
+++ b/lib/pinchflat_web/controllers/pages/page_html/onboarding_checklist.html.heex
@@ -0,0 +1,51 @@
+
+
+
+
+ Welcome to Pinchflat
+ Getting started is easy
+
+
+ 1. Create a Media Profile
+ Media Profiles set your preferences for fetching and downloading media.
+ Don't worry, you can create more Media Profiles later!
+
+ <.link navigate={~p"/media_profiles/new"}>
+ <.button color="bg-primary" rounding="rounded-full" disabled={@media_profiles_exist}>
+ + New Media Profile
+
+
+
+
+
+ 2. Create a Source
+ Sources are the channels and playlists you want to download.
+
+ Each Media Profile can control many Sources so it's easy to add more content!
+
+
+ <.link navigate={~p"/sources/new"}>
+ <.button color="bg-primary" rounding="rounded-full" disabled={not @media_profiles_exist}>
+ + New Source
+
+
+
+
+
+ 3. That's it!
+ Everything is set up and running based on your preferences.
+
+ Remember that indexing and downloading media can take a while, many hours for a large source.
+
+ Feel free to add more Media Profiles or Sources in the meantime!
+
+ <.link navigate={~p"/"}>
+ <.button color="bg-primary" rounding="rounded-full" disabled={not @sources_exist}>
+ Let's Go ๐
+
+
+
+
+
+
+
diff --git a/lib/pinchflat_web/router.ex b/lib/pinchflat_web/router.ex
index 0470029..9ec45b6 100644
--- a/lib/pinchflat_web/router.ex
+++ b/lib/pinchflat_web/router.ex
@@ -17,7 +17,7 @@ defmodule PinchflatWeb.Router do
scope "/", PinchflatWeb do
pipe_through :browser
- get "/", PageController, :home
+ get "/", Pages.PageController, :home
resources "/media_profiles", MediaProfiles.MediaProfileController
resources "/search", Searches.SearchController, only: [:show], singleton: true
diff --git a/test/pinchflat/media_test.exs b/test/pinchflat/media_test.exs
index d116ddf..faeb656 100644
--- a/test/pinchflat/media_test.exs
+++ b/test/pinchflat/media_test.exs
@@ -245,6 +245,18 @@ defmodule Pinchflat.MediaTest do
"video/test.srt"
]
end
+
+ test "strips out nil values" do
+ filepaths = %{
+ media_filepath: "/video/test.mp4",
+ thumbnail_filepath: nil,
+ subtitle_filepaths: [["en", nil]]
+ }
+
+ media_item = media_item_fixture(filepaths)
+
+ assert Media.media_filepaths(media_item) == ["/video/test.mp4"]
+ end
end
describe "create_media_item/1" do
diff --git a/test/pinchflat_web/controllers/media_profile_controller_test.exs b/test/pinchflat_web/controllers/media_profile_controller_test.exs
index 8a2e3e1..7ae2298 100644
--- a/test/pinchflat_web/controllers/media_profile_controller_test.exs
+++ b/test/pinchflat_web/controllers/media_profile_controller_test.exs
@@ -22,6 +22,15 @@ defmodule PinchflatWeb.MediaProfileControllerTest do
conn = get(conn, ~p"/media_profiles/new")
assert html_response(conn, 200) =~ "New Media Profile"
end
+
+ test "renders correct layout when onboarding", %{session_conn: session_conn} do
+ session_conn =
+ session_conn
+ |> put_session(:onboarding, true)
+ |> get(~p"/media_profiles/new")
+
+ refute html_response(session_conn, 200) =~ "MENU"
+ end
end
describe "create media_profile" do
@@ -39,6 +48,24 @@ defmodule PinchflatWeb.MediaProfileControllerTest do
conn = post(conn, ~p"/media_profiles", media_profile: @invalid_attrs)
assert html_response(conn, 200) =~ "New Media Profile"
end
+
+ test "redirects to onboarding when onboarding", %{session_conn: session_conn} do
+ session_conn =
+ session_conn
+ |> put_session(:onboarding, true)
+ |> post(~p"/media_profiles", media_profile: @create_attrs)
+
+ assert redirected_to(session_conn) == ~p"/?onboarding=1"
+ end
+
+ test "renders correct layout on error when onboarding", %{session_conn: session_conn} do
+ session_conn =
+ session_conn
+ |> put_session(:onboarding, true)
+ |> post(~p"/media_profiles", media_profile: @invalid_attrs)
+
+ refute html_response(session_conn, 200) =~ "MENU"
+ end
end
describe "edit media_profile" do
diff --git a/test/pinchflat_web/controllers/page_controller_test.exs b/test/pinchflat_web/controllers/page_controller_test.exs
index 87378f0..bd8d23d 100644
--- a/test/pinchflat_web/controllers/page_controller_test.exs
+++ b/test/pinchflat_web/controllers/page_controller_test.exs
@@ -1,8 +1,52 @@
defmodule PinchflatWeb.PageControllerTest do
use PinchflatWeb.ConnCase
- test "GET /", %{conn: conn} do
- conn = get(conn, ~p"/")
- assert html_response(conn, 200) =~ "Peace of mind from prototype to production"
+ import Pinchflat.ProfilesFixtures
+ import Pinchflat.MediaSourceFixtures
+
+ describe "GET / when testing onboarding" do
+ test "sets the onboarding session to true when onboarding", %{conn: conn} do
+ conn = get(conn, ~p"/")
+ assert get_session(conn, :onboarding)
+ end
+
+ test "displays the onboarding page when no media profiles exist", %{conn: conn} do
+ conn = get(conn, ~p"/")
+ assert html_response(conn, 200) =~ "Welcome to Pinchflat"
+ end
+
+ test "displays the onboarding page when no sources exist", %{conn: conn} do
+ _ = media_profile_fixture()
+
+ conn = get(conn, ~p"/")
+ assert html_response(conn, 200) =~ "Welcome to Pinchflat"
+ end
+
+ test "displays the onboarding page when onboarding is forced", %{conn: conn} do
+ _ = media_profile_fixture()
+ _ = source_fixture()
+
+ conn = get(conn, ~p"/?onboarding=1")
+ assert html_response(conn, 200) =~ "Welcome to Pinchflat"
+ end
+
+ test "sets the onboarding session to false when not onboarding", %{conn: conn} do
+ conn = get(conn, ~p"/")
+ assert get_session(conn, :onboarding)
+
+ _ = media_profile_fixture()
+ _ = source_fixture()
+
+ conn = get(conn, ~p"/")
+ refute get_session(conn, :onboarding)
+ end
+
+ test "displays the home page when not onboarding", %{conn: conn} do
+ _ = media_profile_fixture()
+ _ = source_fixture()
+
+ conn = get(conn, ~p"/")
+ assert html_response(conn, 200) =~ "MENU"
+ end
end
end
diff --git a/test/pinchflat_web/controllers/source_controller_test.exs b/test/pinchflat_web/controllers/source_controller_test.exs
index 9f3e2bd..872bee3 100644
--- a/test/pinchflat_web/controllers/source_controller_test.exs
+++ b/test/pinchflat_web/controllers/source_controller_test.exs
@@ -38,6 +38,15 @@ defmodule PinchflatWeb.SourceControllerTest do
conn = get(conn, ~p"/sources/new")
assert html_response(conn, 200) =~ "New Source"
end
+
+ test "renders correct layout when onboarding", %{session_conn: session_conn} do
+ session_conn =
+ session_conn
+ |> put_session(:onboarding, true)
+ |> get(~p"/sources/new")
+
+ refute html_response(session_conn, 200) =~ "MENU"
+ end
end
describe "create source" do
@@ -56,6 +65,26 @@ defmodule PinchflatWeb.SourceControllerTest do
conn = post(conn, ~p"/sources", source: invalid_attrs)
assert html_response(conn, 200) =~ "New Source"
end
+
+ test "redirects to onboarding when onboarding", %{session_conn: session_conn, create_attrs: create_attrs} do
+ expect(YtDlpRunnerMock, :run, 1, &runner_function_mock/3)
+
+ session_conn =
+ session_conn
+ |> put_session(:onboarding, true)
+ |> post(~p"/sources", source: create_attrs)
+
+ assert redirected_to(session_conn) == ~p"/?onboarding=1"
+ end
+
+ test "renders correct layout on error when onboarding", %{session_conn: session_conn, invalid_attrs: invalid_attrs} do
+ session_conn =
+ session_conn
+ |> put_session(:onboarding, true)
+ |> post(~p"/sources", source: invalid_attrs)
+
+ refute html_response(session_conn, 200) =~ "MENU"
+ end
end
describe "edit source" do
diff --git a/test/support/conn_case.ex b/test/support/conn_case.ex
index ff478a0..1408762 100644
--- a/test/support/conn_case.ex
+++ b/test/support/conn_case.ex
@@ -34,6 +34,10 @@ defmodule PinchflatWeb.ConnCase do
setup tags do
Pinchflat.DataCase.setup_sandbox(tags)
- {:ok, conn: Phoenix.ConnTest.build_conn()}
+
+ conn = Phoenix.ConnTest.build_conn()
+ session_conn = Plug.Test.init_test_session(conn, %{})
+
+ {:ok, conn: conn, session_conn: session_conn}
end
end