fix: review fixes — cache Wikidata calls, add timeout, improve escaping, hide empty popovers
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -21,6 +21,8 @@ export default function ActorPopover({ hintType, hintText }) {
|
|||||||
const dismiss = useDismiss(context);
|
const dismiss = useDismiss(context);
|
||||||
const { getReferenceProps, getFloatingProps } = useInteractions([click, dismiss]);
|
const { getReferenceProps, getFloatingProps } = useInteractions([click, dismiss]);
|
||||||
|
|
||||||
|
if (!hintText) return null;
|
||||||
|
|
||||||
const iconClass = HINT_ICONS[hintType] || 'fa-solid fa-circle-question';
|
const iconClass = HINT_ICONS[hintType] || 'fa-solid fa-circle-question';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ class GameGridGenerator
|
|||||||
$rowOrder = 0;
|
$rowOrder = 0;
|
||||||
$usedMovieRoleIds = [];
|
$usedMovieRoleIds = [];
|
||||||
$usedHintKeys = [];
|
$usedHintKeys = [];
|
||||||
|
$cachedAwards = null;
|
||||||
|
|
||||||
foreach (str_split(strtolower($mainActor->getName())) as $char) {
|
foreach (str_split(strtolower($mainActor->getName())) as $char) {
|
||||||
if (!preg_match('/[a-z]/', $char)) {
|
if (!preg_match('/[a-z]/', $char)) {
|
||||||
@@ -57,7 +58,7 @@ class GameGridGenerator
|
|||||||
$row->setPosition(strpos(strtolower($actor->getName()), $char));
|
$row->setPosition(strpos(strtolower($actor->getName()), $char));
|
||||||
$row->setRowOrder($rowOrder);
|
$row->setRowOrder($rowOrder);
|
||||||
|
|
||||||
$hint = $this->generateHint($mainActor, $usedMovieRoleIds, $usedHintKeys);
|
$hint = $this->generateHint($mainActor, $usedMovieRoleIds, $usedHintKeys, $cachedAwards);
|
||||||
if ($hint !== null) {
|
if ($hint !== null) {
|
||||||
$row->setHintType($hint['type']);
|
$row->setHintType($hint['type']);
|
||||||
$row->setHintData($hint['data']);
|
$row->setHintData($hint['data']);
|
||||||
@@ -138,13 +139,13 @@ class GameGridGenerator
|
|||||||
* @param list<string> $usedHintKeys Semantic keys like "film:42" to avoid duplicate hints
|
* @param list<string> $usedHintKeys Semantic keys like "film:42" to avoid duplicate hints
|
||||||
* @return array{type: string, data: string}|null
|
* @return array{type: string, data: string}|null
|
||||||
*/
|
*/
|
||||||
private function generateHint(Actor $mainActor, array &$usedMovieRoleIds, array &$usedHintKeys): ?array
|
private function generateHint(Actor $mainActor, array &$usedMovieRoleIds, array &$usedHintKeys, ?array &$cachedAwards): ?array
|
||||||
{
|
{
|
||||||
$types = ['film', 'character', 'award'];
|
$types = ['film', 'character', 'award'];
|
||||||
shuffle($types);
|
shuffle($types);
|
||||||
|
|
||||||
foreach ($types as $type) {
|
foreach ($types as $type) {
|
||||||
$hint = $this->resolveHint($type, $mainActor, $usedMovieRoleIds, $usedHintKeys);
|
$hint = $this->resolveHint($type, $mainActor, $usedMovieRoleIds, $usedHintKeys, $cachedAwards);
|
||||||
if ($hint !== null) {
|
if ($hint !== null) {
|
||||||
return $hint;
|
return $hint;
|
||||||
}
|
}
|
||||||
@@ -158,7 +159,7 @@ class GameGridGenerator
|
|||||||
* @param list<string> $usedHintKeys
|
* @param list<string> $usedHintKeys
|
||||||
* @return array{type: string, data: string}|null
|
* @return array{type: string, data: string}|null
|
||||||
*/
|
*/
|
||||||
private function resolveHint(string $type, Actor $mainActor, array &$usedMovieRoleIds, array &$usedHintKeys): ?array
|
private function resolveHint(string $type, Actor $mainActor, array &$usedMovieRoleIds, array &$usedHintKeys, ?array &$cachedAwards): ?array
|
||||||
{
|
{
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case 'film':
|
case 'film':
|
||||||
@@ -196,12 +197,15 @@ class GameGridGenerator
|
|||||||
return ['type' => 'character', 'data' => $roleId];
|
return ['type' => 'character', 'data' => $roleId];
|
||||||
|
|
||||||
case 'award':
|
case 'award':
|
||||||
|
if ($cachedAwards === null) {
|
||||||
try {
|
try {
|
||||||
$awards = $this->wikidataAwardGateway->getAwards($mainActor);
|
$cachedAwards = $this->wikidataAwardGateway->getAwards($mainActor);
|
||||||
} catch (\Throwable) {
|
} catch (\Throwable) {
|
||||||
|
$cachedAwards = [];
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
foreach ($awards as $award) {
|
}
|
||||||
|
foreach ($cachedAwards as $award) {
|
||||||
$text = $award['name'] . ' (' . $award['year'] . ')';
|
$text = $award['name'] . ' (' . $award['year'] . ')';
|
||||||
$key = 'award:' . $text;
|
$key = 'award:' . $text;
|
||||||
if (!in_array($key, $usedHintKeys)) {
|
if (!in_array($key, $usedHintKeys)) {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ class WikidataAwardGateway
|
|||||||
'Accept' => 'application/sparql-results+json',
|
'Accept' => 'application/sparql-results+json',
|
||||||
'User-Agent' => 'LtbxdActorle/1.0',
|
'User-Agent' => 'LtbxdActorle/1.0',
|
||||||
],
|
],
|
||||||
|
'timeout' => 5,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$data = $response->toArray();
|
$data = $response->toArray();
|
||||||
@@ -55,7 +56,7 @@ class WikidataAwardGateway
|
|||||||
|
|
||||||
private function buildQuery(string $actorName): string
|
private function buildQuery(string $actorName): string
|
||||||
{
|
{
|
||||||
$escaped = str_replace('"', '\\"', $actorName);
|
$escaped = str_replace(['\\', '"', "\n", "\r"], ['\\\\', '\\"', '\\n', '\\r'], $actorName);
|
||||||
|
|
||||||
return <<<SPARQL
|
return <<<SPARQL
|
||||||
SELECT ?awardLabel ?year WHERE {
|
SELECT ?awardLabel ?year WHERE {
|
||||||
|
|||||||
Reference in New Issue
Block a user