yad2-flags

Adds dedicated flag buttons for easier marking of real estate search results. Currently "pin", "done" and "hide" flags are supported. Adding new flags is super easy.

当前为 2022-04-26 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         yad2-flags
// @namespace    http://tampermonkey.net/
// @version      0.4
// @description  Adds dedicated flag buttons for easier marking of real estate search results. Currently "pin", "done" and "hide" flags are supported. Adding new flags is super easy.
// @author       Dmitry Gurovich
// @license      UNLICENSE
// @website      https://github.com/yrtimiD/yad2-flags-userscript
// @supportURL   https://github.com/yrtimiD/yad2-flags-userscript/issues
// @match        https://www.yad2.co.il/realestate/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=yad2.co.il
// @grant        none
// @run-at       document-end
// ==/UserScript==

(function () {
	'use strict';

	const PREFIX = 'yad2flags'; //just a random text to ensure uniqueness

	/**
	 * Defines all available flags.
	 * To add a new flag add a new field in FLAGS and (optionally), declare a new class in the below style block.
	 */
	const FLAGS = {
		pin: { icon: '📌', tooltip:'Pin item', class:`${PREFIX}-pin`},
		done: { icon: '✅', tooltip: 'Mark item as done', class: `${PREFIX}-done` },
		hidden: { icon: '❌' /*'💩'*/, tooltip: 'Hide item', class: `${PREFIX}-hidden` },
	};

	const frag = document.createRange().createContextualFragment(`
	<style>
		.${PREFIX}-buttons {
			display: flex;
			flex-direction: column;
			justify-content: space-evenly;
			height: 85px;
		}
		.${FLAGS.pin.class}{
			border: red 2px dashed;
		}
		.${FLAGS.done.class}{
			opacity:50%;
			border: green 2px solid;
		}
		.${FLAGS.hidden.class}{
			opacity:30%;
		}
	</style>
	`);
	document.querySelector('head').append(frag);


	function setFlag(flag, id, value) {
		let data = JSON.parse(localStorage.getItem(PREFIX)) ?? {};
		(data[id] = data[id] ?? {})[flag] = value;
		localStorage.setItem(PREFIX, JSON.stringify(data));
	}

	function getFlag(flag, id, defaultValue) {
		let data = JSON.parse(localStorage.getItem(PREFIX)) ?? {};
		return data[id]?.[flag] ?? defaultValue;
	}

	function toggleFlag(flag, id, ele, value) {
		console.log(`${id} flagged with ${flag}:${value}`);
		setFlag(flag, id, value);

		let item = ele.closest(".feeditem");
		if (value === true) {
			item.classList.add(FLAGS[flag].class);
		} else {
			item.classList.remove(FLAGS[flag].class);
		}
	}

	function addButton(flag, id, ele) {
		let frag = document.createRange().createContextualFragment(`<button title="${FLAGS[flag].tooltip}">${FLAGS[flag].icon}</button>`);
		frag.children[0].addEventListener('click', (e) => { toggleFlag(flag, id, ele, !getFlag(flag, id, true)); e.stopPropagation(); });
		let container = ele.querySelector(`.${PREFIX}-buttons`);
		container.append(frag);
	}

	/** @param ele - item-id element */
	function initItemElement(ele) {
		if (ele.querySelector(`.${PREFIX}-buttons`)) return;

		ele.append(document.createRange().createContextualFragment(`<div class="${PREFIX}-buttons"></div>`));

		let id = ele.getAttribute('item-id');
		Object.keys(FLAGS).forEach(flag => {
			addButton(flag, id, ele);
			toggleFlag(flag, id, ele, getFlag(flag, id, false));
		});
	}

	let lastUpdate = 0;
	let pending = null;
	function update() {
		if (Date.now() - lastUpdate < 5000) {
			if (!pending) pending = setTimeout(update, lastUpdate + 5000 - Date.now());
			return;
		}
		lastUpdate = Date.now();
		pending = null;
		document.querySelectorAll('.feed_list [item-id]').forEach(ele => initItemElement(ele));
	}

	function startObserver() {
		const observer = new MutationObserver(() => update());
		observer.observe(document.body, { childList: true, subtree: true });

		update();
	}

	startObserver();
})();