Repository navigation
Expand file tree
/
Copy pathsort-by-like-count.user.js
More file actions
84 lines (74 loc) · 2.51 KB
/
Copy pathsort-by-like-count.user.js
File metadata and controls
84 lines (74 loc) · 2.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// ==UserScript==
// @name Dribbble: Sort by Likes
// @namespace shiftgeist
// @icon https://www.google.com/s2/favicons?sz=64&domain=dribbble.com
// @version 20260826.0
//
// @match https://dribbble.com/search/*
// @grant none
// @run-at document-idle
//
// @author shiftgeist
// @description Sorts Dribbble search results by like count, descending
// @license GNU GPLv3
//
// @updateURL https://raw.githubusercontent.com/shiftgeist/userscripts/refs/heads/main/dribbble.com/sort-by-like-count.user.js
// @downloadURL https://raw.githubusercontent.com/shiftgeist/userscripts/refs/heads/main/dribbble.com/sort-by-like-count.user.js
// ==/UserScript==
;(() => {
'use strict'
let isSorting = false
function parseLikeCount(text) {
const match = text.trim().match(/^([\d.]+)(k)?$/i)
if (!match) return 0
const value = parseFloat(match[1])
return match[2] ? value * 1000 : value
}
function getLikeCount(item) {
const el = item.querySelector('[data-shot-like-count]')
if (!el) return -1
return parseLikeCount(el.textContent)
}
function sortGrid() {
const grid = document.querySelector('.js-thumbnail-grid')
if (!grid) return
const items = Array.from(grid.querySelectorAll(':scope > li.shot-thumbnail'))
if (items.length < 2) return
const ads = items.filter((item) => item.dataset.boostId)
const shots = items.filter((item) => !item.dataset.boostId)
shots.sort((a, b) => getLikeCount(b) - getLikeCount(a))
isSorting = true
const fragment = document.createDocumentFragment()
shots.forEach((item) => fragment.appendChild(item))
ads.forEach((item) => fragment.appendChild(item))
grid.appendChild(fragment)
isSorting = false
}
function observeGrid(grid) {
let debounceTimer = null
const observer = new MutationObserver(() => {
if (isSorting) return
clearTimeout(debounceTimer)
debounceTimer = setTimeout(sortGrid, 300)
})
observer.observe(grid, { childList: true })
}
function waitForGrid(callback) {
const existing = document.querySelector('.js-thumbnail-grid')
if (existing) {
callback(existing)
return
}
const bodyObserver = new MutationObserver(() => {
const grid = document.querySelector('.js-thumbnail-grid')
if (!grid) return
bodyObserver.disconnect()
callback(grid)
})
bodyObserver.observe(document.body, { childList: true, subtree: true })
}
waitForGrid((grid) => {
sortGrid()
observeGrid(grid)
})
})()