Last active
March 11, 2020 04:58
-
-
Save viettelidc-oss/f0013e72dd7f14f8b25b14444b8a2fec to your computer and use it in GitHub Desktop.
Fork from voz next sticker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Next Sticker | |
// @namespace http://tampermonkey.net/ | |
// @version 1.3.0 | |
// @updateURL https://gist.githubusercontent.com/phonglk/915ecd87e1d14dfd25cecf6215571a9a/raw/next-sticker.user.js | |
// @description Add Sticker to your post | |
// @author greans@voz | |
// @match *.gamevn.com/* | |
// @match https://*.voz.vn/* | |
// @connect imgur.com | |
// @homepage https://next.voz.vn/threads/userscript-sticker-cho-next.854/ | |
// @supportURL https://next.voz.vn/threads/userscript-sticker-cho-next.854/ | |
// @source https://gist.github.com/phonglk/915ecd87e1d14dfd25cecf6215571a9a | |
// @grant GM_getValue | |
// @grant GM_setValue | |
// @grant GM_deleteValue | |
// @grant GM_xmlhttpRequest | |
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/cash.min.js | |
// ==/UserScript== | |
/** | |
* LICENSE: GNU General Public License v3.0 | |
*/ | |
const request = (url, options) => | |
new Promise((resolve, reject) => { | |
GM_xmlhttpRequest({ | |
method: "GET", | |
...options, | |
url, | |
onload: function(response) { | |
if (response.readyState === 4 && response.status === 200) { | |
resolve(JSON.parse(response.responseText)); | |
} else { | |
reject(new Error(`Cannot load url ${url}`)); | |
} | |
} | |
}); | |
}); | |
function addGlobalStyle(css) { | |
var head, style; | |
head = document.getElementsByTagName("head")[0]; | |
if (!head) { | |
return; | |
} | |
style = document.createElement("style"); | |
style.type = "text/css"; | |
style.innerHTML = css; | |
head.appendChild(style); | |
} | |
addGlobalStyle(` | |
#ns { | |
margin-top: 10px; | |
} | |
#ns a.button { | |
display: inline-block; | |
text-decoration: none; | |
border: 1px solid rgba(0,0,0,0.5); | |
padding: 2px; | |
cursor: pointer; | |
min-width: auto; | |
border-radius: 0; | |
} | |
#ns .btn-add { | |
padding-left: 5px; | |
padding-right: 5px; | |
} | |
#ns .btn-sticker { | |
margin-right: 3px; | |
} | |
#ns .sticker-wrapper { | |
background: white; | |
height: 200px; | |
overflow-y: auto; | |
overflow-x: hidden; | |
position: relative; | |
transition: all 0.3s; | |
} | |
#ns .sticker-img { | |
border: 1px solid transparent; | |
transition: all 0.3s; | |
cursor: pointer; | |
display: inline-block; | |
} | |
#ns .sticker-img:hover { | |
border: 1px solid rgba(0,0,0,0.5); | |
} | |
`); | |
const candy = "11f712f3240e20c"; | |
const CONTAINER_ID = "ns"; | |
const BEFORE_SELECTOR = ".js-previewContainer"; | |
const STICKER_SET_LIST_KEY = "sticker_set_list"; | |
const SELECTED_SS_KEY = "selected_sticker_set"; | |
const GET_SET_KEY = url => `sticker_set_${url}`; | |
let stickerSetList = GM_getValue(STICKER_SET_LIST_KEY, []); | |
let selectedSS = GM_getValue(SELECTED_SS_KEY, null); | |
let $root; | |
function insertDom() { | |
if ($(BEFORE_SELECTOR).length === 0) return; | |
let ele = $(`#${CONTAINER_ID}`); | |
if (ele.length > 0) return ($root = ele); | |
ele = $(` | |
<div id="${CONTAINER_ID}"> | |
<div class='sticker-panel'> | |
<a class='btn-delete button'>Delete</a> | |
<div class='sticker-wrapper'></div> | |
</div> | |
<a class='btn-add button button--primary'>ADD STICKER</a> | |
<span class='ss-list'></span> | |
</div> | |
`); | |
ele.insertBefore(".js-previewContainer"); | |
ele.find(".btn-add").on("click", addStickerSet); | |
ele.find(".btn-delete").on("click", deleteStickerSet); | |
$root = ele; | |
} | |
function addStickerSet() { | |
let url = prompt("imgur album url or id", "http://imgur.com/a/"); | |
if (!url.startsWith("http")) url = "http://imgur.com/a/" + url; | |
const albumId = url.match(/a\/([^ ]*)/)[1]; | |
const name = prompt("Sticker name", albumId); | |
stickerSetList.push({ name, url }); | |
GM_setValue(STICKER_SET_LIST_KEY, stickerSetList); | |
renderStickerSetList(); | |
} | |
const deleteStickerSet = () => { | |
stickerSetList = stickerSetList.filter(({ url }) => url !== selectedSS); | |
GM_setValue(STICKER_SET_LIST_KEY, stickerSetList); | |
GM_deleteValue(GET_SET_KEY(selectedSS)) | |
renderStickerSetList(); | |
selectSticker(stickerSetList.length > 0 ? stickerSetList[0].url : null); | |
}; | |
const renderStickerSetList = () => { | |
const $list = $root.find(".ss-list"); | |
$list.empty(); | |
stickerSetList.forEach(({ url, name }) => { | |
const btn = $( | |
`<a class='button btn-sticker ${ | |
url === selectedSS ? "button--primary" : "button--link" | |
}'>${name}</a>` | |
); | |
$list.append(btn); | |
btn.on("click", () => selectSticker(url)); | |
}); | |
}; | |
const selectSticker = url => { | |
selectedSS = url; | |
GM_setValue(SELECTED_SS_KEY, url); | |
renderStickerPanel(); | |
renderStickerSetList(); | |
}; | |
const renderStickerPanel = async () => { | |
const $panel = $root.find(".sticker-panel"); | |
if (!selectedSS) { | |
$panel.css("display", "none"); | |
return; | |
} | |
$panel.css("display", "block"); | |
const $wrapper = $panel.find(".sticker-wrapper"); | |
$wrapper.empty(); | |
const stickerList = GM_getValue(GET_SET_KEY(selectedSS), []); | |
if (stickerList.length === 0) { | |
$wrapper.text("Loading stickers ..."); | |
try { | |
await loadSticker(selectedSS); | |
setTimeout(renderStickerPanel, 300); | |
} catch (e) { | |
$wrapper.text(`Cannot load sticker set from ${selectedSS}`); | |
} | |
return; | |
} | |
stickerList.forEach(url => { | |
const item = $(`<div class="sticker-img"><img src="${url}" /></div>`); | |
$wrapper.append(item); | |
item.find("img").on("click", () => insertStickerImg(url)); | |
}); | |
}; | |
const loadSticker = async url => { | |
const id = url.match(/a\/([^ ]*)/)[1]; | |
const resp = await request(`https://api.imgur.com/3/album/${id}/images`, { | |
headers: { | |
Authorization: `Client-ID ${candy}`, | |
Accept: "application/json" | |
} | |
}); | |
GM_setValue( | |
GET_SET_KEY(url), | |
resp.data.map(({ link }) => link) | |
); | |
}; | |
function insertStickerImg(url) { | |
const sel = window.getSelection(); | |
const img = $(`<img src="${url}" />`)[0]; | |
const target = $("div.fr-view[contenteditable=true] > *"); | |
const node = | |
sel.anchorNode.nodeType === 3 | |
? sel.anchorNode.parentElement | |
: sel.anchorNode; | |
if ( | |
sel.getRangeAt && | |
sel.rangeCount && | |
node.matches("div[contenteditable=true] *") | |
) { | |
const range = sel.getRangeAt(0); | |
range.deleteContents(); | |
range.insertNode(img); | |
sel.modify("move", "right", "character"); | |
} else if (target.length > 0) { | |
target.last()[0].appendChild(img); | |
} | |
} | |
function detectImgurAlbum() { | |
const IMGURL_PREFIX = '://imgur.com/a/' | |
const eles = $(`iframe[src*="${IMGURL_PREFIX}"]`).add(`a[href*="${IMGURL_PREFIX}"]`) | |
const toProcess = [] | |
eles.each((_, node) => { | |
try { | |
const url = node.src || node.href | |
if (node.parentElement.classList.contains('imgur-embed-pub')) { | |
node = node.parentElement.parentElement | |
} | |
const textNode = node.previousSibling | |
const text = textNode.textContent; | |
if (text.length > 20) return; | |
const addBtn = $(`<a class="button button--link">Add Sticker ${text}</a>`) | |
$(textNode).replaceWith(addBtn) | |
addBtn.on('click', () => addStickerFromPage(url.trim(), text.trim())); | |
} catch (e) { | |
throw e | |
} | |
}) | |
} | |
function addStickerFromPage(url, name) { | |
stickerSetList.push({ name, url }); | |
GM_setValue(STICKER_SET_LIST_KEY, stickerSetList); | |
renderStickerSetList(); | |
alert(`Added ${name} from ${url}`) | |
} | |
insertDom(); | |
renderStickerSetList(); | |
renderStickerPanel(); | |
detectImgurAlbum(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment