Skip to content

Commit

Permalink
Add star ranking to similar items (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
philipp-eisen authored May 1, 2020
1 parent 35f210b commit 8e6935a
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 41 deletions.
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dist/
.vscode/
node_modules/
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@
"route-cache": "0.4.3",
"serve-favicon": "^2.4.5",
"vue": "^2.5.22",
"vue-client-only": "^2.0.0",
"vue-router": "^3.0.1",
"vue-server-renderer": "^2.5.22",
"vue-star-rating": "^1.6.1",
"vuex": "^3.0.1",
"vuex-router-sync": "^5.0.0"
},
Expand All @@ -55,4 +57,4 @@
"webpack-merge": "^4.2.1",
"webpack-node-externals": "^1.7.2"
}
}
}
37 changes: 30 additions & 7 deletions src/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ if (api.onServer) {
warmCache()
}

function warmCache () {
function warmCache() {
fetchItems((api.cachedIds.top || []).slice(0, 30))
setTimeout(warmCache, 1000 * 60 * 15)
}

function fetch (child) {
function fetch(child) {
logRequests && console.log(`fetching ${child}...`)
const cache = api.cachedItems
if (cache && cache.has(child)) {
Expand All @@ -41,25 +41,25 @@ function fetch (child) {
}
}

export function fetchIdsByType (type) {
export function fetchIdsByType(type) {
return api.cachedIds && api.cachedIds[type]
? Promise.resolve(api.cachedIds[type])
: fetch(`${type}stories`)
}

export function fetchItem (id) {
export function fetchItem(id) {
return fetch(`item/${id}`)
}

export function fetchItems (ids) {
export function fetchItems(ids) {
return Promise.all(ids.map(id => fetchItem(id)))
}

export function fetchUser (id) {
export function fetchUser(id) {
return fetch(`user/${id}`)
}

export function watchList (type, cb) {
export function watchList(type, cb) {
let first = true
const ref = api.child(`${type}stories`)
const handler = snapshot => {
Expand Down Expand Up @@ -87,3 +87,26 @@ export function fetchSimilar(queries) {
.then(resp => resp.json())
.then(json => json.rankings.map(i => i.entries));
}

function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}

export default function sendFeedBack(query, result, rating) {
if (document.sessionId === undefined) {
document.sessionId = uuidv4()
}
return fetchData('https://textsimilarity.research.peltarion.com/feedback', {
method: 'POST',
body: JSON.stringify({
query: query,
result: result,
rating: rating,
dataset: 'hn-sbert',
sessionId: document.sessionId
})
})
}
105 changes: 72 additions & 33 deletions src/components/Similar.vue
Original file line number Diff line number Diff line change
@@ -1,66 +1,105 @@

<template>
<div class="similar-posts">
<span class="title">Similar: </span>
<span class="title">Similar:</span>
<ul class="list" v-if="story.similar && story.similar.length !== 0">
<li v-for="sim in story.similar" :key="sim.id">
<span class="box" v-bind:style="{ background: getColor(sim.similarity_score)}" v-bind:title="sim.similarity_score"></span>
<router-link :to="'/item/' + sim.id">{{ sim.title }} | <b>{{ new Date(sim.time * 1000).getFullYear() }}</b> | {{ sim.descendants }} comments</router-link>
<li v-for="sim in story.similar" :key="sim.id">
<span
class="box"
v-bind:style="{ background: getColor(sim.similarity_score)}"
v-bind:title="sim.similarity_score"
></span>
<router-link :to="'/item/' + sim.id">
{{ sim.title }} |
<b>{{ new Date(sim.time * 1000).getFullYear() }}</b>
| {{ sim.descendants }} comments |
</router-link>
<client-only>
<div>
<star-rating
v-bind:star-size="15"
active-color="#000000"
v-bind:show-rating="false"
@rating-selected="setRating($event, sim.title, story.title)"
v-bind:inline="true"
></star-rating>
</div>
</client-only>
</li>
</ul>
<div v-else class="no-posts">
<span class="title">No similar posts found.</span>
</div>

</div>
</template>

<script>
import StarRating from "vue-star-rating";
import ClientOnly from "vue-client-only";
import sendFeedBack from "../api";
export default {
name: 'similar-posts',
props: ['story'],
name: "similar-posts",
props: ["story"],
components: {
StarRating,
ClientOnly
},
data: () => {
return {
colorStops: [
{ start: 0, stop: 0.7, color: 'rgba(250, 157, 18, 0.5)' },
{ start: 0.7, stop: 0.8, color: 'rgba(250, 157, 18, 0.75)' },
{ start: 0.8, stop: 2, color: 'rgba(250, 157, 18, 1)' }
{ start: 0, stop: 0.7, color: "rgba(250, 157, 18, 0.5)" },
{ start: 0.7, stop: 0.8, color: "rgba(250, 157, 18, 0.75)" },
{ start: 0.8, stop: 2, color: "rgba(250, 157, 18, 1)" }
]
};
},
methods: {
getColor: function(score) {
const found = this.colorStops.find(cs => score.toFixed(2) >= cs.start && score.toFixed(2) < cs.stop);
const found = this.colorStops.find(
cs => score.toFixed(2) >= cs.start && score.toFixed(2) < cs.stop
);
return found.color;
},
setRating: function(rating, similar, story) {
sendFeedBack(story, similar, rating);
}
}
}
};
</script>

<style lang="stylus">
.similar-posts
line-height 1.2
.similar-posts {
line-height: 1.2;
.box {
width: 12px;
height: 0.85em;
display: inline-block;
margin-right: 8px;
}
.box
width: 12px
height: .85em
display: inline-block
margin-right: 8px
.title {
font-size: 0.85em;
}
ul.list, .no-posts {
background-color: #f3f3f3;
font-size: 0.85em;
margin: 4px 0;
padding: 8px 12px;
border-radius: 4px;
.title
font-size .85em
ul.list, .no-posts
background-color #f3f3f3
font-size .85em
margin 4px 0
padding 8px 12px
border-radius 4px
li
padding: 4px
display: flex
align-items: center
a
color: #828282;
li {
padding: 4px;
display: flex;
align-items: center;
}
}
a {
color: #828282;
}
}
</style>

0 comments on commit 8e6935a

Please sign in to comment.