Update plugin-list/plugin.js
This commit is contained in:
parent
571a439652
commit
0f77d127aa
1 changed files with 206 additions and 1 deletions
|
|
@ -1 +1,206 @@
|
||||||
penpot.ui.open("Plugins list",`?theme=${penpot.theme}`,{width:400,height:800});penpot.on("themechange",e=>{penpot.ui.sendMessage({type:"theme",content:e})});penpot.on("selectionchange",()=>{});
|
(function() {
|
||||||
|
const t=document.createElement("link").relList;
|
||||||
|
if(t&&t.supports&&t.supports("modulepreload"))return;
|
||||||
|
for(const n of document.querySelectorAll('link[rel="modulepreload"]'))o(n);
|
||||||
|
new MutationObserver(n=> {
|
||||||
|
for(const s of n)if(s.type==="childList")for(const a of s.addedNodes)a.tagName==="LINK"&&a.rel==="modulepreload"&&o(a)
|
||||||
|
}
|
||||||
|
).observe(document, {
|
||||||
|
childList:!0,subtree:!0
|
||||||
|
}
|
||||||
|
);
|
||||||
|
function r(n) {
|
||||||
|
const s={};
|
||||||
|
return n.integrity&&(s.integrity=n.integrity),n.referrerPolicy&&(s.referrerPolicy=n.referrerPolicy),n.crossOrigin==="use-credentials"?s.credentials="include":n.crossOrigin==="anonymous"?s.credentials="omit":s.credentials="same-origin",s
|
||||||
|
}
|
||||||
|
function o(n) {
|
||||||
|
if(n.ep)return;
|
||||||
|
n.ep=!0;
|
||||||
|
const s=r(n);
|
||||||
|
fetch(n.href,s)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
)();
|
||||||
|
const h=[ {
|
||||||
|
label:"Name (A-Z)",value:"name",direction:"asc"
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
label:"Name (Z-A)",value:"name",direction:"desc"
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
label:"Author (A-Z)",value:"author",direction:"asc"
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
label:"Author (Z-A)",value:"author",direction:"desc"
|
||||||
|
}
|
||||||
|
],g=new URLSearchParams(window.location.search);
|
||||||
|
document.body.dataset.theme=g.get("theme")??"light";
|
||||||
|
async function m() {
|
||||||
|
const e=await fetch("https://plugins-list.girafic.net/penpot-plugins.json");
|
||||||
|
if(!e.ok)throw new Error("Failed to fetch plugins data");
|
||||||
|
return e.json()
|
||||||
|
}
|
||||||
|
function f() {
|
||||||
|
const e=document.createElement("div");
|
||||||
|
return e.className="loading-state",e.innerHTML=`
|
||||||
|
<svg class="loading-spinner" viewBox="0 0 50 50">
|
||||||
|
<circle cx="25" cy="25" r="20" fill="none" stroke-width="5"></circle>
|
||||||
|
</svg>
|
||||||
|
<span>Loading plugins...</span>
|
||||||
|
`,e
|
||||||
|
}
|
||||||
|
function v(e) {
|
||||||
|
const t=document.createElement("div");
|
||||||
|
t.className="search-container",t.innerHTML=`
|
||||||
|
<div class="search-row">
|
||||||
|
<div class="search-input-wrapper">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="input search-input"
|
||||||
|
placeholder="Search plugins..."
|
||||||
|
id="searchInput"
|
||||||
|
>
|
||||||
|
<button class="search-clear" id="searchClear" type="button">
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16">
|
||||||
|
<path d="M8 6.586L4.293 2.879 2.879 4.293 6.586 8l-3.707 3.707 1.414 1.414L8 9.414l3.707 3.707 1.414-1.414L9.414 8l3.707-3.707-1.414-1.414L8 6.586z"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="select-wrapper">
|
||||||
|
<select class="select sort-select" id="sortSelect">
|
||||||
|
<option value="">Sort by</option>
|
||||||
|
${h.map(s=>`<option value="${s.value},${s.direction}">$ {
|
||||||
|
s.label
|
||||||
|
}
|
||||||
|
</option>`).join("")}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`,e.appendChild(t);
|
||||||
|
const r=t.querySelector("#searchInput"),o=t.querySelector("#sortSelect"),n=t.querySelector("#searchClear");
|
||||||
|
if(r&&o&&n) {
|
||||||
|
const s=()=> {
|
||||||
|
let a=L(r.value);
|
||||||
|
const[i,c]=o.value.split(",");
|
||||||
|
i&&c&&(a=y(a,i,c)),w(a),n.style.display=r.value?"flex":"none"
|
||||||
|
};
|
||||||
|
r.addEventListener("input",s),o.addEventListener("change",s),n.addEventListener("click",()=> {
|
||||||
|
r.value="",r.focus(),s()
|
||||||
|
}
|
||||||
|
),n.style.display="none"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
function y(e,t,r) {
|
||||||
|
return[...e].sort((o,n)=> {
|
||||||
|
const s=o[t].toString().toLowerCase(),a=n[t].toString().toLowerCase();
|
||||||
|
return r==="asc"?s.localeCompare(a):a.localeCompare(s)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
function L(e) {
|
||||||
|
const t=document.querySelector("body");
|
||||||
|
if(!(t!=null&&t.dataset.plugins))return[];
|
||||||
|
const r=JSON.parse(t.dataset.plugins),o=e.toLowerCase().trim();
|
||||||
|
return o===""?r:r.filter(n=>n.name.toLowerCase().includes(o)||n.author.toLowerCase().includes(o)||n.description.toLowerCase().includes(o))
|
||||||
|
}
|
||||||
|
function l(e) {
|
||||||
|
return`
|
||||||
|
<img src="${e.icon}" alt="${e.name}" class="plugin-icon">
|
||||||
|
<div class="plugin-info">
|
||||||
|
<h3 class="plugin-name">${e.name}</h3>
|
||||||
|
<p class="plugin-author">by <button class="author-button">${e.author}</button></p>
|
||||||
|
<p class="plugin-description">${e.description}</p>
|
||||||
|
<div class="plugin-actions">
|
||||||
|
<a href="${e.install.replace("https://design.penpot.app/","https://design.m3.fyi/")}" class="plugin-install" data-appearance="primary" target="_blank">Install</a>
|
||||||
|
<a href="${e.link}" class="plugin-link" data-appearance="secondary" target="_blank">Details</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
function S(e) {
|
||||||
|
const t=document.querySelector("#searchInput"),r=document.querySelector("#sortSelect");
|
||||||
|
t&&r&&(t.value=e,r.value="",t.dispatchEvent(new Event("input")))
|
||||||
|
}
|
||||||
|
function u(e,t) {
|
||||||
|
const r=e.querySelector(".author-button");
|
||||||
|
r&&r.addEventListener("click",()=> {
|
||||||
|
S(t.author)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
function d(e,t,r) {
|
||||||
|
return`
|
||||||
|
<div class="plugins-counter">
|
||||||
|
<div>${e===t?`Showing all $ {
|
||||||
|
t
|
||||||
|
}
|
||||||
|
plugins`:`Showing $ {
|
||||||
|
e
|
||||||
|
}
|
||||||
|
of $ {
|
||||||
|
t
|
||||||
|
}
|
||||||
|
plugins`}</div>
|
||||||
|
<div class="generated-at">Last updated: ${new Date(r).toLocaleString()}</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
function w(e) {
|
||||||
|
const t=document.querySelector(".plugins-list"),r=document.querySelector("body");
|
||||||
|
if(!t||!(r!=null&&r.dataset.plugins))return;
|
||||||
|
const o=JSON.parse(r.dataset.plugins),n=new Date().toISOString();
|
||||||
|
if(t.innerHTML="",e.length===0) {
|
||||||
|
const a=document.createElement("div");
|
||||||
|
a.className="no-results",a.textContent="No plugins found",t.appendChild(a)
|
||||||
|
}
|
||||||
|
else e.forEach(a=> {
|
||||||
|
const i=document.createElement("div");
|
||||||
|
i.className="plugin-item",i.innerHTML=l(a),u(i,a),t.appendChild(i)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const s=document.createElement("div");
|
||||||
|
s.innerHTML=d(e.length,o.length,n),t.appendChild(s)
|
||||||
|
}
|
||||||
|
async function p() {
|
||||||
|
const e=document.querySelector("body");
|
||||||
|
if(!e)return;
|
||||||
|
e.innerHTML="",v(e);
|
||||||
|
const t=document.createElement("div");
|
||||||
|
t.className="plugins-list";
|
||||||
|
const r=f();
|
||||||
|
t.appendChild(r),e.appendChild(t);
|
||||||
|
try {
|
||||||
|
const o=await m(), {
|
||||||
|
plugins:n,generated_at:s
|
||||||
|
}
|
||||||
|
=o;
|
||||||
|
r.remove(),n.forEach(i=> {
|
||||||
|
const c=document.createElement("div");
|
||||||
|
c.className="plugin-item",c.innerHTML=l(i),u(c,i),t.appendChild(c)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const a=document.createElement("div");
|
||||||
|
a.innerHTML=d(n.length,o.plugins.length,s),t.appendChild(a),e.dataset.plugins=JSON.stringify(n)
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
r.innerHTML=`
|
||||||
|
<div class="loading-error">
|
||||||
|
<span>Failed to load plugins</span>
|
||||||
|
<button class="retry-button" data-appearance="primary">Retry</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
const n=r.querySelector(".retry-button");
|
||||||
|
n&&n.addEventListener("click",()=> {
|
||||||
|
p()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
p();
|
||||||
|
window.addEventListener("message",async e=> {
|
||||||
|
e.data.type==="theme"&&(document.body.dataset.theme=e.data.content)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue