Merge pull request #320 from shikorism/fix/318-profile-image-srcset
プロフィール画像のsrcsetを出力するヘルパーを追加
This commit is contained in:
commit
7968019e1c
@ -75,4 +75,21 @@ class Formatter
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* imgタグのsrcsetで使用できる形式で、プロフィール画像URLを生成します。
|
||||
* @param object $user Userなど、getProfileImageUrl()が実装されているオブジェクト
|
||||
* @param int $baseSize 1x解像度における画像サイズ
|
||||
* @param int $maxDensity 最高密度
|
||||
* @return string srcset用の文字列
|
||||
*/
|
||||
public function profileImageSrcSet($user, int $baseSize, int $maxDensity = 3)
|
||||
{
|
||||
$srcset = [];
|
||||
for ($i = 1; $i <= $maxDensity; $i++) {
|
||||
$srcset[] = $user->getProfileImageUrl($baseSize * $i) . " {$i}x";
|
||||
}
|
||||
|
||||
return implode(',', $srcset);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<!-- span -->
|
||||
<div>
|
||||
<h5>
|
||||
<a href="{{ route('user.profile', ['id' => $ejaculation->user->name]) }}" class="text-dark"><img src="{{ $ejaculation->user->getProfileImageUrl(30) }}" width="30" height="30" class="rounded d-inline-block align-bottom"> <bdi>{{ $ejaculation->user->display_name }}</bdi></a>
|
||||
<a href="{{ route('user.profile', ['id' => $ejaculation->user->name]) }}" class="text-dark"><img src="{{ $ejaculation->user->getProfileImageUrl(30) }}" srcset="{{ Formatter::profileImageSrcSet($ejaculation->user, 30) }}" width="30" height="30" class="rounded d-inline-block align-bottom"> <bdi>{{ $ejaculation->user->display_name }}</bdi></a>
|
||||
<a href="{{ route('checkin.show', ['id' => $ejaculation->id]) }}" class="text-muted"><small>{{ $ejaculation->ejaculated_date->format('Y/m/d H:i') }}</small></a>
|
||||
</h5>
|
||||
</div>
|
||||
@ -39,7 +39,7 @@
|
||||
<div class="like-users flex-grow-1 overflow-hidden">
|
||||
@foreach ($ejaculation->likes as $like)
|
||||
@if ($like->user !== null)
|
||||
<a href="{{ route('user.profile', ['name' => $like->user->name]) }}"><img src="{{ $like->user->getProfileImageUrl(30) }}" width="30" height="30" class="rounded" data-toggle="tooltip" data-placement="bottom" title="{{ $like->user->display_name }}"></a>
|
||||
<a href="{{ route('user.profile', ['name' => $like->user->name]) }}"><img src="{{ $like->user->getProfileImageUrl(30) }}" srcset="{{ Formatter::profileImageSrcSet($like->user, 30) }}" width="30" height="30" class="rounded" data-toggle="tooltip" data-placement="bottom" title="{{ $like->user->display_name }}"></a>
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<div class="card mb-4">
|
||||
<div class="card-body">
|
||||
<img src="{{ $user->getProfileImageUrl(128) }}" class="rounded mb-1">
|
||||
<img src="{{ $user->getProfileImageUrl(128) }}" srcset="{{ Formatter::profileImageSrcSet($user, 128) }}" class="rounded mb-1">
|
||||
<h4 class="card-title">
|
||||
<a class="text-dark" href="{{ route('user.profile', ['name' => $user->name]) }}">{{ $user->display_name }}</a>
|
||||
</h4>
|
||||
|
@ -67,7 +67,7 @@
|
||||
<div class="like-users-tall flex-grow-1 overflow-hidden">
|
||||
@foreach ($ejaculation->likes as $like)
|
||||
@if ($like->user !== null)
|
||||
<a href="{{ route('user.profile', ['name' => $like->user->name]) }}"><img src="{{ $like->user->getProfileImageUrl(36) }}" width="36" height="36" class="rounded" data-toggle="tooltip" data-placement="bottom" title="{{ $like->user->display_name }}"></a>
|
||||
<a href="{{ route('user.profile', ['name' => $like->user->name]) }}"><img src="{{ $like->user->getProfileImageUrl(36) }}" srcset="{{ Formatter::profileImageSrcSet($like->user, 36) }}" width="36" height="36" class="rounded" data-toggle="tooltip" data-placement="bottom" title="{{ $like->user->display_name }}"></a>
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
|
@ -10,7 +10,7 @@
|
||||
<div class="card mb-4">
|
||||
<div class="card-body">
|
||||
<div class="d-flex flex-row align-items-end mb-4">
|
||||
<img src="{{ Auth::user()->getProfileImageUrl(48) }}" class="rounded mr-2">
|
||||
<img src="{{ Auth::user()->getProfileImageUrl(48) }}" srcset="{{ Formatter::profileImageSrcSet(Auth::user(), 48) }}" class="rounded mr-2">
|
||||
<div class="d-flex flex-column overflow-hidden">
|
||||
<h5 class="card-title text-truncate">
|
||||
<a class="text-dark" href="{{ route('user.profile', ['name' => Auth::user()->name]) }}">{{ Auth::user()->display_name }}</a>
|
||||
|
@ -40,7 +40,7 @@
|
||||
<div class="d-lg-none navbar-nav">
|
||||
<div class="nav-item dropdown">
|
||||
<a href="#" class="nav-link dropdown-toggle p-2" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<img src="{{ Auth::user()->getProfileImageUrl(30) }}" width="30" height="30" class="rounded d-inline-block align-top">
|
||||
<img src="{{ Auth::user()->getProfileImageUrl(30) }}" srcset="{{ Formatter::profileImageSrcSet(Auth::user(), 30) }}" width="30" height="30" class="rounded d-inline-block align-top">
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right position-absolute" aria-labelledby="navbarDropdownMenuLink" id="navbarAccountDropdownSp">
|
||||
<a href="{{ route('user.profile', ['name' => Auth::user()->name]) }}" class="dropdown-item text-truncate">
|
||||
@ -103,7 +103,7 @@
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item dropdown">
|
||||
<a href="#" class="nav-link dropdown-toggle" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<img src="{{ Auth::user()->getProfileImageUrl(30) }}" width="30" height="30" class="rounded d-inline-block align-top">
|
||||
<img src="{{ Auth::user()->getProfileImageUrl(30) }}" srcset="{{ Formatter::profileImageSrcSet(Auth::user(), 30) }}" width="30" height="30" class="rounded d-inline-block align-top">
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdownMenuLink">
|
||||
<a href="{{ route('user.profile', ['name' => Auth::user()->name]) }}" class="dropdown-item">
|
||||
|
@ -9,7 +9,7 @@
|
||||
{{ csrf_field() }}
|
||||
<div class="from-group">
|
||||
<label for="name">アイコン</label>
|
||||
<img src="{{ Auth::user()->getProfileImageUrl(128) }}" class="rounded d-block">
|
||||
<img src="{{ Auth::user()->getProfileImageUrl(128) }}" srcset="{{ Formatter::profileImageSrcSet(Auth::user(), 128) }}" class="rounded d-block">
|
||||
<small class="form-text text-muted">変更は<a href="https://gravatar.com/" target="_blank">Gravatar</a>から行えます。</small>
|
||||
</div>
|
||||
<div class="from-group mt-3">
|
||||
|
@ -73,7 +73,7 @@
|
||||
<div class="like-users flex-grow-1 overflow-hidden">
|
||||
@foreach ($ejaculation->likes as $like)
|
||||
@if ($like->user !== null)
|
||||
<a href="{{ route('user.profile', ['name' => $like->user->name]) }}"><img src="{{ $like->user->getProfileImageUrl(30) }}" width="30" height="30" class="rounded" data-toggle="tooltip" data-placement="bottom" title="{{ $like->user->display_name }}"></a>
|
||||
<a href="{{ route('user.profile', ['name' => $like->user->name]) }}"><img src="{{ $like->user->getProfileImageUrl(30) }}" srcset="{{ Formatter::profileImageSrcSet($like->user, 30) }}" width="30" height="30" class="rounded" data-toggle="tooltip" data-placement="bottom" title="{{ $like->user->display_name }}"></a>
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
|
@ -54,4 +54,20 @@ class FormatterTest extends TestCase
|
||||
$url = 'http://example.com/path/to?foo=bar&hoge=fuga#';
|
||||
$this->assertEquals('http://example.com/path/to?foo=bar&hoge=fuga', $formatter->normalizeUrl($url));
|
||||
}
|
||||
|
||||
public function testProfileImageSrcSet()
|
||||
{
|
||||
$formatter = new Formatter();
|
||||
$profileImageProvider = new class() {
|
||||
public function getProfileImageUrl(int $size)
|
||||
{
|
||||
return "https://example.com/$size.png";
|
||||
}
|
||||
};
|
||||
|
||||
$this->assertSame(
|
||||
'https://example.com/128.png 1x,https://example.com/256.png 2x',
|
||||
$formatter->profileImageSrcSet($profileImageProvider, 128, 2)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user