Skip to content

Commit

Permalink
feat(market): support similarity-based rating, fix #139
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed May 7, 2023
1 parent f56e515 commit 596602f
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 12 deletions.
6 changes: 3 additions & 3 deletions packages/market/client/components/filter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ watch(() => props.modelValue, (value) => {
const activeSort = computed<string[]>(() => {
let word = words.value.find(w => w.startsWith('sort:'))
if (!word) return ['rating', 'desc']
if (!word) return ['default', 'desc']
word = word.slice(5)
if (word.endsWith('-desc')) {
return [word.slice(0, -5), 'desc']
Expand All @@ -98,8 +98,8 @@ function addWord(word: string) {
function toggleSort(word: string, event: MouseEvent) {
const index = words.value.findIndex(x => x.startsWith('sort:'))
if (index === -1) {
if (word === 'sort:rating') {
addWord('sort:rating-asc')
if (word === 'sort:default') {
addWord('sort:default-asc')
} else {
addWord(word)
}
Expand Down
5 changes: 5 additions & 0 deletions packages/market/client/icons/misc/award.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
<path fill="currentColor" d="M572.1 82.38C569.5 71.59 559.8 64 548.7 64h-100.8c.2422-12.45 .1078-23.7-.1559-33.02C447.3 13.63 433.2 0 415.8 0H160.2C142.8 0 128.7 13.63 128.2 30.98C127.1 40.3 127.8 51.55 128.1 64H27.26C16.16 64 6.537 71.59 3.912 82.38C3.1 85.78-15.71 167.2 37.07 245.9c37.44 55.82 100.6 95.03 187.5 117.4c18.7 4.805 31.41 22.06 31.41 41.37C256 428.5 236.5 448 212.6 448H208c-26.51 0-47.99 21.49-47.99 48c0 8.836 7.163 16 15.1 16h223.1c8.836 0 15.1-7.164 15.1-16c0-26.51-21.48-48-47.99-48h-4.644c-23.86 0-43.36-19.5-43.36-43.35c0-19.31 12.71-36.57 31.41-41.37c86.96-22.34 150.1-61.55 187.5-117.4C591.7 167.2 572.9 85.78 572.1 82.38zM77.41 219.8C49.47 178.6 47.01 135.7 48.38 112h80.39c5.359 59.62 20.35 131.1 57.67 189.1C137.4 281.6 100.9 254.4 77.41 219.8zM498.6 219.8c-23.44 34.6-59.94 61.75-109 81.22C426.9 243.1 441.9 171.6 447.2 112h80.39C528.1 135.7 526.5 178.7 498.6 219.8z"/>
</svg>
</template>
2 changes: 2 additions & 0 deletions packages/market/client/icons/misc/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Asc from './asc.vue'
import Award from './award.vue'
import Balance from './balance.vue'
import Close from './close.vue'
import Desc from './desc.vue'
Expand All @@ -18,6 +19,7 @@ import Verified from './verified.vue'

export default {
'asc': Asc,
'award': Award,
'balance': Balance,
'close': Close,
'desc': Desc,
Expand Down
44 changes: 35 additions & 9 deletions packages/market/client/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ export function getUsers(data: AnalyzedPackage) {
result[user.email] ||= user
}
if (!data.maintainers.some(user => result[user.email])) {
return data.maintainers
return data.maintainers.map(({ email, username }) => ({
email,
name: username,
}))
}
return Object.values(result)
}
Expand Down Expand Up @@ -58,10 +61,37 @@ interface Comparator {
text: string
icon: string
hidden?: boolean
compare(a: AnalyzedPackage, b: AnalyzedPackage): number
compare(a: AnalyzedPackage, b: AnalyzedPackage, words: string[]): number
}

function getSimilarity(data: AnalyzedPackage, word: string) {
word = word.replace('koishi-plugin-', '').replace('@koishijs/plugin-', '')
if (data.shortname === word) return 10
if (data.shortname.startsWith(word)) return 5
if (data.shortname.includes(word)) return 2
return [
...data.keywords,
...Object.values(data.manifest.description),
].some(keyword => keyword.includes(word)) ? 1 : 0
}

function getSimRating(data: AnalyzedPackage, words: string[]) {
words = words.filter(w => w && !w.includes(':'))
let result = 0
for (const word of words) {
const similarity = getSimilarity(data, word)
if (!similarity) return 0
result = Math.max(result, similarity)
}
return data.rating + result
}

export const comparators: Dict<Comparator> = {
default: {
text: '默认排序',
icon: 'solid:all',
compare: (a, b, words) => getSimRating(b, words) - getSimRating(a, words),
},
rating: {
text: '按评分',
icon: 'star-full',
Expand Down Expand Up @@ -125,9 +155,9 @@ export function getSorted(market: AnalyzedPackage[], words: string[]) {
word = word.slice(0, -5)
}
const comparator = comparators[word.slice(5)]
if (comparator) return comparator.compare(a, b) * order
if (comparator) return comparator.compare(a, b, words) * order
}
return comparators.rating.compare(a, b)
return comparators.default.compare(a, b, words)
})
}

Expand Down Expand Up @@ -195,11 +225,7 @@ export function validate(data: AnalyzedPackage, word: string, config: ValidateCo
return true
}

if (data.shortname.includes(word)) return true
return [
...data.keywords,
...Object.values(data.manifest.description),
].some(keyword => keyword.includes(word))
return getSimilarity(data, word) > 0
}

export function timeAgo(time: string) {
Expand Down

0 comments on commit 596602f

Please sign in to comment.