mirror of
https://github.com/PrimalHQ/primal-web-app.git
synced 2024-10-01 17:31:13 +00:00
Add reaction pagination and adjust width
This commit is contained in:
parent
6bf10e83a1
commit
ce6a3c567d
@ -1,6 +1,6 @@
|
||||
.ReactionsModal {
|
||||
position: fixed;
|
||||
width: 432px;
|
||||
width: 632px;
|
||||
color: var(--text-primary);
|
||||
background-color: var(--background-input);
|
||||
border-radius: 8px;
|
||||
@ -157,7 +157,7 @@
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
line-height: 16px;
|
||||
max-width: 248px;
|
||||
max-width: 448px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
@ -223,7 +223,7 @@
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
line-height: 16px;
|
||||
max-width: 248px;
|
||||
max-width: 448px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
@ -279,7 +279,7 @@
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
line-height: 16px;
|
||||
max-width: 248px;
|
||||
max-width: 448px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
@ -3,28 +3,21 @@ import { Tabs } from '@kobalte/core';
|
||||
import { A } from '@solidjs/router';
|
||||
import { Component, createEffect, createSignal, For, Show } from 'solid-js';
|
||||
import { createStore } from 'solid-js/store';
|
||||
import { style } from 'solid-js/web';
|
||||
import { APP_ID } from '../../App';
|
||||
import { defaultZapOptions, Kind } from '../../constants';
|
||||
import { useAccountContext } from '../../contexts/AccountContext';
|
||||
import { Kind } from '../../constants';
|
||||
import { ReactionStats } from '../../contexts/AppContext';
|
||||
import { useSettingsContext } from '../../contexts/SettingsContext';
|
||||
import { hookForDev } from '../../lib/devTools';
|
||||
import { hexToNpub } from '../../lib/keys';
|
||||
import { getEventReactions } from '../../lib/notes';
|
||||
import { truncateNumber } from '../../lib/notifications';
|
||||
import { zapNote, zapProfile } from '../../lib/zap';
|
||||
import { subscribeTo } from '../../sockets';
|
||||
import { userName } from '../../stores/profile';
|
||||
import { toastZapFail, zapCustomOption, actions as tActions, placeholders as tPlaceholders, zapCustomAmount } from '../../translations';
|
||||
import { PrimalNote, PrimalUser, ZapOption } from '../../types/primal';
|
||||
import { actions as tActions, placeholders as tPlaceholders } from '../../translations';
|
||||
import { parseBolt11 } from '../../utils';
|
||||
import Avatar from '../Avatar/Avatar';
|
||||
import ButtonPrimary from '../Buttons/ButtonPrimary';
|
||||
import Loader from '../Loader/Loader';
|
||||
import Modal from '../Modal/Modal';
|
||||
import TextInput from '../TextInput/TextInput';
|
||||
import { useToastContext } from '../Toaster/Toaster';
|
||||
import Paginator from '../Paginator/Paginator';
|
||||
import VerificationCheck from '../VerificationCheck/VerificationCheck';
|
||||
|
||||
import styles from './ReactionsModal.module.scss';
|
||||
@ -44,18 +37,22 @@ const ReactionsModal: Component<{
|
||||
const [zapList, setZapList] = createStore<any[]>([]);
|
||||
const [repostList, setRepostList] = createStore<any[]>([]);
|
||||
|
||||
const [isFetching, setIsFetching] = createSignal(false)
|
||||
const [isFetching, setIsFetching] = createSignal(false);
|
||||
|
||||
let loadedLikes = 0;
|
||||
let loadedZaps = 0;
|
||||
let loadedReposts = 0;
|
||||
|
||||
createEffect(() => {
|
||||
switch (selectedTab()) {
|
||||
case 'likes':
|
||||
getLikes();
|
||||
loadedLikes === 0 && getLikes();
|
||||
break;
|
||||
case 'zaps':
|
||||
getZaps();
|
||||
loadedZaps === 0 && getZaps();
|
||||
break;
|
||||
case 'reposts':
|
||||
getReposts();
|
||||
loadedReposts === 0 && getReposts();
|
||||
break;
|
||||
}
|
||||
});
|
||||
@ -69,7 +66,7 @@ const ReactionsModal: Component<{
|
||||
}
|
||||
});
|
||||
|
||||
const getLikes = () => {
|
||||
const getLikes = (offset = 0) => {
|
||||
if (!props.noteId) return;
|
||||
|
||||
const subId = `nr_l_${props.noteId}_${APP_ID}`;
|
||||
@ -78,7 +75,8 @@ const ReactionsModal: Component<{
|
||||
|
||||
const unsub = subscribeTo(subId, (type,_, content) => {
|
||||
if (type === 'EOSE') {
|
||||
setLikeList(() => [...users]);
|
||||
setLikeList((likes) => [ ...likes, ...users ]);
|
||||
loadedLikes = likeList.length;
|
||||
setIsFetching(() => false);
|
||||
unsub();
|
||||
}
|
||||
@ -102,10 +100,10 @@ const ReactionsModal: Component<{
|
||||
});
|
||||
|
||||
setIsFetching(() => true);
|
||||
getEventReactions(props.noteId, Kind.Reaction, subId);
|
||||
getEventReactions(props.noteId, Kind.Reaction, subId, offset);
|
||||
};
|
||||
|
||||
const getZaps = () => {
|
||||
const getZaps = (offset = 0) => {
|
||||
if (!props.noteId) return;
|
||||
|
||||
const subId = `nr_z_${props.noteId}_${APP_ID}`;
|
||||
@ -120,7 +118,8 @@ const ReactionsModal: Component<{
|
||||
sender: users[zap.pubkey],
|
||||
})));
|
||||
|
||||
setZapList(() => [ ...zapData ]);
|
||||
setZapList((zapItems) => [ ...zapItems, ...zapData ]);
|
||||
loadedZaps = zapList.length;
|
||||
setIsFetching(() => false);
|
||||
unsub();
|
||||
}
|
||||
@ -174,10 +173,10 @@ const ReactionsModal: Component<{
|
||||
});
|
||||
|
||||
setIsFetching(() => true);
|
||||
getEventReactions(props.noteId, Kind.Zap, subId);
|
||||
getEventReactions(props.noteId, Kind.Zap, subId, offset);
|
||||
};
|
||||
|
||||
const getReposts = () => {
|
||||
const getReposts = (offset = 0) => {
|
||||
if (!props.noteId) return;
|
||||
|
||||
const subId = `nr_r_${props.noteId}_${APP_ID}`;
|
||||
@ -186,7 +185,8 @@ const ReactionsModal: Component<{
|
||||
|
||||
const unsub = subscribeTo(subId, (type,_, content) => {
|
||||
if (type === 'EOSE') {
|
||||
setRepostList(() => [...users]);
|
||||
setRepostList((reposts) => [...reposts, ...users]);
|
||||
loadedReposts = repostList.length;
|
||||
setIsFetching(() => false);
|
||||
unsub();
|
||||
}
|
||||
@ -210,7 +210,7 @@ const ReactionsModal: Component<{
|
||||
});
|
||||
|
||||
setIsFetching(() => true);
|
||||
getEventReactions(props.noteId, Kind.Repost, subId);
|
||||
getEventReactions(props.noteId, Kind.Repost, subId, offset);
|
||||
};
|
||||
|
||||
const totalCount = () => props.stats.likes + props.stats.quotes + props.stats.reposts + props.stats.zaps;
|
||||
@ -259,12 +259,13 @@ const ReactionsModal: Component<{
|
||||
</Tabs.List>
|
||||
|
||||
<Tabs.Content class={styles.tabContent} value={'likes'}>
|
||||
<Show
|
||||
when={!isFetching()}
|
||||
fallback={<Loader />}
|
||||
>
|
||||
<For
|
||||
each={likeList}
|
||||
fallback={
|
||||
<Show when={!isFetching()}>
|
||||
{intl.formatMessage(tPlaceholders.noLikeDetails)}
|
||||
</Show>
|
||||
}
|
||||
>
|
||||
{admirer =>
|
||||
<A
|
||||
@ -283,16 +284,33 @@ const ReactionsModal: Component<{
|
||||
</A>
|
||||
}
|
||||
</For>
|
||||
|
||||
<Show when={likeList.length < props.stats.likes}>
|
||||
<Paginator
|
||||
loadNextPage={() => {
|
||||
const len = likeList.length;
|
||||
if (len === 0) return;
|
||||
getLikes(len);
|
||||
}}
|
||||
isSmall={true}
|
||||
/>
|
||||
</Show>
|
||||
|
||||
<Show
|
||||
when={isFetching()}
|
||||
>
|
||||
<Loader />
|
||||
</Show>
|
||||
</Tabs.Content>
|
||||
|
||||
<Tabs.Content class={styles.tabContent} value={'zaps'}>
|
||||
<Show
|
||||
when={!isFetching()}
|
||||
fallback={<Loader />}
|
||||
>
|
||||
<For
|
||||
each={zapList}
|
||||
fallback={
|
||||
<Show when={!isFetching()}>
|
||||
{intl.formatMessage(tPlaceholders.noZapDetails)}
|
||||
</Show>
|
||||
}
|
||||
>
|
||||
{zap =>
|
||||
<A
|
||||
@ -319,15 +337,32 @@ const ReactionsModal: Component<{
|
||||
</A>
|
||||
}
|
||||
</For>
|
||||
|
||||
<Show when={zapList.length < props.stats.zaps}>
|
||||
<Paginator
|
||||
loadNextPage={() => {
|
||||
const len = zapList.length;
|
||||
if (len === 0) return;
|
||||
getZaps(len);
|
||||
}}
|
||||
isSmall={true}
|
||||
/>
|
||||
</Show>
|
||||
|
||||
<Show
|
||||
when={isFetching()}
|
||||
>
|
||||
<Loader />
|
||||
</Show>
|
||||
</Tabs.Content>
|
||||
<Tabs.Content class={styles.tabContent} value={'reposts'}>
|
||||
<Show
|
||||
when={!isFetching()}
|
||||
fallback={<Loader />}
|
||||
>
|
||||
<For
|
||||
each={repostList}
|
||||
fallback={
|
||||
<Show when={!isFetching()}>
|
||||
{intl.formatMessage(tPlaceholders.noRepostDetails)}
|
||||
</Show>
|
||||
}
|
||||
>
|
||||
{reposter =>
|
||||
<A
|
||||
@ -346,6 +381,22 @@ const ReactionsModal: Component<{
|
||||
</A>
|
||||
}
|
||||
</For>
|
||||
|
||||
<Show when={repostList.length < props.stats.reposts}>
|
||||
<Paginator
|
||||
loadNextPage={() => {
|
||||
const len = repostList.length;
|
||||
if (len === 0) return;
|
||||
getReposts(len);
|
||||
}}
|
||||
isSmall={true}
|
||||
/>
|
||||
</Show>
|
||||
|
||||
<Show
|
||||
when={isFetching()}
|
||||
>
|
||||
<Loader />
|
||||
</Show>
|
||||
</Tabs.Content>
|
||||
<Tabs.Content class={styles.tabContent} value={'quotes'}>
|
||||
|
@ -470,10 +470,10 @@ export const triggerImportEvents = (events: NostrRelaySignedEvent[], subId: stri
|
||||
};
|
||||
|
||||
|
||||
export const getEventReactions = (eventId: string, kind: number, subid: string) => {
|
||||
export const getEventReactions = (eventId: string, kind: number, subid: string, offset = 0) => {
|
||||
sendMessage(JSON.stringify([
|
||||
"REQ",
|
||||
subid,
|
||||
{cache: ["event_actions", { event_id: eventId, kind, limit: 100 }]},
|
||||
{cache: ["event_actions", { event_id: eventId, kind, limit: 20, offset }]},
|
||||
]));
|
||||
};
|
||||
|
@ -982,6 +982,21 @@ export const notifications = {
|
||||
};
|
||||
|
||||
export const placeholders = {
|
||||
noLikeDetails: {
|
||||
id: 'placeholders.noLikeDetails',
|
||||
defaultMessage: 'No details for likes found',
|
||||
description: 'Placeholder when there are no like details in reactions modal',
|
||||
},
|
||||
noZapDetails: {
|
||||
id: 'placeholders.noZapDetails',
|
||||
defaultMessage: 'No details for zaps found',
|
||||
description: 'Placeholder when there are no zap details in reactions modal',
|
||||
},
|
||||
noRepostDetails: {
|
||||
id: 'placeholders.noRepostDetails',
|
||||
defaultMessage: 'No details for reposts found',
|
||||
description: 'Placeholder when there are no repost details in reactions modal',
|
||||
},
|
||||
addComment: {
|
||||
id: 'placeholders.addComment',
|
||||
defaultMessage: 'Add a comment...',
|
||||
|
Loading…
Reference in New Issue
Block a user