Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
19 changes: 16 additions & 3 deletions src/components/FrameworkSelect.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import * as React from 'react'
import { create } from 'zustand'
import { useNavigate, useParams } from '@tanstack/react-router'
import { useQueryClient } from '@tanstack/react-query'
import { Select } from './Select'
import { Framework, getLibrary, LibraryId } from '~/libraries'
import { getFrameworkOptions } from '~/libraries/frameworks'
import { useCurrentUserQuery } from '~/hooks/useCurrentUser'
import {
currentUserQueryOptions,
useCurrentUserQuery,
} from '~/hooks/useCurrentUser'
import { updateLastUsedFramework } from '~/utils/users.functions'

function persistFrameworkToServer(framework: string) {
Expand Down Expand Up @@ -72,18 +76,22 @@ export function getStoredFrameworkPreference(): string | undefined {
*/
export function usePersistFrameworkPreference() {
const userQuery = useCurrentUserQuery()
const queryClient = useQueryClient()
const localCurrentFramework = useLocalCurrentFramework()

return React.useCallback(
(framework: string) => {
// Always update localStorage as fallback
localCurrentFramework.setCurrentFramework(framework)
queryClient.setQueryData(currentUserQueryOptions.queryKey, (user) =>
user ? { ...user, lastUsedFramework: framework } : user,
)
// Update DB for logged-in users (fire-and-forget)
if (userQuery.data) {
persistFrameworkToServer(framework)
}
},
[localCurrentFramework, userQuery.data],
[localCurrentFramework, queryClient, userQuery.data],
)
}

Expand Down Expand Up @@ -115,6 +123,7 @@ function useFrameworkConfig({ frameworks }: { frameworks: Framework[] }) {
export function useCurrentFramework(frameworks: Framework[]) {
const navigate = useNavigate()
const userQuery = useCurrentUserQuery()
const queryClient = useQueryClient()

const { framework: paramsFramework } = useParams({
strict: false,
Expand All @@ -138,12 +147,16 @@ export function useCurrentFramework(frameworks: Framework[]) {
})
// Always update localStorage as fallback
localCurrentFramework.setCurrentFramework(framework)
queryClient.setQueryData(currentUserQueryOptions.queryKey, (user) =>
user ? { ...user, lastUsedFramework: framework } : user,
)

// Update DB for logged-in users (fire-and-forget)
if (userQuery.data) {
persistFrameworkToServer(framework)
}
},
[localCurrentFramework, navigate, userQuery.data],
[localCurrentFramework, navigate, queryClient, userQuery.data],
)

React.useEffect(() => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export function Select<T extends SelectOption>({
</span>
</button>
</DropdownTrigger>
<DropdownContent align="start" className="max-h-60 overflow-auto">
<DropdownContent align="start" className="max-h-80 overflow-auto">
{available.map((option) => (
<DropdownItem
key={option.value}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useToast } from '~/components/ToastProvider'
import { Button } from '~/ui'
import { removeProfileImage, revertProfileImage } from '~/utils/users.functions'
import { useUploadThing } from '~/utils/uploadthing.client'
import { currentUserQueryOptions } from '~/hooks/useCurrentUser'

type AccountProfileUser = {
image?: string | null
Expand All @@ -33,7 +34,7 @@ export function AccountProfilePictureSection({
const { startUpload } = useUploadThing('avatarUploader', {
onClientUploadComplete: () => {
setIsUploading(false)
queryClient.invalidateQueries({ queryKey: ['currentUser'] })
queryClient.invalidateQueries(currentUserQueryOptions)
notify(
<div>
<div className="font-medium">Profile picture updated</div>
Expand Down Expand Up @@ -81,7 +82,7 @@ export function AccountProfilePictureSection({
setIsReverting(true)
try {
await revertProfileImage()
queryClient.invalidateQueries({ queryKey: ['currentUser'] })
queryClient.invalidateQueries(currentUserQueryOptions)
notify(
<div>
<div className="font-medium">Profile picture reverted</div>
Expand All @@ -108,7 +109,7 @@ export function AccountProfilePictureSection({
setIsRemoving(true)
try {
await removeProfileImage()
queryClient.invalidateQueries({ queryKey: ['currentUser'] })
queryClient.invalidateQueries(currentUserQueryOptions)
notify(
<div>
<div className="font-medium">Profile picture removed</div>
Expand Down
5 changes: 2 additions & 3 deletions src/components/game/ui/DebugPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,16 @@ import {
PARTNER_UPGRADE_ORDER,
SHOWCASE_UPGRADE_ORDER,
} from '../utils/upgrades'
import { currentUserQueryOptions } from '~/hooks/useCurrentUser'

const UPGRADE_ORDER = [...PARTNER_UPGRADE_ORDER, ...SHOWCASE_UPGRADE_ORDER]
import { getCurrentUser } from '~/utils/auth.functions'

export function DebugPanel() {
const [isCollapsed, setIsCollapsed] = useState(true)

// Fetch user directly without route context dependency
const userQuery = useQuery({
queryKey: ['currentUser'],
queryFn: () => getCurrentUser(),
...currentUserQueryOptions,
staleTime: 30 * 1000,
})

Expand Down
3 changes: 2 additions & 1 deletion src/contexts/LoginModalContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import * as React from 'react'
import { useQueryClient } from '@tanstack/react-query'
import { LoginModal } from '~/components/LoginModal'
import { currentUserQueryOptions } from '~/hooks/useCurrentUser'

interface LoginModalContextValue {
openLoginModal: (options?: { onSuccess?: () => void }) => void
Expand Down Expand Up @@ -47,7 +48,7 @@ export function LoginModalProvider({ children }: LoginModalProviderProps) {
const handleMessage = (event: MessageEvent) => {
if (event.origin !== window.location.origin) return
if (event.data?.type === 'TANSTACK_AUTH_SUCCESS') {
queryClient.invalidateQueries({ queryKey: ['currentUser'] })
queryClient.invalidateQueries(currentUserQueryOptions)
const onSuccess = pendingOnSuccessRef.current
setIsOpen(false)
pendingOnSuccessRef.current = undefined
Expand Down
16 changes: 10 additions & 6 deletions src/hooks/useCurrentUser.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
import { useQuery } from '@tanstack/react-query'
import { useQuery, queryOptions } from '@tanstack/react-query'
import { useRouteContext } from '@tanstack/react-router'
import { getCurrentUser } from '~/utils/auth.functions'

export const currentUserQueryOptions = queryOptions({
queryKey: ['currentUser'],
queryFn: async () => {
return getCurrentUser()
},
staleTime: 5 * 1000,
})

export function useCurrentUserQuery() {
// Get user from route context (set in beforeLoad)
const routeContext = useRouteContext({ strict: false })
const contextUser = routeContext?.user

return useQuery({
queryKey: ['currentUser'],
queryFn: async () => {
return getCurrentUser()
},
...currentUserQueryOptions,
initialData: contextUser,
staleTime: 5 * 1000,
})
}

Expand Down
4 changes: 2 additions & 2 deletions src/libraries/libraries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const query: LibrarySlim = {
tagline:
'Powerful asynchronous state management, server-state utilities and data fetching',
description:
'Powerful asynchronous state management, server-state utilities and data fetching. Fetch, cache, update, and wrangle all forms of async data in your TS/JS, React, Vue, Solid, Svelte & Angular applications all without touching any "global state"',
'Powerful asynchronous state management, server-state utilities and data fetching. Fetch, cache, update, and wrangle all forms of async data in your TS/JS, React, Vue, Solid, Svelte, Angular & Lit applications all without touching any "global state"',
bgStyle: 'bg-red-500',
borderStyle: 'border-red-500/50',
textStyle: 'text-red-500',
Expand All @@ -23,7 +23,7 @@ export const query: LibrarySlim = {
bgRadial: 'from-red-500 via-red-500/60 to-transparent',
badge: undefined,
repo: 'tanstack/query',
frameworks: ['react', 'preact', 'solid', 'vue', 'svelte', 'angular'],
frameworks: ['react', 'preact', 'solid', 'vue', 'svelte', 'angular', 'lit'],
latestVersion: 'v5',
latestBranch: 'main',
availableVersions: ['v5', 'v4', 'v3'],
Expand Down
2 changes: 1 addition & 1 deletion src/libraries/query.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const textStyles = 'text-red-500 dark:text-red-400'
export const queryProject = {
...query,
description:
'Powerful asynchronous state management, server-state utilities and data fetching. Fetch, cache, update, and wrangle all forms of async data in your TS/JS, React, Vue, Solid, Svelte & Angular applications all without touching any "global state"',
'Powerful asynchronous state management, server-state utilities and data fetching. Fetch, cache, update, and wrangle all forms of async data in your TS/JS, React, Vue, Solid, Svelte, Angular & Lit applications all without touching any "global state"',
latestBranch: 'main',
bgRadial: 'from-red-500 via-red-500/60 to-transparent',
textColor: 'text-amber-500',
Expand Down
Loading