some cleanup
Bobby Grayson 1 day ago 3 files (+101, -77)
MODIFIED
lib/blog_web/live/post_live.ex
MODIFIED
lib/blog_web/live/post_live.ex
@@ -48,17 +48,15 @@ |> assign(:post, post)|> assign(meta_attrs: meta_attrs)|> assign(page_title: post.title)- # require IEx; IEx.pryLogger.debug("Found post: #{inspect(post, pretty: true)}")- case Earmark.as_html(post.body, code_class_prefix: "language-") do+ # Filter out tags line and process markdown+ content_without_tags = remove_tags_line(post.body)+ case Earmark.as_html(content_without_tags, code_class_prefix: "language-") do{:ok, html, _} ->- headers = extract_headers(post.body)-socket =assign(socket,html: html,- headers: headers,reader_count: get_reader_count(slug))@@ -67,12 +65,10 @@{:error, html, errors} -># Still show the content even if there are markdown errorsLogger.error("Markdown parsing warnings: #{inspect(errors)}")- headers = extract_headers(post.body)socket =assign(socket,html: html,- headers: headers,post: post)@@ -81,8 +77,24 @@ endendend+ # Remove the tags line from the content+ defp remove_tags_line(content) when is_binary(content) do+ content+ |> String.split("\n")+ |> Enum.reject(&is_tags_line?/1)+ |> Enum.join("\n")+ end++ # Check if a line is a tags line+ defp is_tags_line?(line) do+ String.starts_with?(String.trim(line), "tags:")+ end+defp truncated_post(body) do- String.slice(body, 0, 250) <> "..."+ body+ |> remove_tags_line()+ |> String.slice(0, 250)+ |> Kernel.<>("...")enddef handle_info(%{event: "presence_diff"} = _diff, socket) do@@ -111,19 +123,6 @@ <%= if @reader_count > 1 do %>{@reader_count - 1} other {if @reader_count == 2, do: "person", else: "people"} reading this post<% end %></div>- <div class="mb-12 p-6 bg-gray-50 rounded-lg border-2 border-gray-200">- <h2 class="text-xl font-bold mb-4 pb-2 border-b-2 border-gray-200">Table of Contents</h2>- <ul class="space-y-2">- <%= for {text, level} <- @headers do %>- <li class={[- "hover:text-blue-600 transition-colors",- level_to_padding(level)- ]}>- <a href={"##{generate_id(text)}"}>{text}</a>- </li>- <% end %>- </ul>- </div><article class="p-8 bg-white rounded-lg border-2 border-gray-200"><div@@ -139,40 +138,6 @@ </div>"""end- defp extract_headers(markdown) do- markdown- |> String.split("\n")- |> Enum.filter(&header?/1)- |> Enum.map(fn line ->- {text, level} = parse_header(line)- {text, level}- end)- end-- defp header?(line) do- String.match?(line, ~r/^#+\s+.+$/)- end-- defp parse_header(line) do- [hashes | words] = String.split(line, " ")- level = String.length(hashes)- text = Enum.join(words, " ")- {text, level}- end-- defp generate_id(text) do- text- |> String.downcase()- |> String.replace(~r/[^\w-]+/, "-")- |> String.trim("-")- end-- defp level_to_padding(1), do: "pl-0"- defp level_to_padding(2), do: "pl-4"- defp level_to_padding(3), do: "pl-8"- defp level_to_padding(4), do: "pl-12"- defp level_to_padding(_), do: "pl-16"-defp assign_meta_tags(socket, post) dodescription = get_preview(post.body)@@ -223,8 +188,8 @@ enddefp get_preview(content, max_length \\ 200) docontent+ |> remove_tags_line()|> String.split("\n")- |> Enum.reject(&String.starts_with?(&1, "tags:"))|> Enum.join(" ")|> String.replace(~r/[#*`]/, "")|> String.replace(~r/\s+/, " ")
MODIFIED
lib/blog_web/live/post_live/index.ex
MODIFIED
lib/blog_web/live/post_live/index.ex
@@ -14,6 +14,58 @@ # TODO add meta tagsdef mount(_params, _session, socket) do# Ensure ETS chat store is startedChat.ensure_started()+ demos = [+ %{+ title: "Python Playground",+ description: "Run Python code directly in your browser",+ path: ~p"/python-demo",+ icon: "code", # We'll use heroicons for these+ color: "emerald" # Each demo gets a signature color+ },+ %{+ title: "Cursor Party",+ description: "Watch cursors dance across your screen",+ path: ~p"/cursor-tracker",+ icon: "cursor-arrow-rays",+ color: "fuchsia"+ },+ %{+ title: "Rainbow Chaos",+ description: "Embrace the gay agenda",+ path: ~p"/gay_chaos",+ icon: "sparkles",+ color: "violet"+ },+ %{+ title: "Digital Mirror",+ description: "See yourself in pixels",+ path: ~p"/mirror",+ icon: "camera",+ color: "blue"+ },+ %{+ title: "Reddit Feed",+ description: "Your favorite subreddits, live",+ path: ~p"/reddit-links",+ icon: "newspaper",+ color: "orange"+ },+ %{+ title: "Emoji Skeets",+ description: "Express yourself in flying emojis",+ path: ~p"/emoji-skeets",+ icon: "face-smile",+ color: "yellow"+ },+ %{+ title: "Hacker News Live",+ description: "Real-time tech news feed",+ path: ~p"/hacker-news",+ icon: "command-line",+ color: "red"+ }+ ]+reader_id = if connected?(socket) doid = "reader_#{:crypto.strong_rand_bytes(8) |> Base.encode16()}"@@ -60,6 +112,7 @@{:ok,assign(socket,tech_posts: tech_posts,+ demos: demos,non_tech_posts: non_tech_posts,total_readers: total_readers,page_title: "Thoughts & Tidbits",@@ -420,7 +473,7 @@ <%= for room <- @chat_rooms do %><buttonphx-click="change_room"phx-value-room={room}- class={"w-full text-left mb-2 px-3 py-2 rounded #{if @current_room == room, do: 'bg-yellow-100 border border-yellow-300', else: 'hover:bg-gray-200'}"}+ class={"w-full text-left mb-2 px-3 py-2 rounded #{if @current_room == room, do: "bg-yellow-100 border border-yellow-300", else: "hover:bg-gray-200"}"}><div class="flex items-center justify-between"><div class="flex items-center">@@ -683,26 +736,34 @@ <% end %></div></div>- <!-- Non-Tech Posts Column -->- <div class="bg-gradient-to-br from-cyan-50 to-fuchsia-50 rounded-xl p-6 shadow-lg border border-cyan-100">+ <!-- Tech Demos Column -->+ <div class="bg-gradient-to-br from-indigo-50 to-purple-50 rounded-xl p-6 shadow-lg border border-indigo-100"><div class="flex items-center mb-6">- <div class="w-3 h-3 rounded-full bg-cyan-400 mr-2"></div>- <div class="w-3 h-3 rounded-full bg-fuchsia-400 mr-2"></div>- <div class="w-3 h-3 rounded-full bg-indigo-400 mr-4"></div>- <h2 class="text-2xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-cyan-600 to-fuchsia-600">- Tech Demos+ <div class="w-3 h-3 rounded-full bg-indigo-400 mr-2"></div>+ <div class="w-3 h-3 rounded-full bg-purple-400 mr-2"></div>+ <div class="w-3 h-3 rounded-full bg-pink-400 mr-4"></div>+ <h2 class="text-2xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-indigo-600 to-purple-600">+ Interactive Demos</h2></div><div class="space-y-4">- <%= for post <- @non_tech_posts do %>- <div class="group bg-white rounded-lg p-4 shadow-sm hover:shadow-md transition-all duration-300 border-l-4 border-cyan-400">- <.link navigate={~p"/post/#{post.slug}"} class="block">- <h3 class="text-xl font-bold text-gray-800 group-hover:text-cyan-600 transition-colors">- <%= "Reddit Links Feed" %>- </h3>- </.link>- </div>+ <%= for demo <- @demos do %>+ <.link navigate={demo.path} class="block">+ <div class={"group bg-white rounded-lg p-4 shadow-sm hover:shadow-md transition-all duration-300 border-l-4 border-#{demo.color}-400 hover:border-#{demo.color}-500"}>+ <div class="flex items-center justify-between">+ <div>+ <h3 class={"text-xl font-bold text-gray-800 group-hover:text-#{demo.color}-600 transition-colors"}>+ <%= demo.title %>+ </h3>+ <p class="text-sm text-gray-600 mt-1">+ <%= demo.description %>+ </p>+ </div>+ <span class={"text-#{demo.color}-600 group-hover:translate-x-0.5 transition-transform"}>→</span>+ </div>+ </div>+ </.link><% end %></div></div>@@ -711,9 +772,7 @@ </div><!-- Retro footer --><footer class="mt-16 text-center">- <div class="inline-block px-4 py-2 bg-gradient-to-r from-fuchsia-100 to-cyan-100 rounded-full text-sm text-gray-700">- <span class="font-mono">/* Crafted with ♥ and Elixir */</span>- </div>+ <span class="font-mono">/* Crafted with ♥ and Elixir */</span><!-- Moderator Button - subtle but visible --><div class="mt-4 flex justify-center">
MODIFIED
lib/blog_web/router.ex
MODIFIED
lib/blog_web/router.ex
@@ -20,8 +20,7 @@ pipe_through :browserlive "/", PostLive.Indexlive "/post/:slug", PostLive- live "/faketweets", FakeTweetsLive- live "/vim", VimTweetsLive+live "/keylogger", KeyloggerLivelive "/gay_chaos", RainbowLive, :indexlive "/mirror", MirrorLive, :index@@ -32,6 +31,7 @@ live "/allowed-chats", AllowedChatsLive, :indexlive "/hacker-news", HackerNewsLive, :indexlive "/python", PythonLive.Index, :indexlive "/python-demo", PythonDemoLive, :index+end# Other scopes may use custom stacks.