@takagaki/cortex-decisions-viewer 0.12.174 → 0.12.175

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/render.js +72 -1
  2. package/package.json +1 -1
package/dist/render.js CHANGED
@@ -7795,6 +7795,13 @@ ${story_1.splitByNameLinks.toString()}
7795
7795
  (mfInflight[w.id] = mfInflight[w.id] || []).push(w.box);
7796
7796
  });
7797
7797
  if (!ids.length) return;
7798
+ mfRequest(ids, false);
7799
+ }
7800
+ /**
7801
+ * member-faces を 1 回頼む(200 人まで)。頼んだ人は mfAsked に入れ、答え(または諦め)で待っている丸を最後の形へ。
7802
+ * preload=起動時の先読み。画像もブラウザのキャッシュに載せておく
7803
+ */
7804
+ function mfRequest(ids, preload) {
7798
7805
  ids.forEach(function (id) { mfAsked[id] = 1; });
7799
7806
  var finished = false;
7800
7807
  // 答えが出た(または諦めた)人の待ち行列を空にして、全部の丸を最後の形へ
@@ -7807,7 +7814,10 @@ ${story_1.splitByNameLinks.toString()}
7807
7814
  };
7808
7815
  var give = function (j) {
7809
7816
  (j.people || []).forEach(function (one) {
7810
- if (one && typeof one.userId === "string" && typeof one.avatarUrl === "string" && MF_AVATAR.test(one.avatarUrl)) mfFaces[one.userId] = one.avatarUrl;
7817
+ if (one && typeof one.userId === "string" && typeof one.avatarUrl === "string" && MF_AVATAR.test(one.avatarUrl)) {
7818
+ mfFaces[one.userId] = one.avatarUrl;
7819
+ if (preload) mfWarm(one.avatarUrl);
7820
+ }
7811
7821
  });
7812
7822
  ids.forEach(function (id) { if (!Object.prototype.hasOwnProperty.call(mfFaces, id)) mfFaces[id] = null; });
7813
7823
  if (!finished) { finished = true; clearTimeout(giveUp); drain(); }
@@ -7827,6 +7837,39 @@ ${story_1.splitByNameLinks.toString()}
7827
7837
  else forget();
7828
7838
  }, forget);
7829
7839
  }
7840
+ /** 先読みした画像のパス -> 読み込み済み(読み込み済みなら関係者タブでスケルトンを経ずに写真から出す) */
7841
+ var mfReady = {};
7842
+ function mfWarm(path) {
7843
+ if (Object.prototype.hasOwnProperty.call(mfReady, path)) return;
7844
+ mfReady[path] = false;
7845
+ var img = new Image();
7846
+ img.setAttribute("referrerpolicy", "no-referrer");
7847
+ img.addEventListener("load", function () { mfReady[path] = true; });
7848
+ img.addEventListener("error", function () { delete mfReady[path]; });
7849
+ img.src = PORTAL_ORIGIN + path;
7850
+ }
7851
+ /**
7852
+ * 起動時に 1 回だけ、全部の関係者の portal.id を 200 人ずつ頼んで写真を先読みする(loadLiveFleet と同じ作り)。
7853
+ * 🔴 route() の後に置く(popstate は route だけ通るので、戻る/進むで何度も走らない)。券・intake が無ければ何もしない。
7854
+ * 先読みの飛行中に関係者タブを開いた丸は mfInflight に並び、先読みの答えで同じ流れ(スケルトン → 写真)に乗る。
7855
+ * 失敗は覚えない(mfRequest の forget)。タブを開いたときにもう一度頼める
7856
+ */
7857
+ function mfPreload() {
7858
+ if (!SITE.intake || !actorTicket()) return;
7859
+ var ids = [];
7860
+ (SITE.sections || []).forEach(function (sec) {
7861
+ (sec.records || []).forEach(function (r) {
7862
+ if (!isMemberRec(r)) return;
7863
+ var id = mfPortalId(r);
7864
+ if (id && ids.indexOf(id) < 0 && !Object.prototype.hasOwnProperty.call(mfAsked, id) && !Object.prototype.hasOwnProperty.call(mfFaces, id)) ids.push(id);
7865
+ });
7866
+ });
7867
+ for (var i = 0; i < ids.length; i += 200) {
7868
+ var chunk = ids.slice(i, i + 200);
7869
+ chunk.forEach(function (id) { mfAsked[id] = 1; });
7870
+ mfRequest(chunk, true);
7871
+ }
7872
+ }
7830
7873
  function mfWant(id, box) {
7831
7874
  mfWaiting.push({ id: id, box: box });
7832
7875
  if (!mfTimer) mfTimer = setTimeout(mfFlush, 0);
@@ -7869,6 +7912,32 @@ ${story_1.splitByNameLinks.toString()}
7869
7912
  });
7870
7913
  // 行ごと(カード・詳細)の click に伝えない(カードを押した扱いで詳細へ移らない)
7871
7914
  a.addEventListener("click", function (ev) { ev.stopPropagation(); });
7915
+ // 先読みで答えが分かっている人は、スケルトンを経ずに最後の形から出す(写真は読み込み済みのときだけ)
7916
+ if (Object.prototype.hasOwnProperty.call(mfFaces, id)) {
7917
+ var known = mfFaces[id];
7918
+ if (!known) {
7919
+ a.classList.remove("mface-loading");
7920
+ a.setAttribute("data-state", "initial");
7921
+ a.appendChild(el("span", { class: "mface-initial", text: name }));
7922
+ return a;
7923
+ }
7924
+ if (mfReady[known] === true) {
7925
+ var ready = document.createElement("img");
7926
+ ready.setAttribute("alt", "");
7927
+ ready.setAttribute("referrerpolicy", "no-referrer");
7928
+ ready.addEventListener("error", function () {
7929
+ // 先読みで読めていたはずの画像が壊れたとき(キャッシュ切れ・ポータル不調)も頭文字に落とす
7930
+ if (ready.parentNode) ready.parentNode.removeChild(ready);
7931
+ a.setAttribute("data-state", "initial");
7932
+ a.appendChild(el("span", { class: "mface-initial", text: name }));
7933
+ });
7934
+ ready.setAttribute("src", PORTAL_ORIGIN + known);
7935
+ a.classList.remove("mface-loading");
7936
+ a.setAttribute("data-state", "photo");
7937
+ a.appendChild(ready);
7938
+ return a;
7939
+ }
7940
+ }
7872
7941
  mfWant(id, a);
7873
7942
  return a;
7874
7943
  }
@@ -21776,6 +21845,8 @@ ${story_1.splitByNameLinks.toString()}
21776
21845
  // ビルド時には存在しないので、**焼いた href は起動の時点で既に古いことがある**。
21777
21846
  // 🔴 route() の後に置く——ヘッダー以外の導線は route() が描くまで DOM に無い
21778
21847
  syncAiLinks();
21848
+ /** 関係者の写真の先読み(mfPreload の項)。loadLiveFleet と同じく起動時に 1 回だけ */
21849
+ mfPreload();
21779
21850
  /**
21780
21851
  * 接続状況の先読み(#264)。**開いたタブに関係なく、起動時に1回だけ取りに行く。**
21781
21852
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@takagaki/cortex-decisions-viewer",
3
- "version": "0.12.174",
3
+ "version": "0.12.175",
4
4
  "description": "Cortexの意思決定記録(Decisions/*.md)を静的サイトにビルドして閲覧する。各レコードに「Edit on GitHub」リンクを付与する。",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,