aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2023-11-26 10:39:15 +0000
committers-ol <s+removethis@s-ol.nu>2023-11-26 10:39:15 +0000
commit351f96fce47272b81b3852d6b97462add3f2b35b (patch)
treee1cb7278d60f585c61c40b3a8f8bbbb3e46127a6
parentreact to back button (diff)
downloadfedidag-wip.tar.gz
fedidag-wip.zip
separate out GroupContainerwip
-rw-r--r--client/src/groups.js74
-rw-r--r--client/src/index.js11
-rw-r--r--client/src/ui2.js88
3 files changed, 93 insertions, 80 deletions
diff --git a/client/src/groups.js b/client/src/groups.js
new file mode 100644
index 0000000..03f5369
--- /dev/null
+++ b/client/src/groups.js
@@ -0,0 +1,74 @@
+import { useMemo } from 'preact/hooks';
+
+export const GroupContainer = ({ items, first, render }) => {
+ const groups = useMemo(
+ () => {
+ const groupMap = Object.fromEntries(
+ Object.values(items).map(item => [
+ item.id,
+ {
+ id: item.id,
+ items: [item],
+ next: {},
+ depth: {},
+ },
+ ]),
+ );
+
+ for (const item of Object.values(items)) {
+ const parent = item.inReplyTo.length === 1 && item.inReplyTo[0].id;
+
+ if (parent && items[parent].replies.length === 1) {
+ const self = groupMap[item.id];
+ for (const s of self.items) {
+ groupMap[parent].items.push(s);
+ groupMap[s.id] = groupMap[parent];
+ }
+ }
+ }
+
+ const uniqueGroups = new Set(Object.values(groupMap));
+ const groups = {};
+ for (const group of uniqueGroups) {
+ group.next.up = group.items[0].inReplyTo.map(i => groupMap[i.id].id);
+ group.next.down = group.items[group.items.length-1].replies.map(i => groupMap[i.id].id);
+ groups[group.items[0].id] = group;
+ }
+
+ const updateDepth = (group, dir) => {
+ if (group.depth[dir] !== undefined) {
+ return group.depth[dir];
+ }
+
+ // @TODO: count nodes properly using Set,
+ // this counts nodes multiple times if subgraphs converge
+ let count = group.items.length;
+ for (const id of group.next[dir]) {
+ // go through groupMap here, since when moving 'up',
+ // were not hitting only group-headers
+ count += updateDepth(groupMap[id], dir);
+
+ if (count >= 9) {
+ count = Infinity;
+ break;
+ }
+ }
+
+ group.depth[dir] = count;
+ return count;
+ };
+
+ for (const group of Object.values(groups)) {
+ updateDepth(group, 'up');
+ updateDepth(group, 'down');
+ }
+
+ return groups;
+ },
+ [items]
+ );
+
+ first = groups[first].id;
+
+ return render({ groups, first });
+};
diff --git a/client/src/index.js b/client/src/index.js
index 4a26f66..d6ac076 100644
--- a/client/src/index.js
+++ b/client/src/index.js
@@ -3,6 +3,7 @@ import 'core-js/stable';
import 'regenerator-runtime/runtime';
import { h, Fragment, Component, render } from 'preact';
import { GraphContainer } from './graph';
+import { GroupContainer } from './groups';
//import { Menu, Discussion, Selection } from './ui';
import { Menu } from './ui/Menu';
import { Discussion } from './ui2';
@@ -123,7 +124,15 @@ if (search.has('document') || search.has('note') || search.has('graph')) {
);
}
- return <Discussion name={name} items={items} first={first} />;
+ return (
+ <GroupContainer
+ items={items}
+ first={first}
+ render={(props) => (
+ <Discussion name={name} {...props} />
+ )}
+ />
+ );
/*
return (
<SelectionContainer render={({ selection, toggleSelected }) => (
diff --git a/client/src/ui2.js b/client/src/ui2.js
index e715d4a..f79ffbb 100644
--- a/client/src/ui2.js
+++ b/client/src/ui2.js
@@ -1,5 +1,5 @@
import { h } from 'preact';
-import { useState, useEffect, useMemo } from 'preact/hooks';
+import { useState, useEffect } from 'preact/hooks';
import { TransitionGroup, CSSTransition } from 'preact-transitioning'
import cn from 'classnames';
import ColorHash from 'color-hash';
@@ -121,26 +121,24 @@ css`
const Panel = ({ id, focusDir, activePages, setActivePages, setFocus, groups, className }) => (
<div class={cn('panel', focusDir === 'this' && 'panel-focused', className)}>
<PageIndicator
- group={groups[id]}
dir="up"
+ pages={groups[id].next.up.map(pid => groups[pid])}
active={activePages.up}
focused={focusDir === 'this'}
attached={focusDir === 'up'}
setActivePage={(newId) => setActivePages({ ...activePages, up: newId })}
- groups={groups}
/>
<Group
group={groups[id]}
onClick={focusDir !== 'this' && setFocus}
/>
<PageIndicator
- group={groups[id]}
dir="down"
+ pages={groups[id].next.down.map(pid => groups[pid])}
active={activePages.down}
focused={focusDir === 'this'}
attached={focusDir === 'down'}
setActivePage={(newId) => setActivePages({ ...activePages, down: newId })}
- groups={groups}
/>
</div>
);
@@ -293,13 +291,12 @@ css`
}
`;
-const PageIndicator = ({ group: { id, next }, groups, dir, focused, active, attached, setActivePage }) => {
- const activeIndex = next[dir].indexOf(active);
+const PageIndicator = ({ pages, dir, focused, active, attached, setActivePage }) => {
+ const activeIndex = pages.findIndex(g => g.id === active);
return (
<nav class={cn('page-indicator', `page-indicator-${dir}`, attached && 'page-indicator-attached')}>
<ul>
- {next[dir].map((id, i) => {
- const target = groups[id];
+ {pages.map((target, i) => {
let num = target.depth[dir];
if (num === Infinity) num = '';
@@ -309,11 +306,11 @@ const PageIndicator = ({ group: { id, next }, groups, dir, focused, active, atta
return (
<li
key={target.id}
- class={cn(active === id && 'active')}
+ class={cn(active === target.id && 'active')}
style={{ '--offset': i - activeIndex }}
>
<button
- onClick={setActivePage ? ((e) => { e.preventDefault(); setActivePage(id); }) : null}
+ onClick={setActivePage ? ((e) => { e.preventDefault(); setActivePage(target.id); }) : null}
disabled={!focused}
style={{ '--link-color': color }}
>
@@ -359,74 +356,7 @@ article.discussion > main {
justify-content: center;
}
`
-export const Discussion = ({ name, items, first }) => {
- const groups = useMemo(
- () => {
- const groupMap = Object.fromEntries(
- Object.values(items).map(item => [
- item.id,
- {
- id: item.id,
- items: [item],
- next: {},
- depth: {},
- },
- ]),
- );
-
- for (const item of Object.values(items)) {
- const parent = item.inReplyTo.length === 1 && item.inReplyTo[0].id;
-
- if (parent && items[parent].replies.length === 1) {
- const self = groupMap[item.id];
- for (const s of self.items) {
- groupMap[parent].items.push(s);
- groupMap[s.id] = groupMap[parent];
- }
- }
- }
-
- const uniqueGroups = new Set(Object.values(groupMap));
- const groups = {};
- for (const group of uniqueGroups) {
- group.next.up = group.items[0].inReplyTo.map(i => groupMap[i.id].id);
- group.next.down = group.items[group.items.length-1].replies.map(i => groupMap[i.id].id);
- groups[group.items[0].id] = group;
- }
-
- const updateDepth = (group, dir) => {
- if (group.depth[dir] !== undefined) {
- return group.depth[dir];
- }
-
- // @TODO: count nodes properly using Set,
- // this counts nodes multiple times if subgraphs converge
- let count = group.items.length;
- for (const id of group.next[dir]) {
- // go through groupMap here, since when moving 'up',
- // were not hitting only group-headers
- count += updateDepth(groupMap[id], dir);
-
- if (count >= 9) {
- count = Infinity;
- break;
- }
- }
-
- group.depth[dir] = count;
- return count;
- };
-
- for (const group of Object.values(groups)) {
- updateDepth(group, 'up');
- updateDepth(group, 'down');
- }
-
- return groups;
- },
- [items]
- );
-
+export const Discussion = ({ name, groups, first }) => {
// save/restore focus state
const [focusId, setFocusId] = useState(() => {
const id = window.location.hash.slice(1);