Skip to content

Commit

Permalink
Add 2x support for news cover image
Browse files Browse the repository at this point in the history
  • Loading branch information
nanaya committed Oct 30, 2024
1 parent 87bf4e5 commit 828e3f1
Show file tree
Hide file tree
Showing 10 changed files with 75 additions and 25 deletions.
15 changes: 15 additions & 0 deletions app/Models/NewsPost.php
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,21 @@ public function firstImage($absolute = false)
return $url;
}

public function firstImageWith2x(): array
{
$url = presence($this->firstImage());

if ($url !== null) {
$origUrl = proxy_media_original_url($url);
$url2x = proxy_media(retinaify($origUrl));
}

return [
'1x' => $url,
'2x' => $url2x ?? null,
];
}

public function newer()
{
return $this->memoize(__FUNCTION__, function () {
Expand Down
5 changes: 4 additions & 1 deletion app/Transformers/NewsPostTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@ class NewsPostTransformer extends TransformerAbstract

public function transform(NewsPost $post)
{
$firstImage = $post->firstImageWith2x();

return [
'id' => $post->id,

'author' => $post->author(),
'edit_url' => $post->editUrl(),
'first_image' => $post->firstImage(),
'first_image' => $firstImage['1x'],
'first_image@2x' => $firstImage['2x'],
'published_at' => json_time($post->published_at),
'updated_at' => json_time($post->updated_at),
'slug' => $post->slug,
Expand Down
11 changes: 11 additions & 0 deletions app/helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -1128,6 +1128,17 @@ function proxy_media($url)
return $GLOBALS['cfg']['osu']['camo']['prefix']."{$secret}/{$hexUrl}";
}

function proxy_media_original_url(?string $url): ?string
{
if ($url === null) {
return null;
}

return str_starts_with($url, $GLOBALS['cfg']['osu']['camo']['prefix'])
? hex2bin(substr($url, strrpos($url, '/') + 1))
: $url;
}

function lazy_load_image($url, $class = '', $alt = '')
{
return "<img class='{$class}' src='{$url}' alt='{$alt}' loading='lazy' />";
Expand Down
3 changes: 2 additions & 1 deletion resources/css/bem/news-post-preview.less
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
}

&__image {
.at2x-simple-var(--bg);
width: 100%;
height: 130px;
background-size: cover;
background-position: 50%;
display: block;
background-color: @osu-colour-b6;
background-color: hsl(var(--hsl-b6));
.@{top}--collapsed & {
display: none;
}
Expand Down
2 changes: 1 addition & 1 deletion resources/css/bem/page-nav-fancy.less
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
.page-nav-fancy {
@_top: page-nav-fancy;

.at2x-simple("~@images/headers/news-show-default.jpg");
.at2x-fallback(--bg, "~@images/headers/news-show-default.jpg");
.link-plain();
.link-white();
background-position: center;
Expand Down
17 changes: 14 additions & 3 deletions resources/js/interfaces/news-post-json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,26 @@ interface Navigation {
older?: NewsPostJson;
}

export default interface NewsPostJson {
interface HasFirstImage {
first_image: string;
'first_image@2x': string;
}

interface HasNoFirstImage {
first_image: null;
'first_image@2x': null;
}

type NewsPostJson = {
author: string;
content?: string;
edit_url: string;
first_image?: string;
id: number;
navigation?: Navigation;
preview?: string;
published_at: string;
slug: string;
title: string;
}
} & (HasFirstImage | HasNoFirstImage);

export default NewsPostJson;
5 changes: 3 additions & 2 deletions resources/js/news-index/post-item.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the GNU Affero General Public License v3.0.
// See the LICENCE file in the repository root for full licence text.

import Img2x from 'components/img2x';
import StringWithComponent from 'components/string-with-component';
import PostJson from 'interfaces/news-post-json';
import { route } from 'laroute';
Expand All @@ -13,7 +14,7 @@ export default function PostItem({ modifiers, post }: { modifiers?: string[]; po
let cover;

if (post.first_image != null) {
cover = <img className='news-card__cover' src={post.first_image} />;
cover = <Img2x className='news-card__cover' src={post.first_image} src2x={post['first_image@2x']} />;
}

let preview = post.preview;
Expand All @@ -40,8 +41,8 @@ export default function PostItem({ modifiers, post }: { modifiers?: string[]; po
<div className='news-card__main'>
<div className='news-card__row news-card__row--title'>{post.title}</div>
<div
dangerouslySetInnerHTML={{ __html: preview }}
className='news-card__row news-card__row--preview'
dangerouslySetInnerHTML={{ __html: preview }}
/>
<div className='news-card__row news-card__row--author'>
<StringWithComponent
Expand Down
13 changes: 8 additions & 5 deletions resources/js/news-show/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { route } from 'laroute';
import PostItem from 'news-index/post-item';
import NewsSidebar from 'news-sidebar/main';
import * as React from 'react';
import { classWithModifiers, urlPresence } from 'utils/css';
import { classWithModifiers, Modifiers, urlPresence } from 'utils/css';
import { trans } from 'utils/lang';

interface Props {
Expand All @@ -20,7 +20,7 @@ interface Props {
sidebarMeta: NewsSidebarMetaJson;
}

function NavPost({ post, subtitle, modifiers }: { modifiers: string[]; post?: NewsPostJson; subtitle: string }) {
function NavPost({ post, subtitle, modifiers }: { modifiers: Modifiers; post?: NewsPostJson; subtitle: string }) {
if (post == null) {
return null;
}
Expand All @@ -29,7 +29,10 @@ function NavPost({ post, subtitle, modifiers }: { modifiers: string[]; post?: Ne
<a
className={classWithModifiers('page-nav-fancy', modifiers)}
href={route('news.show', { news: post.slug })}
style={{ backgroundImage: urlPresence(post.first_image) }}
style={{
'--bg': urlPresence(post.first_image),
'--bg-2x': urlPresence(post['first_image@2x']),
} as React.CSSProperties}
>
<div className='page-nav-fancy__label'>
<div className='page-nav-fancy__subtitle'>
Expand Down Expand Up @@ -166,8 +169,8 @@ export default class Main extends React.Component<Props> {

return (
<>
<NavPost modifiers={['next']} post={newerPost} subtitle={trans('news.show.nav.newer')} />
<NavPost modifiers={['prev']} post={olderPost} subtitle={trans('news.show.nav.older')} />
<NavPost modifiers='next' post={newerPost} subtitle={trans('news.show.nav.newer')} />
<NavPost modifiers='prev' post={olderPost} subtitle={trans('news.show.nav.older')} />
</>
);
};
Expand Down
21 changes: 11 additions & 10 deletions resources/views/docs/_structures/news_post.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
## NewsPost

Field | Type | Description
-------------|-------------------------|------------
author | string | |
edit_url | string | Link to the file view on GitHub.
first_image | string? | Link to the first image in the document.
id | integer | |
published_at | [Timestamp](#timestamp) | |
slug | string | Filename without the extension, used in URLs.
title | string | |
updated_at | [Timestamp](#timestamp) | |
Field | Type | Description
-------------- | ----------------------- | -----------
author | string | |
edit_url | string | Link to the file view on GitHub.
first_image | string? | Link to the first image in the document.
first_image@2x | string? | Larger size version of `first_image`.
id | integer | |
published_at | [Timestamp](#timestamp) | |
slug | string | Filename without the extension, used in URLs.
title | string | |
updated_at | [Timestamp](#timestamp) | |

### Optional Attributes

Expand Down
8 changes: 6 additions & 2 deletions resources/views/home/_user_news_post_preview.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@
--}}
@php
$publishedAt = $post->published_at;
$firstImage = $post->firstImageWith2x();
@endphp
<div class="news-post-preview{{$collapsed ? ' news-post-preview--collapsed' : ''}}">
<a
class="news-post-preview__image"
href='{{ route('news.show', $post->slug) }}'
{!! background_image($post->firstImage()) !!}
href="{{ route('news.show', $post->slug) }}"
style="
--bg: url('{{ $firstImage['1x'] }}');
--bg-2x: url('{{ $firstImage['2x'] }}');
"
></a>
<div class="news-post-preview__body">
<div class="news-post-preview__post-date js-tooltip-time" title="{{ json_time($publishedAt) }}">
Expand Down

0 comments on commit 828e3f1

Please sign in to comment.