1
0
mirror of git://f0xx.org/ac/ac-be-issues synced 2026-07-29 04:38:47 +03:00
Files
ac-be-issues/views/report_detail.php
Anton Afanasyeu d5b8c54b5b initial
2026-06-23 12:29:35 +02:00

186 lines
9.0 KiB
PHP

<?php
$p = is_array($report['payload'] ?? null) ? $report['payload'] : [];
$device = is_array($p['device'] ?? null) ? $p['device'] : [];
$app = is_array($p['app'] ?? null) ? $p['app'] : [];
$pageTitle = 'Report ' . ($report['report_id'] ?? '');
$view = 'reports';
$jsonFlags = JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE;
$rawJson = safe_json_encode($p, $jsonFlags);
$sessionJson = !empty($p['session_context'])
? safe_json_encode($p['session_context'], $jsonFlags)
: '';
$bp = Auth::basePath();
$reportDbId = (int) ($report['id'] ?? 0);
$deviceName = device_display_name($device);
$deviceFamily = device_model_family(
(string) ($device['manufacturer'] ?? ''),
(string) ($device['model'] ?? '')
);
$filterDeviceQ = $deviceFamily !== '' ? $deviceFamily : $deviceName;
$similarUrl = $bp . '/?view=reports&similar_to=' . $reportDbId;
$filterDeviceUrl = $bp . '/?view=reports&filter_device=' . rawurlencode($filterDeviceQ);
$sdk = (int) ($device['sdk_int'] ?? 0);
$release = (string) ($device['release'] ?? '');
$filterOsUrl = $sdk > 0
? $bp . '/?view=reports&filter_os_sdk=' . $sdk
: ($release !== '' ? $bp . '/?view=reports&filter_os_release=' . rawurlencode($release) : '');
$abiList = [];
if (!empty($device['abis']) && is_array($device['abis'])) {
foreach ($device['abis'] as $abi) {
if (is_scalar($abi) && trim((string) $abi) !== '') {
$abiList[] = trim((string) $abi);
}
}
}
?>
<div class="detail-header">
<a href="<?= h($bp) ?>/?view=reports" class="back-link" data-i18n-aria="detail.back" data-i18n-title="detail.back" aria-label="Back to reports list" title="Back to list">
<span class="back-icon" aria-hidden="true"></span>
</a>
<div>
<h1 data-i18n="detail.title">Issue report</h1>
<p class="muted" data-i18n="detail.report_meta" data-i18n-id="<?= h($report['report_id'] ?? '') ?>" data-i18n-type="<?= h($p['crash_type'] ?? '') ?>">Report <?= h($report['report_id'] ?? '') ?> · <?= h($p['crash_type'] ?? '') ?></p>
</div>
</div>
<section class="tag-editor" id="tag-editor" data-report-id="<?= $reportDbId ?>">
<div class="tag-editor-head">
<h2 data-i18n="detail.tags">Tags</h2>
<p class="muted tag-editor-hint" data-i18n="tag.hint_auto">Auto tags (NDK / Java / Android / new) appear in the list. Add custom labels below.</p>
</div>
<div class="tag-editor-preview" id="tag-editor-preview" aria-live="polite"></div>
<?php if (Auth::canEditTags()): ?>
<ul class="tag-editor-list" id="tag-editor-list"></ul>
<form class="tag-editor-add" id="tag-editor-add">
<label class="tag-field">
<span data-i18n="tag.label">Label</span>
<input type="text" name="label" maxlength="40" required data-i18n-placeholder="tag.placeholder" placeholder="e.g. regression">
</label>
<label class="tag-field">
<span data-i18n="tag.color">Color</span>
<input type="color" name="bg" value="#5c6b82">
</label>
<button type="submit" class="btn" data-i18n="tag.add_tag">Add tag</button>
</form>
<div class="tag-preset-bar" id="tag-preset-bar" hidden>
<span class="muted" data-i18n="tag.suggestions">Suggestions:</span>
<div class="tag-preset-chips" id="tag-preset-chips"></div>
</div>
<div class="tag-editor-actions">
<button type="button" class="btn btn-primary" id="tag-editor-save">Save tags</button>
<span class="tag-editor-status muted" id="tag-editor-status"></span>
</div>
<?php else: ?>
<p class="muted" data-i18n="tag.hint_admin">Sign in as admin to edit custom tags.</p>
<?php endif; ?>
</section>
<script type="application/json" id="report-custom-tags-data"><?=
safe_json_encode($report['tags'] ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
?></script>
<div class="cards cards--lift">
<div class="card card--lift"><h3>Device</h3>
<?php if ($deviceName !== ''): ?>
<p><a class="detail-filter-link detail-filter-link--tag" href="<?= h($filterDeviceUrl) ?>" title="Show reports for similar devices"><?= h($deviceName) ?></a></p>
<?php else: ?>
<p class="muted">—</p>
<?php endif; ?>
<?php if ($filterOsUrl !== ''): ?>
<p><a class="detail-filter-link detail-filter-link--tag" href="<?= h($filterOsUrl) ?>" title="Show reports on this OS">Android <?= h($release) ?> (SDK <?= $sdk ?>)</a></p>
<?php else: ?>
<p>Android <?= h($release) ?> (SDK <?= $sdk ?>)</p>
<?php endif; ?>
<?php if ($abiList !== []): ?>
<p class="muted detail-abi-row">ABIs:
<?php foreach ($abiList as $i => $abi): ?>
<?php if ($i > 0): ?>, <?php endif; ?>
<a class="detail-filter-link detail-filter-link--tag" href="<?= h($bp . '/?view=reports&filter_abi=' . rawurlencode($abi)) ?>"><?= h($abi) ?></a>
<?php endforeach; ?>
</p>
<?php endif; ?>
</div>
<div class="card card--lift"><h3 data-i18n="detail.app">App</h3>
<p><?= h($app['package'] ?? '') ?></p>
<?php
$versionName = (string) ($app['version_name'] ?? '');
$filterAppUrl = $versionName !== ''
? $bp . '/?view=reports&filter_app_version=' . rawurlencode($versionName)
: '';
?>
<?php if ($filterAppUrl !== ''): ?>
<p><a class="detail-filter-link detail-filter-link--tag" href="<?= h($filterAppUrl) ?>" data-i18n-title="detail.filter_version" title="Show reports for this app version">v<?= h($versionName) ?></a> <span class="muted">(<?= h((string)($app['version_code'] ?? '')) ?>)</span></p>
<?php else: ?>
<p>v<?= h($versionName) ?> (<?= h((string)($app['version_code'] ?? '')) ?>)</p>
<?php endif; ?>
<?php if (!empty($p['build'])):
$b = $p['build'];
$buildId = trim((string) ($b['git_commit'] ?? $b['git'] ?? ''));
$filterBuildUrl = $buildId !== ''
? $bp . '/?view=reports&filter_build=' . rawurlencode($buildId)
: '';
?>
<?php if ($filterBuildUrl !== ''): ?>
<p><span class="muted" data-i18n="detail.build">Build:</span> <a class="detail-filter-link detail-filter-link--tag" href="<?= h($filterBuildUrl) ?>" data-i18n-title="detail.filter_build" title="Show reports from this build"><?= h($buildId) ?></a></p>
<?php else: ?>
<p class="muted"><span data-i18n="detail.build">Build:</span> <?= h($buildId) ?></p>
<?php endif; ?>
<?php endif; ?>
</div>
<div class="card card--lift"><h3>Timing</h3>
<p>Generated: <?= h(date('c', (int)(($p['generated_at_epoch_ms'] ?? 0)/1000))) ?></p>
<p>Received: <?= h(date('c', (int)(($report['received_at_ms'] ?? 0)/1000))) ?></p>
<p class="muted">Fingerprint: <code><?= h($p['fingerprint'] ?? $report['fingerprint'] ?? '') ?></code></p>
</div>
</div>
<?php if (!empty($p['java'])): $j = $p['java']; ?>
<section class="stack-block">
<div class="stack-block-head">
<h2>Java exception</h2>
<a class="btn btn-similar" href="<?= h($similarUrl) ?>">Find similar reports</a>
</div>
<p class="exc"><?= h($j['exception'] ?? '') ?><?= !empty($j['message']) ? ': ' . h($j['message']) : '' ?></p>
<p class="muted"><span data-i18n="detail.thread">Thread:</span> <?= h($j['thread'] ?? '') ?></p>
<pre class="stack"><?php foreach ($j['stack_frames'] ?? [] as $frame) { echo h((string)$frame) . "\n"; } ?></pre>
</section>
<?php endif; ?>
<?php if (!empty($p['native'])): $n = $p['native']; ?>
<section class="stack-block">
<div class="stack-block-head">
<h2 data-i18n="detail.native_crash">Native issue</h2>
<a class="btn btn-similar" href="<?= h($similarUrl) ?>">Find similar reports</a>
</div>
<p class="exc">Signal: <?= h($n['signal'] ?? '') ?></p>
<pre class="stack"><?php foreach ($n['backtrace'] ?? [] as $frame) { echo h((string)$frame) . "\n"; } ?></pre>
</section>
<?php endif; ?>
<div class="detail-tree" id="detail-tree">
<?php if ($sessionJson !== ''): ?>
<div class="detail-tree-item">
<div class="detail-tree-row report-row" role="button" tabindex="0" data-tree-toggle data-controls="detail-session">
<span class="report-tree-cell">
<button type="button" class="report-tree-toggle" aria-expanded="false" aria-controls="detail-session" tabindex="-1">
<span class="report-tree-arrow" aria-hidden="true"></span>
</button>
</span>
<span class="detail-tree-caption" data-i18n="detail.session_context">Session context (issue)</span>
</div>
<div class="detail-tree-body" id="detail-session" hidden>
<pre class="stack"><?= h($sessionJson) ?></pre>
</div>
</div>
<?php endif; ?>
<div class="detail-tree-item">
<div class="detail-tree-row report-row" role="button" tabindex="0" data-tree-toggle data-controls="detail-raw-json">
<span class="report-tree-cell">
<button type="button" class="report-tree-toggle" aria-expanded="false" aria-controls="detail-raw-json" tabindex="-1">
<span class="report-tree-arrow" aria-hidden="true"></span>
</button>
</span>
<span class="detail-tree-caption" data-i18n="detail.raw_json">Raw JSON</span>
</div>
<div class="detail-tree-body" id="detail-raw-json" hidden>
<pre class="stack raw-json"><?= h($rawJson) ?></pre>
</div>
</div>
</div>