@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.
- package/dist/app.js +29 -29
- package/dist/app.meta.json +1 -1
- package/dist/server.js.map +1 -1
- package/dist/server.meta.json +1 -1
- package/features/thread-list/data/useNeedsYouHold.ts +4 -4
- package/features/thread-list/model/families.ts +3 -1
- package/features/thread-list/model/needs-you.ts +32 -11
- package/features/thread-list/model/view.ts +2 -1
- package/package.json +1 -1
package/dist/server.meta.json
CHANGED
|
@@ -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<
|
|
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
|
-
|
|
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:
|
|
97
|
-
*
|
|
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
|
-
|
|
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
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
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:
|
|
110
|
-
if (openFamily === undefined) return
|
|
111
|
-
|
|
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
|
|