Compare commits

...

2 Commits

Author SHA1 Message Date
Timothy Warren ca3fa85df3 Update service worker so it only caches images 2018-08-21 17:11:03 -04:00
Timothy Warren 1fa5695a9f Anime Collection improvements
* Allow editing title and alternate title
* Show list of genres on list view of collection
2018-08-21 17:09:42 -04:00
7 changed files with 193 additions and 110 deletions

View File

@ -0,0 +1,84 @@
<article
class="media"
data-kitsu-id="<?= $item['id'] ?>"
data-mal-id="<?= $item['mal_id'] ?>"
>
<?php if ($auth->isAuthenticated()): ?>
<button title="Increment episode count" class="plus_one" hidden>+1 Episode</button>
<?php endif ?>
<img src="<?= $urlGenerator->assetUrl("images/anime/{$item['anime']['id']}.jpg") ?>" alt=""/>
<div class="name">
<a href="<?= $url->generate('anime.details', ['id' => $item['anime']['slug']]); ?>">
<span class="canonical"><?= $item['anime']['title'] ?></span>
<?php foreach ($item['anime']['titles'] as $title): ?>
<br/>
<small><?= $title ?></small>
<?php endforeach ?>
</a>
</div>
<div class="table">
<?php if ($item['private'] || $item['rewatching']): ?>
<div class="row">
<?php foreach (['private', 'rewatching'] as $attr): ?>
<?php if ($item[$attr]): ?>
<span class="item-<?= $attr ?>"><?= ucfirst($attr) ?></span>
<?php endif ?>
<?php endforeach ?>
</div>
<?php endif ?>
<?php if ($item['rewatched'] > 0): ?>
<div class="row">
<div>Rewatched <?= $item['rewatched'] ?> time(s)</div>
</div>
<?php endif ?>
<?php if (count($item['anime']['streaming_links']) > 0): ?>
<div class="row">
<?php foreach ($item['anime']['streaming_links'] as $link): ?>
<div class="cover_streaming_link">
<?php if ($link['meta']['link']): ?>
<a href="<?= $link['link'] ?>"
title="Stream '<?= $item['anime']['title'] ?>' on <?= $link['meta']['name'] ?>">
<img class="streaming-logo" width="20" height="20"
src="<?= $urlGenerator->assetUrl('images', $link['meta']['image']) ?>"
alt="<?= $link['meta']['name'] ?> logo"/>
</a>
<?php else: ?>
<img class="streaming-logo" width="20" height="20"
src="<?= $urlGenerator->assetUrl('images', $link['meta']['image']) ?>"
alt="<?= $link['meta']['name'] ?> logo"/>
<?php endif ?>
</div>
<?php endforeach ?>
</div>
<?php endif ?>
<?php if ($auth->isAuthenticated()): ?>
<div class="row">
<span class="edit">
<a class="bracketed" title="Edit information about this anime" href="<?=
$url->generate('edit', [
'controller' => 'anime',
'id' => $item['id'],
'status' => $item['watching_status']
]);
?>">Edit</a>
</span>
</div>
<?php endif ?>
<div class="row">
<div class="user_rating">Rating: <?= $item['user_rating'] ?> / 10</div>
<div class="completion">Episodes:
<span class="completed_number"><?= $item['episodes']['watched'] ?></span> /
<span class="total_number"><?= $item['episodes']['total'] ?></span>
</div>
</div>
<div class="row">
<div class="media_type"><?= $escape->html($item['anime']['show_type']) ?></div>
<div class="airing_status"><?= $escape->html($item['airing']['status']) ?></div>
<div class="age_rating"><?= $escape->html($item['anime']['age_rating']) ?></div>
</div>
</div>
</article>

View File

@ -17,80 +17,7 @@
<section class="media-wrap">
<?php foreach($items as $item): ?>
<?php if ($item['private'] && ! $auth->isAuthenticated()) continue; ?>
<article class="media" data-kitsu-id="<?= $item['id'] ?>" data-mal-id="<?= $item['mal_id'] ?>">
<?php if ($auth->isAuthenticated()): ?>
<button title="Increment episode count" class="plus_one" hidden>+1 Episode</button>
<?php endif ?>
<img src="<?= $urlGenerator->assetUrl("images/anime/{$item['anime']['id']}.jpg") ?>" alt="" />
<div class="name">
<a href="<?= $url->generate('anime.details', ['id' => $item['anime']['slug']]); ?>">
<span class="canonical"><?= $item['anime']['title'] ?></span>
<?php foreach ($item['anime']['titles'] as $title): ?>
<br /><small><?= $title ?></small>
<?php endforeach ?>
</a>
</div>
<div class="table">
<?php if ($item['private'] || $item['rewatching']): ?>
<div class="row">
<?php foreach(['private', 'rewatching'] as $attr): ?>
<?php if($item[$attr]): ?>
<span class="item-<?= $attr ?>"><?= ucfirst($attr) ?></span>
<?php endif ?>
<?php endforeach ?>
</div>
<?php endif ?>
<?php if ($item['rewatched'] > 0): ?>
<div class="row">
<div>Rewatched <?= $item['rewatched'] ?> time(s)</div>
</div>
<?php endif ?>
<?php if (count($item['anime']['streaming_links']) > 0): ?>
<div class="row">
<?php foreach($item['anime']['streaming_links'] as $link): ?>
<div class="cover_streaming_link">
<?php if($link['meta']['link']): ?>
<a href="<?= $link['link']?>" title="Stream '<?= $item['anime']['title'] ?>' on <?= $link['meta']['name'] ?>">
<img class="streaming-logo" width="20" height="20" src="<?= $urlGenerator->assetUrl('images', $link['meta']['image']) ?>" alt="<?= $link['meta']['name'] ?> logo" />
</a>
<?php else: ?>
<img class="streaming-logo" width="20" height="20" src="<?= $urlGenerator->assetUrl('images', $link['meta']['image']) ?>" alt="<?= $link['meta']['name'] ?> logo" />
<?php endif ?>
</div>
<?php endforeach ?>
</div>
<?php endif ?>
<?php if ($auth->isAuthenticated()): ?>
<div class="row">
<span class="edit">
<a class="bracketed" title="Edit information about this anime" href="<?=
$url->generate('edit', [
'controller' => 'anime',
'id' => $item['id'],
'status' => $item['watching_status']
]);
?>">Edit</a>
</span>
</div>
<?php endif ?>
<div class="row">
<div class="user_rating">Rating: <?= $item['user_rating'] ?> / 10</div>
<div class="completion">Episodes:
<span class="completed_number"><?= $item['episodes']['watched'] ?></span> /
<span class="total_number"><?= $item['episodes']['total'] ?></span>
</div>
</div>
<div class="row">
<div class="media_type"><?= $escape->html($item['anime']['show_type']) ?></div>
<div class="airing_status"><?= $escape->html($item['airing']['status']) ?></div>
<div class="age_rating"><?= $escape->html($item['anime']['age_rating']) ?></div>
</div>
</div>
</article>
<?php include __DIR__ . '/cover-item.php' ?>
<?php endforeach ?>
</section>
</section>

View File

@ -3,24 +3,26 @@
<h2>Edit Anime Collection Item</h2>
<form action="<?= $action_url ?>" method="post">
<table class="invisible form" style="border:0">
<thead>
<tr>
<th>
<h3><?= $escape->html($item['title']) ?></h3>
<?php if($item['alternate_title'] != ""): ?>
<h4><?= $item['alternate_title'] ?></h4>
<?php endif ?>
</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="4" class="align_center">
<td rowspan="6" class="align_center">
<article class="media">
<?= $helper->img($urlGenerator->assetUrl("images/anime/{$item['hummingbird_id']}.jpg")); ?>
</article>
</td>
</tr>
<tr>
<td class="align_right"><label for="title">Title</label></td>
<td class="align_left">
<input type="text" name="title" value="<?= $item['title'] ?>" />
</td>
</tr>
<tr>
<td class="align_right"><label for="title">Alternate Title</label></td>
<td class="align_left">
<input type="text" name="alternate_title" value="<?= $item['alternate_title'] ?>"/>
</td>
</tr>
<tr>
<td class="align_right"><label for="media_id">Media</label></td>
<td class="align_left">

View File

@ -15,5 +15,6 @@
<td><?= $item['episode_length'] ?></td>
<td><?= $item['show_type'] ?></td>
<td><?= $item['age_rating'] ?></td>
<td class="align_left"><?= implode(', ', $item['genres']) ?></td>
<td class="align_left"><?= $item['notes'] ?></td>
</tr>

View File

@ -24,6 +24,7 @@
<th>Episode Length</th>
<th>Show Type</th>
<th>Age Rating</th>
<th>Genres</th>
<th>Notes</th>
</tr>
</thead>

View File

@ -121,9 +121,20 @@ final class AnimeCollection extends Collection {
->join('media', 'media.id=a.media_id', 'inner')
->order_by('media')
->order_by('title')
->group_by('a.hummingbird_id')
->get();
return $query->fetchAll(PDO::FETCH_ASSOC);
// Add genres associated with each item
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
$genres = $this->getGenresForList();
foreach($rows as &$row)
{
$row['genres'] = $genres[$row['hummingbird_id']];
sort($row['genres']);
}
return $rows;
}
/**
@ -210,6 +221,24 @@ final class AnimeCollection extends Collection {
return $query->fetch(PDO::FETCH_ASSOC);
}
private function getGenresForList(): array
{
$query = $this->db->select('hummingbird_id, genre')
->from('genres g')
->join('genre_anime_set_link gasl', 'gasl.genre_id=g.id')
->get();
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
$output = [];
foreach($rows as $row)
{
$output[$row['hummingbird_id']][] = $row['genre'];
}
return $output;
}
/**
* Update genre information for selected anime
*

87
sw.js
View File

@ -1,36 +1,75 @@
const CACHE_NAME = 'hummingbird-anime-client';
async function fromCache (request) {
const cache = await caches.open(CACHE_NAME);
return await cache.match(request);
}
async function fromNetwork (request) {
return await fetch(request);
}
async function update (request) {
const cache = await caches.open(CACHE_NAME);
const response = await fetch(request);
if (request.url.includes('/public/images/')) {
console.log('Saving to cache: ', request.url);
await cache.put(request, response.clone());
}
return response;
}
function refresh (response) {
return self.clients.matchAll().then(clients => {
clients.forEach(client => {
const message = {
type: 'refresh',
url: response.url,
eTag: response.headers.get('ETag')
};
client.postMessage(JSON.stringify(message));
})
});
}
self.addEventListener('install', event => {
console.log('Worker installed');
console.log('Public Folder Worker installed');
event.waitUntil(
caches.open('hummingbird-anime-client')
caches.open(CACHE_NAME)
.then(cache => cache.addAll([
'public/images/icons/favicon.ico',
'public/css/app.min.css',
'public/js/index.min.js',
'public/js/index-authed.min.js',
'public/js/tables.min.js',
'public/images/streaming-logos/amazon.svg',
'public/images/streaming-logos/crunchyroll.svg',
'public/images/streaming-logos/daisuki.svg',
'public/images/streaming-logos/funimation.svg',
'public/images/streaming-logos/hidive.svg',
'public/images/streaming-logos/hulu.svg',
'public/images/streaming-logos/netflix.svg',
'public/images/streaming-logos/tubitv.svg',
'public/images/streaming-logos/viewster.svg',
]))
);
)
});
self.addEventListener('activate', event => {
console.log('Public Folder Worker activated');
});
// Pull css, images, and javascript from cache
self.addEventListener('fetch', event => {
fromCache(event.request).then(cached => {
if (cached !== undefined) {
event.respondWith(cached);
} else {
event.respondWith(fromNetwork(event.request));
}
});
event.respondWith(
caches.match(event.request).then(response => {
if (response !== undefined) {
// Return cached version
return response;
}
return fetch(event.request).then(response => {
const clone = response.clone();
caches.open('hummingbird-anime-client').then(cache => {
cache.put(event.request, clone);
});
return response;
});
})
event.waitUntil(
update(event.request).then(refresh)
);
});