Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Script for tampermonkey to add articles count in selection list (My list, archive, favorites)
// ==UserScript==
// @name Pocket Counters
// @namespace http://vanadium23.me/
// @version 0.3
// @description Add counters to pocket list
// @author vanadium23
// @match https://app.getpocket.com/*
// @ran-at document-idle
// @grant none
// ==/UserScript==
(function () {
var observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (!mutation.addedNodes) return
for (var i = 0; i < mutation.addedNodes.length; i++) {
// do things to your newly added nodes here
var node = mutation.addedNodes[i];
if (document.querySelector('ul')) {
observer.disconnect();
setupCounters();
}
}
})
})
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: false,
characterData: true
})
function setupCounters() {
'use strict';
let globalState = {
counters: {
queue: 0,
favorite: 0,
archive: 0,
},
articles: {
queue: {},
favorite: {},
archive: {},
},
};
const ARTICLE_TIME_PROPERTY = {
queue: 'time_added',
favorite: 'time_favorited',
archive: 'time_read',
}
const ARTICLE_STATES = {
queue: 'section-mylist',
favorite: 'section-favorites',
archive: 'section-archive',
};
const ARTICLE_STATES_APP = {
queue: 'My List',
favorite: 'Favorites',
archive: 'Archive',
};
const states = Object.keys(ARTICLE_STATES);
const COUNTER_POSTFIX = '-counter';
const FAKE_COUNT_NUMBER = 1000;
// fetch all articles
function fetchArticlesV2(state, offset = 0, count = 100) {
const object = {
"images": 1,
"videos": 1,
"tags": 1,
"taglist": 1,
"account": 1,
"rediscovery": 1,
"posts": 1,
"total": 1,
"state": state,
"locale_lang": "en-US",
"passedChunk": 12,
"count": count,
"offset": offset
}
if (state == 'favorite') {
object.state = '';
object.favorite = 1;
}
return fetch("https://getpocket.com/v3/fetch?enable_cors=1&consumer_key=78809-9423d8c743a58f62b23ee85c", {
"credentials": "include",
"headers": {
"accept": "*/*",
"accept-language": "en-GB,en;q=0.9,en-US;q=0.8,ru;q=0.7",
"content-type": "application/json",
"x-accept": "application/json; charset=UTF8"
},
"referrer": "https://app.getpocket.com/",
"referrerPolicy": "no-referrer-when-downgrade",
"body": JSON.stringify(object),
"method": "POST",
"mode": "cors"
})
.then(response => response.json());
}
function countArticles(state, offset = 0) {
fetchArticlesV2(state, offset)
.then(data => {
// if meta result == 1000, then it is not a real count
let count = parseInt(data.search_meta.total_result_count);
let metaCount = true;
if (count == FAKE_COUNT_NUMBER) {
count = offset === 0 ? FAKE_COUNT_NUMBER : Object.keys(data.list).length;
metaCount = false;
} else if (isNaN(count)) {
count = parseInt(data.total);
metaCount = false;
}
// update storage
globalState.counters[state] += count;
Object.assign(globalState.articles[state], data.list);
// update UI
drawCounter(state);
});
}
function getMonday(date) {
var day = date.getDay() || 7;
if (day !== 1)
date.setHours(-24 * (day - 1));
return date;
}
function drawCounter(state) {
for (let counterType of ['', '-today-', '-week-']) {
const selector = `.${ARTICLE_STATES[state]}${counterType}${COUNTER_POSTFIX}`;
let counter = document.querySelector(selector);
if (counter) {
let unreadCount = '?';
if (counterType === '') {
unreadCount = globalState.counters[state];
} else if (counterType === '-today-') {
const timeProperty = ARTICLE_TIME_PROPERTY[state];
const articles = globalState.articles[state];
const today = new Date();
today.setHours(0, 0, 0, 0);
unreadCount = Object.keys(articles).filter(
itemId => (parseInt(articles[itemId][timeProperty]) * 1000) > today
).length;
} else if (counterType === '-week-') {
const timeProperty = ARTICLE_TIME_PROPERTY[state];
const articles = globalState.articles[state];
const monday = getMonday(new Date());
monday.setHours(0, 0, 0, 0);
unreadCount = Object.keys(articles).filter(
itemId => (parseInt(articles[itemId][timeProperty]) * 1000) > monday
).length;
}
counter.innerHTML = ` (${unreadCount})`;
}
}
}
function setupCounter(state) {
const listClass = ARTICLE_STATES[state];
const selector = `.${listClass}`;
let listElement = document.querySelector(selector);
if (listElement === null) {
const ulLists = document.querySelectorAll('ul');
for (let ulList of ulLists) {
if (ulList.previousSibling && ulList.previousSibling.textContent === 'Lists') {
for (let child of ulList.childNodes) {
if (child.textContent === ARTICLE_STATES_APP[state]) {
listElement = child.querySelector('button');
break;
}
}
}
if (listElement) {
break;
}
}
}
const counterSelector = `${selector}${COUNTER_POSTFIX}`;
const counterElement = document.querySelector(counterSelector);
if (listElement && !counterElement) {
const detailedStatistics = `
<span class="${listClass}${COUNTER_POSTFIX}">?</span>
`;
listElement.innerHTML = listElement.innerHTML + detailedStatistics;
}
}
for (let state of states) {
setupCounter(state);
countArticles(state);
}
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.