// ==UserScript== // @name c.AI Search Sort // @author EnergoStalin // @description Sort search so cards with public definition stays on top and marked with a star // @license AGPL-3.0-only // @version 1.0.2 // @namespace https://c.ai // @match https://character.ai/search* // @run-at document-body // @icon https://www.google.com/s2/favicons?sz=64&domain=character.ai // @downloadURL none // ==/UserScript== (async () => { var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); // src/util.ts async function waitNotNull(func, timeout = 1e4, interval = 1e3) { return new Promise((res, rej) => { let time = timeout; const i = setInterval(async () => { const c = await func(); time -= interval; if (time <= 0) { clearInterval(i); rej(); } if (!c) return; clearInterval(i); res(c); }, interval); }); } __name(waitNotNull, "waitNotNull"); // src/api.ts var pageProps = await waitNotNull(() => document.querySelector("#__NEXT_DATA__")?.textContent).then((e) => JSON.parse(e).props.pageProps); var token = pageProps.token; async function getCharacterInfo(id) { return await fetch(`https://plus.character.ai/chat/character/info/`, { headers: { Authorization: `Token ${token}`, Origin: "https://character.ai/", Referer: "https://character.ai/", "Content-Type": "application/json", Accept: "application/json" }, method: "POST", body: JSON.stringify({ external_id: id }) }).then((e) => e.json()).then((e) => e.character); } __name(getCharacterInfo, "getCharacterInfo"); // src/icons.ts var starredIcon = ''; var pendingIcon = ''; // src/statuses.ts function clearStatus(card) { card.querySelector("div[data-status]")?.remove(); } __name(clearStatus, "clearStatus"); function statusWrapper(card, status) { const height = card.querySelector("img")?.height; const d = document.createElement("div"); d.dataset.status = status; d.classList.add("flex", "items-center", "relative", "flex-row"); d.style = `min-height: ${height}px; flex-direction: column;`; card.append(d); return d; } __name(statusWrapper, "statusWrapper"); function isStarred(card) { return Boolean(card.querySelector('div[data-status="starred"]')); } __name(isStarred, "isStarred"); function setStarredStatus(card, label) { statusWrapper(card, "starred").innerHTML = `