Add: plugin system[WIP]
This commit is contained in:
parent
8873af4597
commit
7169f1147b
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -25,3 +25,4 @@ app/git
|
||||||
*.code-workspace
|
*.code-workspace
|
||||||
releasenote.md
|
releasenote.md
|
||||||
app/yarn-error.log
|
app/yarn-error.log
|
||||||
|
app/js/platform/aiscript.js
|
||||||
|
|
10
app/aiscript.js
Normal file
10
app/aiscript.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
const { AiScript, parse, values, utils } = require('@syuilo/aiscript')
|
||||||
|
global.asValue = values
|
||||||
|
global.AiScript = AiScript
|
||||||
|
global.asParse = parse
|
||||||
|
global.asCommon = {
|
||||||
|
'TheDesk:console': values.FN_NATIVE((z) => {
|
||||||
|
console.log(z[0].value)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
global.asUtil = utils
|
|
@ -1,3 +1,9 @@
|
||||||
|
window.onload = function () {
|
||||||
|
console.log('loaded')
|
||||||
|
initPostbox()
|
||||||
|
connection()
|
||||||
|
initPlugin(plugins)
|
||||||
|
}
|
||||||
$.strip_tags = function (str, allowed) {
|
$.strip_tags = function (str, allowed) {
|
||||||
if (!str) {
|
if (!str) {
|
||||||
return ''
|
return ''
|
||||||
|
|
152
app/js/platform/plugin.js
Normal file
152
app/js/platform/plugin.js
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
|
||||||
|
var plugins = getPlugin()
|
||||||
|
function getPlugin() {
|
||||||
|
const json = localStorage.getItem('plugins')
|
||||||
|
let ret = {
|
||||||
|
buttonOnPostbox: [],
|
||||||
|
buttonOnToot: []
|
||||||
|
}
|
||||||
|
//if(!json) return ret
|
||||||
|
//const plugins = JSON.parse(json)
|
||||||
|
const plugins = [
|
||||||
|
{
|
||||||
|
id: randomStr(20),
|
||||||
|
content: `### {
|
||||||
|
name: "マイ・ファースト・プラグイン"
|
||||||
|
version: 1
|
||||||
|
event: "buttonOnPostbox"
|
||||||
|
author: "Cutls P"
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
]
|
||||||
|
for (let plugin of plugins) {
|
||||||
|
const meta = getMeta(plugin.content)
|
||||||
|
if (!meta) continue
|
||||||
|
const type = meta.event
|
||||||
|
ret[type] ? ret[type].push(plugin) : ret[type] = [plugin]
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
function initPlugin() {
|
||||||
|
asCommon['TheDesk:dialog'] = asValue.FN_NATIVE((z) => {
|
||||||
|
Swal.fire({
|
||||||
|
title: z[0].value,
|
||||||
|
icon: z[2] ? z[2].value : 'info',
|
||||||
|
text: z[1] ? z[1].value : ''
|
||||||
|
})
|
||||||
|
})
|
||||||
|
asCommon['TheDesk:confirm'] = asValue.FN_NATIVE(async (z) => {
|
||||||
|
const alert = await Swal.fire({
|
||||||
|
title: z[0].value,
|
||||||
|
text: z[1].value,
|
||||||
|
icon: z[2] ? z[2].value : 'info',
|
||||||
|
showCancelButton: true
|
||||||
|
})
|
||||||
|
return asUtil.jsToVal(!!(alert.value && alert.value === true))
|
||||||
|
})
|
||||||
|
asCommon['TheDesk:css'] = asValue.FN_NATIVE((z) => {
|
||||||
|
$(escapeHTML(z[0].value)).css(escapeHTML(z[1].value), escapeHTML(z[2].value))
|
||||||
|
})
|
||||||
|
asCommon['TheDesk:api'] = asValue.FN_NATIVE(async (z) => {
|
||||||
|
try {
|
||||||
|
if (!getMeta(exe).apiGet && z[0].value == "GET") return asUtil.jsToVal(false)
|
||||||
|
if (!getMeta(exe).apiPost && (z[0].value == "POST" || z[0].value == "DELETE" || z[0].value == "PUT")) return asUtil.jsToVal(false)
|
||||||
|
const domain = localStorage.getItem(`domain_${z[3].value}`)
|
||||||
|
const at = localStorage.getItem(`acct_${z[3].value}_at`)
|
||||||
|
const start = `https://${domain}/api/${z[1].value}`
|
||||||
|
const q = {
|
||||||
|
method: z[0].value,
|
||||||
|
headers: {
|
||||||
|
'content-type': 'application/json',
|
||||||
|
Authorization:
|
||||||
|
`Bearer ${at}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (z[2]) q.body = z[2].value
|
||||||
|
const promise = await fetch(start, q)
|
||||||
|
const json = await promise.json()
|
||||||
|
return asUtil.jsToVal(json)
|
||||||
|
} catch (e) {
|
||||||
|
return asUtil.jsToVal(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
const { buttonOnPostbox, init } = plugins
|
||||||
|
for (let target of buttonOnPostbox) {
|
||||||
|
const meta = getMeta(target.content)
|
||||||
|
$('#dropdown2').append(`<li><a onclick="execPlugin('${target.id}','buttonOnPostbox', null);">${escapeHTML(meta.name)}</a></li>`)
|
||||||
|
}
|
||||||
|
for (let target of init) {
|
||||||
|
const as = new AiScript(asCommon)
|
||||||
|
const meta = getMeta(target.content)
|
||||||
|
M.toast({ html: `${escapeHTML(meta.name)}を実行しました`, displayLength: 1000 })
|
||||||
|
if (target) as.exec(asParse(target.content))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function getMeta(plugin) {
|
||||||
|
try {
|
||||||
|
return AiScript.collectMetadata(asParse(plugin)).get(null)
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function execPlugin(id, source, args) {
|
||||||
|
const coh = plugins[source]
|
||||||
|
let exe = null
|
||||||
|
for (let plugin of coh) {
|
||||||
|
if (plugin.id == id) {
|
||||||
|
exe = plugin.content
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const common = _.cloneDeep(asCommon)
|
||||||
|
if (source == 'buttonOnToot') {
|
||||||
|
common.DATA = args
|
||||||
|
const domain = localStorage.getItem(`domain_${args.acct_id}`)
|
||||||
|
const at = localStorage.getItem(`acct_${args.acct_id}_at`)
|
||||||
|
const start = `https://${domain}/api/v1/statuses/${args.id}`
|
||||||
|
const promise = await fetch(start, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'content-type': 'application/json',
|
||||||
|
Authorization:
|
||||||
|
`Bearer ${at}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const json = await promise.json()
|
||||||
|
common.TOOT = asUtil.jsToVal(json)
|
||||||
|
common['TheDesk:changeText'] = asValue.FN_NATIVE((z) => {
|
||||||
|
if (getMeta(exe).dangerHtml) $(`[unique-id=${args.id}] .cvo`).html(z[0].value)
|
||||||
|
})
|
||||||
|
} else if (source == 'buttonOnPostbox') {
|
||||||
|
const postDt = post(null, false, true)
|
||||||
|
common.POST = asUtil.jsToVal(postDt)
|
||||||
|
common.ACCT_ID = asUtil.jsToVal(postDt.TheDeskAcctId)
|
||||||
|
common['TheDesk:postText'] = asValue.FN_NATIVE((z) => {
|
||||||
|
$('#textarea').val(z[0].value)
|
||||||
|
})
|
||||||
|
common['TheDesk:postCW'] = asValue.FN_NATIVE((z) => {
|
||||||
|
if (z[1]) $('#cw-text').val(z[1].value)
|
||||||
|
cw(z[0] ? z[0].value : false)
|
||||||
|
})
|
||||||
|
common['TheDesk:postNSFW'] = asValue.FN_NATIVE((z) => {
|
||||||
|
nsfw(z[0] ? z[0].value : false)
|
||||||
|
})
|
||||||
|
common['TheDesk:postVis'] = asValue.FN_NATIVE((z) => {
|
||||||
|
vis(z[0].value)
|
||||||
|
})
|
||||||
|
common['TheDesk:postClearbox'] = asValue.FN_NATIVE(() => {
|
||||||
|
clear()
|
||||||
|
})
|
||||||
|
common['TheDesk:postExec'] = asValue.FN_NATIVE(() => {
|
||||||
|
if (getMeta(exe).apiPost) post()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
common['TheDesk:console'] = asValue.FN_NATIVE((z) => {
|
||||||
|
console.log(z[0].value)
|
||||||
|
})
|
||||||
|
const as = new AiScript(common)
|
||||||
|
if (exe) as.exec(asParse(exe))
|
||||||
|
}
|
|
@ -1,14 +1,14 @@
|
||||||
/*保護系*/
|
/*保護系*/
|
||||||
//画像保護
|
//画像保護
|
||||||
function nsfw() {
|
function nsfw(force) {
|
||||||
if ($('#nsfw').hasClass('nsfw-avail')) {
|
if (force || !$('#nsfw').hasClass('nsfw-avail')) {
|
||||||
$('#nsfw').removeClass('yellow-text')
|
|
||||||
$('#nsfw').html('visibility_off')
|
|
||||||
$('#nsfw').removeClass('nsfw-avail')
|
|
||||||
} else {
|
|
||||||
$('#nsfw').addClass('yellow-text')
|
$('#nsfw').addClass('yellow-text')
|
||||||
$('#nsfw').html('visibility')
|
$('#nsfw').html('visibility')
|
||||||
$('#nsfw').addClass('nsfw-avail')
|
$('#nsfw').addClass('nsfw-avail')
|
||||||
|
} else {
|
||||||
|
$('#nsfw').removeClass('yellow-text')
|
||||||
|
$('#nsfw').html('visibility_off')
|
||||||
|
$('#nsfw').removeClass('nsfw-avail')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,12 +80,7 @@ loadVis()
|
||||||
|
|
||||||
//コンテントワーニング
|
//コンテントワーニング
|
||||||
function cw(force) {
|
function cw(force) {
|
||||||
if ($('#cw').hasClass('cw-avail') || !force) {
|
if (force || !$('#cw').hasClass('cw-avail')) {
|
||||||
$('#cw-text').val()
|
|
||||||
$('#cw-text').hide()
|
|
||||||
$('#cw').removeClass('yellow-text')
|
|
||||||
$('#cw').removeClass('cw-avail')
|
|
||||||
} else {
|
|
||||||
$('#cw-text').show()
|
$('#cw-text').show()
|
||||||
$('#cw').addClass('yellow-text')
|
$('#cw').addClass('yellow-text')
|
||||||
$('#cw').addClass('cw-avail')
|
$('#cw').addClass('cw-avail')
|
||||||
|
@ -93,6 +88,11 @@ function cw(force) {
|
||||||
if (cwt) {
|
if (cwt) {
|
||||||
$('#cw-text').val(cwt)
|
$('#cw-text').val(cwt)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$('#cw-text').val()
|
||||||
|
$('#cw-text').hide()
|
||||||
|
$('#cw').removeClass('yellow-text')
|
||||||
|
$('#cw').removeClass('cw-avail')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//TLでコンテントワーニングを表示トグル
|
//TLでコンテントワーニングを表示トグル
|
||||||
|
|
|
@ -437,7 +437,6 @@ function draftToPost(json, acct_id, id) {
|
||||||
$('#post-acct-sel').val(acct_id)
|
$('#post-acct-sel').val(acct_id)
|
||||||
$('select').formSelect()
|
$('select').formSelect()
|
||||||
mdCheck()
|
mdCheck()
|
||||||
var medias = $('[toot-id=' + id + ']').attr('data-medias')
|
|
||||||
mediack = null
|
mediack = null
|
||||||
if(json.media_attachments) mediack = json.media_attachments[0]
|
if(json.media_attachments) mediack = json.media_attachments[0]
|
||||||
//メディアがあれば
|
//メディアがあれば
|
||||||
|
@ -684,9 +683,9 @@ function staEx(mode) {
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
function toggleAction(id) {
|
function toggleAction(elm) {
|
||||||
const elm = document.getElementById(id)
|
console.log(elm)
|
||||||
const instance = M.Dropdown.init(elm);
|
const instance = M.Dropdown.init(elm)
|
||||||
console.log(instance.isOpen)
|
console.log(instance.isOpen)
|
||||||
instance.open()
|
instance.open()
|
||||||
}
|
}
|
||||||
|
|
|
@ -334,9 +334,14 @@ function cardCheck(tlid) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mov(id, tlid, type) {
|
function mov(id, tlid, type, rand, target) {
|
||||||
const dropdownTrigger = `dropdown_${tlid}_${id}`
|
const dropdownTrigger = `dropdown_${rand}`
|
||||||
const elm = document.getElementById(dropdownTrigger)
|
let elm = document.querySelector(`#timeline_${tlid} #${dropdownTrigger}`)
|
||||||
|
if(tlid == 'notf') {
|
||||||
|
const timeline = $(target).parents('.notf-indv-box').attr('id')
|
||||||
|
elm = document.querySelector(`#${timeline} #${dropdownTrigger}`)
|
||||||
|
console.log(`#${timeline} #${dropdownTrigger}`)
|
||||||
|
}
|
||||||
const instance = M.Dropdown.getInstance(elm)
|
const instance = M.Dropdown.getInstance(elm)
|
||||||
if(instance) {
|
if(instance) {
|
||||||
if(instance.isOpen) return false
|
if(instance.isOpen) return false
|
||||||
|
|
|
@ -765,9 +765,10 @@ function misskeyParse(obj, mix, acct_id, tlid, popup, mutefilter) {
|
||||||
} else {
|
} else {
|
||||||
var actemojick = false
|
var actemojick = false
|
||||||
}
|
}
|
||||||
|
var rand = randomStr(8)
|
||||||
templete = templete + '<div id="pub_' + toot.id + '" class="cvo ' +
|
templete = templete + '<div id="pub_' + toot.id + '" class="cvo ' +
|
||||||
boostback + ' ' + fav_app + ' ' + rt_app + ' ' + hasmedia + '" toot-id="' + id + '" unique-id="' + uniqueid + '" data-medias="' + media_ids + ' " unixtime="' + date(obj[
|
boostback + ' ' + fav_app + ' ' + rt_app + ' ' + hasmedia + '" toot-id="' + id + '" unique-id="' + uniqueid + '" data-medias="' + media_ids + ' " unixtime="' + date(obj[
|
||||||
key].created_at, 'unix') + '" ' + if_notf + ' onmouseover="mov(\'' + toot.id + '\',\'' + tlid + '\',\'mv\')" onclick="mov(\'' + toot.id + '\',\'' + tlid + '\',\'cl\')" onmouseout="resetmv(\'mv\')" reacted="' + reacted + '">' +
|
key].created_at, 'unix') + '" ' + if_notf + ' onmouseover="mov(\'' + toot.id + '\',\'' + tlid + '\',\'mv\', \''+rand+'\')" onclick="mov(\'' + toot.id + '\',\'' + tlid + '\',\'cl\', \''+rand+'\')" onmouseout="resetmv(\'mv\')" reacted="' + reacted + '">' +
|
||||||
'<div class="area-notice"><span class="gray sharesta">' + notice + home +
|
'<div class="area-notice"><span class="gray sharesta">' + notice + home +
|
||||||
'</span></div>' +
|
'</span></div>' +
|
||||||
'<div class="area-icon"><a onclick="udg(\'' + toot.user.id +
|
'<div class="area-icon"><a onclick="udg(\'' + toot.user.id +
|
||||||
|
|
|
@ -271,8 +271,7 @@ function parse(obj, mix, acct_id, tlid, popup, mutefilter, type) {
|
||||||
var noticetext = `<span onclick="notfFilter('${toot.account.id}','${tlid}');" class=" pointer big-text ${notfFilHide}"><i class="fas fa-filter"
|
var noticetext = `<span onclick="notfFilter('${toot.account.id}','${tlid}');" class=" pointer big-text ${notfFilHide}"><i class="fas fa-filter"
|
||||||
title="${lang.lang_parse_notffilter}">
|
title="${lang.lang_parse_notffilter}">
|
||||||
</i><span class="voice">${lang.lang_parse_notffilter}</span></span>
|
</i><span class="voice">${lang.lang_parse_notffilter}</span></span>
|
||||||
<span class="cbadge cbadge-hover" title="${date(toot.created_at, 'absolute')}(${
|
<span class="cbadge cbadge-hover" title="${date(toot.created_at, 'absolute')}(${lang.lang_parse_notftime
|
||||||
lang.lang_parse_notftime
|
|
||||||
})" aria-hidden="true"><i class="far fa-clock"></i>
|
})" aria-hidden="true"><i class="far fa-clock"></i>
|
||||||
${date(toot.created_at, datetype)}
|
${date(toot.created_at, datetype)}
|
||||||
</span>
|
</span>
|
||||||
|
@ -709,8 +708,7 @@ function parse(obj, mix, acct_id, tlid, popup, mutefilter, type) {
|
||||||
var featured = ` <a onclick="tagFeature('${tag.name}','${acct_id}')" class="pointer" title="add it to Featured tags">Feature</a> `
|
var featured = ` <a onclick="tagFeature('${tag.name}','${acct_id}')" class="pointer" title="add it to Featured tags">Feature</a> `
|
||||||
tags =
|
tags =
|
||||||
tags +
|
tags +
|
||||||
`<span class="hide" data-tag="${tag.name}" data-regTag="${tag.name.toLowerCase()}">#${
|
`<span class="hide" data-tag="${tag.name}" data-regTag="${tag.name.toLowerCase()}">#${tag.name
|
||||||
tag.name
|
|
||||||
}:
|
}:
|
||||||
<a onclick="tl('tag','${tag.name}','${acct_id}','add')" class="pointer"
|
<a onclick="tl('tag','${tag.name}','${acct_id}','add')" class="pointer"
|
||||||
title="${lang.lang_parse_tagTL.replace(
|
title="${lang.lang_parse_tagTL.replace(
|
||||||
|
@ -957,11 +955,9 @@ function parse(obj, mix, acct_id, tlid, popup, mutefilter, type) {
|
||||||
bgColorCSS = bgColorCSS + bg + ','
|
bgColorCSS = bgColorCSS + bg + ','
|
||||||
}
|
}
|
||||||
bgColorCSS = `linear-gradient(90deg, ${bgColorCSS} transparent)`
|
bgColorCSS = `linear-gradient(90deg, ${bgColorCSS} transparent)`
|
||||||
var tickerdom = `<div aria-hidden="true" style="user-select:none;cursor:default;background:${bgColorCSS} !important; color:${
|
var tickerdom = `<div aria-hidden="true" style="user-select:none;cursor:default;background:${bgColorCSS} !important; color:${fontColor
|
||||||
fontColor
|
|
||||||
};width:100%; height:0.9rem; font-size:0.8rem;" class="tickers">
|
};width:100%; height:0.9rem; font-size:0.8rem;" class="tickers">
|
||||||
<img draggable="false" src="${
|
<img draggable="false" src="${value.favicon
|
||||||
value.favicon
|
|
||||||
}" style="height:100%;" onerror="this.src=\'../../img/loading.svg\'" loading="lazy">
|
}" style="height:100%;" onerror="this.src=\'../../img/loading.svg\'" loading="lazy">
|
||||||
<span style="position:relative; top:-0.2rem;">${escapeHTML(value.name)}</span>
|
<span style="position:relative; top:-0.2rem;">${escapeHTML(value.name)}</span>
|
||||||
</div>`
|
</div>`
|
||||||
|
@ -981,8 +977,7 @@ function parse(obj, mix, acct_id, tlid, popup, mutefilter, type) {
|
||||||
poll +
|
poll +
|
||||||
`<div class="quote-renote">
|
`<div class="quote-renote">
|
||||||
<div class="renote-icon">
|
<div class="renote-icon">
|
||||||
<a onclick="udg('${toot.quote.account.id}','${acct_id}');" user="${
|
<a onclick="udg('${toot.quote.account.id}','${acct_id}');" user="${toot.quote.account.acct
|
||||||
toot.quote.account.acct
|
|
||||||
}" class="udg">
|
}" class="udg">
|
||||||
<img draggable="false" src="${toot.quote.account.avatar}" loading="lazy">
|
<img draggable="false" src="${toot.quote.account.avatar}" loading="lazy">
|
||||||
</a>
|
</a>
|
||||||
|
@ -994,8 +989,7 @@ function parse(obj, mix, acct_id, tlid, popup, mutefilter, type) {
|
||||||
${toot.quote.content}
|
${toot.quote.content}
|
||||||
</div>
|
</div>
|
||||||
<div class="renote-details">
|
<div class="renote-details">
|
||||||
<a onclick="details('${
|
<a onclick="details('${toot.quote.id
|
||||||
toot.quote.id
|
|
||||||
}','${acct_id}','${tlid}','normal')" class="waves-effect waves-dark btn-flat details" style="padding:0">
|
}','${acct_id}','${tlid}','normal')" class="waves-effect waves-dark btn-flat details" style="padding:0">
|
||||||
<i class="text-darken-3 material-icons">more_vert</i>
|
<i class="text-darken-3 material-icons">more_vert</i>
|
||||||
</a>
|
</a>
|
||||||
|
@ -1022,6 +1016,15 @@ function parse(obj, mix, acct_id, tlid, popup, mutefilter, type) {
|
||||||
if (trans != '') {
|
if (trans != '') {
|
||||||
menuct++
|
menuct++
|
||||||
}
|
}
|
||||||
|
//このトゥート内のアクションを完了させるために、適当にIDを振る
|
||||||
|
var rand = randomStr(8)
|
||||||
|
//プラグイン機構
|
||||||
|
var plugin = plugins.buttonOnToot
|
||||||
|
var pluginHtml = ''
|
||||||
|
for (let target of plugin) {
|
||||||
|
const meta = getMeta(target.content)
|
||||||
|
pluginHtml = pluginHtml + `<li><a onclick="execPlugin('${target.id}','buttonOnToot',{id: '${uniqueid}', acct_id: '${acct_id}'});">${escapeHTML(meta.name)}</a></li>`
|
||||||
|
}
|
||||||
templete =
|
templete =
|
||||||
templete +
|
templete +
|
||||||
`<div
|
`<div
|
||||||
|
@ -1032,8 +1035,8 @@ function parse(obj, mix, acct_id, tlid, popup, mutefilter, type) {
|
||||||
'unix'
|
'unix'
|
||||||
)}"
|
)}"
|
||||||
${if_notf}
|
${if_notf}
|
||||||
onmouseover="mov('${uniqueid}','${tlid}','mv')"
|
onmouseover="mov('${uniqueid}','${tlid}','mv', '${rand}', this)"
|
||||||
onclick="mov('${uniqueid}','${tlid}','cl')"
|
onclick="mov('${uniqueid}','${tlid}','cl', '${rand}', this)"
|
||||||
onmouseout="resetmv('mv')"
|
onmouseout="resetmv('mv')"
|
||||||
>
|
>
|
||||||
<div class="area-notice grid"><span class="gray sharesta">${notice}${home}</span></div>
|
<div class="area-notice grid"><span class="gray sharesta">${notice}${home}</span></div>
|
||||||
|
@ -1094,8 +1097,7 @@ function parse(obj, mix, acct_id, tlid, popup, mutefilter, type) {
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="action ${can_rt} ${disp['rt']} ${noauth}">
|
<div class="action ${can_rt} ${disp['rt']} ${noauth}">
|
||||||
<a onclick="rt('${
|
<a onclick="rt('${toot.id
|
||||||
toot.id
|
|
||||||
}','${acct_id}','${tlid}')" class="waves-effect waves-dark btn-flat actct bt-btn"
|
}','${acct_id}','${tlid}')" class="waves-effect waves-dark btn-flat actct bt-btn"
|
||||||
style="padding:0" title="${lang.lang_parse_bt}">
|
style="padding:0" title="${lang.lang_parse_bt}">
|
||||||
<i class="fas fa-retweet ${if_rt} rt_${toot.id}"></i>
|
<i class="fas fa-retweet ${if_rt} rt_${toot.id}"></i>
|
||||||
|
@ -1130,8 +1132,8 @@ function parse(obj, mix, acct_id, tlid, popup, mutefilter, type) {
|
||||||
</div>
|
</div>
|
||||||
<div class="area-side">
|
<div class="area-side">
|
||||||
<div class="action ${noauth}">
|
<div class="action ${noauth}">
|
||||||
<a onclick="toggleAction('trigger_${tlid}_${uniqueid}')" data-target="dropdown_${tlid}_${uniqueid}"
|
<a onclick="toggleAction(this)" data-target="dropdown_${rand}"
|
||||||
class="ctxMenu waves-effect waves-dark btn-flat" style="padding:0" id="trigger_${tlid}_${uniqueid}">
|
class="ctxMenu waves-effect waves-dark btn-flat" style="padding:0" id="trigger_${rand}">
|
||||||
<i class="text-darken-3 material-icons act-icon" aria-hidden="true">expand_more</i>
|
<i class="text-darken-3 material-icons act-icon" aria-hidden="true">expand_more</i>
|
||||||
<span class="voice">Other actions</span>
|
<span class="voice">Other actions</span>
|
||||||
</a>
|
</a>
|
||||||
|
@ -1144,7 +1146,7 @@ function parse(obj, mix, acct_id, tlid, popup, mutefilter, type) {
|
||||||
<span class="voice">${lang.lang_parse_detail}</span>
|
<span class="voice">${lang.lang_parse_detail}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul class="dropdown-content contextMenu" id="dropdown_${tlid}_${uniqueid}">
|
<ul class="dropdown-content contextMenu" id="dropdown_${rand}">
|
||||||
<li class="${viashow} via-dropdown" onclick="client('${$.strip_tags(via)}')" title="${lang.lang_parse_clientop}">
|
<li class="${viashow} via-dropdown" onclick="client('${$.strip_tags(via)}')" title="${lang.lang_parse_clientop}">
|
||||||
via ${escapeHTML(via)}</a>
|
via ${escapeHTML(via)}</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -1169,6 +1171,7 @@ function parse(obj, mix, acct_id, tlid, popup, mutefilter, type) {
|
||||||
style="padding:0">
|
style="padding:0">
|
||||||
<i class="fas text-darken-3 fa-globe"></i>${lang.lang_parse_link}
|
<i class="fas text-darken-3 fa-globe"></i>${lang.lang_parse_link}
|
||||||
</li>
|
</li>
|
||||||
|
${pluginHtml}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
|
|
|
@ -101,7 +101,6 @@ if (location.search) {
|
||||||
$('.mini-btn').text('expand_less')
|
$('.mini-btn').text('expand_less')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
window.onload = function () { initPostbox(); connection() }
|
|
||||||
function initPostbox() {
|
function initPostbox() {
|
||||||
$('#posttgl').click(function (e) {
|
$('#posttgl').click(function (e) {
|
||||||
if (!$('#post-box').hasClass('appear')) {
|
if (!$('#post-box').hasClass('appear')) {
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
"construct": "cd view/make && node make --automatic && cd ../../",
|
"construct": "cd view/make && node make --automatic && cd ../../ && browserify aiscript.js -o js/platform/aiscript.js",
|
||||||
"construct:store": "cd view/make && node make --automatic --store && cd ../../",
|
"construct:store": "cd view/make && node make --automatic --store && cd ../../ && browserify aiscript.js -o js/platform/aiscript.js",
|
||||||
"dev": "npx electron ./ --dev",
|
"dev": "npx electron ./ --dev",
|
||||||
"dist": "build --linux snap",
|
"dist": "build --linux snap",
|
||||||
"watchview": "node view/make/make.js --automatic --watch",
|
"watchview": "node view/make/make.js --automatic --watch",
|
||||||
|
@ -60,6 +60,7 @@
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-free": "^5.15.1",
|
"@fortawesome/fontawesome-free": "^5.15.1",
|
||||||
|
"@syuilo/aiscript": "^0.11.1",
|
||||||
"electron-dl": "^3.0.2",
|
"electron-dl": "^3.0.2",
|
||||||
"jimp": "^0.16.1",
|
"jimp": "^0.16.1",
|
||||||
"jquery": "^3.5.1",
|
"jquery": "^3.5.1",
|
||||||
|
@ -76,6 +77,7 @@
|
||||||
"itunes-nowplaying-mac": "0.3.1"
|
"itunes-nowplaying-mac": "0.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"browserify": "^17.0.0",
|
||||||
"chokidar": "^3.4.3",
|
"chokidar": "^3.4.3",
|
||||||
"electron": "^10.1.5",
|
"electron": "^10.1.5",
|
||||||
"electron-builder": "^22.9.1",
|
"electron-builder": "^22.9.1",
|
||||||
|
|
|
@ -1221,8 +1221,10 @@
|
||||||
<!--JS-->
|
<!--JS-->
|
||||||
<script type="text/javascript" src="../../@@node_base@@/jquery/dist/jquery.js"></script>
|
<script type="text/javascript" src="../../@@node_base@@/jquery/dist/jquery.js"></script>
|
||||||
<script type="text/javascript" src="../../js/platform/first.js"></script>
|
<script type="text/javascript" src="../../js/platform/first.js"></script>
|
||||||
<script type="text/javascript" src="../../@@node_base@@/grapheme-splitter/index.js"></script>
|
<script type="text/javascript" src="../../js/platform/aiscript.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/platform/plugin.js"></script>
|
||||||
<script type="text/javascript" src="../../@@node_base@@/materialize-css/dist/js/materialize.js"></script>
|
<script type="text/javascript" src="../../@@node_base@@/materialize-css/dist/js/materialize.js"></script>
|
||||||
|
<script type="text/javascript" src="../../@@node_base@@/grapheme-splitter/index.js"></script>
|
||||||
<script type="text/javascript" src="../../@@node_base@@/lodash/lodash.min.js"></script>
|
<script type="text/javascript" src="../../@@node_base@@/lodash/lodash.min.js"></script>
|
||||||
<script type="text/javascript" src="main.js"></script>
|
<script type="text/javascript" src="main.js"></script>
|
||||||
<script type="text/javascript" src="../../js/common/time.js"></script>
|
<script type="text/javascript" src="../../js/common/time.js"></script>
|
||||||
|
|
|
@ -385,13 +385,6 @@
|
||||||
</template><br>
|
</template><br>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<div class="collapsible-header">
|
|
||||||
<i class="material-icons">keyboard</i>@@keysc@@
|
|
||||||
</div>
|
|
||||||
<div class="collapsible-body">
|
|
||||||
<h5>@@iks@@</h5>
|
<h5>@@iks@@</h5>
|
||||||
@@okswarn@@<br>
|
@@okswarn@@<br>
|
||||||
Ctrl+Shift+1:<input type="text" style="width:11.5rem" id="oks-1">
|
Ctrl+Shift+1:<input type="text" style="width:11.5rem" id="oks-1">
|
||||||
|
@ -400,6 +393,15 @@
|
||||||
<button onclick="oks(2)" class="btn waves-effect" style="width:7.7rem;">@@set@@</button><br><br>
|
<button onclick="oks(2)" class="btn waves-effect" style="width:7.7rem;">@@set@@</button><br><br>
|
||||||
Ctrl+Shift+3:<input type="text" style="width:11.5rem" id="oks-3">
|
Ctrl+Shift+3:<input type="text" style="width:11.5rem" id="oks-3">
|
||||||
<button onclick="oks(3)" class="btn waves-effect" style="width:7.7rem;">@@set@@</button><br><br>
|
<button onclick="oks(3)" class="btn waves-effect" style="width:7.7rem;">@@set@@</button><br><br>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="collapsible-header">
|
||||||
|
<i class="material-icons">power</i>@@plugin@@
|
||||||
|
</div>
|
||||||
|
<div class="collapsible-body">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
|
|
1054
app/yarn.lock
1054
app/yarn.lock
File diff suppressed because it is too large
Load Diff
117
plugin.md
Normal file
117
plugin.md
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
# TheDesk Plugin
|
||||||
|
|
||||||
|
[AiScript](https://github.com/syuilo/aiscript)で書きます。
|
||||||
|
|
||||||
|
[AiScriptの書き方](https://github.com/syuilo/aiscript/blob/master/docs/get-started.md)
|
||||||
|
|
||||||
|
## メタデータ
|
||||||
|
```
|
||||||
|
### {
|
||||||
|
name: "マイ・ファースト・プラグイン"
|
||||||
|
version: 1
|
||||||
|
event: "buttonOnPostbox"
|
||||||
|
author: "Cutls P"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
これを冒頭に入れます。
|
||||||
|
|
||||||
|
* dangerHtml: true|false
|
||||||
|
`TheDesk:changeText`にアクセスするために必要です。
|
||||||
|
* apiGetl: true|false
|
||||||
|
`TheDesk:api`にGETメソッドでアクセスするときに必要です。
|
||||||
|
* apiPost: true|false
|
||||||
|
`TheDesk:api`にPOST/PUT/DELETEメソッドでアクセスするときや、`postExec`を実行するときに必要です。
|
||||||
|
|
||||||
|
### event
|
||||||
|
|
||||||
|
eventに設定できるもの
|
||||||
|
|
||||||
|
* `buttonOnPostbox`
|
||||||
|
投稿フォームの…(90°回転)で出てくるメニュー内に表示されます
|
||||||
|
* `buttonOnToot`
|
||||||
|
トゥートの詳細メニューに表示されます
|
||||||
|
* `init`
|
||||||
|
起動時(なるべく早い段階で)
|
||||||
|
|
||||||
|
追加予定…
|
||||||
|
|
||||||
|
## 変数
|
||||||
|
|
||||||
|
### buttonOnTootのとき
|
||||||
|
|
||||||
|
* DATA
|
||||||
|
```
|
||||||
|
{
|
||||||
|
id: "トゥートのID文字列",
|
||||||
|
acct_id: "アカウントのTheDesk内部ID"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
* TOOT
|
||||||
|
|
||||||
|
トゥートのAPIを叩いた時と同じオブジェクトが返ります。なお、プラグインが実行されてから取得します。
|
||||||
|
プラグインの実行ボタン押下から実行までの時間差はこれによるものです。
|
||||||
|
|
||||||
|
### buttonOnPostboxのとき
|
||||||
|
|
||||||
|
* POST
|
||||||
|
投稿するときのオブジェクトがそのまま入りますが、`TheDeskAcctId`というTheDeskが内部で扱うアカウントのID(string)が入ったプロパティが追加されます。
|
||||||
|
* ACCT_ID
|
||||||
|
TheDeskが内部で扱うアカウントのID(string)
|
||||||
|
|
||||||
|
|
||||||
|
## 関数
|
||||||
|
|
||||||
|
### TheDesk:dialog(title: string, text: string, type?: string)
|
||||||
|
typeのデフォルトは'info'で、他に'error','question','success'などがある
|
||||||
|
|
||||||
|
### TheDesk:confirm(title: string, text: string, type?: string)
|
||||||
|
typeのデフォルトは'info'で、他に'error','question','success'などがある
|
||||||
|
返り値はboolean(true|false)
|
||||||
|
|
||||||
|
### TheDesk:css(query: string, attr: string, val: string)
|
||||||
|
jQueryの`$(query).css(attr, val)`に相当
|
||||||
|
|
||||||
|
### TheDesk:api(method: 'GET'|'POST'|'PUT'|'DELETE', endpoint: string, body: string, acct_id: string)
|
||||||
|
bodyにもstringを投げてください。
|
||||||
|
endpointは`v1`から書いてください。(`v1/accounts...`)
|
||||||
|
|
||||||
|
返り値はjsonのオブジェクト。
|
||||||
|
|
||||||
|
### TheDesk:changeText(body: string)
|
||||||
|
`buttonOnToot`で使用可能
|
||||||
|
|
||||||
|
該当トゥート(や他タイムラインの同一トゥート)のテキストを書き換えます。
|
||||||
|
`dangerHtml`をtrueにしてください。
|
||||||
|
HTMLを引数にすることに留意してください。
|
||||||
|
|
||||||
|
### TheDesk:postText(text: string)
|
||||||
|
`buttonOnPostbox`で使用可能
|
||||||
|
|
||||||
|
トゥートボックスの中身を書き換えます。
|
||||||
|
|
||||||
|
### TheDesk:postCW(force: boolean, text: string)
|
||||||
|
`buttonOnPostbox`で使用可能
|
||||||
|
|
||||||
|
CWを切り替えます。forceはデフォルトでfalseで、trueにするとオンに、falseにするとトグルになります。
|
||||||
|
textには警告文を入れます。
|
||||||
|
|
||||||
|
### TheDesk:postNSFW(force: boolean)
|
||||||
|
`buttonOnPostbox`で使用可能
|
||||||
|
|
||||||
|
NSFWを切り替えます。forceはデフォルトでfalseで、trueにするとオンに、falseにするとトグルになります。
|
||||||
|
|
||||||
|
### TheDesk:postVis(vis: 'public'|'unlisted'|'private'|'direct')
|
||||||
|
`buttonOnPostbox`で使用可能
|
||||||
|
|
||||||
|
公開範囲を変更します。
|
||||||
|
|
||||||
|
### TheDesk:postNSFW(force: postClearbox)
|
||||||
|
`buttonOnPostbox`で使用可能
|
||||||
|
|
||||||
|
投稿ボックスをクリアします。
|
||||||
|
|
||||||
|
### TheDesk:postExec()
|
||||||
|
`buttonOnPostbox`で使用可能
|
||||||
|
|
||||||
|
`apiPost`をtrueにしてください。
|
||||||
|
トゥートボタンを押したのと同じ挙動をします。
|
Loading…
Reference in New Issue
Block a user