script.jsimport {makeSprint} from '/api/code/takker/takker-sprint_template/makeSprint.js';
const zero = n => String(n).padStart(2, '0');
const toYYYYMMDD = d => `${d.getFullYear()}-${zero(d.getMonth() + 1)}-${zero(d.getDate())}`;
const toHHMM = d => `${zero(d.getHours())}:${zero(d.getMinutes())}`;
const modalId = 'takker-add-task-window';
const confirmId = 'confirmBtn';
const projectName = scrapbox.Project.name;
export default async function() {
const modal = new ModalWindow();
await modal.create();
modal.show();
}
class ModalWindow {
constructor() {
this.modal = document.getElementById(modalId);
this.confirm = document.getElementById(confirmId);
this.nameBox = undefined;
this.dateBox = undefined;
this.timeBox = undefined;
this.checkBox = undefined;
}
// create the modal window
async create() {
if (this.modal) return;
const div = document.createElement('div');
div.innerHTML =
`<dialog id="takker-add-task-window">
<form method="dialog">
<p><label>
task name:
<input type="text" value="" />
</label></p>
<p><label>
date:
<input type="date" />
</label></p>
<p><label>
time:
<input type="time" value="00:00" />
</label></p>
<p><label>
make collecting task:
<input type="checkbox" checked />
</label></p>
<menu>
<button value="cancel">Cancel</button>
<button id="confirmBtn" value="{}">Confirm</button>
</menu>
</form>
</dialog>`;
document.body.appendChild(div);
this.modal = document.getElementById(modalId);
this.confirm = document.getElementById(confirmId);
this.nameBox = this.modal.querySelector('input[type="text"]');
this.dateBox = this.modal.querySelector('input[type="date"]');
this.timeBox = this.modal.querySelector('input[type="time"]');
this.checkBox = this.modal.querySelector('input[type="checkbox"]');
this._reset();
this.nameBox.addEventListener('change', () => {
let value = this._json;
value.name = this.nameBox.value;
this._json = value;
});
this.dateBox.addEventListener('change', () => {
let value = this._json;
const [year, month, date] = this.dateBox.value.split('-');
value.year = year;
value.month = month;
value.date = date;
this._json = value;
});
this.timeBox.addEventListener('change', () => {
let value = this._json;
const [hour, minute] = this.timeBox.value.split(':');
value.hour = hour;
value.minute = minute;
this._json = value;
});
this.modal.addEventListener('close', () => {
if (this.modal.returnValue === "cancel") return;
const result = this._json;
makeMainTask(result);
if (this._checked) {
makeCollectingTask(result);
makeSprint([` [🔳${result.name}]`, ` [🔳情報集め | ${result.name}]`]);
} else {
makeSprint([` [🔳${result.name}]`]);
}
this._reset();
});
}
show() {
this.modal.showModal();
}
get _checked() {
return this.checkBox.checked;
}
_reset() {
// 初期化
const today = new Date();
this.nameBox.value = ` | ${scrapbox.Page.title.replace(/^(🔳|✅)(.*)$/, '$2')}`; // Scriptを発動したページのタイトルが含まれるようにする
this.dateBox.value = toYYYYMMDD(today);
this.timeBox.value = '00:00';
this._json = {
name: this.nameBox.value,
year: today.getFullYear(),
month: today.getMonth()+1,
date: today.getDate(),
hour: '00', minute: '00'};
}
get _json() {
//console.log(`data: ${this.confirm.value}`);
const temp = JSON.parse(this.confirm.value) ?? undefined;
return {name: temp.name,year: temp.year,month: temp.month,
date: temp.date, hour: temp.hour,minute: temp.minute};
}
set _json({name,year,month,date,hour,minute}) {
this.confirm.value = JSON.stringify({name,year,month,date,hour,minute});
}
dispose() {
const div = this.modal.parentNode;
div.parentNode.removeChild(div);
}
}
function makeMainTask({name,year,month,date,hour,minute}) {
const e = array => encodeURIComponent(array.join('\n'));
const deadline = new Date(year, month - 1, date, hour, minute, 0);
const toTimestamp = d => `[${toYYYYMMDD(d)}] ${toHHMM(d)}`;
const now = new Date();
const todayStr = (d => `${toYYYYMMDD(d)} ${toHHMM(d)}`)(now);
// main task page
const lines = [
'',
'',
'やること',
' ',
'',
'期日',
` ${toTimestamp(deadline)}`,
'',
`#${todayStr}`];
const title = `🔳${name}`;
window.open(`https://scrapbox.io/${projectName}/${title}?body=${e(lines)}`);
}
// 情報集め task page
function makeCollectingTask({name,year,month,date,hour,minute}) {
const e = array => encodeURIComponent(array.join('\n'));
const deadline = new Date(year, month - 1, date, hour, minute, 0);
const toTimestamp = d => `[${toYYYYMMDD(d)}] ${toHHMM(d)}`;
const now = new Date();
const todayStr = (d => `${toYYYYMMDD(d)} ${toHHMM(d)}`)(now);
// 期日までの残り時間を計算
const duration = deadline.getTime() - now.getTime();
const length = duration < 0 ? 0 :
duration / (24*3600*1000) < 1.0 ?
// 一日を切っていたら、残り時間の5%に設定する
duration * 0.05 :
24*3600*1000;
let infoDeadline = new Date();
infoDeadline.setTime(now.getTime() + length);
const lines = [
`[🔳${name}]を実行するための情報を集める`,
'',
'やること',
' ',
'',
'期日',
` ${toTimestamp(infoDeadline)}`,
'',
`#${todayStr}`];
const title = `🔳情報集め | ${name}`;
window.open(`https://scrapbox.io/${projectName}/${title}?body=${e(lines)}`);
}