参加している他のprojectに同じページがあったら教えてほしい
project横断検索でもできるが、タイトルをコピーして検索→横断検索→projectに移動→pageに移動とやや手間
ページを作るときだけじゃなくていいか
自分が参加しているprojectだけじゃなく、各自でprojectを指定できるようにしたほうがいい?
参加していないprojectも入れるなら、同じタイトルのページを取得するより、似たタイトルのページを検索した方がいい?
実装
PageMenuのボタンを押したら、検索して同名ページへのリンク一覧をItemとして出すとか?
指定したプロジェクトの同名ページをfetchし、status codeが200ならmenuにappendする?
run.js_(js)const projects = ["villagepump","hub", "shokai","nishio","rashitamemo"];
for (const project of projects) {
fetch("https://scrapbox.io/api/pages/" + project + `/${scrapbox.Page.title}`)
.then((response) => {
console.log(response.ok)
if(response.ok==true){
window.open("https://scrapbox.io/"+ project + `/${scrapbox.Page.title}`)
}
}
)
}
参加しているプロジェクトだと、ページが存在せずともtrueになって開いてしまう
404じゃないからか
status codeを利用しないで処理しよう
window.open()
きれいに1つずつ開けない気がする
2つ以上開いてしまうことがある
run.js__(js)const projects = ["villagepump", "hub", "shokai", "nishio", "rashitamemo"];
for (const project of projects) {
fetch(`https://scrapbox.io/api/pages/${project}/${scrapbox.Page.title}`)
.then((body) => body.json())
.then((data) => {
console.log(data.lines.length);
if (data.lines.length != 1) {
window.open(`https://scrapbox.io/${project}/${scrapbox.Page.title}`);
}
});
}
linesが0なら開かない
お、ロジックはできたぞ
エラーがいろいろ出ているが
page menuにappendするか?
run.jsconst projects = ["villagepump", "hub", "shokai", "nishio", "rashitamemo"];
scrapbox.PageMenu.addMenu({
title: "OtherProjects",
image: "https://gyazo.com/676238d800a673a77be27d8c310e2d24/raw",
});
for (const project of projects) {
fetch(`/api/pages/${project}/${scrapbox.Page.title}`)
.then((body) => body.json())
.then((data) => {
console.log(data.lines.length);
if (data.lines.length != 1) {
scrapbox.PageMenu("OtherProjects").addItem({
title: () => `/${project}/${scrapbox.Page.title}`,
onClick: () =>
window.open(
`https://scrapbox.io/${project}/${scrapbox.Page.title}`
),
});
}
});
}
今度は押したときに実行するようにするか
手直ししてみた
response.ok
と行数で判断する
押すたびにページを取得し直す
fetch
を待たない
参加しているprojectすべてから検索する
試し方
js(async () => {
const {execute} = await import('/api/code/programming-notes/参加している他のprojectに同じページがあったら教えてほしい/run2.js');
execute(["villagepump", "hub", "shokai", "nishio", "rashitamemo"]);
})();
run2.jsconst id = "OtherProjects";
export async function execute(extraProjects = []) {
const response = await fetch('/api/projects');
const json = await response.json();
run2.js const projects = [...new Set([
...extraProjects,
...json.projects.map(({name}) => name),
])
].filter(project => project !== scrapbox.Project.name); // 現在のprojectは除く
scrapbox.PageMenu.addMenu({
title: id,
image: "https://gyazo.com/676238d800a673a77be27d8c310e2d24/raw",
onClick: async () => {
const menu = scrapbox.PageMenu(id);
menu.removeAllItems();
menu.emitChange();
const isFound = await Promise.all(projects.map(project => addItem(project, menu)));
if (isFound.some(i => i)) return;
menu.addItem({ title: 'No page found.', onClick: () => {} });
},
});
}
forEachはPromiseを待ってくれないことを利用?
for
loopでも同じことできます
.jsfor (const project of projects) {
addItem(project);
}
特に待つ必要もないので、
await
しなかっただけです
ヒットするページでクリックした後、ヒットしないページでクリックすると、前のページでの結果が残ったままになる
仕様なのか…?
emitChange()を追加したら直った
調査していただき感謝です
変だなあと思いつつ放置してた
確かに直感とは違う挙動ではある
1つもヒットしなかったら「見つかりませんでした」的なことを表示するにはどうしたらいいんだろう
すぐ思いつくのは、DOMの数を数える方法
もしかしたらitemsを数えるためのmethodがあるかもしれない
smartphoneからcodingすることになるとは考えもしなかった
つよすぎ
ちょっとした修正なら簡単(狂気)
動いた
consoleに404が何個も出てしまうのが気になるかも
extraProjectにページが存在しない時に出る
run2.jsasync function addItem(project, menu) {
const response = await fetch(`/api/pages/${project}/${scrapbox.Page.title}`);
if (!response.ok) return false;
const {lines} = await response.json();
//console.log(lines);
if (lines.length < 3 && !lines[1]?.text) return false; // タイトルを除いて1行以内かつ1行目が空のとき、空ページだと判断する
menu.addItem({
title: `/${project}/${scrapbox.Page.title}`,
onClick: () =>
window.open(
`https://scrapbox.io/${project}/${scrapbox.Page.title}`
),
});
return true;
}