Skip to content

Commit c79b792

Browse files
committed
Async Github identicon avatars detection on user signup
1 parent 49f5115 commit c79b792

File tree

6 files changed

+71
-1
lines changed

6 files changed

+71
-1
lines changed

app/Http/Controllers/Auth/RegisterController.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use App\Http\Controllers\Controller;
66
use App\Http\Requests\RegisterRequest;
77
use App\Jobs\RegisterUser;
8+
use App\Jobs\UpdateUserIdenticonStatus;
89
use App\Models\User;
910
use App\Providers\AppServiceProvider;
1011
use Illuminate\Auth\Events\Registered;
@@ -70,6 +71,8 @@ public function register(RegisterRequest $request)
7071
protected function create(RegisterRequest $request): User
7172
{
7273
$this->dispatchSync(RegisterUser::fromRequest($request));
74+
$user = User::findByEmailAddress($request->emailAddress());
75+
$this->dispatch(new UpdateUserIdenticonStatus($user));
7376

7477
return User::findByEmailAddress($request->emailAddress());
7578
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace App\Jobs;
4+
5+
use Illuminate\Contracts\Queue\ShouldQueue;
6+
use Illuminate\Foundation\Bus\Dispatchable;
7+
use Illuminate\Foundation\Queue\Queueable;
8+
use Illuminate\Queue\InteractsWithQueue;
9+
use Illuminate\Queue\SerializesModels;
10+
use App\Models\User;
11+
use App\Social\GithubUserApi;
12+
13+
final class UpdateUserIdenticonStatus implements ShouldQueue
14+
{
15+
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
16+
17+
public function __construct(private User $user) {}
18+
19+
public function handle(GithubUserApi $github): void
20+
{
21+
$hasIdenticon = $github->hasIdenticon($this->user->githubId());
22+
$this->user->update(['has_identicon' => $hasIdenticon]);
23+
}
24+
}

app/Models/User.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ final class User extends Authenticatable implements MustVerifyEmail
5858
'remember_token',
5959
'bio',
6060
'banned_reason',
61+
'has_identicon'
6162
];
6263

6364
/**
@@ -113,6 +114,11 @@ public function githubUsername(): string
113114
return $this->github_username ?? '';
114115
}
115116

117+
public function hasIdenticon(): bool
118+
{
119+
return (bool) $this->has_identicon;
120+
}
121+
116122
public function twitter(): ?string
117123
{
118124
return $this->twitter;

app/Social/GithubUserApi.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,25 @@ public function find(int|string $id): ?GitHubUser
1414

1515
return $response->failed() ? null : new GitHubUser($response->json());
1616
}
17+
18+
public function hasIdenticon(int|string $id): bool
19+
{
20+
$detectionSize = 40;
21+
$response = Http::retry(3, 300, fn ($exception) => $exception instanceof ConnectionException)
22+
->get("https://avatars.githubusercontent.com/u/{$id}?v=4&s={$detectionSize}");
23+
24+
if ($response->failed()) {
25+
return true;
26+
}
27+
28+
$info = getimagesizefromstring($response->body());
29+
30+
if (!$info) {
31+
return true;
32+
}
33+
34+
[$width, $height] = $info;
35+
36+
return !($width === 420 && $height === 420);
37+
}
1738
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class extends Migration
8+
{
9+
public function up(): void
10+
{
11+
Schema::table('users', function (Blueprint $table) {
12+
$table->boolean('has_identicon')->after('bio')->default(false);
13+
});
14+
}
15+
16+
};

resources/views/components/avatar.blade.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
])
55

66
<?php
7-
$src = $user->githubId()
7+
$src = $user->githubId() && !$user->hasIdenticon()
88
? sprintf('https://avatars.githubusercontent.com/u/%s', $user->githubId())
99
: asset('https://laravel.io/images/laravelio-icon-gray.svg');
1010
?>

0 commit comments

Comments
 (0)