您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Checks the last online on page user and in dialog
当前为
- /* globals vk, cur, getDateText, GM, GM_xmlhttpRequest */
- /* eslint padded-blocks: ["error", { "blocks": "always" }]
- object-curly-spacing: ["error", "always", { "objectsInObjects": false }]
- curly: ["error", "multi"] */
- // ==UserScript==
- // @name VK: Check Online
- // @name:ru ВК: Проверка онлайна
- // @description Checks the last online on page user and in dialog
- // @description:ru Проверяет последний онлайн пользователя на странице и в диалогe
- // @namespace vk-check-online.user.js
- // @license MIT
- // @author askornot
- // @version 1.0.5
- // @match https://vk.com/*
- // @connect vk.com
- // @compatible chrome Violentmonkey 2.12.7
- // @compatible firefox Violentmonkey 2.12.7
- // @homepageURL https://greasyfork.org/en/scripts/403717-vk-check-online
- // @supportURL https://greasyfork.org/en/scripts/403717-vk-check-online/feedback
- // @grant GM_xmlhttpRequest
- // @grant GM.xmlHttpRequest
- // @run-at document-end
- // @noframes
- // ==/UserScript==
- 'use strict';
- const USERS = new Map();
- const request = (id, data = {}) => new Promise((resolve, reject) => {
- data.method = 'GET';
- data.url = `/foaf.php?id=${id}`;
- data.responseType = 'document';
- /* eslint-disable unicorn/prefer-add-event-listener, no-unused-expressions, no-constant-condition, operator-linebreak, new-cap */
- data.onload = resolve;
- data.onerror = reject;
- typeof !GM && typeof !GM.xmlHttpRequest
- ? GM.xmlHttpRequest(data)
- : GM_xmlhttpRequest(data);
- /* eslint-enable */
- });
- const floor = time => Math.floor(time);
- const now = () => (floor(Date.now()));
- const render = uts => {
- const online = document.querySelector('.mail_box_label_info') ||
- document.querySelector('.profile_online_lv') ||
- document.querySelector('._im_page_peer_online');
- const { lang } = vk;
- const text = lang === 3 ? 'last seen' : 'заходил(а)';
- online.textContent = `${text} ${getDateText(uts, null)}`;
- };
- const getTs = rdf => {
- // eslint-disable-next-line unicorn/prefer-query-selector
- const [element] = rdf.getElementsByTagName('ya:lastloggedin');
- if (!element) return 0;
- const date = element.getAttribute('dc:date');
- const uts = floor(Date.parse(date) / 1000); // A getDateText requires unixtime
- return uts;
- };
- const getUser = user => USERS.has(user) ? USERS.get(user) : {};
- const start = async () => {
- const { options = {}, peer } = cur; // VK object
- // eslint-disable-next-line no-prototype-builtins
- const userId = (peer ? peer : (options.hasOwnProperty('user_id') ? options.user_id : 0));
- if (userId === 0 || Math.sign(userId) === -1) return;
- let { expires = 0, uts = 0 } = getUser(userId);
- if (expires < now()) { // eslint-disable-line curly
- try {
- const { response } = await request(userId);
- uts = getTs(response);
- USERS.set(userId, {
- uts,
- expires: now() + 60000 // Every one minute
- });
- } catch (error) {
- console.error(error.stack);
- }
- }
- if (uts === 0) return;
- render(uts);
- };
- start().catch(console.error);
- const filterMutsByClassName = muts => {
- return muts.filter((array, i, self) => self.findIndex(_array => (array.target.className === _array.target.className)) === i);
- };
- new MutationObserver(muts => {
- muts = filterMutsByClassName(muts);
- for (const { target, addedNodes } of muts) {
- const { tagName } = target;
- if (tagName === 'DIV' || tagName === 'SPAN') {
- const { classList } = target;
- if ( // eslint-disable-line curly
- (classList.contains('wide_column') && addedNodes.length >= 2) ||
- classList.contains('box_body') ||
- classList.contains('_im_page_peer_online') ||
- classList.contains('im-page-chat-contain')
- ) {
- setTimeout(start, 1000);
- }
- }
- }
- }).observe(document.body || document, {
- childList: true,
- subtree: true
- });