mirror of
https://github.com/PrimalHQ/primal-web-app.git
synced 2024-10-01 17:31:13 +00:00
Instant refresh top zaps
This commit is contained in:
parent
26d24179e2
commit
b0091ccfe1
@ -130,9 +130,7 @@ const CustomZap: Component<{
|
|||||||
|
|
||||||
const handleZap = (success = false) => {
|
const handleZap = (success = false) => {
|
||||||
if (success) {
|
if (success) {
|
||||||
setTimeout(() => {
|
props.onSuccess(selectedValue());
|
||||||
props.onSuccess(selectedValue());
|
|
||||||
}, 2_000)
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,9 @@ import { CustomZapInfo, useAppContext } from '../../contexts/AppContext';
|
|||||||
import NoteContextTrigger from './NoteContextTrigger';
|
import NoteContextTrigger from './NoteContextTrigger';
|
||||||
import { date, longDate, veryLongDate } from '../../lib/dates';
|
import { date, longDate, veryLongDate } from '../../lib/dates';
|
||||||
import { hexToNpub } from '../../lib/keys';
|
import { hexToNpub } from '../../lib/keys';
|
||||||
import { zapCustomOption } from '../../translations';
|
import { thread, zapCustomOption } from '../../translations';
|
||||||
|
import { useAccountContext } from '../../contexts/AccountContext';
|
||||||
|
import { uuidv4 } from '../../utils';
|
||||||
|
|
||||||
export type NoteFooterState = {
|
export type NoteFooterState = {
|
||||||
likes: number,
|
likes: number,
|
||||||
@ -37,6 +39,7 @@ export type NoteFooterState = {
|
|||||||
hideZapIcon: boolean,
|
hideZapIcon: boolean,
|
||||||
moreZapsAvailable: boolean,
|
moreZapsAvailable: boolean,
|
||||||
isRepostMenuVisible: boolean,
|
isRepostMenuVisible: boolean,
|
||||||
|
topZaps: TopZap[],
|
||||||
};
|
};
|
||||||
|
|
||||||
const Note: Component<{
|
const Note: Component<{
|
||||||
@ -49,6 +52,7 @@ const Note: Component<{
|
|||||||
|
|
||||||
const threadContext = useThreadContext();
|
const threadContext = useThreadContext();
|
||||||
const app = useAppContext();
|
const app = useAppContext();
|
||||||
|
const account = useAccountContext();
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const noteType = () => props.noteType || 'feed';
|
const noteType = () => props.noteType || 'feed';
|
||||||
@ -76,6 +80,7 @@ const Note: Component<{
|
|||||||
hideZapIcon: false,
|
hideZapIcon: false,
|
||||||
moreZapsAvailable: false,
|
moreZapsAvailable: false,
|
||||||
isRepostMenuVisible: false,
|
isRepostMenuVisible: false,
|
||||||
|
topZaps: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
let noteContextMenu: HTMLDivElement | undefined;
|
let noteContextMenu: HTMLDivElement | undefined;
|
||||||
@ -94,6 +99,27 @@ const Note: Component<{
|
|||||||
const onSuccessZap = (zapOption: ZapOption) => {
|
const onSuccessZap = (zapOption: ZapOption) => {
|
||||||
app?.actions.closeCustomZapModal();
|
app?.actions.closeCustomZapModal();
|
||||||
app?.actions.resetCustomZap();
|
app?.actions.resetCustomZap();
|
||||||
|
|
||||||
|
const pubkey = account?.publicKey;
|
||||||
|
|
||||||
|
if (!pubkey) return;
|
||||||
|
|
||||||
|
const oldZaps = [ ...reactionsState.topZaps ];
|
||||||
|
|
||||||
|
const newZap = {
|
||||||
|
amount: zapOption.amount || 0,
|
||||||
|
message: zapOption.message || '',
|
||||||
|
pubkey,
|
||||||
|
eventId: props.note.post.id,
|
||||||
|
id: uuidv4() as string,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!threadContext?.users.find((u) => u.pubkey === pubkey)) {
|
||||||
|
threadContext?.actions.fetchUsers([pubkey])
|
||||||
|
}
|
||||||
|
|
||||||
|
const zaps = [ ...oldZaps, { ...newZap }].sort((a, b) => b.amount - a.amount);
|
||||||
|
|
||||||
batch(() => {
|
batch(() => {
|
||||||
updateReactionsState('zapCount', (z) => z + 1);
|
updateReactionsState('zapCount', (z) => z + 1);
|
||||||
// updateFooterState('satsZapped', (z) => z + (zapOption.amount || 0));
|
// updateFooterState('satsZapped', (z) => z + (zapOption.amount || 0));
|
||||||
@ -102,8 +128,8 @@ const Note: Component<{
|
|||||||
updateReactionsState('showZapAnim', () => false);
|
updateReactionsState('showZapAnim', () => false);
|
||||||
updateReactionsState('hideZapIcon', () => false);
|
updateReactionsState('hideZapIcon', () => false);
|
||||||
updateReactionsState('zapped', () => true);
|
updateReactionsState('zapped', () => true);
|
||||||
|
updateReactionsState('topZaps', () => [...zaps]);
|
||||||
});
|
});
|
||||||
threadContext?.actions.fetchTopZaps(props.note.post.id);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onFailZap = (zapOption: ZapOption) => {
|
const onFailZap = (zapOption: ZapOption) => {
|
||||||
@ -169,12 +195,10 @@ const Note: Component<{
|
|||||||
return (likes || 0) + (zapCount || 0) + (reposts || 0);
|
return (likes || 0) + (zapCount || 0) + (reposts || 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
const topZaps = () => threadContext?.topZaps[props.note.post.id] || [];
|
const firstZap = createMemo(() => reactionsState.topZaps[0]);
|
||||||
|
|
||||||
const firstZap = createMemo(() => topZaps()[0]);
|
|
||||||
|
|
||||||
const restZaps = createMemo(() => {
|
const restZaps = createMemo(() => {
|
||||||
const zaps = topZaps().slice(1);
|
const zaps = reactionsState.topZaps.slice(1);
|
||||||
|
|
||||||
let limit = 0;
|
let limit = 0;
|
||||||
let digits = 0;
|
let digits = 0;
|
||||||
@ -200,11 +224,15 @@ const Note: Component<{
|
|||||||
}
|
}
|
||||||
|
|
||||||
return rest;
|
return rest;
|
||||||
})
|
});
|
||||||
|
|
||||||
const zapSender = (zap: TopZap) => {
|
const zapSender = (zap: TopZap) => {
|
||||||
return threadContext?.users.find(u => u.pubkey === zap.pubkey);
|
return threadContext?.users.find(u => u.pubkey === zap.pubkey);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
createEffect(() => {
|
||||||
|
updateReactionsState('topZaps', () => [ ...(threadContext?.topZaps[props.note.post.id] || []) ]);
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Switch>
|
<Switch>
|
||||||
@ -260,7 +288,7 @@ const Note: Component<{
|
|||||||
<ParsedNote note={props.note} width={Math.min(574, window.innerWidth)} />
|
<ParsedNote note={props.note} width={Math.min(574, window.innerWidth)} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class={`${styles.zapHighlights} ${topZaps().length < 4 ? styles.onlyFew : ''}`}>
|
<div class={`${styles.zapHighlights} ${reactionsState.topZaps.length < 4 ? styles.onlyFew : ''}`}>
|
||||||
<Show when={firstZap()}>
|
<Show when={firstZap()}>
|
||||||
<button
|
<button
|
||||||
class={styles.firstZap}
|
class={styles.firstZap}
|
||||||
|
@ -279,13 +279,11 @@ const NoteFooter: Component<{
|
|||||||
props.updateState('isZapping', () => false);
|
props.updateState('isZapping', () => false);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
setTimeout(() => {
|
props.customZapInfo.onSuccess({
|
||||||
props.customZapInfo.onSuccess({
|
emoji,
|
||||||
emoji,
|
amount,
|
||||||
amount,
|
message,
|
||||||
message,
|
});
|
||||||
});
|
|
||||||
}, 2_000);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@ import { APP_ID } from "../App";
|
|||||||
import { useAccountContext } from "./AccountContext";
|
import { useAccountContext } from "./AccountContext";
|
||||||
import { getEventZaps, setLinkPreviews } from "../lib/notes";
|
import { getEventZaps, setLinkPreviews } from "../lib/notes";
|
||||||
import { parseBolt11 } from "../utils";
|
import { parseBolt11 } from "../utils";
|
||||||
|
import { getUserProfiles } from "../lib/profile";
|
||||||
|
|
||||||
export type TopZap = {
|
export type TopZap = {
|
||||||
id: string,
|
id: string,
|
||||||
@ -69,6 +70,7 @@ export type ThreadContextStore = {
|
|||||||
savePage: (page: FeedPage) => void,
|
savePage: (page: FeedPage) => void,
|
||||||
setPrimaryNote: (context: PrimalNote | undefined) => void,
|
setPrimaryNote: (context: PrimalNote | undefined) => void,
|
||||||
fetchTopZaps: (noteId: string) => void,
|
fetchTopZaps: (noteId: string) => void,
|
||||||
|
fetchUsers: (pubkeys: string[]) => void,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,6 +294,10 @@ export const ThreadProvider = (props: { children: ContextChildren }) => {
|
|||||||
getEventZaps(noteId, account?.publicKey, `thread_zapps_${APP_ID}`, 10, 0);
|
getEventZaps(noteId, account?.publicKey, `thread_zapps_${APP_ID}`, 10, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fetchUsers = (pubkeys: string[]) => {
|
||||||
|
getUserProfiles(pubkeys, `thread_pk_${APP_ID}`);
|
||||||
|
};
|
||||||
|
|
||||||
// SOCKET HANDLERS ------------------------------
|
// SOCKET HANDLERS ------------------------------
|
||||||
|
|
||||||
const onMessage = (event: MessageEvent) => {
|
const onMessage = (event: MessageEvent) => {
|
||||||
@ -351,6 +357,17 @@ export const ThreadProvider = (props: { children: ContextChildren }) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (subId === `thread_pk_${APP_ID}`) {
|
||||||
|
if (type === 'EOSE') {
|
||||||
|
savePage(store.page);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'EVENT') {
|
||||||
|
updatePage(content);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSocketClose = (closeEvent: CloseEvent) => {
|
const onSocketClose = (closeEvent: CloseEvent) => {
|
||||||
@ -420,6 +437,7 @@ export const ThreadProvider = (props: { children: ContextChildren }) => {
|
|||||||
savePage,
|
savePage,
|
||||||
setPrimaryNote,
|
setPrimaryNote,
|
||||||
fetchTopZaps,
|
fetchTopZaps,
|
||||||
|
fetchUsers,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user