feat: add a modern design for the result image - #833
Conversation
PR Summary by QodoRedesign shared result PNG to match modern dark UI
AI Description
Diagram
High-Level Assessment
Files changed (1)
|
46b1144 to
80f50ff
Compare
Code Review by Qodo
1. Polygon call incompatible
|
| imagefilledpolygon($im, [ | ||
| (int) $cx, (int) ($tipY + $dir * $head * 0.5), | ||
| (int) ($cx - $head), (int) ($tipY - $dir * $head * 0.55), | ||
| (int) ($cx + $head), (int) ($tipY - $dir * $head * 0.55), | ||
| ], $color); |
There was a problem hiding this comment.
1. Polygon call incompatible 🐞 Bug ☼ Reliability
directionBadge() calls imagefilledpolygon() with the 3-argument form, which can break deployments on older PHP versions that this repo’s docs still claim to support. On such systems, generating /results/?id=… can error out before producing an image.
Agent Prompt
### Issue description
`directionBadge()` uses `imagefilledpolygon($im, $points, $color)`. Some PHP/GD versions require the legacy signature `imagefilledpolygon($im, $points, $num_points, $color)`. Since project docs still state PHP 5.4+ support, this can make result image generation fail on those deployments.
### Issue Context
- The code path is executed for every rendered image (download/upload badges).
- Docs still describe supporting older PHP versions.
### Fix Focus Areas
- results/index.php[300-321]
### Suggested fix
Use a version-safe call, e.g.:
- Build `$points = [...]` once
- If `PHP_VERSION_ID >= 80000` call the 3-arg variant; else call the 4-arg variant with `$numPoints = (int)(count($points)/2)`.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| while ('' !== $text && textWidth($text.'…', $font, $size) > $maxWidth) { | ||
| $text = substr($text, 0, -1); | ||
| } | ||
|
|
There was a problem hiding this comment.
2. Costly byte truncation 🐞 Bug ➹ Performance
fitText() shrinks strings by repeatedly removing a byte with substr() and re-measuring via imageftbbox(), which is inefficient for long inputs and can split multibyte UTF-8 characters. This matters because the rendered client string comes directly from the stored HTTP_USER_AGENT and can be arbitrarily long.
Agent Prompt
### Issue description
`fitText()` truncates with `substr($text, 0, -1)` in a loop and calls `imageftbbox()` each iteration. This is inefficient for long strings and byte-based truncation can corrupt UTF-8 sequences.
### Issue Context
- `drawImage()` applies `fitText()` to the stored user-agent (`$data['ua']`).
- Telemetry stores `ua` directly from `$_SERVER['HTTP_USER_AGENT']`.
### Fix Focus Areas
- results/index.php[360-378]
- results/index.php[522-533]
- results/telemetry.php[7-12]
### Suggested fix
- Impose a hard maximum length before measuring (e.g., cap UA to N characters).
- Truncate by Unicode characters (e.g., use `preg_split('//u', ...)` and pop chars) rather than `substr` bytes.
- Reduce measurement calls (e.g., binary search for the longest fitting prefix instead of per-character iteration).
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
80f50ff to
c9606ae
Compare
|
I like the design. |
464b0b6 to
0102d48
Compare
The shared result image had one look, and it no longer matched the modern frontend. The renderer can now draw either design. The image follows the same useNewDesign setting as the frontend, so a deployment has one switch rather than two that can disagree, and classic remains the fallback. - An explicit style query parameter overrides it, which is how the modern frontend asks for the design it matches. - The modern design reuses the frontend palette and shows the client, address family and timestamp already present in the result data.
0102d48 to
c01e7fe
Compare
|
Oh, okay! :) Should be done. |
The shared result image had one look, black on white in the classic style,
while
index-modern.htmlandfrontend/styling/describe a dark interface.Sharing a result from the modern frontend posted an image that did not look
like the site it came from.
The result image now follows the same
useNewDesignsetting as the frontend,while an explicit
stylequery parameter can override it. Classic remains thefallback, and
DESIGN_SWITCH.mddocuments both.Colours are taken from
frontend/styling/colors.cssrather than invented, sothe two stay in step. Three things the image already carried but never showed
are drawn in the modern design, all from columns the query selects today: the
client, the address family, and a timestamp split into a date and a time.
Rendered at 3x and scaled down, because GD antialiases nothing it fills and
circles and rounded corners would otherwise come out stepped. No new
dependency, and the same two fonts already in
results/.Edge cases, rendered: a browser user agent, which is shortened to fit, a long
provider name, and
redact_ip_addresseson, where the family is dropped ratherthan reporting the stored placeholder as IPv4.
The panels carry a gradient rather than a sparkline on purpose: a curve inside
a result reads as measured data, and no per-second samples are kept for a
shared result, so it would be invented.
Rebased onto 6.2.1.