Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions app/Filament/Resources/GameScreenshotModerationResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ public static function table(Table $table): Table
->modalSubmitAction(function (Action $action, GameScreenshot $record) {
if (
$record->type === ScreenshotType::Ingame
&& $record->game->gameScreenshots()->ofType(ScreenshotType::Ingame)->approved()->count() >= 20
&& $record->game->gameScreenshots()->ofType(ScreenshotType::Ingame)->approved()->count() >= ScreenshotType::Ingame->approvedCap()
) {
return $action->hidden();
}
Expand Down Expand Up @@ -395,11 +395,12 @@ private static function buildApproveIngameDescription(

$countLabel = $approvedCount === 1 ? 'screenshot' : 'screenshots';
$mediaPageUrl = GameResource::getUrl('media', ['record' => $record->game]);
$cap = ScreenshotType::Ingame->approvedCap();

if ($approvedCount >= 20) {
if ($approvedCount >= $cap) {
return new HtmlString(
$subjectLine
. self::buildApproveExplanation('This game already has 20 in-game screenshots approved. (20 max)')
. self::buildApproveExplanation("This game already has {$approvedCount} in-game screenshots approved. ({$cap} max)")
. self::buildApproveExplanation("To approve this submission, first remove a screenshot from the <a href=\"{$mediaPageUrl}\" target=\"_blank\" style=\"text-decoration: underline;\">game's media page</a>.")
. self::buildCenteredPreview(self::buildApproveImageTag($submissionUrl, $submissionResolution, ''))
);
Expand All @@ -419,7 +420,7 @@ private static function buildApproveIngameDescription(
return new HtmlString(
$subjectLine
. self::buildApproveExplanation('This will replace the current primary in-game screenshot (invalid resolution) and add it to the gallery.')
. self::buildApproveExplanation("{$approvedCount} in-game {$countLabel} currently approved.&nbsp;(20&nbsp;max)")
. self::buildApproveExplanation("{$approvedCount} in-game {$countLabel} currently approved.&nbsp;({$cap}&nbsp;max)")
. $mixedResolutionWarning
. self::buildComparisonPreview(
currentLabel: 'Current Primary (' . $currentResolutionLabel . ')',
Expand All @@ -433,7 +434,7 @@ private static function buildApproveIngameDescription(
return new HtmlString(
$subjectLine
. self::buildApproveExplanation("This will add the screenshot to the game's gallery.")
. self::buildApproveExplanation("{$approvedCount} in-game {$countLabel} currently approved.&nbsp;(20&nbsp;max)")
. self::buildApproveExplanation("{$approvedCount} in-game {$countLabel} currently approved.&nbsp;({$cap}&nbsp;max)")
. self::buildCenteredPreview(self::buildApproveImageTag($submissionUrl, $submissionResolution, ''))
);
}
Expand Down
16 changes: 7 additions & 9 deletions app/Platform/Actions/AddGameScreenshotAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,15 @@ public function execute(
if ($shouldBePrimary) {
$legacyPath = (new CreateLegacyScreenshotPngAction())->execute($imageContents);

// Demote existing approved screenshots of this type to pending. This
// prevents the 20-screenshot cap from being hit by normal editor
// uploads and keeps demoted screenshots available for future gallery
// management (Set as Primary, Delete, etc).
$demotedStatus = match ($type) {
ScreenshotType::Title, ScreenshotType::Completion => GameScreenshotStatus::Replaced,
ScreenshotType::Ingame => GameScreenshotStatus::Pending,
};

$game->gameScreenshots()
->ofType($type)
->approved()
->update(['is_primary' => false, 'status' => GameScreenshotStatus::Pending]);
->update(['is_primary' => false, 'status' => $demotedStatus]);
}

$customProperties = ['sha1' => $hash];
Expand Down Expand Up @@ -146,10 +147,7 @@ private function validateCap(Game $game, ScreenshotType $type, bool $isPrimary =
return;
}

$cap = match ($type) {
ScreenshotType::Ingame => 20,
ScreenshotType::Title, ScreenshotType::Completion => 1,
};
$cap = $type->approvedCap();

$approvedCount = $game->gameScreenshots()
->ofType($type)
Expand Down
5 changes: 3 additions & 2 deletions app/Platform/Actions/ApproveGameScreenshotAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,10 @@ public function execute(GameScreenshot $screenshot, User $reviewer): void
->approved()
->count();

if ($approvedCount >= 20) {
$cap = ScreenshotType::Ingame->approvedCap();
if ($approvedCount >= $cap) {
throw ValidationException::withMessages([
'screenshot' => 'This game has reached the maximum of 20 approved in-game screenshots.',
'screenshot' => "This game has reached the maximum of {$cap} approved in-game screenshots.",
]);
}

Expand Down
8 changes: 8 additions & 0 deletions app/Platform/Enums/ScreenshotType.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,12 @@ public function label(): string
self::Completion => 'Completion',
};
}

public function approvedCap(): int
{
return match ($this) {
self::Title, self::Completion => 1,
self::Ingame => 10,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated: Why wasn't this InGame?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mirrors the schema for consistency (but not a hard opinion, we can change it):

Image

};
}
}
24 changes: 20 additions & 4 deletions tests/Feature/Platform/Actions/AddGameScreenshotActionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,22 @@
expect($first->fresh()->status)->toEqual(GameScreenshotStatus::Pending);
});

it('archives the prior completion image as replaced when a new completion is uploaded', function () {
// ARRANGE
$game = Game::factory()->create(['system_id' => System::factory()]);
$action = new AddGameScreenshotAction();
$first = $action->execute($game, UploadedFile::fake()->image('completion-1.png', 256, 224), ScreenshotType::Completion);

// ACT
$second = $action->execute($game, UploadedFile::fake()->image('completion-2.png', 320, 240), ScreenshotType::Completion, isPrimary: true);

// ASSERT
expect($second->is_primary)->toBeTrue();
expect($second->status)->toEqual(GameScreenshotStatus::Approved);
expect($first->fresh()->is_primary)->toBeFalse();
expect($first->fresh()->status)->toEqual(GameScreenshotStatus::Replaced);
});

it('rejects duplicate images for the same game', function () {
// ARRANGE
$game = Game::factory()->create(['system_id' => System::factory()]);
Expand Down Expand Up @@ -110,10 +126,10 @@
$action->execute($game->fresh(), $duplicate, ScreenshotType::Ingame);
})->throws(ValidationException::class);

it('enforces a cap of 20 approved ingame screenshots', function () {
it('enforces a cap of 10 approved ingame screenshots', function () {
// ARRANGE
$game = Game::factory()->create(['system_id' => System::factory()]);
GameScreenshot::factory()->count(20)->for($game)->ingame()->create();
GameScreenshot::factory()->count(10)->for($game)->ingame()->create();
$file = UploadedFile::fake()->image('screenshot.png', 256, 224);

// ASSERT
Expand All @@ -123,7 +139,7 @@
it('does not enforce the ingame cap for title screenshots', function () {
// ARRANGE
$game = Game::factory()->create(['system_id' => System::factory()]);
GameScreenshot::factory()->count(20)->for($game)->ingame()->create();
GameScreenshot::factory()->count(10)->for($game)->ingame()->create();
$file = UploadedFile::fake()->image('title.png', 256, 224);

// ACT
Expand Down Expand Up @@ -159,7 +175,7 @@
expect($second->is_primary)->toBeTrue();
expect($second->status)->toEqual(GameScreenshotStatus::Approved);
expect($first->fresh()->is_primary)->toBeFalse();
expect($first->fresh()->status)->toEqual(GameScreenshotStatus::Pending);
expect($first->fresh()->status)->toEqual(GameScreenshotStatus::Replaced);
});

it('rejects a file smaller than 64x64', function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,13 +243,13 @@ function createPendingScreenshotForApprovalTest(
expect($fileManipulator->createdDerivedFilesFor)->toHaveCount(1);
});

it('enforces the 20 approved ingame screenshot cap during approval', function () {
it('enforces the 10 approved ingame screenshot cap during approval', function () {
// ARRANGE
$game = Game::factory()->create(['system_id' => System::factory()]);
$submitter = User::factory()->create();
$reviewer = User::factory()->create();

GameScreenshot::factory()->count(20)->for($game)->ingame()->create();
GameScreenshot::factory()->count(10)->for($game)->ingame()->create();

$pending = createPendingScreenshotForApprovalTest($game, $submitter, ScreenshotType::Ingame);

Expand Down
Loading