Skip to content

Commit

Permalink
feat(home): show user's current AOTW unlock status (#3054)
Browse files Browse the repository at this point in the history
  • Loading branch information
wescopeland authored Jan 18, 2025
1 parent 67af73a commit 19808d4
Show file tree
Hide file tree
Showing 20 changed files with 365 additions and 106 deletions.
34 changes: 22 additions & 12 deletions app/Http/Actions/BuildAchievementOfTheWeekDataAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,24 @@

namespace App\Http\Actions;

use App\Http\Data\AchievementOfTheWeekPropsData;
use App\Models\EventAchievement;
use App\Models\User;
use App\Platform\Data\EventAchievementData;

class BuildAchievementOfTheWeekDataAction
{
public function execute(): ?EventAchievementData
public function execute(?User $user = null): ?AchievementOfTheWeekPropsData
{
$achievementOfTheWeek = EventAchievement::active()
->whereNotNull('active_from')
->whereNotNull('active_until')
->whereHas('achievement.game', function ($query) { // only from the current AotW event
$query->where('Title', 'like', '%of the week%');
})
->whereRaw(dateCompareStatement('active_until', 'active_from', '< 20')) // ignore AotM achievements - don't specifically look for 7 days because of the extended duration of the week 52 event
->with(['achievement.game', 'sourceAchievement.game'])
$achievementOfTheWeek = EventAchievement::currentAchievementOfTheWeek()
->with(['event', 'achievement.game', 'sourceAchievement.game'])
->first();

if (!$achievementOfTheWeek?->source_achievement_id) {
if (!$achievementOfTheWeek?->sourceAchievement) {
return null;
}

$data = EventAchievementData::from($achievementOfTheWeek)->include(
$currentEventAchievementData = EventAchievementData::from($achievementOfTheWeek)->include(
'achievement.id',
'achievement.title',
'achievement.description',
Expand All @@ -38,6 +34,20 @@ public function execute(): ?EventAchievementData
'activeUntil',
);

return $data;
return new AchievementOfTheWeekPropsData(
currentEventAchievement: $currentEventAchievementData,
doesUserHaveUnlock: $this->getDoesUserHaveUnlock($user, $achievementOfTheWeek),
);
}

private function getDoesUserHaveUnlock(?User $user, EventAchievement $achievementOfTheWeek): bool
{
if (!$user) {
return false;
}

return $user->playerAchievements()
->whereAchievementId($achievementOfTheWeek->achievement_id)
->exists();
}
}
7 changes: 4 additions & 3 deletions app/Http/Controllers/HomeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,13 @@ public function index(
BuildHomePageClaimsDataAction $buildHomePageClaimsData,
BuildThinRecentForumPostsDataAction $buildThinRecentForumPostsData,
): InertiaResponse {
/** @var ?User $user */
$user = Auth::user();

$staticData = StaticData::first();
$staticDataData = StaticDataData::fromStaticData($staticData);

$achievementOfTheWeek = $buildAchievementOfTheWeekData->execute();
$achievementOfTheWeek = $buildAchievementOfTheWeekData->execute($user);
$mostRecentGameMastered = $buildMostRecentGameAwardData->execute($staticData, AwardType::Mastery);
$mostRecentGameBeaten = $buildMostRecentGameAwardData->execute($staticData, AwardType::GameBeaten);
$recentNews = $buildNewsData->execute();
Expand All @@ -53,8 +56,6 @@ public function index(
$activePlayers = $buildActivePlayers->execute(perPage: 20, search: $persistedActivePlayersSearch);
$trendingGames = $buildTrendingGames->execute();

/** @var ?User $user */
$user = Auth::user();
$permissions = $user ? (int) $user->getAttribute('Permissions') : Permissions::Unregistered;
$recentForumPosts = $buildThinRecentForumPostsData->execute(
permissions: $permissions,
Expand Down
19 changes: 19 additions & 0 deletions app/Http/Data/AchievementOfTheWeekPropsData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace App\Http\Data;

use App\Platform\Data\EventAchievementData;
use Spatie\LaravelData\Data;
use Spatie\TypeScriptTransformer\Attributes\TypeScript;

#[TypeScript('AchievementOfTheWeekProps')]
class AchievementOfTheWeekPropsData extends Data
{
public function __construct(
public EventAchievementData $currentEventAchievement,
public bool $doesUserHaveUnlock,
) {
}
}
3 changes: 1 addition & 2 deletions app/Http/Data/HomePagePropsData.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
use App\Data\PaginatedData;
use App\Data\StaticDataData;
use App\Data\StaticGameAwardData;
use App\Platform\Data\EventAchievementData;
use Illuminate\Support\Collection;
use Spatie\LaravelData\Data;
use Spatie\TypeScriptTransformer\Attributes\TypeScript;
Expand All @@ -29,7 +28,7 @@ class HomePagePropsData extends Data
*/
public function __construct(
public StaticDataData $staticData,
public ?EventAchievementData $achievementOfTheWeek,
public ?AchievementOfTheWeekPropsData $achievementOfTheWeek,
public ?StaticGameAwardData $mostRecentGameMastered,
public ?StaticGameAwardData $mostRecentGameBeaten,
public Collection $recentNews,
Expand Down
10 changes: 10 additions & 0 deletions app/Models/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

use App\Support\Database\Eloquent\BaseModel;
use Carbon\Carbon;
use Database\Factories\EventFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
Expand All @@ -15,6 +17,9 @@

class Event extends BaseModel
{
/** @use HasFactory<EventFactory> */
use HasFactory;

use LogsActivity {
LogsActivity::activities as auditLog;
}
Expand All @@ -39,6 +44,11 @@ class Event extends BaseModel
'active_through',
];

protected static function newFactory(): EventFactory
{
return EventFactory::new();
}

// == logging

public function getActivitylogOptions(): LogOptions
Expand Down
25 changes: 25 additions & 0 deletions app/Models/EventAchievement.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,19 @@

use App\Support\Database\Eloquent\BaseModel;
use Carbon\Carbon;
use Database\Factories\EventAchievementFactory;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasOneThrough;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Traits\LogsActivity;

class EventAchievement extends BaseModel
{
/** @use HasFactory<EventAchievementFactory> */
use HasFactory;

use LogsActivity {
LogsActivity::activities as auditLog;
}
Expand All @@ -37,6 +42,11 @@ class EventAchievement extends BaseModel
'active_through',
];

protected static function newFactory(): EventAchievementFactory
{
return EventAchievementFactory::new();
}

public const RAEVENTS_USER_ID = 279854;
public const DEVQUEST_USER_ID = 240336;

Expand Down Expand Up @@ -112,6 +122,21 @@ public function sourceAchievement(): BelongsTo

// == scopes

/**
* @param Builder<EventAchievement> $query
* @return Builder<EventAchievement>
*/
public function scopeCurrentAchievementOfTheWeek(Builder $query): Builder
{
return $query->active()
->whereHas('achievement.game', function ($query) { // only from the current AotW event
$query->where('Title', 'like', '%of the week%');
})
->whereNotNull('active_from')
->whereNotNull('active_until')
->whereRaw(dateCompareStatement('active_until', 'active_from', '< 20')); // ignore AotM achievements.
}

/**
* @param Builder<EventAchievement> $query
* @return Builder<EventAchievement>
Expand Down
30 changes: 30 additions & 0 deletions database/factories/EventAchievementFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace Database\Factories;

use App\Models\Achievement;
use App\Models\EventAchievement;
use Illuminate\Database\Eloquent\Factories\Factory;

/**
* @extends Factory<EventAchievement>
*/
class EventAchievementFactory extends Factory
{
protected $model = EventAchievement::class;

/**
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'achievement_id' => Achievement::factory(),
'source_achievement_id' => Achievement::factory(),
'active_from' => now(),
'active_until' => now()->addWeek(),
];
}
}
33 changes: 33 additions & 0 deletions database/factories/EventFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Database\Factories;

use App\Models\Event;
use App\Models\Game;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Carbon;

/**
* @extends Factory<Event>
*/
class EventFactory extends Factory
{
protected $model = Event::class;

/**
* @return array<string, mixed>
*/
public function definition(): array
{
$activeFrom = Carbon::instance($this->faker->dateTimeBetween('-1 year', '+1 year'));

return [
'legacy_game_id' => Game::factory(),
'slug' => $this->faker->unique()->slug(),
'active_from' => $activeFrom,
'active_until' => $activeFrom->clone()->addYear(),
];
}
}
5 changes: 2 additions & 3 deletions public/API/API_GetAchievementOfTheWeek.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<?php

use App\Http\Actions\BuildAchievementOfTheWeekDataAction;
use App\Models\Achievement;
use App\Models\EventAchievement;
use Illuminate\Support\Facades\DB;

Expand Down Expand Up @@ -49,7 +48,7 @@

$aotwData = (new BuildAchievementOfTheWeekDataAction())->execute();

$achievementId = $aotwData->achievement->id ?? 0;
$achievementId = $aotwData->currentEventAchievement->achievement->id ?? 0;
$eventAchievement = EventAchievement::active()->where('achievement_id', $achievementId)->first();

if (!$eventAchievement?->sourceAchievement) {
Expand Down Expand Up @@ -86,7 +85,7 @@
];

$forumTopic = [
'ID' => $aotwData->forumTopicId->resolve() ?? null,
'ID' => $aotwData->currentEventAchievement->forumTopicId->resolve() ?? null,
];

$unlocks = collect();
Expand Down
Loading

0 comments on commit 19808d4

Please sign in to comment.