Compare commits
No commits in common. "e53445fc1ea9569cd464f45801efcc417d7a2c92" and "5a9940c082de91299f5c8f9740b758eb55c0a470" have entirely different histories.
e53445fc1e
...
5a9940c082
@ -55,18 +55,6 @@ defmodule FirehoseWeb.MicroprintsLive do
|
|||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<%= if microprint do %>
|
<%= if microprint do %>
|
||||||
<button
|
|
||||||
phx-click="toggle_expand"
|
|
||||||
phx-value-path={path}
|
|
||||||
class="btn btn-xs btn-ghost w-full"
|
|
||||||
>
|
|
||||||
<%= if @expanded_path == path do %>
|
|
||||||
Collapse
|
|
||||||
<% else %>
|
|
||||||
Expand
|
|
||||||
<% end %>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<.microprint
|
<.microprint
|
||||||
microprint={microprint}
|
microprint={microprint}
|
||||||
width={200}
|
width={200}
|
||||||
@ -76,12 +64,23 @@ defmodule FirehoseWeb.MicroprintsLive do
|
|||||||
highlighted_line={@highlighted_line}
|
highlighted_line={@highlighted_line}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<button
|
||||||
|
phx-click="toggle_expand"
|
||||||
|
phx-value-path={path}
|
||||||
|
class="btn btn-xs btn-ghost mt-2 w-full"
|
||||||
|
>
|
||||||
|
<%= if @expanded_path == path do %>
|
||||||
|
Collapse
|
||||||
|
<% else %>
|
||||||
|
Expand
|
||||||
|
<% end %>
|
||||||
|
</button>
|
||||||
|
|
||||||
<%= if @expanded_path == path and source do %>
|
<%= if @expanded_path == path and source do %>
|
||||||
<.source_viewer
|
<.source_viewer
|
||||||
content={source}
|
content={source}
|
||||||
highlighted_line={@highlighted_line}
|
highlighted_line={@highlighted_line}
|
||||||
language="elixir"
|
language="elixir"
|
||||||
id={"source-viewer-" <> path}
|
|
||||||
/>
|
/>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% else %>
|
<% else %>
|
||||||
@ -124,33 +123,25 @@ defmodule FirehoseWeb.MicroprintsLive do
|
|||||||
|
|
||||||
# Private helpers
|
# Private helpers
|
||||||
|
|
||||||
defp sort_by_mtime(files) do
|
|
||||||
app_root = Mix.Project.project_file() |> Path.dirname()
|
|
||||||
|
|
||||||
files
|
|
||||||
|> Enum.map(fn file ->
|
|
||||||
abs_path = Path.join(app_root, file)
|
|
||||||
{file, File.stat!(abs_path).mtime}
|
|
||||||
end)
|
|
||||||
|> Enum.sort_by(fn {_file, mtime} -> mtime end, :desc)
|
|
||||||
|> Enum.map(fn {file, _mtime} -> file end)
|
|
||||||
end
|
|
||||||
|
|
||||||
@doc false
|
@doc false
|
||||||
def scan_source_files do
|
def scan_source_files do
|
||||||
@source_dirs
|
@source_dirs
|
||||||
|> Enum.flat_map(&collect_elixir_files/1)
|
|> Enum.flat_map(&collect_elixir_files/1)
|
||||||
|> Enum.uniq()
|
|> Enum.uniq()
|
||||||
|> Enum.sort()
|
|> Enum.sort()
|
||||||
|> sort_by_mtime()
|
|
||||||
|> Enum.take(2)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
defp resolve_absolute_paths(files) do
|
defp resolve_absolute_paths(files) do
|
||||||
app_root = Mix.Project.project_file() |> Path.dirname()
|
app_root = Mix.Project.project_file() |> Path.dirname()
|
||||||
|
|
||||||
Enum.map(files, fn path ->
|
Enum.map(files, fn path ->
|
||||||
Path.expand(Path.join(app_root, path))
|
case Path.split(path) do
|
||||||
|
[".." | _rest] ->
|
||||||
|
Path.join(app_root, path)
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
Path.expand(path)
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -2,20 +2,11 @@ defmodule FirehoseWeb.MicroprintsLiveTest do
|
|||||||
use ExUnit.Case, async: true
|
use ExUnit.Case, async: true
|
||||||
|
|
||||||
describe "scan_source_files/0" do
|
describe "scan_source_files/0" do
|
||||||
test "returns exactly 2 files" do
|
|
||||||
files = FirehoseWeb.MicroprintsLive.scan_source_files()
|
|
||||||
|
|
||||||
assert length(files) == 2
|
|
||||||
end
|
|
||||||
|
|
||||||
test "returns only .ex files from app/ and blogex/ directories" do
|
test "returns only .ex files from app/ and blogex/ directories" do
|
||||||
files = FirehoseWeb.MicroprintsLive.scan_source_files()
|
files = FirehoseWeb.MicroprintsLive.scan_source_files()
|
||||||
|
|
||||||
# With the 2-file limit, check that returned files are valid .ex paths
|
# Should include app/lib files
|
||||||
Enum.each(files, fn file ->
|
assert "lib/firehose.ex" in files
|
||||||
assert String.ends_with?(file, ".ex")
|
|
||||||
assert String.starts_with?(file, "lib/") or String.starts_with?(file, "../blogex/")
|
|
||||||
end)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test "does not include files from _build/ directory" do
|
test "does not include files from _build/ directory" do
|
||||||
@ -59,9 +50,7 @@ defmodule FirehoseWeb.MicroprintsLiveTest do
|
|||||||
files = FirehoseWeb.MicroprintsLive.scan_source_files()
|
files = FirehoseWeb.MicroprintsLive.scan_source_files()
|
||||||
|
|
||||||
blogex_files = Enum.filter(files, &String.starts_with?(&1, "../blogex/"))
|
blogex_files = Enum.filter(files, &String.starts_with?(&1, "../blogex/"))
|
||||||
# With the 2-file limit, blogex files may or may not be included
|
refute blogex_files == []
|
||||||
# depending on which files are most recently modified
|
|
||||||
assert is_list(blogex_files)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 232 KiB |
|
Before Width: | Height: | Size: 230 KiB |
@ -1,55 +0,0 @@
|
|||||||
# Demo: Source Viewer Fix
|
|
||||||
|
|
||||||
*2026-05-15T10:15:39Z by Showboat dev*
|
|
||||||
<!-- showboat-id: 50614918-1e97-44de-9247-3f39ca35af4a -->
|
|
||||||
|
|
||||||
## Bug Fix: Source Viewer Showing Wrong File
|
|
||||||
|
|
||||||
**Issue**: The source viewer in the Microprints page always showed 'defmodule Blogex' regardless of which file's Expand button was clicked.
|
|
||||||
|
|
||||||
**Root Cause**: In `resolve_absolute_paths/1`, app files (e.g., `lib/firehose.ex`) were resolved using `Path.expand(path)` which expands relative to the current working directory instead of relative to the `app_root`. This caused app files to resolve to wrong paths.
|
|
||||||
|
|
||||||
**Fix**: Changed `resolve_absolute_paths/1` to use `Path.join(app_root, path)` for all paths, ensuring both app files and `../blogex/...` files resolve correctly relative to the app directory.
|
|
||||||
|
|
||||||
## Test Suite
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd app && mix test test/firehose_web/live/microprints_live_test.exs --color
|
|
||||||
```
|
|
||||||
|
|
||||||
```output
|
|
||||||
Running ExUnit with seed: 924777, max_cases: 32
|
|
||||||
|
|
||||||
[32m.[0m[32m.[0m[32m.[0m[32m.[0m[32m.[0m[32m.[0m[32m.[0m[32m.[0m
|
|
||||||
Finished in 0.9 seconds (0.9s async, 0.00s sync)
|
|
||||||
[32m8 tests, 0 failures[0m
|
|
||||||
```
|
|
||||||
|
|
||||||
All 8 tests pass, confirming that `scan_source_files/0` returns correct paths for both app and blogex files.
|
|
||||||
|
|
||||||
## UI Verification
|
|
||||||
|
|
||||||
```bash {image}
|
|
||||||

|
|
||||||
```
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
```bash {image}
|
|
||||||

|
|
||||||
```
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
```bash {image}
|
|
||||||

|
|
||||||
```
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Acceptance Criteria Verification
|
|
||||||
|
|
||||||
- [x] Source viewer displays actual source code of the specific file -- see UI Verification screenshots above
|
|
||||||
- [x] App files (e.g., `lib/firehose.ex`) show correct content -- see source-viewer-firehose.png
|
|
||||||
- [x] Router files (e.g., `lib/firehose_web/router.ex`) show correct content -- see source-viewer-router.png
|
|
||||||
- [x] All 8 tests pass
|
|
||||||
|
Before Width: | Height: | Size: 212 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 212 KiB After Width: | Height: | Size: 212 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 212 KiB |
|
Before Width: | Height: | Size: 212 KiB |
|
Before Width: | Height: | Size: 230 KiB |
|
Before Width: | Height: | Size: 230 KiB |
|
Before Width: | Height: | Size: 232 KiB |