2021-07-25 19:01:25 +02:00
|
|
|
|
<template>
|
|
|
|
|
|
<table class="table is-fullwidth is-striped">
|
|
|
|
|
|
<thead>
|
|
|
|
|
|
<tr>
|
|
|
|
|
|
<th>title</th>
|
|
|
|
|
|
<th>year</th>
|
|
|
|
|
|
<th>type</th>
|
|
|
|
|
|
<th>rating</th>
|
|
|
|
|
|
<th>runtime</th>
|
|
|
|
|
|
</tr>
|
|
|
|
|
|
</thead>
|
|
|
|
|
|
<tbody>
|
|
|
|
|
|
<tr v-for="item in items" :data-unwind-id="item.id">
|
|
|
|
|
|
<td v-if="item.original_title">
|
|
|
|
|
|
<a :href="`https://www.imdb.com/title/${item.imdb_id}/`">
|
|
|
|
|
|
<span>{{ item.original_title }}</span>
|
|
|
|
|
|
</a>
|
|
|
|
|
|
<span v-if="item.title != item.original_title"> ({{ item.title }})</span>
|
|
|
|
|
|
</td>
|
|
|
|
|
|
<td v-else>
|
|
|
|
|
|
<a :href="`https://www.imdb.com/title/${item.imdb_id}/`">
|
|
|
|
|
|
<span>{{ item.title }}</span>
|
|
|
|
|
|
</a>
|
|
|
|
|
|
</td>
|
|
|
|
|
|
<td>
|
|
|
|
|
|
<span class="year">{{ item.release_year }}</span>
|
|
|
|
|
|
</td>
|
|
|
|
|
|
<td>
|
|
|
|
|
|
<span class="mediatype">{{ item.media_type }}</span>
|
|
|
|
|
|
</td>
|
|
|
|
|
|
<td>
|
2021-08-04 01:04:13 +02:00
|
|
|
|
<span class="score imdb-score tag is-large" :title="`IMDb rating (1-10) / ${item.imdb_votes} votes`">{{ imdb_rating(item.imdb_score) }}</span>
|
|
|
|
|
|
<span class="score tag is-info is-large" :title="`User rating (1-10) / ${item.user_scores.length} votes / σ = ${imdb_stdev(item.user_scores)}`">{{ avg_imdb_rating(item.user_scores) }}</span>
|
2021-07-25 19:01:25 +02:00
|
|
|
|
</td>
|
|
|
|
|
|
<td>
|
|
|
|
|
|
<span>{{ duration(item.runtime) }}</span>
|
|
|
|
|
|
</td>
|
|
|
|
|
|
</tr>
|
|
|
|
|
|
</tbody>
|
|
|
|
|
|
</table>
|
|
|
|
|
|
|
|
|
|
|
|
<div ref="sentinel"></div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script lang="ts">
|
|
|
|
|
|
import { defineComponent } from "vue"
|
2021-08-04 01:04:13 +02:00
|
|
|
|
import { mean, pstdev } from "../utils.ts"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function avg_imdb_rating(scores) {
|
|
|
|
|
|
return imdb_rating(scores.length === 0 ? null : mean(scores))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function imdb_stdev(scores) {
|
|
|
|
|
|
return pstdev(scores.map(imdb_rating_from_score))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function imdb_rating_from_score(score) {
|
2021-08-04 17:10:44 +02:00
|
|
|
|
return Math.round((score * 9) / 10 + 10) / 10
|
2021-08-04 01:04:13 +02:00
|
|
|
|
}
|
2021-07-25 19:01:25 +02:00
|
|
|
|
|
|
|
|
|
|
function imdb_rating(score) {
|
|
|
|
|
|
if (score == null) {
|
|
|
|
|
|
return "-"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-08-04 17:10:44 +02:00
|
|
|
|
const deci = 10 * imdb_rating_from_score(score)
|
2021-07-25 19:01:25 +02:00
|
|
|
|
return `${(deci / 10) | 0}.${deci % 10}`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function duration(minutes_total) {
|
|
|
|
|
|
if (minutes_total == null) {
|
|
|
|
|
|
return "-"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const m = minutes_total % 60
|
|
|
|
|
|
const h = (minutes_total / 60) | 0
|
|
|
|
|
|
return `${h} h ${m} m`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export default defineComponent({
|
|
|
|
|
|
props: {
|
|
|
|
|
|
items: {
|
|
|
|
|
|
type: Array,
|
|
|
|
|
|
required: true,
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
emits: ["reach-bottom"],
|
|
|
|
|
|
mounted() {
|
|
|
|
|
|
const options = {
|
|
|
|
|
|
rootMargin: "500px",
|
|
|
|
|
|
}
|
|
|
|
|
|
const observer = new IntersectionObserver(([e]) => {
|
|
|
|
|
|
if (!e.isIntersecting) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
this.$emit("reach-bottom")
|
|
|
|
|
|
}, options)
|
|
|
|
|
|
observer.observe(this.$refs.sentinel)
|
|
|
|
|
|
},
|
|
|
|
|
|
methods: {
|
2021-08-04 01:04:13 +02:00
|
|
|
|
avg_imdb_rating,
|
2021-07-25 19:01:25 +02:00
|
|
|
|
imdb_rating,
|
2021-08-04 01:04:13 +02:00
|
|
|
|
imdb_stdev,
|
2021-07-25 19:01:25 +02:00
|
|
|
|
duration,
|
|
|
|
|
|
},
|
|
|
|
|
|
})
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
.year {
|
|
|
|
|
|
color: grey;
|
|
|
|
|
|
}
|
|
|
|
|
|
.mediatype {
|
|
|
|
|
|
color: grey;
|
|
|
|
|
|
}
|
|
|
|
|
|
.score {
|
|
|
|
|
|
width: 2em;
|
|
|
|
|
|
height: 2em;
|
|
|
|
|
|
}
|
|
|
|
|
|
.score + .score {
|
|
|
|
|
|
margin-left: 1em;
|
|
|
|
|
|
}
|
|
|
|
|
|
.imdb-score {
|
|
|
|
|
|
background-color: rgb(245, 197, 24);
|
|
|
|
|
|
}
|
|
|
|
|
|
.user-score {
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|