Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Without virtualisation #266

Merged
merged 14 commits into from
Jan 26, 2025
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 43 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@
"@mui/icons-material": "^5.14.16",
"@mui/material": "^5.14.20",
"@mui/styles": "^5.14.20",
"@tanstack/react-query": "^5.61.4",
"@tanstack/react-query": "^5.64.1",
"@yornaath/batshit": "^0.10.1",
"ag-grid-community": "^31.0.2",
"ag-grid-react": "^31.0.3",
"fuse.js": "^7.0.0",
"iso-web": "^1.0.6",
"p-queue": "8.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.28.0"
Expand Down
17 changes: 15 additions & 2 deletions src/api/lists.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { unwrapShortHandle } from '.';
import { fetchClearskyApi, unwrapClearskyURL } from './core';
import { useResolveHandleOrDid } from './resolve-handle-or-did';
import { useInfiniteQuery, useQuery } from '@tanstack/react-query';
import PQueue from 'p-queue';

const PAGE_SIZE = 100;

Expand Down Expand Up @@ -86,7 +87,6 @@ async function getList(shortHandle, currentPage = 1) {
*/
async function getListTotal(shortHandle) {
const handleURL = 'get-list/total/' + unwrapShortHandle(shortHandle);

/** @type {{ data: { count: number; pages: number } }} */
const re = await fetchClearskyApi('v1', handleURL);
return re.data;
Expand All @@ -101,7 +101,9 @@ async function getListSize(listUrl) {
const apiUrl = unwrapClearskyURL(
`/api/v1/anon/get-list/specific/total/${encodeURIComponent(listUrl)}`
);
const resp = await fetch(apiUrl);
const resp = await listSizeQueue.add(() => fetch(apiUrl), {
throwOnTimeout: true,
});
if (resp.ok) {
/** @type {{ data: { count: number }, list_uri: string }} */
const respData = await resp.json();
Expand All @@ -112,3 +114,14 @@ async function getListSize(listUrl) {
}
throw new Error('getListSize error: ' + resp.statusText);
}

/**
* create a queue where only one request can be in flight at a time,
* and at most 1 may be sent in any 500 millisecond interval
*/
const listSizeQueue = new PQueue({
concurrency: 1,
intervalCap: 1,
interval: 500,
timeout: 500,
});
2 changes: 1 addition & 1 deletion src/common-components/account-short-entry.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ function getAvatarDelay(account) {
const rnd = Math.abs(hash) - Math.floor(Math.abs(hash));
delay = (rnd * 40).toFixed(3) + 's';
avatarDelays[avatarUrl] = delay;
console.log('Avatar delay', account.shortHandle, { delay, hash, rnd });
//console.log('Avatar delay', account.shortHandle, { delay, hash, rnd });
return delay;
}

Expand Down
20 changes: 13 additions & 7 deletions src/detail-panels/lists/list-view.css
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
.lists-as-list-view {
margin: 0;
padding: 0
padding: 0;
}

.lists-as-list-view .lists-entry {
list-style-type: none;
height: 3.5em;
height: auto;
border-top: solid 1px #dbdbdb;
padding-top: 0.4em;
padding-left: 0.7em;
Expand Down Expand Up @@ -39,15 +39,21 @@
.lists-as-list-view .lists-entry .list-name {
grid-row: 1/ 2;
grid-column: 1 / 2;
padding-left: 1.7em;
padding-left: 0.5em;
font-weight: bold;
}

.lists-as-list-view .lists-entry .list-description {
grid-row: 1 / 2;
grid-column: 2 / 3;
opacity: 0.6;
overflow: hidden;
text-overflow: ellipsis;
padding-left: 0.5em;
}
padding-left: 1.7em;
white-space: normal;
word-wrap: break-word;
}

.lists-as-list-view .lists-entry .list-count {
padding-left: 0.3em;
color: green;
}

45 changes: 30 additions & 15 deletions src/detail-panels/lists/list-view.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// @ts-check

import { CircularProgress } from '@mui/material';
import { AccountShortEntry } from '../../common-components/account-short-entry';
import { FormatTimestamp } from '../../common-components/format-timestamp';

import { useListSize } from '../../api/lists';
import './list-view.css';

/**
Expand All @@ -15,9 +16,7 @@ export function ListView({ className, list }) {
return (
<ul className={'lists-as-list-view ' + (className || '')}>
{(list || []).map((entry, i) => (
<ListViewEntry
key={i}
entry={entry} />
<ListViewEntry key={i} entry={entry} style={{}} />
))}
</ul>
);
Expand All @@ -26,31 +25,47 @@ export function ListView({ className, list }) {
/**
* @param {{
* className?: string,
* entry: AccountListEntry
* entry: AccountListEntry,
* style:any
* }} _
*/
function ListViewEntry({ className, entry }) {
export function ListViewEntry({ className, entry, style }) {
const { data: sizeData, isLoading } = useListSize(entry?.url);
const count = sizeData?.count || '';

return (
<li className={'lists-entry ' + (className || '')}>
<div className='row'>
<div className="row">
<AccountShortEntry
className='list-owner'
className="list-owner"
withDisplayName
account={entry.did}
/>
<FormatTimestamp
timestamp={entry.date_added}
noTooltip
className='list-add-date' />
className="list-add-date"
/>
</div>
<div className='row'>
<span className='list-name'>
{entry.name}
<div className="row">
<span className="list-name">
<a href={entry.url} target="__blank">
{entry.name}
</a>
</span>
<span className='list-description'>
{entry.description && ' ' + entry.description}
<span className="list-count">
{isLoading ? (
<CircularProgress color="inherit" size="0.75em" />
) : (
count
)}
</span>
</div>
{entry.description && (
<div className="row">
<span className="list-description">{' ' + entry.description}</span>
</div>
)}
</li>
);
}
}
Loading