Merge remote-tracking branch 'origin/develop'
This commit is contained in:
commit
629f7f1045
@ -17,6 +17,13 @@ use function Aviat\AnimeClient\getLocalImg;
|
||||
<td><?= $data['status'] ?></td>
|
||||
</tr>
|
||||
|
||||
<?php if ( ! empty($data['airDate'])): ?>
|
||||
<tr>
|
||||
<td>Original Airing</td>
|
||||
<td><?= $data['airDate'] ?></td>
|
||||
</tr>
|
||||
<?php endif ?>
|
||||
|
||||
<tr>
|
||||
<td>Show Type</td>
|
||||
<td><?= (strlen($data['show_type']) > 3) ? ucfirst(strtolower($data['show_type'])) : $data['show_type'] ?></td>
|
||||
@ -122,8 +129,8 @@ use function Aviat\AnimeClient\getLocalImg;
|
||||
<?= $link['meta']['name'] ?>
|
||||
<?php endif ?>
|
||||
</td>
|
||||
<td><?= implode(', ', $link['subs']) ?></td>
|
||||
<td><?= implode(', ', $link['dubs']) ?></td>
|
||||
<td><?= implode(', ', array_map(fn ($sub) => Locale::getDisplayLanguage($sub, 'en'), $link['subs'])) ?></td>
|
||||
<td><?= implode(', ', array_map(fn ($dub) => Locale::getDisplayLanguage($dub, 'en'), $link['dubs'])) ?></td>
|
||||
</tr>
|
||||
<?php endforeach ?>
|
||||
</tbody>
|
||||
|
@ -628,6 +628,14 @@ picture.cover {
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
/* There are two .name elements, just darken them both in this case! */
|
||||
.media.search.disabled .name {
|
||||
background-color: #000;
|
||||
background-color: rgba(0, 0, 0, 0.75);
|
||||
background-size: cover;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.media.search > .row {
|
||||
z-index: 6;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import _ from './anime-client.js'
|
||||
import { renderAnimeSearchResults } from './template-helpers.js'
|
||||
import { renderSearchResults } from './template-helpers.js'
|
||||
|
||||
const search = (query) => {
|
||||
// Show the loader
|
||||
@ -13,7 +13,7 @@ const search = (query) => {
|
||||
_.hide('.cssload-loader');
|
||||
|
||||
// Show the results
|
||||
_.$('#series-list')[ 0 ].innerHTML = renderAnimeSearchResults(searchResults);
|
||||
_.$('#series-list')[ 0 ].innerHTML = renderSearchResults('anime', searchResults);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
import _ from './anime-client.js'
|
||||
import { renderMangaSearchResults } from './template-helpers.js'
|
||||
import { renderSearchResults } from './template-helpers.js'
|
||||
|
||||
const search = (query) => {
|
||||
_.show('.cssload-loader');
|
||||
return _.get(_.url('/manga/search'), { query }, (searchResults, status) => {
|
||||
searchResults = JSON.parse(searchResults);
|
||||
_.hide('.cssload-loader');
|
||||
_.$('#series-list')[ 0 ].innerHTML = renderMangaSearchResults(searchResults);
|
||||
_.$('#series-list')[ 0 ].innerHTML = renderSearchResults('manga', searchResults);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -7,52 +7,55 @@ _.on('main', 'change', '.big-check', (e) => {
|
||||
document.getElementById(`mal_${id}`).checked = true;
|
||||
});
|
||||
|
||||
export function renderAnimeSearchResults (data) {
|
||||
return data.map(item => {
|
||||
const titles = item.titles.join('<br />');
|
||||
/**
|
||||
* On search results with an existing library entry, this shows that fact, with an edit link for the existing
|
||||
* library entry
|
||||
*
|
||||
* @param {'anime'|'manga'} type
|
||||
* @param {Object} item
|
||||
* @returns {String}
|
||||
*/
|
||||
function renderEditLink (type, item) {
|
||||
if (item.libraryEntry === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return `
|
||||
<article class="media search">
|
||||
<div class="name">
|
||||
<input type="radio" class="mal-check" id="mal_${item.slug}" name="mal_id" value="${item.mal_id}" />
|
||||
<input type="radio" class="big-check" id="${item.slug}" name="id" value="${item.id}" />
|
||||
<label for="${item.slug}">
|
||||
<picture width="220">
|
||||
<source srcset="/public/images/anime/${item.id}.webp" type="image/webp" />
|
||||
<source srcset="/public/images/anime/${item.id}.jpg" type="image/jpeg" />
|
||||
<img src="/public/images/anime/${item.id}.jpg" alt="" width="220" />
|
||||
</picture>
|
||||
<span class="name">
|
||||
${item.canonicalTitle}<br />
|
||||
<small>${titles}</small>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="table">
|
||||
<div class="row">
|
||||
<span class="edit">
|
||||
<a class="bracketed" href="/anime/details/${item.slug}">Info Page</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
`;
|
||||
}).join('');
|
||||
return `
|
||||
<div class="row">
|
||||
<span class="edit"><big>[ Already in List ]</big></span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="edit">
|
||||
<a class="bracketed" href="/${type}/edit/${item.libraryEntry.id}/${item.libraryEntry.status}">Edit</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="row"><span class="edit"> </span></div>
|
||||
`
|
||||
}
|
||||
|
||||
export function renderMangaSearchResults (data) {
|
||||
/**
|
||||
* Show the search results for a media item
|
||||
*
|
||||
* @param {'anime'|'manga'} type
|
||||
* @param {Object} data
|
||||
* @returns {String}
|
||||
*/
|
||||
export function renderSearchResults (type, data) {
|
||||
return data.map(item => {
|
||||
const titles = item.titles.join('<br />');
|
||||
const disabled = item.libraryEntry !== null ? 'disabled' : '';
|
||||
const editLink = renderEditLink(type, item);
|
||||
|
||||
return `
|
||||
<article class="media search">
|
||||
<article class="media search ${disabled}">
|
||||
<div class="name">
|
||||
<input type="radio" id="mal_${item.slug}" name="mal_id" value="${item.mal_id}" />
|
||||
<input type="radio" class="big-check" id="${item.slug}" name="id" value="${item.id}" />
|
||||
<input type="radio" class="mal-check" id="mal_${item.slug}" name="mal_id" value="${item.mal_id}" ${disabled} />
|
||||
<input type="radio" class="big-check" id="${item.slug}" name="id" value="${item.id}" ${disabled} />
|
||||
<label for="${item.slug}">
|
||||
<picture width="220">
|
||||
<source srcset="/public/images/manga/${item.id}.webp" type="image/webp" />
|
||||
<source srcset="/public/images/manga/${item.id}.jpg" type="image/jpeg" />
|
||||
<img src="/public/images/manga/${item.id}.jpg" alt="" width="220" />
|
||||
<source srcset="/public/images/${type}/${item.id}.webp" type="image/webp" />
|
||||
<source srcset="/public/images/${type}/${item.id}.jpg" type="image/jpeg" />
|
||||
<img src="/public/images/${type}/${item.id}.jpg" alt="" width="220" />
|
||||
</picture>
|
||||
<span class="name">
|
||||
${item.canonicalTitle}<br />
|
||||
@ -61,9 +64,10 @@ export function renderMangaSearchResults (data) {
|
||||
</label>
|
||||
</div>
|
||||
<div class="table">
|
||||
${editLink}
|
||||
<div class="row">
|
||||
<span class="edit">
|
||||
<a class="bracketed" href="/manga/details/${item.slug}">Info Page</a>
|
||||
<a class="bracketed" href="/${type}/details/${item.slug}">Info Page</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
2
public/css/auto.min.css
vendored
2
public/css/auto.min.css
vendored
File diff suppressed because one or more lines are too long
2
public/css/dark.min.css
vendored
2
public/css/dark.min.css
vendored
File diff suppressed because one or more lines are too long
2
public/css/light.min.css
vendored
2
public/css/light.min.css
vendored
File diff suppressed because one or more lines are too long
2
public/js/scripts.min.js
vendored
2
public/js/scripts.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -535,6 +535,7 @@ final class Model {
|
||||
'slug' => $item['slug'],
|
||||
'canonicalTitle' => $item['titles']['canonical'],
|
||||
'titles' => array_values(K::getTitles($item['titles'])),
|
||||
'libraryEntry' => $item['myLibraryEntry'],
|
||||
];
|
||||
|
||||
// Search for MAL mapping
|
||||
|
@ -30,6 +30,12 @@ query ($slug: String!) {
|
||||
canonical
|
||||
localized
|
||||
}
|
||||
...on Anime {
|
||||
episodeCount
|
||||
}
|
||||
...on Manga {
|
||||
chapterCount
|
||||
}
|
||||
}
|
||||
updatedAt
|
||||
}
|
||||
|
@ -14,6 +14,10 @@ query ($query: String!) {
|
||||
localized
|
||||
alternatives
|
||||
}
|
||||
myLibraryEntry {
|
||||
id
|
||||
status
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -14,6 +14,10 @@ query ($query: String!) {
|
||||
localized
|
||||
alternatives
|
||||
}
|
||||
myLibraryEntry {
|
||||
id
|
||||
status
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -121,6 +121,7 @@ final class AnimeTransformer extends AbstractTransformer {
|
||||
}
|
||||
|
||||
return AnimePage::from([
|
||||
'airDate' => Kitsu::formatAirDates($base['startDate'], $base['endDate']),
|
||||
'age_rating' => $base['ageRating'],
|
||||
'age_rating_guide' => $base['ageRatingGuide'],
|
||||
'characters' => $characters,
|
||||
|
@ -65,6 +65,7 @@ abstract class HistoryTransformer {
|
||||
|
||||
foreach ($base as $entry)
|
||||
{
|
||||
// Filter out other media types
|
||||
if (strtolower($entry['media']['__typename']) !== $this->type)
|
||||
{
|
||||
continue;
|
||||
@ -195,6 +196,19 @@ abstract class HistoryTransformer {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Hide the last episode update (Anime)
|
||||
foreach (['episodeCount', 'chapterCount'] as $count)
|
||||
{
|
||||
if ( ! empty($entry['media'][$count]))
|
||||
{
|
||||
$update = $entry['changedData']['progress'][1] ?? 0;
|
||||
if ($update === $entry['media'][$count])
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$action = ($this->isReconsuming($entry))
|
||||
? "{$this->reconsumeAction} {$item}"
|
||||
: "{$this->progressAction} {$item}";
|
||||
|
@ -68,6 +68,57 @@ final class Kitsu {
|
||||
return AnimeAiringStatus::NOT_YET_AIRED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reformat the airing date range for an Anime
|
||||
*
|
||||
* @param string|null $startDate
|
||||
* @param string|null $endDate
|
||||
* @return string
|
||||
*/
|
||||
public static function formatAirDates(string $startDate = NULL, string $endDate = NULL): string
|
||||
{
|
||||
if (empty($startDate))
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
$monthMap = [
|
||||
'01' => 'Jan',
|
||||
'02' => 'Feb',
|
||||
'03' => 'Mar',
|
||||
'04' => 'Apr',
|
||||
'05' => 'May',
|
||||
'06' => 'Jun',
|
||||
'07' => 'Jul',
|
||||
'08' => 'Aug',
|
||||
'09' => 'Sep',
|
||||
'10' => 'Oct',
|
||||
'11' => 'Nov',
|
||||
'12' => 'Dec',
|
||||
];
|
||||
|
||||
[$startYear, $startMonth, $startDay] = explode('-', $startDate);
|
||||
|
||||
if ($startDate === $endDate)
|
||||
{
|
||||
return "{$monthMap[$startMonth]} $startDay, $startYear";
|
||||
}
|
||||
|
||||
if (empty($endDate))
|
||||
{
|
||||
return "{$monthMap[$startMonth]} {$startYear} - ";
|
||||
}
|
||||
|
||||
[$endYear, $endMonth] = explode('-', $endDate);
|
||||
|
||||
if ($startYear === $endYear)
|
||||
{
|
||||
return "{$monthMap[$startMonth]} - {$monthMap[$endMonth]} $startYear";
|
||||
}
|
||||
|
||||
return "{$monthMap[$startMonth]} {$startYear} - {$monthMap[$endMonth]} {$endYear}";
|
||||
}
|
||||
|
||||
public static function getPublishingStatus(string $kitsuStatus, string $startDate = NULL, string $endDate = NULL): string
|
||||
{
|
||||
$startPubDate = new DateTimeImmutable($startDate ?? 'tomorrow');
|
||||
@ -263,8 +314,15 @@ final class Kitsu {
|
||||
|
||||
if (array_key_exists('localized', $titles) && is_array($titles['localized']))
|
||||
{
|
||||
foreach($titles['localized'] as $alternateTitle)
|
||||
foreach($titles['localized'] as $locale => $alternateTitle)
|
||||
{
|
||||
// Really don't care about languages that aren't english
|
||||
// or Japanese for titles
|
||||
if ( ! in_array($locale, ['en', 'en_us', 'en_jp', 'ja_jp']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (self::titleIsUnique($alternateTitle, $valid))
|
||||
{
|
||||
$valid[] = $alternateTitle;
|
||||
|
@ -25,4 +25,6 @@ final class AnimePage extends Anime {
|
||||
public array $links = [];
|
||||
|
||||
public array $staff = [];
|
||||
|
||||
public ?string $airDate = '';
|
||||
}
|
@ -43,6 +43,7 @@ staff:
|
||||
'Theme Song Lyrics, Inserted Song Performance': [{ id: '17751', name: mpi, image: { original: 'https://media.kitsu.io/people/images/17751/original.jpg?1533270888' }, slug: mpi }]
|
||||
'Theme Song Lyrics, Theme Song Composition, Theme Song Arrangement': [{ id: '17299', name: Revo, image: { original: 'https://media.kitsu.io/people/images/17299/original.jpg?1533270886' }, slug: revo }]
|
||||
'Theme Song Performance': [{ id: '18196', name: 'Cinema Staff', image: { original: 'https://media.kitsu.io/people/images/18196/original.jpg?1533273064' }, slug: cinema-staff }, { id: '8718', name: 'Linked Horizon', image: { original: 'https://media.kitsu.io/people/images/8718/original.jpg?1416270072' }, slug: linked-horizon }, { id: '6847', name: 'Yoko Hikasa', image: { original: 'https://media.kitsu.io/people/images/6847/original.jpg?1416268029' }, slug: yoko-hikasa }]
|
||||
airDate: 'Apr - Sep 2013'
|
||||
age_rating: R
|
||||
age_rating_guide: 'Violence, Profanity'
|
||||
cover_image: 'https://media.kitsu.io/anime/poster_images/7442/small.jpg?1597698856'
|
||||
|
Loading…
Reference in New Issue
Block a user