// ==UserScript== // @name 清水河畔表情包计划 // @namespace http://tampermonkey.net/ // @version 0.2.5 // @description 请自己研究尝试 // @author DARK-FLAME-MASTER FROM RIVERSIDE // @match https://bbs.uestc.edu.cn/forum.php?mod=viewthread* // @match *://bbs-uestc-edu-cn-s.vpn.uestc.edu.cn:*/forum.php?mod=viewthread* // @icon https://www.google.com/s2/favicons?sz=64&domain=uestc.edu.cn // @require https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.slim.min.js // @require https://cdn.jsdelivr.net/npm/cfb@1.2.2/dist/cfb.min.js // @require https://cdn.jsdelivr.net/npm/vue@3.2.41/dist/vue.global.js // @license WTFPL // @run-at document-body // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @grant GM_listValues // @grant unsafeWindow // @downloadURL none // ==/UserScript== (function () { 'use strict'; unsafeWindow.Vue = Vue let setAddedImg; let storageVar = "emojiSet"; let storageAlbum = "emojiAlbum" let storageGroup = "selectedGroup" //GM_setValue('version','0.1') let version = GM_getValue('version', 'NULL') if(version != '0.2' && version != 'NULL'){ let temp = [] let emoji_set = GM_getValue('emoji_set') for(let tagName in emoji_set){ let images = [] for(let i = 0;i #mine { background: #F2F2F2; text-indent: 0; display: inline; } .menu { margin: 0; background: #fff; z-index: 3000; position: absolute; list-style-type: none; padding: 5px 0; border-radius: 4px; font-size: 12px; font-weight: 400; color: #333; box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3); } .menu li { margin: 0; padding: 7px 16px; cursor: pointer; } .menu li:hover { background: #eee; } .clicked:hover { cursor: pointer; } #emojiPreview { width: 30%; } #emojiPreview>img { max-width: 100%; } #mine_menu { display: flex; align-items: flex-end; z-index: 999; position: absolute; width: 70%; } img.emoji { height: 50px; } #emoHead { padding: 3px; display: flex; border-bottom: 2px dashed lightsteelblue; justify-content: center; } #emoHead>div { font-size: 20px; } #emoContent { display: flex; overflow: auto; max-height: 300px; display: flex; flex-wrap: wrap; justify-content: space-evenly; align-items: center; scrollbar-gutter: stable; } #emoji { background: rgb(232, 241, 252); border: 2px solid lightsteelblue; border-radius: 5px; width: 50%; height: fit-content; } #emoTag { display: flex; height: 45px; background-color: lightsteelblue; align-items: center; width: fit-content; border-radius: 0px 0px 4px; border: 0px solid lightsteelblue; } #emoAdd { font-size: 40px; line-height: 109%; margin-right: 5px; } #groupAdd { font-size: 25px; } img.emoji { padding: 2px; border-radius: 10px; } .emoDel { position: absolute; top: 38px; right: -2px; font-size: 10px; } .emoSel { position: absolute; top: -2px; left: -2px; font-size: 10px; } .emoMov { position: absolute; top: -2px; right: -2px; font-size: 13px; } #emoContent>div { position: relative; } .selectedEmoji { display: inline; } div.tag { height: 45px; padding: 0 3px 0 3px; border-radius: 2px; display: flex; align-items: center; } div.tag>img { height: 30px; border-radius: 2px; } .selected { background: rgb(232, 241, 252); }
🤤
{{emoji[selectedGroup].tag}}
⚙️
{{parseInt(progress*100)}}%
🕊️
❇️
🗃️
` ) Vue.createApp({ data() { return { //version, menu: { left:0, top:0, visible:false }, emojiVisible:false, addedImg:{id:'default',src:'data/attachment/common/star/common_25_icon.png'}, uploadTotalCount: 0, uploadNowCount: 0, renameGroup: false, emojiAlbum: emojiAlbum, selectedGroup: 0, selectedEmoji: -1, post_params: post_params, formhash: formhash, emojiTemp: [], emoji: emoji } }, methods: { switchTag(index) { this.selectedGroup = index }, switchEmoji(index) { this.selectedEmoji = index }, delEmoji(index, group = this.selectedGroup) { this.emoji[group].images.splice(index, 1) }, addEmoji(emoji, group = this.selectedGroup, notice = false) { this.emoji[group].images.unshift(emoji) if(notice) this.notice(`已将表情添加至${this.emoji[group].tag}`) }, addGroup(group) { this.emoji.push(group) return this.emoji.length - 1 }, delGroup(index) { if(confirm(`您确定要删除分组${this.emoji[index].tag}吗?`)){ if (index == this.emoji.length - 1) this.selectedGroup -= 1 this.emoji.splice(index, 1) this.notice("已删除该分组") } }, emoAsTagImg(img, group = this.selectedGroup) { this.emoji[group].tagImg = img }, insertEmojiInForum(emoji) { eval("seditor_insertunit(document.getElementById('postat') != null ? 'post' : 'fastpost' ,'[img]" + emoji.src + "[/img]')") }, notice(message) { Notification.requestPermission().then((result) => { if (result === 'granted') { let n = new Notification(message); setTimeout(n.close.bind(n), 1800) } }) }, setEmojiAlbum() { emojiAlbum = prompt('请输入表情保存的相册ID:') if (emojiAlbum != null) { this.emojiAlbum = emojiAlbum GM_setValue(storageAlbum,emojiAlbum) notice("相册设置成功") } }, getFiles(event) { return event.target.files }, uploadFiles(files, group) { this.uploadTotalCount += 2*files.length; for (let i = 0; i < files.length; ++i) { let file = { name: files[i].name, size: files[i].size, type: files[i].type, dom: files[i], }; let data = new FormData(); for (let k in this.post_params) data.append(k, this.post_params[k]); data.append('type', 'image'); data.append('filetype', file.type) data.append('Filename', file.name); data.append('Filedata', file.dom); let pid, src; fetch("/misc.php?mod=swfupload&action=swfupload&operation=album", { "headers": { }, "method": "POST", "mode": "cors", "body": data, "credentials": "include", }).then((res) => res.json()).then((data) => { this.uploadNowCount += 1; pid = data.picid; src = data.bigimg; return fetch("/home.php?mod=spacecp&ac=upload", { "headers": { "content-type": "application/x-www-form-urlencoded", }, "body": "title[" + pid + "]=&albumid=" + this.emojiAlbum + "&albumsubmit=true&albumsubmit_btn=true&formhash=" + this.formhash, "method": "POST", "mode": "cors", "credentials": "include" }) }).then((data) => { this.emojiTemp.push({ group: group, img: { id: pid, src: src } }); this.uploadNowCount += 1; }) } }, uploadEif(files, allowedExts = []) { let f = new FileReader() f.readAsBinaryString(files[0]); let addGroup = this.addGroup let uploadFiles = this.uploadFiles f.onload = function () { let eif = CFB.read(this.result, { type: 'binary' }) let validPaths = [] let validContent = eif.FileIndex.filter((e, i) => { if (e.size > 0) { validPaths.push(eif.FullPaths[i]) return true } return false }) let s = new Set() let fileList = {} for (let idx in validContent) { let entry = validContent[idx] let extName = entry.name.substring(entry.name.lastIndexOf(".") + 1) if (entry.type == 2 && (!allowedExts || allowedExts.includes(extName))) { let name = validPaths[idx].substring(0, validPaths[idx].lastIndexOf(".")) if (!s.has(name)) { let group = validPaths[idx].match(/Entry\/(\d+)\//)[1] let f = new File([new Uint8Array(entry.content)], entry.name, { type: "image/" + extName }) if (fileList[group]) { fileList[group].push(f) } else { fileList[group] = [f] } s.add(name + 'fix') } } } for (let group in fileList) { uploadFiles(fileList[group], addGroup({tag:group,tagImg:{id:'default',src:'data/attachment/common/star/common_25_icon.png'}, images:[]})) } } }, setAddedImg(img){ this.addedImg = img }, openMenu(e, item) { this.rightClickItem = item; let x = e.pageX; let y = e.pageY; this.menu.top = y; this.menu.left = x; this.menu.visible = true; }, closeMenu() { this.menu.visible = false; } }, watch: { uploadNowCount(newCount) { if (newCount == this.uploadTotalCount) { for (let data of this.emojiTemp) { this.addEmoji(data.img, data.group) } this.emojiTemp = [] this.notice("表情上传完成") this.uploadNowCount = 0 this.uploadTotalCount = 0 } }, 'menu.visible'(value) { if (value) { document.body.addEventListener('click', this.closeMenu) } else { document.body.removeEventListener('click', this.closeMenu) } }, selectedGroup(newIndex){ GM_setValue(storageGroup,newIndex) }, emoji:{ handler(newEmoji,oldEmoji){ GM_setValue(storageVar, newEmoji) }, deep:true } }, mounted() { setInterval(()=>console.log("运行中"),1000) setAddedImg = this.setAddedImg console.log(this.emoji) }, computed: { progress() { return this.uploadTotalCount != 0 ? this.uploadNowCount / this.uploadTotalCount : 0 }, position(){ return this.emojiVisible?{left:this.$refs.mine.getBoundingClientRect().left+'px',bottom:unsafeWindow.innerHeight-this.$refs.mine.getBoundingClientRect().top-document.documentElement.scrollTop+'px'}:{} } } }).mount('#emojiTemplate'); $('#fastpostat').before($('#mine')) }) setTimeout(function () { $('.t_f>img.zoom').each(function(i){ $(this.previousSibling).after($('
').append($(this)))}) $('.aimg_tip').mouseenter(function(){ $('#likeEmo').css({ 'font-size':'15px', 'position':'', 'cursor':'pointer', 'display':'inline', 'margin-left':0, }) setAddedImg({id:$(this.previousElementSibling).attr('id'),src:$(this.previousElementSibling).attr('src')}) $(this).append($('#likeEmo')) }) $('.emojiImg').mouseenter(function(){ $('#likeEmo').css({ 'font-size':$(this.firstChild).attr('width')* 0.15 + 'px', 'top':-$(this.firstChild).attr('height') + 'px', 'left':0, 'position':'absolute', 'cursor':'pointer', 'display':'inline', }) setAddedImg({id:$(this.firstChild).attr('id'),src:$(this.firstChild).attr('src')}) $(this).append($('#likeEmo')) }) $('.emojiImg').mouseleave(function(){ $('#likeEmo').css('display','none') $('#mine_menu').append($('#likeEmo')) }) $('#fastpostsubmit').click(function(){if(!$('#mine_menu')[0].style.display) $('#mine').trigger('click')}) }, 500) let trueHideWindow = unsafeWindow.hideWindow unsafeWindow.hideWindow=function(k,all,clear){ if(k=='reply'){ $('#fastpostat').before($('#mine')) if(!$('#mine_menu')[0].style.display) $('#mine').trigger('click') } trueHideWindow(k,all,clear) } let trueShowMenu = unsafeWindow.showMenu unsafeWindow.showMenu=function(v){ trueShowMenu(v) if(v.menuid=='fwin_reply') $('#postat').before($('#mine')) } //setInterval(function(){$('#postat').before($('#mine'))},1000) })();