scrapbox-commit-viewer@0.2.0
deprecatd
/icons/hr.icon
code:sh
code:script.js
import{html as f,render as w}from"../htm@3.0.4%2Fpreact/script.js";import{useState as h,useEffect as v}from"../preact@10.5.13/hooks.js";import{useState as _,useEffect as E,useCallback as I}from"../preact@10.5.13/hooks.js";function k(o,{delay:c},e){lets,p=_(!1),a=I(o,e);return E(()=>{(async()=>{let l=setTimeout(()=>p(!0),c);await a(),clearTimeout(l),p(!1)})()},a,c,...e),{loading:s}}var S=()=>{leto,c=h(!1),e,s=h(0),p,a=h(0),l,u=h(()=>()=>""),{loading:g}=k(async()=>{if(!o)return;let{length:r,getSnapshot:i}=await $();s(r-1),a(r-1),u(()=>i)},{delay:1e3},o);v(()=>{scrapbox.PageMenu.addItem({title:"open commit viewer",image:"https://1.bp.blogspot.com/-UZtkSEX0wh4/U5l5_dNcEsI/AAAAAAAAhWs/UzJGVzyiX8Y/s800/kaichu_dokei.png",onClick:()=>c(!0)})},[]);let t=()=>c(!1);return f` <style>
:host {
}
.background {
position: fixed;
top: 0;
right: 0;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.4);
z-index: 89999;
}
.container {
position: fixed;
top: 5px;
left: 5px;
width: calc(100% - 10px);
max-height: 80vh;
z-index: 90000;
}
.close-button {
font-size: 30px;
line-height: 1em;
padding: 0;
width: 30px;
height: 30px;
}
pre {
width: 100%;
max-height: 70vh; /* なぜか100%だとはみ出てしまった */
overflow-y: auto;
font-family: var(--history-slider-pre-font, Menlo,Monaco,Consolas,"Courier New",monospace);
word-break: break-all;
word-wrap: break-word;
white-space: pre-wrap;
}
input {
width: 90%;
}
</style>
${o&&f`
<div class="background" onClick="${t}"/>
<div class="container">
${g?"Loading...":f`
<div style="display: inline">
<input type="range" max="${e}" min="0" step="1" value="${p}"
onInput="${({target:{value:r}})=>a(r)}" />
<button class="close-button" onClick="${t}">x</button>
</div>
<pre>${l(parseInt(p,10))}</pre>
`}
</div>
`}
},m=document.createElement("div");m.dataset.userscriptName="history-slider";m.attachShadow({mode:"open"});document.body.append(m);w(f<${S} />,m.shadowRoot);var x="_insert",b="_update",y="_delete";async function $(){let o=await fetch(/api/commits/${scrapbox.Project.name}/${scrapbox.Page.id}),{commits:c}=await o.json(),e=c.flatMap(({changes:t,created:n})=>t.flatMap(r=>{let i=T(r,n);return i?[i]:[]})),s=[],p,[a,...l]=e;switch(console.debug({initChange:a,restChanges:l,changes:e}),a.type){case x:s.push(a.lines.text),p={id:a.lines.id,updatedAt:[0]};break;case b:s.push(a.lines.text),p={id:a.targetId,updatedAt:[0]};break;default:console.error("init change neither _insert nor _update")}let u=l.reduce((t,n,r)=>{let i=t.findIndex(d=>d.id===n.targetId);switch(n.type){case x:s.push(n.lines.text);let d={id:n.lines.id,updatedAt:[s.length-1]};if(n.targetId==="_end"){t.push(d);break}if(i===-1)return t;t.splice(i,0,d);break;case b:if(s.push(n.lines.text),i===-1)return t;t[i].updatedAt.push(s.length-1);break;case y:if(s.push(null),i===-1)return t;t[i].deletedAt=s.length-1;break;default:break}return t},[p]);console.debug({allHistory:u});let g=t=>u.flatMap(({updatedAt:n,deletedAt:r,id:i})=>{let d=n.filter(A=>A<=t).pop();return d===void 0||r!==void 0&&r<=t?[]:[{id:i,textIndex:d}]});return{length:s.length,getSnapshot:t=>g(t).map(n=>s[n.textIndex]).join(
`)}}function T(o,c){let e={created:c};if(o.lines&&(e.lines=o.lines),o._insert)e.type=x,e.targetId=oe.type;else if(o._update)e.type=b,e.targetId=oe.type;else if(o._delete)e.type=y,e.targetId=oe.type;else return;return e}