From de64c6c54aaacc4123031f2e3d5bfb9fc9c517fe Mon Sep 17 00:00:00 2001
From: FloatingGhost <hannah@coffee-and-dreams.uk>
Date: Tue, 28 Mar 2023 12:44:52 +0100
Subject: [PATCH] add selection UI

---
 config/description.exs                        |  6 ++++++
 .../controllers/frontend_switcher.ex          | 20 +++++++++++++++++++
 .../web/akkoma_api/views/frontend_switcher.ex |  3 +++
 lib/pleroma/web/plugs/frontend_static.ex      |  8 ++++++--
 lib/pleroma/web/router.ex                     |  7 +++++++
 .../frontend_switcher/switch.html.eex         |  7 +++++++
 6 files changed, 49 insertions(+), 2 deletions(-)
 create mode 100644 lib/pleroma/web/akkoma_api/controllers/frontend_switcher.ex
 create mode 100644 lib/pleroma/web/akkoma_api/views/frontend_switcher.ex
 create mode 100644 lib/pleroma/web/templates/akkoma_api/frontend_switcher/switch.html.eex

diff --git a/config/description.exs b/config/description.exs
index 2a2d70a7b..75fd23566 100644
--- a/config/description.exs
+++ b/config/description.exs
@@ -3148,6 +3148,12 @@
         description:
           "A map containing available frontends and parameters for their installation.",
         children: frontend_options
+      },
+      %{
+          key: :pickable,
+          type: {:list, :string},
+          description:
+            "A list containing all frontends users can pick as their preference, format is :name/:ref, e.g pleroma-fe/stable."
       }
     ]
   },
diff --git a/lib/pleroma/web/akkoma_api/controllers/frontend_switcher.ex b/lib/pleroma/web/akkoma_api/controllers/frontend_switcher.ex
new file mode 100644
index 000000000..2095db4b5
--- /dev/null
+++ b/lib/pleroma/web/akkoma_api/controllers/frontend_switcher.ex
@@ -0,0 +1,20 @@
+defmodule Pleroma.Web.AkkomaAPI.FrontendSwitcherController do
+  use Pleroma.Web, :controller
+  alias Pleroma.Config
+
+  @doc "GET /akkoma/frontend"
+  def switch(conn, _params) do
+    pickable = Config.get([:frontends, :pickable], [])
+
+    conn
+    |> put_view(Pleroma.Web.AkkomaAPI.FrontendSwitcherView)
+    |> render("switch.html", choices: pickable)
+  end
+
+  @doc "POST /akkoma/frontend"
+  def do_switch(conn, params) do
+    conn
+    |> put_resp_cookie("preferred_frontend", params["frontend"])
+    |> html("<meta http-equiv=\"refresh\" content=\"0; url=/\">")
+  end
+end
diff --git a/lib/pleroma/web/akkoma_api/views/frontend_switcher.ex b/lib/pleroma/web/akkoma_api/views/frontend_switcher.ex
new file mode 100644
index 000000000..1564c9e44
--- /dev/null
+++ b/lib/pleroma/web/akkoma_api/views/frontend_switcher.ex
@@ -0,0 +1,3 @@
+defmodule Pleroma.Web.AkkomaAPI.FrontendSwitcherView do
+  use Pleroma.Web, :view
+end
diff --git a/lib/pleroma/web/plugs/frontend_static.ex b/lib/pleroma/web/plugs/frontend_static.ex
index 62283353e..91dfc77c3 100644
--- a/lib/pleroma/web/plugs/frontend_static.ex
+++ b/lib/pleroma/web/plugs/frontend_static.ex
@@ -50,6 +50,7 @@ def init(opts) do
   end
 
   def call(conn, opts) do
+    IO.inspect("OPTS: #{inspect(opts)}")
     with false <- api_route?(conn.path_info),
          false <- invalid_path?(conn.path_info),
          true <- enabled?(opts[:if]),
@@ -71,16 +72,19 @@ def preferred_frontend(conn) do
     Map.get(cookies, @frontend_cookie_name)
   end
 
-  def preferred_or_fallback(conn, fallback) do
+  # Only override primary frontend
+  def preferred_or_fallback(conn, :primary) do
     case preferred_frontend(conn) do
       nil ->
-        fallback
+        :primary
 
       frontend ->
         frontend
     end
   end
 
+  def preferred_or_fallback(conn, fallback), do: fallback
+
   defp enabled?(if_opt) when is_function(if_opt), do: if_opt.()
   defp enabled?(true), do: true
   defp enabled?(_), do: false
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index 3db8ddab7..d02ae3460 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -466,6 +466,13 @@ defmodule Pleroma.Web.Router do
     put("/statuses/:id/emoji_reactions/:emoji", EmojiReactionController, :create)
   end
 
+  scope "/akkoma/", Pleroma.Web.AkkomaAPI do
+    pipe_through(:browser)
+
+    get("/frontend", FrontendSwitcherController, :switch)
+    post("/frontend", FrontendSwitcherController, :do_switch)
+  end
+
   scope "/api/v1/akkoma", Pleroma.Web.AkkomaAPI do
     pipe_through(:api)
 
diff --git a/lib/pleroma/web/templates/akkoma_api/frontend_switcher/switch.html.eex b/lib/pleroma/web/templates/akkoma_api/frontend_switcher/switch.html.eex
new file mode 100644
index 000000000..0692ddfb8
--- /dev/null
+++ b/lib/pleroma/web/templates/akkoma_api/frontend_switcher/switch.html.eex
@@ -0,0 +1,7 @@
+<h2>Switch Frontend</h2>
+
+<%= form_for @conn, Routes.frontend_switcher_path(@conn, :do_switch), fn f -> %>
+  <%= select(f, :frontend, @choices) %>
+
+  <%= submit do: "submit" %>
+<% end %>