mirror of
git://f0xx.org/ac/ac-platform-php
synced 2026-08-12 18:13:05 +03:00
Nav shell: friendly English labels (no missing i18n keys).
Use plain labels for console/git/issues/live/education/short links and refresh branded QR logo rendering. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 8.2 KiB |
@@ -28,16 +28,16 @@ function platform_render_nav_shell(array $opts = []): void
|
||||
$isActive = static fn(string $id): string => $active === $id ? ' active' : '';
|
||||
|
||||
$items = [
|
||||
['id' => 'console', 'href' => $issuesBase . '/?view=home', 'icon' => 'home', 'label' => 'Console', 'desc' => 'Crash triage home and workspace cards.', 'i18n' => 'nav.console', 'i18n_desc' => 'nav.console_desc'],
|
||||
['id' => 'git', 'href' => $projectBase . '/git/', 'icon' => 'git', 'label' => 'Git', 'desc' => 'Browse repos, branches, and tags.', 'i18n' => 'nav.git', 'i18n_desc' => 'nav.git_desc'],
|
||||
['id' => 'issues', 'href' => $issuesBase . '/?view=reports', 'icon' => 'reports', 'label' => 'Issues', 'desc' => 'Browse and triage crash reports.', 'i18n' => 'nav.issues', 'i18n_desc' => 'nav.issues_desc'],
|
||||
['id' => 'console', 'href' => $issuesBase . '/?view=home', 'icon' => 'home', 'label' => 'Home', 'desc' => 'Console dashboard and workspace overview.'],
|
||||
['id' => 'git', 'href' => $projectBase . '/git/', 'icon' => 'git', 'label' => 'Source code', 'desc' => 'Repositories, branches, tags, and releases.'],
|
||||
['id' => 'issues', 'href' => $issuesBase . '/?view=reports', 'icon' => 'reports', 'label' => 'Crash reports', 'desc' => 'Search, filter, and triage incoming crash reports.'],
|
||||
['id' => 'tickets', 'href' => $issuesBase . '/?view=tickets', 'icon' => 'tickets', 'label' => 'Tickets', 'desc' => 'Roadmap tasks, QA items, and tags.', 'i18n' => 'nav.tickets', 'i18n_desc' => 'nav.tickets_desc'],
|
||||
['id' => 'graphs', 'href' => $projectBase . '/graphs/', 'icon' => 'graphs', 'label' => 'Analytics', 'desc' => 'Sessions, live cast stats, and device activity.', 'i18n' => 'nav.graphs', 'i18n_desc' => 'nav.graphs_desc'],
|
||||
['id' => 'monitor', 'href' => $projectBase . '/monitor/', 'icon' => 'monitor', 'label' => 'Monitoring', 'desc' => 'Grafana dashboards — cluster health, alerts, exporters.', 'i18n' => 'nav.monitor', 'i18n_desc' => 'nav.monitor_desc'],
|
||||
['id' => 'live_sessions', 'href' => $issuesBase . '/?view=live_sessions', 'icon' => 'live', 'label' => 'Live sessions', 'desc' => 'Cast intents, join stats, session history.', 'i18n' => 'nav.live_sessions', 'i18n_desc' => 'nav.live_sessions_desc'],
|
||||
['id' => 'education', 'href' => $issuesBase . '/live/education', 'icon' => 'education', 'label' => 'Education (demo)', 'desc' => 'Browser screen-share trial (5 min).', 'i18n' => 'nav.education', 'i18n_desc' => 'nav.education_desc'],
|
||||
['id' => 'live_sessions', 'href' => $issuesBase . '/?view=live_sessions', 'icon' => 'live', 'label' => 'Live casting', 'desc' => 'Active cast sessions, join stats, and session history.'],
|
||||
['id' => 'education', 'href' => $issuesBase . '/live/education', 'icon' => 'education', 'label' => 'Try screen share', 'desc' => 'Five-minute browser demo — share your screen, no app install.'],
|
||||
['id' => 'remote', 'href' => $issuesBase . '/?view=remote_access', 'icon' => 'remote', 'label' => 'Remote access', 'desc' => 'WireGuard sessions and device reachability.', 'i18n' => 'nav.remote', 'i18n_desc' => 'nav.remote_desc'],
|
||||
['id' => 'short_links', 'href' => $issuesBase . '/?view=short_links', 'icon' => 'link', 'label' => 'Short links', 'desc' => 'Mint bearer tokens and shorten URLs for s.f0xx.org.', 'i18n' => 'nav.short_links', 'i18n_desc' => 'nav.short_links_desc'],
|
||||
['id' => 'short_links', 'href' => $issuesBase . '/?view=short_links', 'icon' => 'link', 'label' => 'Short links', 'desc' => 'Shorten URLs and manage API tokens for s.f0xx.org.'],
|
||||
['id' => 'builder', 'href' => $projectBase . '/build/', 'icon' => 'builder', 'label' => 'Builder', 'desc' => 'Docker CI for APK baking and OTA artifacts.', 'i18n' => 'nav.builder', 'i18n_desc' => 'nav.builder_desc'],
|
||||
];
|
||||
?>
|
||||
@@ -48,16 +48,21 @@ function platform_render_nav_shell(array $opts = []): void
|
||||
<span class="nav-icon nav-icon--menu" aria-hidden="true"></span>
|
||||
</button>
|
||||
<ul class="nav-list">
|
||||
<?php foreach ($items as $item): ?>
|
||||
<?php foreach ($items as $item):
|
||||
$i18n = isset($item['i18n']) ? (string) $item['i18n'] : '';
|
||||
$i18nDesc = isset($item['i18n_desc']) ? (string) $item['i18n_desc'] : '';
|
||||
$label = (string) $item['label'];
|
||||
$desc = (string) $item['desc'];
|
||||
?>
|
||||
<li>
|
||||
<a href="<?= platform_nav_h((string) $item['href']) ?>"
|
||||
class="nav-link<?= $isActive((string) $item['id']) ?>"
|
||||
data-i18n-title="<?= platform_nav_h((string) $item['i18n']) ?>"
|
||||
title="<?= platform_nav_h((string) $item['label']) ?>">
|
||||
<?php if ($i18n !== ''): ?>data-i18n-title="<?= platform_nav_h($i18n) ?>"<?php endif; ?>
|
||||
title="<?= platform_nav_h($label) ?>">
|
||||
<span class="nav-icon nav-icon--<?= platform_nav_h((string) $item['icon']) ?>" aria-hidden="true"></span>
|
||||
<span class="nav-text">
|
||||
<span class="nav-label" data-i18n="<?= platform_nav_h((string) $item['i18n']) ?>"><?= platform_nav_h((string) $item['label']) ?></span>
|
||||
<span class="nav-desc" data-i18n="<?= platform_nav_h((string) $item['i18n_desc']) ?>"><?= platform_nav_h((string) $item['desc']) ?></span>
|
||||
<span class="nav-label"<?php if ($i18n !== ''): ?> data-i18n="<?= platform_nav_h($i18n) ?>"<?php endif; ?>><?= platform_nav_h($label) ?></span>
|
||||
<span class="nav-desc"<?php if ($i18nDesc !== ''): ?> data-i18n="<?= platform_nav_h($i18nDesc) ?>"<?php endif; ?>><?= platform_nav_h($desc) ?></span>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
@@ -3,8 +3,8 @@ declare(strict_types=1);
|
||||
|
||||
/** Branded QR PNG: high error correction + centered app logo with white border. */
|
||||
final class QrBrandedRenderer {
|
||||
private const LOGO_FRACTION = 0.22;
|
||||
private const BORDER_FRACTION = 0.045;
|
||||
private const LOGO_FRACTION = 0.24;
|
||||
private const BORDER_FRACTION = 0.05;
|
||||
|
||||
private function __construct() {
|
||||
}
|
||||
@@ -32,10 +32,25 @@ final class QrBrandedRenderer {
|
||||
|
||||
/** @return list<string> */
|
||||
private static function logoCandidates(): array {
|
||||
return [
|
||||
__DIR__ . '/../public/assets/ac_qr_logo.png',
|
||||
__DIR__ . '/../assets/ac_qr_logo.png',
|
||||
];
|
||||
$paths = [];
|
||||
$env = getenv('AC_QR_LOGO_PATH');
|
||||
if (is_string($env) && $env !== '') {
|
||||
$paths[] = $env;
|
||||
}
|
||||
$paths[] = __DIR__ . '/../public/assets/ac_qr_logo.png';
|
||||
$paths[] = __DIR__ . '/../assets/ac_qr_logo.png';
|
||||
$paths[] = dirname(__DIR__, 2) . '/ac-ms-url-shortener/assets/ac_qr_logo.png';
|
||||
return $paths;
|
||||
}
|
||||
|
||||
/** @return \GdImage|false */
|
||||
private static function loadLogoImage(string $path) {
|
||||
$bytes = @file_get_contents($path);
|
||||
if (!is_string($bytes) || $bytes === '') {
|
||||
return false;
|
||||
}
|
||||
$img = @imagecreatefromstring($bytes);
|
||||
return $img !== false ? $img : false;
|
||||
}
|
||||
|
||||
private static function logoPath(): ?string {
|
||||
@@ -79,7 +94,7 @@ final class QrBrandedRenderer {
|
||||
if ($qr === false) {
|
||||
return null;
|
||||
}
|
||||
$logo = @imagecreatefrompng($logoPath);
|
||||
$logo = self::loadLogoImage($logoPath);
|
||||
if ($logo === false) {
|
||||
imagedestroy($qr);
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user