mirror of
https://github.com/sp-tarkov/forge.git
synced 2025-02-12 20:20:41 -05:00
Search SPT Version & Homepage Queries
The global search results now include the SPT version number the latest version of the mod is compatible with. Additionally, mod thumbnails and the SPT version numbers Homepage queries have been further optimized and are now cached for 5 minutes.
This commit is contained in:
parent
69857abe4f
commit
49fd8b83df
@ -28,9 +28,8 @@ class ModController extends Controller
|
||||
public function show(int $modId, string $slug)
|
||||
{
|
||||
$mod = Mod::select()
|
||||
->withLatestSptVersion()
|
||||
->withTotalDownloads()
|
||||
->with('users:id,name')
|
||||
->with(['latestSptVersion', 'users:id,name'])
|
||||
->with('license:id,name,link')
|
||||
->find($modId);
|
||||
|
||||
|
@ -56,6 +56,7 @@ class ImportHubData implements ShouldBeUnique, ShouldQueue
|
||||
Artisan::call('scout:delete-all-indexes');
|
||||
Artisan::call('scout:sync-index-settings');
|
||||
Artisan::call('scout:import', ['model' => '\App\Models\Mod']);
|
||||
Artisan::call('scout:import', ['model' => '\App\Models\User']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -42,8 +42,8 @@ class GlobalSearch extends Component
|
||||
|
||||
if (Str::length($query)) {
|
||||
$results['data'] = [
|
||||
'user' => User::search($query)->get(),
|
||||
'mod' => Mod::search($query)->get(),
|
||||
'user' => collect(User::search($query)->raw()['hits']),
|
||||
'mod' => collect(Mod::search($query)->raw()['hits']),
|
||||
];
|
||||
$results['total'] = $this->countTotalResults($results['data']);
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
@ -50,55 +51,15 @@ class Mod extends Model
|
||||
*/
|
||||
public function scopeWithTotalDownloads($query)
|
||||
{
|
||||
return $query->addSelect(['total_downloads' => ModVersion::selectRaw('SUM(downloads) AS total_downloads')
|
||||
->whereColumn('mod_id', 'mods.id'),
|
||||
return $query->addSelect([
|
||||
'total_downloads' => ModVersion::selectRaw('SUM(downloads) AS total_downloads')
|
||||
->whereColumn('mod_id', 'mods.id'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function latestSptVersion(): BelongsTo
|
||||
public function lastUpdatedVersion(): HasOne
|
||||
{
|
||||
return $this->belongsTo(ModVersion::class, 'latest_spt_version_id');
|
||||
}
|
||||
|
||||
public function scopeWithLatestSptVersion($query)
|
||||
{
|
||||
return $query
|
||||
->addSelect(['latest_spt_version_id' => ModVersion::select('id')
|
||||
->whereColumn('mod_id', 'mods.id')
|
||||
->orderByDesc(
|
||||
SptVersion::select('version')
|
||||
->whereColumn('mod_versions.spt_version_id', 'spt_versions.id')
|
||||
->orderByDesc('version')
|
||||
->take(1),
|
||||
)
|
||||
->orderByDesc('version')
|
||||
->take(1),
|
||||
])
|
||||
->havingNotNull('latest_spt_version_id')
|
||||
->with(['latestSptVersion', 'latestSptVersion.sptVersion']);
|
||||
}
|
||||
|
||||
public function lastUpdatedVersion(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(ModVersion::class, 'last_updated_spt_version_id');
|
||||
}
|
||||
|
||||
public function scopeWithLastUpdatedVersion($query)
|
||||
{
|
||||
return $query
|
||||
->addSelect(['last_updated_spt_version_id' => ModVersion::select('id')
|
||||
->whereColumn('mod_id', 'mods.id')
|
||||
->orderByDesc('updated_at')
|
||||
->take(1),
|
||||
])
|
||||
->orderByDesc(
|
||||
ModVersion::select('updated_at')
|
||||
->whereColumn('mod_id', 'mods.id')
|
||||
->orderByDesc('updated_at')
|
||||
->take(1)
|
||||
)
|
||||
->havingNotNull('last_updated_spt_version_id')
|
||||
->with(['lastUpdatedVersion', 'lastUpdatedVersion.sptVersion']);
|
||||
return $this->hasOne(ModVersion::class)->orderByDesc('updated_at')->with('sptVersion');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -106,6 +67,8 @@ class Mod extends Model
|
||||
*/
|
||||
public function toSearchableArray(): array
|
||||
{
|
||||
$latestSptVersion = $this->latestSptVersion()->first();
|
||||
|
||||
return [
|
||||
'id' => (int) $this->id,
|
||||
'name' => $this->name,
|
||||
@ -115,9 +78,25 @@ class Mod extends Model
|
||||
'featured' => $this->featured,
|
||||
'created_at' => strtotime($this->created_at),
|
||||
'updated_at' => strtotime($this->updated_at),
|
||||
'latestSptVersion' => $latestSptVersion?->sptVersion->version,
|
||||
'latestSptVersionColorClass' => $latestSptVersion?->sptVersion->color_class,
|
||||
];
|
||||
}
|
||||
|
||||
public function latestSptVersion(): HasOne
|
||||
{
|
||||
return $this->hasOne(ModVersion::class)
|
||||
->orderByDesc(
|
||||
SptVersion::select('version')
|
||||
->whereColumn('mod_versions.spt_version_id', 'spt_versions.id')
|
||||
->orderByDesc('version')
|
||||
->take(1),
|
||||
)
|
||||
->with('sptVersion')
|
||||
->orderByDesc('version')
|
||||
->take(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the model should be searchable.
|
||||
*/
|
||||
|
@ -3,8 +3,10 @@
|
||||
namespace App\View\Components;
|
||||
|
||||
use App\Models\Mod;
|
||||
use App\Models\ModVersion;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\View\Component;
|
||||
|
||||
class ModListSection extends Component
|
||||
@ -24,36 +26,44 @@ class ModListSection extends Component
|
||||
|
||||
private function fetchFeaturedMods(): Collection
|
||||
{
|
||||
return Mod::select(['id', 'name', 'slug', 'teaser', 'thumbnail', 'featured'])
|
||||
->withLatestSptVersion()
|
||||
->withTotalDownloads()
|
||||
->with('users:id,name')
|
||||
->where('featured', true)
|
||||
->latest()
|
||||
->limit(6)
|
||||
->get();
|
||||
return Cache::remember('homepage-featured-mods', now()->addMinutes(5), function () {
|
||||
return Mod::select(['id', 'name', 'slug', 'teaser', 'thumbnail', 'featured'])
|
||||
->withTotalDownloads()
|
||||
->with(['latestSptVersion', 'users:id,name'])
|
||||
->where('featured', true)
|
||||
->latest()
|
||||
->limit(6)
|
||||
->get();
|
||||
});
|
||||
}
|
||||
|
||||
private function fetchLatestMods(): Collection
|
||||
{
|
||||
return Mod::select(['id', 'name', 'slug', 'teaser', 'thumbnail', 'featured', 'created_at'])
|
||||
->withLatestSptVersion()
|
||||
->withTotalDownloads()
|
||||
->with('users:id,name')
|
||||
->latest()
|
||||
->limit(6)
|
||||
->get();
|
||||
return Cache::remember('homepage-latest-mods', now()->addMinutes(5), function () {
|
||||
return Mod::select(['id', 'name', 'slug', 'teaser', 'thumbnail', 'featured', 'created_at'])
|
||||
->withTotalDownloads()
|
||||
->with(['latestSptVersion', 'users:id,name'])
|
||||
->latest()
|
||||
->limit(6)
|
||||
->get();
|
||||
});
|
||||
}
|
||||
|
||||
private function fetchUpdatedMods(): Collection
|
||||
{
|
||||
return Mod::select(['id', 'name', 'slug', 'teaser', 'thumbnail', 'featured'])
|
||||
->withLastUpdatedVersion()
|
||||
->withTotalDownloads()
|
||||
->with('users:id,name')
|
||||
->latest()
|
||||
->limit(6)
|
||||
->get();
|
||||
return Cache::remember('homepage-updated-mods', now()->addMinutes(5), function () {
|
||||
return Mod::select(['id', 'name', 'slug', 'teaser', 'thumbnail', 'featured'])
|
||||
->withTotalDownloads()
|
||||
->with(['lastUpdatedVersion', 'users:id,name'])
|
||||
->orderByDesc(
|
||||
ModVersion::select('updated_at')
|
||||
->whereColumn('mod_id', 'mods.id')
|
||||
->orderByDesc('updated_at')
|
||||
->take(1)
|
||||
)
|
||||
->limit(6)
|
||||
->get();
|
||||
});
|
||||
}
|
||||
|
||||
public function render(): View
|
||||
|
@ -1,9 +1,12 @@
|
||||
<a href="/mod/{{ $result->id }}/{{ $result->slug }}" class="{{ $linkClass }}" role="listitem" tabindex="0">
|
||||
<a href="/mod/{{ $result['id'] }}/{{ $result['slug'] }}" class="{{ $linkClass }}" role="listitem" tabindex="0" class="flex flex-col">
|
||||
@if(empty($result->thumbnail))
|
||||
<img src="https://placehold.co/450x450/EEE/31343C?font=source-sans-pro&text={{ $result->name }}" alt="{{ $result->name }}" class="block dark:hidden h-6 w-6 flex-none border border-gray-200 group-hover/global-search-link:border-gray-400">
|
||||
<img src="https://placehold.co/450x450/31343C/EEE?font=source-sans-pro&text={{ $result->name }}" alt="{{ $result->name }}" class="hidden dark:block h-6 w-6 flex-none border border-gray-700 group-hover/global-search-link:border-gray-600">
|
||||
<img src="https://placehold.co/450x450/EEE/31343C?font=source-sans-pro&text={{ $result['name'] }}" alt="{{ $result['name'] }}" class="block dark:hidden h-6 w-6 self-center border border-gray-200 group-hover/global-search-link:border-gray-400">
|
||||
<img src="https://placehold.co/450x450/31343C/EEE?font=source-sans-pro&text={{ $result['name'] }}" alt="{{ $result['name'] }}" class="hidden dark:block h-6 w-6 self-center border border-gray-700 group-hover/global-search-link:border-gray-600">
|
||||
@else
|
||||
<img src="{{ Storage::url($result->thumbnail) }}" alt="{{ $result->name }}" class="h-6 w-6 flex-none">
|
||||
<img src="{{ Storage::url($result['thumbnail']) }}" alt="{{ $result['name'] }}" class="h-6 w-6 self-center">
|
||||
@endif
|
||||
<p>{{ $result->name }}</p>
|
||||
<p class="flex-grow">{{ $result['name'] }}</p>
|
||||
<p class="ml-auto self-center badge-version {{ $result['latestSptVersionColorClass'] }} }} inline-flex items-center rounded-md px-2 py-1 text-xs font-medium text-nowrap">
|
||||
{{ $result['latestSptVersion'] }}
|
||||
</p>
|
||||
</a>
|
||||
|
@ -1,3 +1,3 @@
|
||||
<a href="#/{{ Str::slug($result->name) }}" class="{{ $linkClass }}">
|
||||
<p>{{ $result->name }}</p>
|
||||
<a href="#/{{ Str::slug($result['name']) }}" class="{{ $linkClass }}">
|
||||
<p>{{ $result['name'] }}</p>
|
||||
</a>
|
||||
|
@ -10,13 +10,15 @@
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
|
||||
</svg>
|
||||
</h4>
|
||||
@foreach($typeResults as $result)
|
||||
@component('components.global-search-result-' . Str::lower($typeName), [
|
||||
'result' => $result,
|
||||
'linkClass' => 'group/global-search-link flex flex-row gap-3 py-1.5 px-4 text-gray-900 dark:text-gray-100 hover:bg-gray-200 dark:hover:bg-gray-800 transition-colors duration-100 ease-in-out',
|
||||
])
|
||||
@endcomponent
|
||||
@endforeach
|
||||
<div class="divide-y divide-dashed divide-gray-200 dark:divide-gray-800">
|
||||
@foreach($typeResults as $result)
|
||||
@component('components.global-search-result-' . Str::lower($typeName), [
|
||||
'result' => $result,
|
||||
'linkClass' => 'group/global-search-link flex flex-row gap-3 py-1.5 px-4 text-gray-900 dark:text-gray-100 hover:bg-gray-200 dark:hover:bg-gray-800 transition-colors duration-200 ease-in-out',
|
||||
])
|
||||
@endcomponent
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
|
@ -16,9 +16,6 @@
|
||||
<div class="flex flex-col w-full justify-between p-5">
|
||||
<div>
|
||||
<div class="flex justify-between items-center space-x-3">
|
||||
@if(is_null($mod->{$versionScope}))
|
||||
@dd($mod)
|
||||
@endif
|
||||
<h3 class="block mt-1 text-lg leading-tight font-medium text-black dark:text-white group-hover:underline">{{ $mod->name }}</h3>
|
||||
<span class="badge-version {{ $mod->{$versionScope}->sptVersion->color_class }} inline-flex items-center rounded-md px-2 py-1 text-xs font-medium text-nowrap">
|
||||
{{ $mod->{$versionScope}->sptVersion->version }}
|
||||
|
Loading…
x
Reference in New Issue
Block a user