diff --git a/pkg/interface/src/logic/api/graph.ts b/pkg/interface/src/logic/api/graph.ts index 28387e34e1..4881d113b3 100644 --- a/pkg/interface/src/logic/api/graph.ts +++ b/pkg/interface/src/logic/api/graph.ts @@ -4,7 +4,7 @@ import { Patp, Path, PatpNoSig } from '~/types/noun'; import _ from 'lodash'; import {makeResource, resourceFromPath} from '../lib/group'; import {GroupPolicy, Enc, Post, NodeMap, Content} from '~/types'; -import { numToUd, unixToDa } from '~/logic/lib/util'; +import { numToUd, unixToDa, decToUd } from '~/logic/lib/util'; export const createBlankNodeWithChildPost = ( parentIndex: string = '', @@ -263,6 +263,28 @@ export default class GraphApi extends BaseApi { }); } + async getNewest(ship: string, resource: string, count: number, index = '') { + const data = await this.scry('graph-store', `/newest/${ship}/${resource}/${count}${index}`); + this.store.handleEvent({ data }); + } + + async getOlderSiblings(ship: string, resource: string, count: number, index = '') { + const idx = index.split('/').map(decToUd).join('/'); + const data = await this.scry('graph-store', + `/node-siblings/older/${ship}/${resource}/${count}${idx}` + ); + this.store.handleEvent({ data }); + } + + async getYoungerSiblings(ship: string, resource: string, count: number, index = '') { + const idx = index.split('/').map(decToUd).join('/'); + const data = await this.scry('graph-store', + `/node-siblings/younger/${ship}/${resource}/${count}${idx}` + ); + this.store.handleEvent({ data }); + } + + getGraphSubset(ship: string, resource: string, start: string, end: string) { return this.scry( 'graph-store', diff --git a/pkg/interface/src/logic/reducers/graph-update.js b/pkg/interface/src/logic/reducers/graph-update.js index d5884b4fef..2cfd48f4d8 100644 --- a/pkg/interface/src/logic/reducers/graph-update.js +++ b/pkg/interface/src/logic/reducers/graph-update.js @@ -123,7 +123,9 @@ const addNodes = (json, state) => { if (!('graphs' in state)) { return; } let resource = data.resource.ship + '/' + data.resource.name; - if (!(resource in state.graphs)) { return; } + if (!(resource in state.graphs)) { + state.graphs[resource] = new BigIntOrderedMap(); + } for (let i in data.nodes) { let item = data.nodes[i]; diff --git a/pkg/interface/src/views/apps/chat/ChatResource.tsx b/pkg/interface/src/views/apps/chat/ChatResource.tsx index 18d4762165..f9364f27f6 100644 --- a/pkg/interface/src/views/apps/chat/ChatResource.tsx +++ b/pkg/interface/src/views/apps/chat/ChatResource.tsx @@ -66,7 +66,7 @@ export function ChatResource(props: ChatResourceProps) { const chatInput = useRef(); useEffect(() => { - props.api.graph.getGraph(owner,name); + props.api.graph.getNewest(owner, name, 10); }, [station]); const onFileDrag = useCallback( diff --git a/pkg/interface/src/views/apps/chat/components/ChatInput.tsx b/pkg/interface/src/views/apps/chat/components/ChatInput.tsx index 8a0cf316f3..a9b70a66b4 100644 --- a/pkg/interface/src/views/apps/chat/components/ChatInput.tsx +++ b/pkg/interface/src/views/apps/chat/components/ChatInput.tsx @@ -58,29 +58,6 @@ export default class ChatInput extends Component }); } - getLetterType(letter) { - if (letter.startsWith('/me ')) { - letter = letter.slice(4); - // remove insignificant leading whitespace. - // aces might be relevant to style. - while (letter[0] === '\n') { - letter = letter.slice(1); - } - - return { - me: letter - }; - } else if (isUrl(letter)) { - return { - url: letter - }; - } else { - return { - text: letter - }; - } - } - submit(text) { const { props, state } = this; const [,,ship,name] = props.station.split('/'); diff --git a/pkg/interface/src/views/apps/chat/components/ChatWindow.tsx b/pkg/interface/src/views/apps/chat/components/ChatWindow.tsx index c364383517..dacab1d660 100644 --- a/pkg/interface/src/views/apps/chat/components/ChatWindow.tsx +++ b/pkg/interface/src/views/apps/chat/components/ChatWindow.tsx @@ -58,6 +58,8 @@ export default class ChatWindow extends Component; private prevSize = 0; + private loadedNewest = false; + private loadedOldest = false; INITIALIZATION_MAX_TIME = 1500; @@ -80,12 +82,12 @@ export default class ChatWindow extends Component { if(this.props.scrollTo) { this.scrollToUnread(); @@ -111,26 +113,6 @@ export default class ChatWindow extends Component 0) { - const start = Math.min(mailboxSize - unreadCount, mailboxSize - DEFAULT_BACKLOG_SIZE); - this.stayLockedIfActive(); - this.fetchMessages(start, start + DEFAULT_BACKLOG_SIZE, true).then(() => { - if (!this.virtualList) return; - this.setState({ idle: false }); - this.setState({ initialized: true }); - this.dismissIfLineVisible(); - }); - } else { - setTimeout(() => { - this.initialFetch(); - }, 2000); - } - */ - } - componentDidUpdate(prevProps: ChatWindowProps, prevState) { const { isChatMissing, history, graph, unreadCount, station } = this.props; @@ -151,9 +133,6 @@ export default class ChatWindow extends Component { - start = Math.max(start, 0); - end = Math.max(end, 0); - const { api, mailboxSize, station } = this.props; + async fetchMessages(newer: boolean, force = false): Promise { + const { api, station, graph } = this.props; - if ( - (this.state.fetchPending || - mailboxSize <= 0) - && !force - ) { - return new Promise((resolve, reject) => {}); + if ( this.state.fetchPending && !force) { + return new Promise((resolve, reject) => {}); } this.setState({ fetchPending: true }); - start = Math.min(mailboxSize - start, mailboxSize); - end = Math.max(mailboxSize - end, 0, start - MAX_BACKLOG_SIZE); + const [,, ship, name] = station.split('/'); + const currSize = graph.size; + if(newer && !this.loadedNewest) { + const [index] = graph.peekLargest()!; + await api.graph.getYoungerSiblings(ship,name, 5, `/${index.toString()}`) + if(currSize === graph.size) { + console.log('loaded all newest'); + this.loadedNewest = true; + } + } else if(!newer && !this.loadedOldest) { + const [index] = graph.peekSmallest()!; + await api.graph.getOlderSiblings(ship,name, 5, `/${index.toString()}`) + if(currSize === graph.size) { + console.log('loaded all oldest'); + this.loadedOldest = true; + } + } + this.setState({ fetchPending: false }); - return api.chat - .fetchMessages(end, start, station) - .finally(() => { - this.setState({ fetchPending: false }); - }); } onScroll({ scrollTop, scrollHeight, windowHeight }) { @@ -319,8 +303,8 @@ export default class ChatWindow extends Component ); }} - loadRows={(start, end) => { - this.fetchMessages(start.toJSNumber(), end.toJSNumber()); + loadRows={(newer) => { + this.fetchMessages(newer); }} /> diff --git a/pkg/interface/src/views/apps/chat/components/content/text.js b/pkg/interface/src/views/apps/chat/components/content/text.js index f616de3a18..c7da104e0a 100644 --- a/pkg/interface/src/views/apps/chat/components/content/text.js +++ b/pkg/interface/src/views/apps/chat/components/content/text.js @@ -28,6 +28,9 @@ const renderers = { inlineCode: ({language, value}) => { return {value} }, + paragraph: ({ children }) => { + return ({children}); + }, code: ({language, value}) => { return ; renderer: (props: RendererProps) => JSX.Element | null; onStartReached?(): void; @@ -69,7 +69,7 @@ export default class VirtualScroller extends Component this.heightOf(index))); - //const list = [...data]; - //console.log(list[0][0].toString()); - // console.log(list[list.length - 1][0].toString()); [...data].forEach(([index, datum]) => { const height = this.heightOf(index); if (startgap < scrollTop && !startGapFilled) { - console.log(index.toString()); startBuffer.set(index, datum); startgap += height; } else if (heightShown < windowHeight) { @@ -164,31 +159,26 @@ export default class VirtualScroller extends Component { startgap -= this.heightOf(index); }); - console.log(startBuffer.size); - console.log(startgap); - const firstVisibleKey = visibleItems.peekLargest()?.[0] ?? this.estimateIndexFromScrollTop(scrollTop)!; - const firstNeededKey = bigIntUtils.max(firstVisibleKey.subtract(bigInt(this.OVERSCAN_SIZE)), bigInt.zero) - if (!data.has(firstNeededKey.add(bigInt.one))) { - this.loadRows(firstNeededKey, firstVisibleKey.subtract(bigInt.one)); + const firstVisibleKey = visibleItems.peekSmallest()?.[0] ?? this.estimateIndexFromScrollTop(scrollTop)!; + if (data.peekSmallest()![0].eq(firstVisibleKey)) { + this.loadRows(false); } const lastVisibleKey = - visibleItems.peekSmallest()?.[0] + visibleItems.peekLargest()?.[0] ?? bigInt(this.estimateIndexFromScrollTop(scrollTop + windowHeight)!); - const lastNeededKey = bigIntUtils.min(lastVisibleKey.add(bigInt(this.OVERSCAN_SIZE)), bigInt(totalSize)); - if (!data.has(lastNeededKey.subtract(bigInt.one))) { - this.loadRows(lastVisibleKey.add(bigInt.one), lastNeededKey); + if (data.peekLargest()![0].eq(lastVisibleKey)) { + this.loadRows(true); } onCalculateVisibleItems ? onCalculateVisibleItems(visibleItems) : null; this.setState({ @@ -198,25 +188,8 @@ export default class VirtualScroller extends Component { - if (!this.pendingLoad) return; - start = bigIntUtils.max(this.pendingLoad.start, bigInt.zero); - end = bigIntUtils.min(bigIntUtils.max(this.pendingLoad.end, bigInt.zero), bigInt(this.props.size)); - if (start < end) { - this.props.loadRows(start, end); - } - clearTimeout(this.pendingLoad.timeout); - this.pendingLoad = undefined; - }, 500), - start, end - }; + loadRows(newer: boolean) { + this.props.loadRows(newer); } scrollKeyMap(): Map {