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>
|
<td><?= $data['status'] ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<?php if ( ! empty($data['airDate'])): ?>
|
||||||
|
<tr>
|
||||||
|
<td>Original Airing</td>
|
||||||
|
<td><?= $data['airDate'] ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php endif ?>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>Show Type</td>
|
<td>Show Type</td>
|
||||||
<td><?= (strlen($data['show_type']) > 3) ? ucfirst(strtolower($data['show_type'])) : $data['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'] ?>
|
<?= $link['meta']['name'] ?>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
</td>
|
</td>
|
||||||
<td><?= implode(', ', $link['subs']) ?></td>
|
<td><?= implode(', ', array_map(fn ($sub) => Locale::getDisplayLanguage($sub, 'en'), $link['subs'])) ?></td>
|
||||||
<td><?= implode(', ', $link['dubs']) ?></td>
|
<td><?= implode(', ', array_map(fn ($dub) => Locale::getDisplayLanguage($dub, 'en'), $link['dubs'])) ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -628,6 +628,14 @@ picture.cover {
|
|||||||
background-size: contain;
|
background-size: contain;
|
||||||
background-repeat: no-repeat;
|
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 {
|
.media.search > .row {
|
||||||
z-index: 6;
|
z-index: 6;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import _ from './anime-client.js'
|
import _ from './anime-client.js'
|
||||||
import { renderAnimeSearchResults } from './template-helpers.js'
|
import { renderSearchResults } from './template-helpers.js'
|
||||||
|
|
||||||
const search = (query) => {
|
const search = (query) => {
|
||||||
// Show the loader
|
// Show the loader
|
||||||
@ -13,7 +13,7 @@ const search = (query) => {
|
|||||||
_.hide('.cssload-loader');
|
_.hide('.cssload-loader');
|
||||||
|
|
||||||
// Show the results
|
// 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 _ from './anime-client.js'
|
||||||
import { renderMangaSearchResults } from './template-helpers.js'
|
import { renderSearchResults } from './template-helpers.js'
|
||||||
|
|
||||||
const search = (query) => {
|
const search = (query) => {
|
||||||
_.show('.cssload-loader');
|
_.show('.cssload-loader');
|
||||||
return _.get(_.url('/manga/search'), { query }, (searchResults, status) => {
|
return _.get(_.url('/manga/search'), { query }, (searchResults, status) => {
|
||||||
searchResults = JSON.parse(searchResults);
|
searchResults = JSON.parse(searchResults);
|
||||||
_.hide('.cssload-loader');
|
_.hide('.cssload-loader');
|
||||||
_.$('#series-list')[ 0 ].innerHTML = renderMangaSearchResults(searchResults);
|
_.$('#series-list')[ 0 ].innerHTML = renderSearchResults('manga', searchResults);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -7,20 +7,55 @@ _.on('main', 'change', '.big-check', (e) => {
|
|||||||
document.getElementById(`mal_${id}`).checked = true;
|
document.getElementById(`mal_${id}`).checked = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
export function renderAnimeSearchResults (data) {
|
/**
|
||||||
|
* 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 `
|
||||||
|
<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>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 => {
|
return data.map(item => {
|
||||||
const titles = item.titles.join('<br />');
|
const titles = item.titles.join('<br />');
|
||||||
|
const disabled = item.libraryEntry !== null ? 'disabled' : '';
|
||||||
|
const editLink = renderEditLink(type, item);
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<article class="media search">
|
<article class="media search ${disabled}">
|
||||||
<div class="name">
|
<div class="name">
|
||||||
<input type="radio" class="mal-check" id="mal_${item.slug}" name="mal_id" value="${item.mal_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}" />
|
<input type="radio" class="big-check" id="${item.slug}" name="id" value="${item.id}" ${disabled} />
|
||||||
<label for="${item.slug}">
|
<label for="${item.slug}">
|
||||||
<picture width="220">
|
<picture width="220">
|
||||||
<source srcset="/public/images/anime/${item.id}.webp" type="image/webp" />
|
<source srcset="/public/images/${type}/${item.id}.webp" type="image/webp" />
|
||||||
<source srcset="/public/images/anime/${item.id}.jpg" type="image/jpeg" />
|
<source srcset="/public/images/${type}/${item.id}.jpg" type="image/jpeg" />
|
||||||
<img src="/public/images/anime/${item.id}.jpg" alt="" width="220" />
|
<img src="/public/images/${type}/${item.id}.jpg" alt="" width="220" />
|
||||||
</picture>
|
</picture>
|
||||||
<span class="name">
|
<span class="name">
|
||||||
${item.canonicalTitle}<br />
|
${item.canonicalTitle}<br />
|
||||||
@ -29,41 +64,10 @@ export function renderAnimeSearchResults (data) {
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="table">
|
<div class="table">
|
||||||
|
${editLink}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<span class="edit">
|
<span class="edit">
|
||||||
<a class="bracketed" href="/anime/details/${item.slug}">Info Page</a>
|
<a class="bracketed" href="/${type}/details/${item.slug}">Info Page</a>
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</article>
|
|
||||||
`;
|
|
||||||
}).join('');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function renderMangaSearchResults (data) {
|
|
||||||
return data.map(item => {
|
|
||||||
const titles = item.titles.join('<br />');
|
|
||||||
return `
|
|
||||||
<article class="media search">
|
|
||||||
<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}" />
|
|
||||||
<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" />
|
|
||||||
</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="/manga/details/${item.slug}">Info Page</a>
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</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'],
|
'slug' => $item['slug'],
|
||||||
'canonicalTitle' => $item['titles']['canonical'],
|
'canonicalTitle' => $item['titles']['canonical'],
|
||||||
'titles' => array_values(K::getTitles($item['titles'])),
|
'titles' => array_values(K::getTitles($item['titles'])),
|
||||||
|
'libraryEntry' => $item['myLibraryEntry'],
|
||||||
];
|
];
|
||||||
|
|
||||||
// Search for MAL mapping
|
// Search for MAL mapping
|
||||||
|
@ -30,6 +30,12 @@ query ($slug: String!) {
|
|||||||
canonical
|
canonical
|
||||||
localized
|
localized
|
||||||
}
|
}
|
||||||
|
...on Anime {
|
||||||
|
episodeCount
|
||||||
|
}
|
||||||
|
...on Manga {
|
||||||
|
chapterCount
|
||||||
|
}
|
||||||
}
|
}
|
||||||
updatedAt
|
updatedAt
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,10 @@ query ($query: String!) {
|
|||||||
localized
|
localized
|
||||||
alternatives
|
alternatives
|
||||||
}
|
}
|
||||||
|
myLibraryEntry {
|
||||||
|
id
|
||||||
|
status
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -14,6 +14,10 @@ query ($query: String!) {
|
|||||||
localized
|
localized
|
||||||
alternatives
|
alternatives
|
||||||
}
|
}
|
||||||
|
myLibraryEntry {
|
||||||
|
id
|
||||||
|
status
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -121,6 +121,7 @@ final class AnimeTransformer extends AbstractTransformer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return AnimePage::from([
|
return AnimePage::from([
|
||||||
|
'airDate' => Kitsu::formatAirDates($base['startDate'], $base['endDate']),
|
||||||
'age_rating' => $base['ageRating'],
|
'age_rating' => $base['ageRating'],
|
||||||
'age_rating_guide' => $base['ageRatingGuide'],
|
'age_rating_guide' => $base['ageRatingGuide'],
|
||||||
'characters' => $characters,
|
'characters' => $characters,
|
||||||
|
@ -65,6 +65,7 @@ abstract class HistoryTransformer {
|
|||||||
|
|
||||||
foreach ($base as $entry)
|
foreach ($base as $entry)
|
||||||
{
|
{
|
||||||
|
// Filter out other media types
|
||||||
if (strtolower($entry['media']['__typename']) !== $this->type)
|
if (strtolower($entry['media']['__typename']) !== $this->type)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@ -195,6 +196,19 @@ abstract class HistoryTransformer {
|
|||||||
return NULL;
|
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))
|
$action = ($this->isReconsuming($entry))
|
||||||
? "{$this->reconsumeAction} {$item}"
|
? "{$this->reconsumeAction} {$item}"
|
||||||
: "{$this->progressAction} {$item}";
|
: "{$this->progressAction} {$item}";
|
||||||
|
@ -68,6 +68,57 @@ final class Kitsu {
|
|||||||
return AnimeAiringStatus::NOT_YET_AIRED;
|
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
|
public static function getPublishingStatus(string $kitsuStatus, string $startDate = NULL, string $endDate = NULL): string
|
||||||
{
|
{
|
||||||
$startPubDate = new DateTimeImmutable($startDate ?? 'tomorrow');
|
$startPubDate = new DateTimeImmutable($startDate ?? 'tomorrow');
|
||||||
@ -263,8 +314,15 @@ final class Kitsu {
|
|||||||
|
|
||||||
if (array_key_exists('localized', $titles) && is_array($titles['localized']))
|
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))
|
if (self::titleIsUnique($alternateTitle, $valid))
|
||||||
{
|
{
|
||||||
$valid[] = $alternateTitle;
|
$valid[] = $alternateTitle;
|
||||||
|
@ -25,4 +25,6 @@ final class AnimePage extends Anime {
|
|||||||
public array $links = [];
|
public array $links = [];
|
||||||
|
|
||||||
public array $staff = [];
|
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, 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 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 }]
|
'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: R
|
||||||
age_rating_guide: 'Violence, Profanity'
|
age_rating_guide: 'Violence, Profanity'
|
||||||
cover_image: 'https://media.kitsu.io/anime/poster_images/7442/small.jpg?1597698856'
|
cover_image: 'https://media.kitsu.io/anime/poster_images/7442/small.jpg?1597698856'
|
||||||
|
Loading…
Reference in New Issue
Block a user