@gperezmz/bb-plugin-thread-glance 0.2.0 → 0.2.1

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.
@@ -3,7 +3,7 @@
3
3
  "sdkVersion": "0.5.9",
4
4
  "artifactFormatVersion": 1,
5
5
  "pluginId": "thread-glance",
6
- "pluginVersion": "0.2.0",
6
+ "pluginVersion": "0.2.1",
7
7
  "builtWith": {
8
8
  "bbVersion": "0.43.4",
9
9
  "pluginSdkVersion": "0.5.9"
@@ -1,11 +1,11 @@
1
- // Which family Needs you holds while one of its threads is open. Diffed
1
+ // Which family Needs you holds, and which family is open, while one of its threads is open. Diffed
2
2
  // render to render, as auto-expansion is; nothing here is persisted.
3
3
  import { useRef } from "react";
4
4
  import type { Forest } from "../model/families";
5
- import { holdNeedsYou } from "../model/needs-you";
5
+ import { holdNeedsYou, NO_HOLD, type NeedsYouHold } from "../model/needs-you";
6
6
 
7
7
  export function useNeedsYouHold(forest: Forest | null, activeThreadId: string | null): string | null {
8
- const held = useRef<string | null>(null);
8
+ const held = useRef<NeedsYouHold>(NO_HOLD);
9
9
  const lastForest = useRef<Forest | null>(null);
10
10
  const lastActive = useRef<string | null | undefined>(undefined);
11
11
  // Derived during render, so the family never leaves for a frame. Idempotent:
@@ -15,5 +15,5 @@ export function useNeedsYouHold(forest: Forest | null, activeThreadId: string |
15
15
  lastForest.current = forest;
16
16
  lastActive.current = activeThreadId;
17
17
  }
18
- return held.current;
18
+ return held.current.heldRootId;
19
19
  }
@@ -249,7 +249,9 @@ export function buildForest(inputs: ForestInputs): Forest {
249
249
  if (info.needsYou.size > 0) quiet = quietIgnoringOpen = false;
250
250
  } else {
251
251
  if (!info.quiet) quiet = false;
252
- if (!isQuietThread(info.state, info.unread, false)) quietIgnoringOpen = false;
252
+ // A child reads as its own fold does, so with `blocked` an unread child
253
+ // does not keep an old family out of the group's fold.
254
+ if (!info.quietIgnoringOpen) quietIgnoringOpen = false;
253
255
  }
254
256
  }
255
257
  const flags = new Set<Flag>(descendantFlags);
@@ -92,21 +92,42 @@ export function revealsOn(needsYou: ReadonlySet<Flag>, isRoot: boolean): boolean
92
92
  /** What the section reads of a family. */
93
93
  type SectionFamily = Pick<Family, "root" | "needsYouFlags">;
94
94
 
95
+ /** What Needs you remembers between renders: the family it holds, and the family that was open. */
96
+ export interface NeedsYouHold {
97
+ /** The root of the family held in the section, if any. */
98
+ heldRootId: string | null;
99
+ /** The root of the family the open thread belonged to at the last render, if any. */
100
+ openRootId: string | null;
101
+ }
102
+
103
+ export const NO_HOLD: NeedsYouHold = { heldRootId: null, openRootId: null };
104
+
95
105
  /**
96
- * Whether a family is in the Needs you section: one of its threads needs
97
- * you, or it is the family the section holds while one of its threads is open.
106
+ * Whether a family is in the Needs you section: it is the held family, or one
107
+ * of its threads needs you and none of them is open. Nothing moves while you
108
+ * are inside a family, so the open family only enters by being judged when
109
+ * opened (see `holdNeedsYou`).
98
110
  */
99
- export function inNeedsYou(family: SectionFamily, heldRootId: string | null): boolean {
100
- return family.needsYouFlags.size > 0 || family.root.thread.id === heldRootId;
111
+ export function inNeedsYou(family: SectionFamily, heldRootId: string | null, openRootId: string | null): boolean {
112
+ const rootId = family.root.thread.id;
113
+ if (rootId === heldRootId) return true;
114
+ return family.needsYouFlags.size > 0 && rootId !== openRootId;
101
115
  }
102
116
 
103
117
  /**
104
- * The family Needs you holds after a render, by its root's id: the open
105
- * thread's family, when it needs you now or was already held. Held, it stays
106
- * in the section after nothing in it needs you, until a thread outside it is
107
- * opened; a family that never needed you is not pulled in by opening it.
118
+ * The hold after a render. A family is judged when a thread in it is opened
119
+ * from outside it: it is held if something in it needs you then, and it stays
120
+ * held while one of its threads is open, after nothing in it needs you any
121
+ * more, until a thread outside it is opened. A family that does not need you
122
+ * when opened is not pulled in later, whatever happens in it; nor is one
123
+ * that never needed you. Opening another thread of the open family judges
124
+ * nothing again.
108
125
  */
109
- export function holdNeedsYou(previous: string | null, openFamily: SectionFamily | undefined): string | null {
110
- if (openFamily === undefined) return null;
111
- return inNeedsYou(openFamily, previous) ? openFamily.root.thread.id : null;
126
+ export function holdNeedsYou(previous: NeedsYouHold, openFamily: SectionFamily | undefined): NeedsYouHold {
127
+ if (openFamily === undefined) return NO_HOLD;
128
+ const openRootId = openFamily.root.thread.id;
129
+ if (openRootId === previous.openRootId) {
130
+ return { heldRootId: previous.heldRootId === openRootId ? openRootId : null, openRootId };
131
+ }
132
+ return { heldRootId: openFamily.needsYouFlags.size > 0 ? openRootId : null, openRootId };
112
133
  }
@@ -599,6 +599,7 @@ export function buildListView(inputs: ViewInputs): ListView {
599
599
  const byGroup = new Map<string, Family[]>();
600
600
  const homeOf = new Map<Family, string>();
601
601
  const section: Family[] = [];
602
+ const openRootId = inputs.activeThreadId === null ? null : (forest.familyOf.get(inputs.activeThreadId)?.root.thread.id ?? null);
602
603
  for (const family of forest.families) {
603
604
  const id = groupIdForRoot(family.root.thread, {
604
605
  mode: prefs.organizationMode,
@@ -608,7 +609,7 @@ export function buildListView(inputs: ViewInputs): ListView {
608
609
  list.push(family);
609
610
  byGroup.set(id, list);
610
611
  homeOf.set(family, id);
611
- if (inNeedsYou(family, inputs.heldRootId)) section.push(family);
612
+ if (inNeedsYou(family, inputs.heldRootId, openRootId)) section.push(family);
612
613
  }
613
614
  const inSection = new Set(section);
614
615
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gperezmz/bb-plugin-thread-glance",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "bb": ">=0.43",