From c884d1aae70aa28a6c339dfa055581713d10f6f9 Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Sat, 9 Sep 2023 11:34:17 -0700 Subject: [PATCH 1/8] build(ui): bump tanstack deps --- package-lock.json | 45 +++++++++++++++++++++++++++------------------ ui/package.json | 6 +++--- ui/src/main.ts | 5 +++-- 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1ead7184..4b20531e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1228,20 +1228,20 @@ } }, "node_modules/@tanstack/query-core": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.33.0.tgz", - "integrity": "sha512-qYu73ptvnzRh6se2nyBIDHGBQvPY1XXl3yR769B7B6mIDD7s+EZhdlWHQ67JI6UOTFRaI7wupnTnwJ3gE0Mr/g==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.35.0.tgz", + "integrity": "sha512-4GMcKQuLZQi6RFBiBZNsLhl+hQGYScRZ5ZoVq8QAzfqz9M7vcGin/2YdSESwl7WaV+Qzsb5CZOAbMBes4lNTnA==", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" } }, "node_modules/@tanstack/query-persist-client-core": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@tanstack/query-persist-client-core/-/query-persist-client-core-4.33.0.tgz", - "integrity": "sha512-3P16+2JjcUU5CHi10jJuwd0ZQYvQtSuzLvCUCjVuAnj3GZjfSso1v8t6WAObAr9RPuIC6vDXeOQ3mr07EF/NxQ==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@tanstack/query-persist-client-core/-/query-persist-client-core-4.35.0.tgz", + "integrity": "sha512-un1zoD6D80lrJ1x1jtPzhm1xrdPbhG9unf4y0Tl58/eCZz1VIjw+rR4hG+kn/hfzxX/kY4AMvtwMPxtt3HiAdg==", "dependencies": { - "@tanstack/query-core": "4.33.0" + "@tanstack/query-core": "4.35.0" }, "funding": { "type": "github", @@ -1249,11 +1249,11 @@ } }, "node_modules/@tanstack/query-sync-storage-persister": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@tanstack/query-sync-storage-persister/-/query-sync-storage-persister-4.33.0.tgz", - "integrity": "sha512-V6igMcdEOXPRpvmNFQ6I/iJaw9NhxWy7x8PWamm2cgSsLi8bHaDvUVuWkZm+ikI47QjoCUk7qll/82JYLaH+pw==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@tanstack/query-sync-storage-persister/-/query-sync-storage-persister-4.35.0.tgz", + "integrity": "sha512-idNCZ7GF401X/NUHS0G0VQNhB36h1VTPobWBJYAEGkz6uvS8CpVuruGyvmVPuR61SE2k94g/Qc4jWQMcDeFM+g==", "dependencies": { - "@tanstack/query-persist-client-core": "4.33.0" + "@tanstack/query-persist-client-core": "4.35.0" }, "funding": { "type": "github", @@ -1261,12 +1261,12 @@ } }, "node_modules/@tanstack/vue-query": { - "version": "4.34.0", - "resolved": "https://registry.npmjs.org/@tanstack/vue-query/-/vue-query-4.34.0.tgz", - "integrity": "sha512-jXqvP5z+9mAuUVELH4A9j+KYhu84IpBFDGo60Z+9GV/td+CeDBLRoijBEixBg87SEilCCpJugc0yx2MOCwlwew==", + "version": "4.35.2", + "resolved": "https://registry.npmjs.org/@tanstack/vue-query/-/vue-query-4.35.2.tgz", + "integrity": "sha512-zaEbtALVuYd+8phh7toDaXMCjS5AH13uPoU46CdiszX5QVRQYOhWMnAkW4jxLGbmLSNvdvYXvZsQG5TrwCM7zg==", "dependencies": { "@tanstack/match-sorter-utils": "^8.1.1", - "@tanstack/query-core": "4.33.0", + "@tanstack/query-core": "4.35.2", "@vue/devtools-api": "^6.4.2", "vue-demi": "^0.13.11" }, @@ -1284,6 +1284,15 @@ } } }, + "node_modules/@tanstack/vue-query/node_modules/@tanstack/query-core": { + "version": "4.35.2", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.35.2.tgz", + "integrity": "sha512-IJYT+VVx0SGe3QWqL6XUgzEY1re3szCdGMSGD1VRdEej6Uq3O+qELR2Ypw1/a4bUYKXiDUpK4BAcBynWb6nbkQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, "node_modules/@tanstack/vue-query/node_modules/vue-demi": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz", @@ -7418,9 +7427,9 @@ "@holochain-open-dev/profiles": "^0.16.1", "@holochain/client": "^0.15.0", "@shoelace-style/shoelace": "^2.4.0", - "@tanstack/query-persist-client-core": "^4.33.0", - "@tanstack/query-sync-storage-persister": "^4.33.0", - "@tanstack/vue-query": "^4.34.0", + "@tanstack/query-persist-client-core": "^4.35.0", + "@tanstack/query-sync-storage-persister": "^4.35.0", + "@tanstack/vue-query": "^4.35.2", "@tauri-apps/api": "^1.4.0", "async-retry": "^1.3.3", "dayjs": "^1.11.7", diff --git a/ui/package.json b/ui/package.json index c47179b2..93bd04a8 100644 --- a/ui/package.json +++ b/ui/package.json @@ -20,9 +20,9 @@ "@holochain-open-dev/profiles": "^0.16.1", "@holochain/client": "^0.15.0", "@shoelace-style/shoelace": "^2.4.0", - "@tanstack/query-persist-client-core": "^4.33.0", - "@tanstack/query-sync-storage-persister": "^4.33.0", - "@tanstack/vue-query": "^4.34.0", + "@tanstack/query-persist-client-core": "^4.35.0", + "@tanstack/query-sync-storage-persister": "^4.35.0", + "@tanstack/vue-query": "^4.35.2", "@tauri-apps/api": "^1.4.0", "async-retry": "^1.3.3", "dayjs": "^1.11.7", diff --git a/ui/src/main.ts b/ui/src/main.ts index 74fd8050..dca92fbe 100644 --- a/ui/src/main.ts +++ b/ui/src/main.ts @@ -15,7 +15,6 @@ import App from "./App.vue"; import { router } from "./router"; import piniaPluginPersistedState from "pinia-plugin-persistedstate"; import { - QueryClient, VueQueryPlugin, type VueQueryPluginOptions, } from "@tanstack/vue-query"; @@ -52,8 +51,10 @@ const vueQueryOptions: VueQueryPluginOptions = { }, }, }, - clientPersister: (queryClient: QueryClient) => { + clientPersister: (queryClient) => { return persistQueryClient({ + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore queryClient, persister: createSyncStoragePersister({ storage: localStorage, From 17c427032a9d56e5b29d0d2d5f70edf1709d54c7 Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Sat, 9 Sep 2023 12:24:02 -0700 Subject: [PATCH 2/8] fix(ui): ensure tanstack query key is reactively updated when agentPubKey prop or client.myPubKey changes --- ui/components.d.ts | 2 +- ui/src/components/AgentProfileDetail.vue | 6 ++++-- ui/src/components/ButtonFollow.vue | 3 ++- ui/src/components/CreatorsListDialog.vue | 9 +++----- ui/src/components/FollowersListDialog.vue | 9 +++----- ui/src/layouts/MainLayout.vue | 9 ++++---- ui/src/pages/AgentProfile.vue | 26 ++++++----------------- ui/src/pages/MewYarn.vue | 4 ++-- ui/src/pages/MewsFeed.vue | 15 ++++--------- ui/src/pages/MyNotifications.vue | 9 ++++---- 10 files changed, 36 insertions(+), 56 deletions(-) diff --git a/ui/components.d.ts b/ui/components.d.ts index 2cd89fc1..d9dd84ca 100644 --- a/ui/components.d.ts +++ b/ui/components.d.ts @@ -47,7 +47,7 @@ declare module 'vue' { CreatorsListDialog: typeof import('./src/components/CreatorsListDialog.vue')['default'] EditAgentProfileDialog: typeof import('./src/components/EditAgentProfileDialog.vue')['default'] FollowersListDialog: typeof import('./src/components/FollowersListDialog.vue')['default'] - HoloLogin: typeof import('./src/components/HoloLogin.vue')['default'] + RandomMewWithTagList: typeof import('./src/components/RandomMewWithTagList.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] SearchEverythingDialog: typeof import('./src/components/SearchEverythingDialog.vue')['default'] diff --git a/ui/src/components/AgentProfileDetail.vue b/ui/src/components/AgentProfileDetail.vue index 620a84d6..11f92f98 100644 --- a/ui/src/components/AgentProfileDetail.vue +++ b/ui/src/components/AgentProfileDetail.vue @@ -12,10 +12,11 @@ diff --git a/ui/src/pages/DiscoverCreators.vue b/ui/src/pages/DiscoverCreators.vue index 0b22572f..2605366f 100644 --- a/ui/src/pages/DiscoverCreators.vue +++ b/ui/src/pages/DiscoverCreators.vue @@ -38,93 +38,9 @@ - - - - - - - - - - - - - - - + + + @@ -219,199 +135,27 @@ onMounted(async () => { await refetchMews(); } if (randomTags.value === undefined || randomTags.value.length === 0) { - refetchTags(); + refetchRandomTags(); } }); -const fetchRandomMewHashesWithTag = (tag: string): Promise => - client.callZome({ - role_name: "mewsfeed", - zome_name: "mews", - fn_name: "get_random_mew_hashes_for_tag", - payload: { - tag: tag, - count: 3, - }, - }); - -const tag1Enabled = computed( - () => - randomTags.value !== undefined && - randomTags.value.length > 0 && - randomTags.value[0] !== undefined -); -const tag2Enabled = computed( - () => - randomTags.value !== undefined && - randomTags.value.length > 1 && - randomTags.value[1] !== undefined -); -const tag3Enabled = computed( - () => - randomTags.value !== undefined && - randomTags.value.length > 2 && - randomTags.value[2] !== undefined -); - -// Random Mews with Tag 1 - -const { - data: randomMewHashesWithTag1, - error: errorRandomMewHashesWithTag1, - isLoading: isLoadingRandomMewHashesWithTag1, - refetch: refetchRandomMewHashesWithTag1, -} = useQuery({ - queryKey: ["mews", "get_random_mew_hashes_for_tag", randomTags.value[0]], - enabled: tag1Enabled, - queryFn: () => fetchRandomMewHashesWithTag(randomTags.value[0]), - refetchOnWindowFocus: false, - refetchOnMount: false, - refetchOnReconnect: false, -}); -watch(errorRandomMewHashesWithTag1, console.error); -const hasRandomMewHashesWithTag1 = computed( - () => - tag1Enabled.value && - randomMewHashesWithTag1.value && - randomMewHashesWithTag1.value.length > 0 +const tag1 = computed(() => + randomTags.value ? randomTags.value[0] : undefined ); - -const { - data: randomMewsWithTag1, - error: errorRandomMewsWithTag1, - isFetching: isFetchingRandomMewsWithTag1, - refetch: refetchRandomMewsWithTag1, -} = useQuery({ - queryKey: [ - "mews", - "get_random_mew_hashes_for_tag", - randomTags.value[0], - "get_batch_mews_with_context", - ], - - queryFn: () => - fetchMewsWithContext(toRaw(randomMewHashesWithTag1.value as ActionHash[])), - enabled: hasRandomMewHashesWithTag1, - refetchOnWindowFocus: false, - refetchOnMount: false, - refetchOnReconnect: false, -}); -watch(errorRandomMewsWithTag1, console.error); - -// Random Mews with Tag 2 - -const { - data: randomMewHashesWithTag2, - error: errorRandomMewHashesWithTag2, - isLoading: isLoadingRandomMewHashesWithTag2, - refetch: refetchRandomMewHashesWithTag2, -} = useQuery({ - queryKey: ["mews", "get_random_mew_hashes_for_tag", randomTags.value[1]], - enabled: tag2Enabled, - queryFn: () => fetchRandomMewHashesWithTag(randomTags.value[1]), - refetchOnWindowFocus: false, - refetchOnMount: false, - refetchOnReconnect: false, -}); -watch(errorRandomMewHashesWithTag2, console.error); -const hasRandomMewHashesWithTag2 = computed( - () => - tag2Enabled.value && - randomMewHashesWithTag2.value && - randomMewHashesWithTag2.value.length > 0 +const tag2 = computed(() => + randomTags.value ? randomTags.value[1] : undefined ); - -const { - data: randomMewsWithTag2, - error: errorRandomMewsWithTag2, - isFetching: isFetchingRandomMewsWithTag2, - refetch: refetchRandomMewsWithTag2, -} = useQuery({ - queryKey: [ - "mews", - "get_random_mew_hashes_for_tag", - randomTags.value[1], - "get_batch_mews_with_context", - ], - - queryFn: () => - fetchMewsWithContext(toRaw(randomMewHashesWithTag2.value as ActionHash[])), - enabled: hasRandomMewHashesWithTag2, - refetchOnWindowFocus: false, - refetchOnMount: false, - refetchOnReconnect: false, -}); -watch(errorRandomMewsWithTag2, console.error); - -// Random Mews with Tag 3 - -const { - data: randomMewHashesWithTag3, - error: errorRandomMewHashesWithTag3, - isLoading: isLoadingRandomMewHashesWithTag3, - refetch: refetchRandomMewHashesWithTag3, -} = useQuery({ - queryKey: ["mews", "get_random_mew_hashes_for_tag", randomTags.value[2]], - enabled: tag1Enabled, - queryFn: () => fetchRandomMewHashesWithTag(randomTags.value[2]), - refetchOnWindowFocus: false, - refetchOnMount: false, - refetchOnReconnect: false, -}); -watch(errorRandomMewHashesWithTag3, console.error); -const hasRandomMewHashesWithTag3 = computed( - () => - tag3Enabled.value && - randomMewHashesWithTag3.value && - randomMewHashesWithTag3.value.length > 0 +const tag3 = computed(() => + randomTags.value ? randomTags.value[2] : undefined ); -const { - data: randomMewsWithTag3, - error: errorRandomMewsWithTag3, - isFetching: isFetchingRandomMewsWithTag3, - refetch: refetchRandomMewsWithTag3, -} = useQuery({ - queryKey: [ - "mews", - "get_random_mew_hashes_for_tag", - randomTags.value[2], - "get_batch_mews_with_context", - ], - - queryFn: () => - fetchMewsWithContext(toRaw(randomMewHashesWithTag3.value as ActionHash[])), - enabled: hasRandomMewHashesWithTag3, - refetchOnWindowFocus: false, - refetchOnMount: false, - refetchOnReconnect: false, -}); -watch(errorRandomMewsWithTag3, console.error); - const shuffle = async () => { await refetchMews(); - await refetchTags(); + await refetchRandomTags(); }; const refetchMews = async () => { await refetchRandomMewHashes(); refetchRandomMews(); }; - -const refetchTags = async () => { - await refetchRandomTags(); - - if (tag1Enabled.value) { - await refetchRandomMewHashesWithTag1(); - refetchRandomMewsWithTag1(); - } - if (tag2Enabled.value) { - await refetchRandomMewHashesWithTag2(); - refetchRandomMewsWithTag2(); - } - if (tag3Enabled.value) { - await refetchRandomMewHashesWithTag3(); - refetchRandomMewsWithTag3(); - } -}; From f8f384c796b42c9c13a50f7cd70343fdaf14e3e2 Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Sat, 9 Sep 2023 13:24:40 -0700 Subject: [PATCH 4/8] fix(ui): wrap props in computed before using in tanstack queryKey to ensure reactive updating --- ui/src/components/RandomMewWithTagList.vue | 6 +-- ui/src/pages/AgentProfile.vue | 50 ++++++++-------------- ui/src/pages/MewYarn.vue | 9 ++-- ui/src/pages/MewsListAuthor.vue | 7 +-- ui/src/pages/MewsListCashtag.vue | 18 +++----- ui/src/pages/MewsListHashtag.vue | 17 +++----- ui/src/pages/MewsListMention.vue | 15 ++----- 7 files changed, 41 insertions(+), 81 deletions(-) diff --git a/ui/src/components/RandomMewWithTagList.vue b/ui/src/components/RandomMewWithTagList.vue index 7b80d776..e239d74e 100644 --- a/ui/src/components/RandomMewWithTagList.vue +++ b/ui/src/components/RandomMewWithTagList.vue @@ -40,9 +40,8 @@ const props = defineProps<{ const tagRef = computed(() => props.tag); -const fetchRandomMewHashesWithTag = (): Promise => { - console.log("fetchRandomMewHashesWithTag", props.tag); - return client.callZome({ +const fetchRandomMewHashesWithTag = (): Promise => + client.callZome({ role_name: "mewsfeed", zome_name: "mews", fn_name: "get_random_mew_hashes_for_tag", @@ -51,7 +50,6 @@ const fetchRandomMewHashesWithTag = (): Promise => { count: 3, }, }); -}; const { data: randomMewHashesWithTag, diff --git a/ui/src/pages/AgentProfile.vue b/ui/src/pages/AgentProfile.vue index bf576856..69e96bf2 100644 --- a/ui/src/pages/AgentProfile.vue +++ b/ui/src/pages/AgentProfile.vue @@ -123,11 +123,11 @@ @@ -162,7 +162,7 @@ const agentPubKey = computed(() => const showEditProfileDialog = ref(false); const showFollowersListDialog = ref(false); const showCreatorsListDialog = ref(false); - +const agentPubKeyRef = computed(() => route.params.agentPubKey); const pageLimit = 5; const fetchAuthoredMews = () => @@ -184,11 +184,7 @@ const { error: errorAuthoredMews, refetch: refetchAuthoredMews, } = useQuery({ - queryKey: [ - "profiles", - "get_agent_mews_with_context", - route.params.agentPubKey, - ], + queryKey: ["profiles", "get_agent_mews_with_context", agentPubKeyRef], queryFn: fetchAuthoredMews, }); watch(errorAuthoredMews, console.error); @@ -207,11 +203,7 @@ const { error: errorPinnedMews, refetch: refetchPinnedMews, } = useQuery({ - queryKey: [ - "profiles", - "get_mews_for_pinner_with_context", - route.params.agentPubKey, - ], + queryKey: ["profiles", "get_mews_for_pinner_with_context", agentPubKeyRef], queryFn: fetchPinnedMews, }); watch(errorPinnedMews, console.error); @@ -241,7 +233,7 @@ const { error: errorProfile, refetch: refetchProfile, } = useQuery({ - queryKey: ["profiles", "getAgentProfile", route.params.agentPubKey], + queryKey: ["profiles", "getAgentProfile", agentPubKeyRef], queryFn: fetchProfileWithContext, }); watch(errorProfile, console.error); @@ -252,7 +244,7 @@ const fetchFollowers = async () => { zome_name: "follows", fn_name: "get_followers_for_creator", payload: { - creator: decodeHashFromBase64(route.params.agentPubKey as string), + creator: agentPubKey.value, page: { limit: pageLimit, }, @@ -260,12 +252,12 @@ const fetchFollowers = async () => { }); const agentProfiles = await Promise.all( - agents.map(async (agentPubKey) => { - const profile = await profilesStore.client.getAgentProfile(agentPubKey); + agents.map(async (key) => { + const profile = await profilesStore.client.getAgentProfile(key); if (!profile) return null; return { - agentPubKey, + agentPubKey: key, profile: profile, }; }) @@ -275,7 +267,7 @@ const fetchFollowers = async () => { }; const { data: followers, error: errorFollowers } = useQuery({ - queryKey: ["follows", "get_followers_for_creator", route.params.agentPubKey], + queryKey: ["follows", "get_followers_for_creator", agentPubKeyRef], queryFn: fetchFollowers, }); watch(errorFollowers, console.error); @@ -286,7 +278,7 @@ const fetchCreators = async () => { zome_name: "follows", fn_name: "get_creators_for_follower", payload: { - follower: decodeHashFromBase64(route.params.agentPubKey as string), + follower: agentPubKey.value, page: { limit: pageLimit, }, @@ -309,7 +301,7 @@ const fetchCreators = async () => { }; const { data: creators, error: errorCreators } = useQuery({ - queryKey: ["follows", "get_creators_for_follower", route.params.agentPubKey], + queryKey: ["follows", "get_creators_for_follower", agentPubKeyRef], queryFn: fetchCreators, }); watch(errorCreators, console.error); @@ -319,15 +311,11 @@ const fetchCreatorsCount = async (): Promise => role_name: "mewsfeed", zome_name: "follows", fn_name: "count_creators_for_follower", - payload: decodeHashFromBase64(route.params.agentPubKey as string), + payload: agentPubKey.value, }); const { data: creatorsCount, error: errorCreatorsCount } = useQuery({ - queryKey: [ - "follows", - "count_creators_for_follower", - route.params.agentPubKey, - ], + queryKey: ["follows", "count_creators_for_follower", agentPubKeyRef], queryFn: fetchCreatorsCount, }); watch(errorCreatorsCount, console.error); @@ -337,7 +325,7 @@ const fetchFollowersCount = async (): Promise => role_name: "mewsfeed", zome_name: "follows", fn_name: "count_followers_for_creator", - payload: decodeHashFromBase64(route.params.agentPubKey as string), + payload: agentPubKey.value, }); const { @@ -345,11 +333,7 @@ const { error: errorFollowersCount, refetch: refetchFollowersCount, } = useQuery({ - queryKey: [ - "follows", - "count_followers_for_creator", - route.params.agentPubKey, - ], + queryKey: ["follows", "count_followers_for_creator", agentPubKeyRef], queryFn: fetchFollowersCount, }); watch(errorFollowersCount, console.error); diff --git a/ui/src/pages/MewYarn.vue b/ui/src/pages/MewYarn.vue index d407de0f..3847c959 100644 --- a/ui/src/pages/MewYarn.vue +++ b/ui/src/pages/MewYarn.vue @@ -80,6 +80,7 @@ const pageLimit = 10; const actionHash = computed(() => decodeHashFromBase64(route.params.actionHash as string) ); +const actionHashB64 = computed(() => route.params.actionHash); const hasActionHash = computed(() => actionHash.value !== undefined); const fetchMew = () => @@ -96,7 +97,7 @@ const { isInitialLoading: isInitialLoadingMew, refetch: refetchMew, } = useQuery({ - queryKey: ["mews", "get_mew_with_context", route.params.actionHash], + queryKey: ["mews", "get_mew_with_context", actionHashB64], queryFn: fetchMew, enabled: hasActionHash, refetchInterval: 1000 * 60 * 2, // 2 minutes @@ -128,11 +129,7 @@ const { isInitialLoading: isInitialLoadingReplies, refetch: refetchReplies, } = useInfiniteQuery({ - queryKey: [ - "mews", - "get_responses_for_mew_with_context", - route.params.actionHash, - ], + queryKey: ["mews", "get_responses_for_mew_with_context", actionHashB64], queryFn: fetchReplies, enabled: hasMew, getNextPageParam: (lastPage) => { diff --git a/ui/src/pages/MewsListAuthor.vue b/ui/src/pages/MewsListAuthor.vue index 9cc11872..7964fee4 100644 --- a/ui/src/pages/MewsListAuthor.vue +++ b/ui/src/pages/MewsListAuthor.vue @@ -62,7 +62,7 @@