Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: use total volume for featured collections and remove volume column #683

Merged
merged 9 commits into from
Mar 12, 2024
5 changes: 3 additions & 2 deletions app/Data/Collections/CollectionFeaturedData.php
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@
namespace App\Data\Collections;

use App\Data\Gallery\GalleryNftData;
use App\Data\VolumeData;
use App\Enums\CurrencyCode;
use App\Models\Collection;
use App\Transformers\IpfsGatewayUrlTransformer;
@@ -44,7 +45,7 @@ public function __construct(
public DataCollection $nfts,
public bool $isFeatured,
public ?string $description,
public ?string $volume,
public VolumeData $volume,
) {
}

@@ -72,7 +73,7 @@ public static function fromModel(Collection $collection, CurrencyCode $currency)
supply: $collection->supply,
isFeatured: $collection->is_featured,
description: $description,
volume: $collection->volume,
volume: $collection->createVolumeData(period: null, currency: $currency),
);
}
}
15 changes: 2 additions & 13 deletions app/Http/Controllers/CollectionController.php
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@
use App\Models\CollectionWinner;
use App\Models\User;
use App\Repositories\ArticleRepository;
use App\Repositories\CollectionRepository;
use App\Support\Queues;
use App\Support\RateLimiterHelpers;
use Carbon\Carbon;
@@ -77,21 +78,9 @@ private function getFeaturedCollections(Request $request): SupportCollection
{
$currency = $request->user()?->currency() ?? CurrencyCode::USD;

$collections = Cache::remember(
'featured-collections',
now()->addHour(),
fn () => Collection::featured()
->with([
'network',
'floorPriceToken',
'nfts' => fn ($q) => $q->inRandomOrder()->limit(3),
])
->get()
);
$collections = app(CollectionRepository::class)->featured();

return $collections->map(function (Collection $collection) use ($currency) {
$collection->nfts->each->setRelation('collection', $collection);

return CollectionFeaturedData::fromModel($collection, $currency);
});
}
1 change: 0 additions & 1 deletion app/Jobs/FetchCollectionVolume.php
Original file line number Diff line number Diff line change
@@ -47,7 +47,6 @@ public function handle(): void
], uniqueBy: ['collection_id', 'created_at']);

$this->collection->update([
'volume' => $volume->value,
'volume_1d' => $this->collection->totalVolumeSince(now()->subDays(1)),
'volume_7d' => $this->collection->totalVolumeSince(now()->subDays(7)),
'volume_30d' => $this->collection->totalVolumeSince(now()->subDays(30)),
2 changes: 1 addition & 1 deletion app/Models/Traits/HasVolume.php
Original file line number Diff line number Diff line change
@@ -51,7 +51,7 @@ public function getVolume(?Period $period = null): ?string
/**
* Create a volume DTO based on the volume in the given period.
*/
public function createVolumeData(Period $period, ?CurrencyCode $currency = CurrencyCode::USD): VolumeData
public function createVolumeData(?Period $period, ?CurrencyCode $currency = CurrencyCode::USD): VolumeData
{
$volume = $this->getVolume($period);
$token = $this->nativeToken();
27 changes: 27 additions & 0 deletions app/Repositories/CollectionRepository.php
Original file line number Diff line number Diff line change
@@ -9,9 +9,36 @@
use App\Enums\Period;
use App\Models\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection as LaravelCollection;
use Illuminate\Support\Facades\Cache;

class CollectionRepository
{
/**
* Get all of the currently featured collections.
*
* @return LaravelCollection<int, Collection>
*/
public function featured(): LaravelCollection
{
$ttl = now()->addHour();

$collections = Cache::remember('featured-collections', $ttl, function () {
return Collection::featured()->with([
'network',
'network.nativeToken',
'floorPriceToken',
'nfts' => fn ($q) => $q->inRandomOrder()->limit(3),
])->get();
});

return $collections->map(function (Collection $collection) {
$collection->nfts->each->setRelation('collection', $collection);

return $collection;
});
}

/**
* Get all of the popular collections that match the given filters.
*
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('collections', function (Blueprint $table) {
$table->dropColumn('volume');
});
}
};
2 changes: 1 addition & 1 deletion database/seeders/TopCollectionsNftsSeeder.php
Original file line number Diff line number Diff line change
@@ -149,7 +149,7 @@ private function createCollection(
'symbol' => $collection->symbol ?? $collection->name,
'floor_price' => $collection->floor_price * 1e18,
'floor_price_token_id' => $token->id,
'volume' => $collection->volume_total,
'total_volume' => $collection->volume_total,
'supply' => $collection->items_total,
'type' => $collection->erc_type === 'erc721' ? TokenType::Erc721->value : TokenType::Erc1155->value,
'minted_block' => $collection->deploy_block_number,
1 change: 1 addition & 0 deletions lang/en/common.php
Original file line number Diff line number Diff line change
@@ -65,6 +65,7 @@
'market_cap' => 'Market Cap',
'volume' => 'Volume',
'volume_frequency' => 'Volume :frequency',
'volume_total' => 'Total Volume',
'value' => 'Value',
'last_n_days' => 'Last :count Days',
'details' => 'Details',
2 changes: 1 addition & 1 deletion resources/js/I18n/Locales/en.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ export const FeaturedCollectionStats = ({
floorPriceCurrency: string | null;
floorPriceDecimals: number | null;
nftsCount: number | null;
volume: string | null;
volume: App.Data.VolumeData;
}): JSX.Element => {
const { t } = useTranslation();

@@ -34,6 +34,7 @@ export const FeaturedCollectionStats = ({
value={nftsCount !== null ? formatNumbershort(nftsCount) : null}
/>
<div className="mx-4 h-8 w-px bg-theme-secondary-300 dark:bg-theme-dark-700 sm:mx-6" />

<GridHeader
className="!px-0"
wrapperClassName="w-fit"
@@ -45,15 +46,21 @@ export const FeaturedCollectionStats = ({
/>
}
/>

<div className="mx-4 h-8 w-px bg-theme-secondary-300 dark:bg-theme-dark-700 sm:mx-6" />

<GridHeader
className="!px-0"
wrapperClassName="w-fit"
title={t("common.volume", { frequency: "" })}
title={t("common.volume_total")}
value={
<FormatCrypto
value={volume ?? "0"}
token={token}
value={volume.value ?? "0"}
token={{
name: volume.currency,
symbol: volume.currency,
decimals: volume.decimals,
}}
maximumFractionDigits={2}
/>
}
2 changes: 1 addition & 1 deletion resources/types/generated.d.ts
Original file line number Diff line number Diff line change
@@ -203,7 +203,7 @@ declare namespace App.Data.Collections {
nfts: Array<App.Data.Gallery.GalleryNftData>;
isFeatured: boolean;
description: string | null;
volume: string | null;
volume: App.Data.VolumeData;
};
export type CollectionNftData = {
id: number;
8 changes: 1 addition & 7 deletions tests/App/Jobs/FetchCollectionVolumeTest.php
Original file line number Diff line number Diff line change
@@ -17,25 +17,19 @@

$network = Network::polygon();

$collection = Collection::factory()->for($network)->create([
'volume' => null,
]);
$collection = Collection::factory()->for($network)->create();

TradingVolume::factory()->for($collection)->create([
'volume' => '10',
'created_at' => now()->subDays(3),
]);

expect($collection->volume)->toBeNull();

(new FetchCollectionVolume($collection))->handle();

expect($collection->fresh()->volume)->toBe('123');
expect(TradingVolume::count())->toBe(2);

$volume = TradingVolume::latest('id')->first();

expect($volume->volume)->toBe('123');
expect($volume->created_at->toDateString())->toBe(today()->toDateString());
});