Remember last 10 visited profiles

This commit is contained in:
Bojan Mojsilovic 2024-01-10 18:25:24 +01:00
parent fd9d28fa11
commit 05b0fe9219
3 changed files with 71 additions and 14 deletions

View File

@ -13,6 +13,7 @@ import { placeholders, search as t } from '../../translations';
import styles from './Search.module.scss'; import styles from './Search.module.scss';
import SearchOption from './SearchOption'; import SearchOption from './SearchOption';
import { hookForDev } from '../../lib/devTools'; import { hookForDev } from '../../lib/devTools';
import { useProfileContext } from '../../contexts/ProfileContext';
const Search: Component<{ const Search: Component<{
@ -28,6 +29,7 @@ const Search: Component<{
const search = useSearchContext(); const search = useSearchContext();
const navigate = useNavigate(); const navigate = useNavigate();
const intl = useIntl(); const intl = useIntl();
const profile = useProfileContext();
const [query, setQuery] = createSignal(''); const [query, setQuery] = createSignal('');
const [isFocused, setIsFocused] = createSignal(false); const [isFocused, setIsFocused] = createSignal(false);
@ -103,7 +105,7 @@ const Search: Component<{
createEffect(() => { createEffect(() => {
if (query().length === 0) { if (query().length === 0) {
search?.actions.getRecomendedUsers(); search?.actions.getRecomendedUsers(profile?.profileHistory.profiles || []);
return; return;
} }
@ -174,7 +176,7 @@ const Search: Component<{
title={userName(user)} title={userName(user)}
description={nip05Verification(user)} description={nip05Verification(user)}
icon={<Avatar user={user} size="vvs" />} icon={<Avatar user={user} size="vvs" />}
statNumber={search?.scores[user.pubkey]} statNumber={profile?.profileHistory.stats[user.pubkey]?.followers_count || search?.scores[user.pubkey]}
statLabel={intl.formatMessage(t.followers)} statLabel={intl.formatMessage(t.followers)}
onClick={() => selectUser(user)} onClick={() => selectUser(user)}
/> />

View File

@ -53,10 +53,8 @@ import { parseBolt11 } from "../utils";
import { convertToUser } from "../stores/profile"; import { convertToUser } from "../stores/profile";
import { sortBreakpoints } from "@solid-primitives/media"; import { sortBreakpoints } from "@solid-primitives/media";
export type ProfileContextStore = { export type UserStats = {
profileKey: string | undefined, pubkey: string,
userProfile: PrimalUser | undefined,
userStats: {
follows_count: number, follows_count: number,
followers_count: number, followers_count: number,
note_count: number, note_count: number,
@ -65,7 +63,12 @@ export type ProfileContextStore = {
total_zap_count: number, total_zap_count: number,
total_satszapped: number, total_satszapped: number,
relay_count: number, relay_count: number,
}, };
export type ProfileContextStore = {
profileKey: string | undefined,
userProfile: PrimalUser | undefined,
userStats: UserStats,
fetchedUserStats: boolean, fetchedUserStats: boolean,
knownProfiles: VanityProfiles, knownProfiles: VanityProfiles,
notes: PrimalNote[], notes: PrimalNote[],
@ -100,6 +103,10 @@ export type ProfileContextStore = {
isFetchingZaps: boolean, isFetchingZaps: boolean,
profileStats: Record<string, number>, profileStats: Record<string, number>,
relays: NostrRelays, relays: NostrRelays,
profileHistory: {
profiles: PrimalUser[],
stats: Record<string, UserStats>,
},
actions: { actions: {
saveNotes: (newNotes: PrimalNote[]) => void, saveNotes: (newNotes: PrimalNote[]) => void,
clearNotes: () => void, clearNotes: () => void,
@ -129,6 +136,7 @@ export type ProfileContextStore = {
} }
export const emptyStats = { export const emptyStats = {
pubkey: '',
follows_count: 0, follows_count: 0,
followers_count: 0, followers_count: 0,
note_count: 0, note_count: 0,
@ -195,6 +203,10 @@ export const initialData = {
noteActions: {}, noteActions: {},
}, },
}, },
profileHistory: {
profiles: [],
stats: {},
},
}; };
@ -892,6 +904,42 @@ export const ProfileProvider = (props: { children: ContextChildren }) => {
const refreshNotes = () => { const refreshNotes = () => {
}; };
const addProfileToHistory = (user: PrimalUser) => {
let list = [...store.profileHistory.profiles];
const index = list.findIndex(u => u.pubkey === user.pubkey)
// user is first in the list so the job is done
if (index === 0) return;
if (index > 0) {
list.splice(index, 1);
updateStore('profileHistory', 'profiles', () => [user, ...list]);
return;
}
list.unshift(user);
if (list.length > 10) {
const last = list[list.length - 1].pubkey;
let stats = { ...store.profileHistory.stats };
delete stats[last];
updateStore('profileHistory', 'stats', reconcile(stats));
list.pop()
}
updateStore('profileHistory', 'profiles', () => [...list]);
};
const addStatsToHistory = (stats: UserStats) => {
updateStore('profileHistory', 'stats', () => ({ [stats.pubkey]: stats }));
};
// SOCKET HANDLERS ------------------------------ // SOCKET HANDLERS ------------------------------
const onMessage = (event: MessageEvent) => { const onMessage = (event: MessageEvent) => {
@ -959,6 +1007,7 @@ export const ProfileProvider = (props: { children: ContextChildren }) => {
user.created_at = content.created_at; user.created_at = content.created_at;
updateStore('userProfile', () => user); updateStore('userProfile', () => user);
addProfileToHistory(user);
return; return;
} }
@ -966,6 +1015,7 @@ export const ProfileProvider = (props: { children: ContextChildren }) => {
const stats = JSON.parse(content.content); const stats = JSON.parse(content.content);
updateStore('userStats', () => ({ ...stats })); updateStore('userStats', () => ({ ...stats }));
addStatsToHistory(stats)
updateStore('fetchedUserStats', () => true); updateStore('fetchedUserStats', () => true);
return; return;
} }

View File

@ -26,6 +26,7 @@ import { subscribeTo } from "../sockets";
import { nip19 } from "nostr-tools"; import { nip19 } from "nostr-tools";
import { useAccountContext } from "./AccountContext"; import { useAccountContext } from "./AccountContext";
import { npubToHex } from "../lib/keys"; import { npubToHex } from "../lib/keys";
import { useProfileContext } from "./ProfileContext";
const recomendedUsers = [ const recomendedUsers = [
'82341f882b6eabcd2ba7f1ef90aad961cf074af15b9ef44a09f9d2a8fbfbe6a2', // jack '82341f882b6eabcd2ba7f1ef90aad961cf074af15b9ef44a09f9d2a8fbfbe6a2', // jack
@ -59,7 +60,7 @@ export type SearchContextStore = {
findContentUsers: (query: string, pubkey?: string) => void, findContentUsers: (query: string, pubkey?: string) => void,
findContent: (query: string) => void, findContent: (query: string) => void,
setContentQuery: (query: string) => void, setContentQuery: (query: string) => void,
getRecomendedUsers: () => void, getRecomendedUsers: (profiles?: PrimalUser[]) => void,
findFilteredUserByNpub: (npub: string) => void, findFilteredUserByNpub: (npub: string) => void,
}, },
} }
@ -147,7 +148,7 @@ export function SearchProvider(props: { children: number | boolean | Node | JSX.
getUserProfiles([hex], subId); getUserProfiles([hex], subId);
}; };
const getRecomendedUsers = () => { const getRecomendedUsers = (profiles?: PrimalUser[]) => {
const subid = `recomended_users_${APP_ID}`; const subid = `recomended_users_${APP_ID}`;
let users: PrimalUser[] = []; let users: PrimalUser[] = [];
@ -182,6 +183,10 @@ export function SearchProvider(props: { children: number | boolean | Node | JSX.
sorted[index] = { ...user }; sorted[index] = { ...user };
}); });
if (profiles) {
sorted = [...profiles, ...sorted].slice(0, 9);
}
updateStore('users', () => sorted); updateStore('users', () => sorted);
updateStore('isFetchingUsers', () => false); updateStore('isFetchingUsers', () => false);