您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Checks the last online on page user and in dialog
当前为
- // ==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.6
- // @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
- // @run-at document-end
- // @noframes
- // ==/UserScript==
- 'use strict';
- const W = unsafeWindow || window;
- const MINUTE = 60 * 1000;
- const UNIXTIME = 1000;
- class Cache {
- constructor() {
- this.default = { uts: 0, expires: 0 };
- this.data = new Map();
- }
- get(key) {
- const exist = this.data.get(key);
- if (exist) return exist;
- return this.default;
- }
- set(key, value) {
- const expires = Date.now() + MINUTE;
- this.data.set(key, { uts: value, expires });
- }
- }
- const request = (url, callback) => {
- const xhr = new XMLHttpRequest();
- xhr.onreadystatechange = () => {
- if (xhr.readyState === 4) {
- const container =
- document.implementation.createHTMLDocument().documentElement;
- if (xhr.status === 0 || xhr.status === 200) {
- container.innerHTML = xhr.responseText;
- }
- callback(container);
- }
- };
- xhr.open('GET', url, true);
- xhr.send();
- };
- const render = (uts) => {
- const online =
- document.querySelector('.mail_box_label_info') ||
- document.querySelector('.profile_online_lv') ||
- document.querySelector('._im_page_peer_online');
- const { lang } = window.vk;
- const text = lang === 3 ? 'last seen' : 'заходил(а)';
- online.textContent = `${text} ${window.getDateText(uts, null)}`;
- };
- const extractTimestamp = (body) => {
- const [element] = body.getElementsByTagName('ya:lastloggedin');
- if (!element) return 0;
- const date = element.getAttribute('dc:date');
- const uts = Math.floor(Date.parse(date) / UNIXTIME);
- return uts;
- };
- const extract = () => {
- const { options, peer } = window.cur;
- const id = peer || (options && options.user_id);
- return id || 0;
- };
- const start = () => {
- const id = extract();
- if (id === 0 || Math.sign(id) === -1) return;
- const { expires } = cache.get(id);
- if (expires > Date.now()) {
- render(expires);
- return;
- }
- request(`/foaf.php?id=${id}`, (body) => {
- const uts = extractTimestamp(body);
- if (uts === 0) return;
- render(uts);
- cache.set(id, uts);
- });
- };
- const observable = (target) => {
- const handlers = [];
- const observe = (handler) => {
- handlers.push(handler);
- };
- const proxy = new Proxy(target, {
- get(...args) {
- const output = Reflect.get(...args);
- if (output) {
- handlers.forEach((fn) => fn(output));
- }
- return output;
- },
- });
- return [proxy, observe];
- };
- const throttle = (timeout, fn) => {
- let timer;
- let wait = false;
- let wrapped = null;
- const throttled = () => {
- timer = undefined;
- if (wait) wrapped();
- };
- wrapped = (...args) => {
- if (!timer) {
- timer = setTimeout(throttled, timeout);
- wait = false;
- return fn(...args);
- } else {
- wait = true;
- }
- };
- return wrapped;
- };
- const throttledStart = throttle(3000, start);
- const types = {
- object: throttledStart,
- };
- const [instance, observe] = observable(W.nav);
- W.nav = instance;
- observe((data) => {
- const type = typeof data;
- const fn = types[type];
- if (fn) fn();
- });
- const cache = new Cache();
- throttledStart();