refactor: remove unnecessary window checks across components

- Eliminated checks for `typeof window !== 'undefined'` in various components and utility functions, simplifying the codebase.
- Updated logic to directly access `window` properties, assuming the code runs in a browser environment.
- Improved readability and maintainability by streamlining conditional checks related to window availability.

Signed-off-by: Innei <tukon479@gmail.com>
This commit is contained in:
Innei
2025-11-13 15:03:46 +08:00
parent 76a4c251e4
commit 936666d8a2
16 changed files with 15 additions and 106 deletions

View File

@@ -118,11 +118,6 @@ export const usePhotoViewerTransitions = ({
if (!isOpen || !currentPhoto) return
if (entryTransition || isViewerContentVisible) return
if (typeof window === 'undefined') {
setIsViewerContentVisible(true)
return
}
const triggerEl = resolveTriggerElement()
if (!triggerEl) {
@@ -208,12 +203,6 @@ export const usePhotoViewerTransitions = ({
return
}
if (typeof window === 'undefined') {
wasOpenRef.current = false
restoreTriggerElementVisibility()
return
}
const triggerEl = resolveTriggerElement()
if (!triggerEl || !triggerEl.isConnected) {

View File

@@ -15,7 +15,7 @@ const THUMBNAIL_PADDING = {
} as const
export const escapeAttributeValue = (value: string) => {
if (typeof window !== 'undefined' && window.CSS?.escape) {
if (window.CSS?.escape) {
return window.CSS.escape(value)
}
@@ -23,14 +23,13 @@ export const escapeAttributeValue = (value: string) => {
}
const getRootFontSize = () => {
if (typeof window === 'undefined') return 16
const value = window.getComputedStyle(document.documentElement).fontSize
const parsed = Number.parseFloat(value || '16')
return Number.isNaN(parsed) ? 16 : parsed
}
export const getBorderRadius = (element: Element | null) => {
if (typeof window === 'undefined' || !element) return 0
if (!element) return 0
const computedStyle = window.getComputedStyle(element)
const radiusCandidates = [

View File

@@ -11,7 +11,7 @@ const defaultInjectConfig = {
export const injectConfig = merge(defaultInjectConfig, __CONFIG__)
const getInjectedSiteConfig = (): Partial<SiteConfig> | undefined => {
if (typeof window !== 'undefined' && window.__SITE_CONFIG__) {
if (window.__SITE_CONFIG__) {
return window.__SITE_CONFIG__
}

View File

@@ -1,7 +1,6 @@
export const isSafari = /Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent)
export const isMobileDevice = (() => {
if (typeof window === 'undefined') return false
return (
/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ||
// 现代检测方式:支持触摸且屏幕较小

View File

@@ -19,21 +19,18 @@ export function ErrorElement() {
}, [error])
const reloadTriggeredRef = useRef(false)
const hasWindow = typeof window !== 'undefined'
const shouldAttemptReload =
hasWindow &&
message.startsWith('Failed to fetch dynamically imported module') &&
window.sessionStorage.getItem('reload') !== '1'
message.startsWith('Failed to fetch dynamically imported module') && window.sessionStorage.getItem('reload') !== '1'
useEffect(() => {
if (!shouldAttemptReload || reloadTriggeredRef.current || !hasWindow) {
if (!shouldAttemptReload || reloadTriggeredRef.current) {
return
}
reloadTriggeredRef.current = true
window.sessionStorage.setItem('reload', '1')
window.location.reload()
}, [hasWindow, shouldAttemptReload])
}, [shouldAttemptReload])
if (shouldAttemptReload) {
return null

View File

@@ -17,7 +17,7 @@ export const coreApi = $fetch.create({
setAccessDenied({
active: true,
status: 403,
path: typeof window !== 'undefined' ? window.location.pathname : current?.path,
path: window.location.pathname,
scope: current?.scope ?? 'api',
reason: detail,
source: 'api',

View File

@@ -33,10 +33,8 @@ export const SocialAuthButtons = memo(function SocialAuthButtons({
if (callbackURL) {
return callbackURL
}
if (typeof window !== 'undefined') {
return window.location.href
}
return
return window.location.href
}, [callbackURL])
const handleSocialClick = useCallback(

View File

@@ -46,11 +46,6 @@ export function SocialConnectionSettings() {
const handleConnect = useCallback(
async (providerId: string, providerName: string) => {
if (typeof window === 'undefined') {
toast.error('当前环境不支持 OAuth 绑定')
return
}
const url = new URL(window.location.href)
url.searchParams.set('auth-flow', 'link')
url.searchParams.set('provider', providerId)

View File

@@ -25,7 +25,7 @@ export function useLogin() {
const loginMutation = useMutation({
mutationFn: async (data: LoginRequest) => {
if (data.requireRootDomain) {
const slug = typeof window !== 'undefined' ? getTenantSlugFromHost(window.location.hostname) : null
const slug = getTenantSlugFromHost(window.location.hostname)
if (slug !== 'root') {
const rootUrl = buildRootTenantUrl('/root-login')
window.location.replace(rootUrl)
@@ -56,7 +56,7 @@ export function useLogin() {
const isSuperAdmin = session.user.role === 'superadmin'
if (tenant && !tenant.isPlaceholder && tenant.slug) {
const currentSlug = typeof window !== 'undefined' ? getTenantSlugFromHost(window.location.hostname) : null
const currentSlug = getTenantSlugFromHost(window.location.hostname)
if (!isSuperAdmin && tenant.slug !== currentSlug) {
try {
const targetUrl = buildTenantUrl(tenant.slug, '/')

View File

@@ -65,10 +65,6 @@ export function buildTenantUrl(slug: string, path = '/'): string {
throw new Error('Workspace slug is required to build tenant URL.')
}
if (typeof window === 'undefined') {
throw new TypeError('Cannot build tenant URL outside the browser environment.')
}
const { protocol, hostname, port } = window.location
const baseDomain = resolveBaseDomain(hostname)

View File

@@ -44,7 +44,6 @@ const STAGE_ORDER: PhotoSyncProgressStage[] = [
]
const MAX_SYNC_LOGS = 200
const PHOTO_SYNC_RESULT_STORAGE_KEY = 'photo-sync:last-result'
function createInitialStages(totals: PhotoSyncProgressState['totals']): PhotoSyncProgressState['stages'] {
return STAGE_ORDER.reduce<PhotoSyncProgressState['stages']>(
@@ -73,32 +72,6 @@ export function PhotoPage() {
const [resolvingConflictId, setResolvingConflictId] = useState<string | null>(null)
const [syncProgress, setSyncProgress] = useState<PhotoSyncProgressState | null>(null)
useEffect(() => {
if (typeof window === 'undefined') {
return
}
const restoreStoredResult = () => {
try {
const cached = window.sessionStorage.getItem(PHOTO_SYNC_RESULT_STORAGE_KEY)
if (!cached) {
return
}
const parsed = JSON.parse(cached) as { result?: PhotoSyncResult; lastWasDryRun?: boolean | null }
if (parsed?.result) {
setResult(parsed.result)
setLastWasDryRun(parsed.lastWasDryRun ?? null)
}
} catch (error) {
console.error('Failed to restore cached photo sync result', error)
window.sessionStorage.removeItem(PHOTO_SYNC_RESULT_STORAGE_KEY)
}
}
restoreStoredResult()
}, [])
useEffect(() => {
setActiveTab(normalizedInitialTab)
}, [normalizedInitialTab])
@@ -303,16 +276,7 @@ export function PhotoPage() {
setResult(data)
setLastWasDryRun(context.dryRun)
setSyncProgress(null)
if (typeof window !== 'undefined') {
try {
window.sessionStorage.setItem(
PHOTO_SYNC_RESULT_STORAGE_KEY,
JSON.stringify({ result: data, lastWasDryRun: context.dryRun }),
)
} catch (error) {
console.error('Failed to persist photo sync result snapshot', error)
}
}
void summaryQuery.refetch()
void listQuery.refetch()
},

View File

@@ -173,10 +173,6 @@ export function PhotoSyncConflictsPanel({
}
const confirmAction = (message: string, onConfirm: () => void | Promise<void>) => {
if (typeof window === 'undefined') {
return onConfirm()
}
Prompt.prompt({
title: '确认操作',
description: message,

View File

@@ -1,7 +1,4 @@
export const getCurrentHostname = (): string | null => {
if (typeof window === 'undefined') {
return null
}
try {
return window.location.hostname
} catch {
@@ -10,10 +7,6 @@ export const getCurrentHostname = (): string | null => {
}
export const buildRegistrationUrl = (): string => {
if (typeof window === 'undefined') {
return '/platform/welcome'
}
try {
const { protocol, host } = window.location
return `${protocol}//${host}/platform/welcome`
@@ -23,10 +16,6 @@ export const buildRegistrationUrl = (): string => {
}
export const buildHomeUrl = (): string => {
if (typeof window === 'undefined') {
return '/'
}
try {
const { protocol, hostname, port } = window.location
const normalizedPort = port ? `:${port}` : ''

View File

@@ -12,9 +12,6 @@ export function Component() {
const [password, setPassword] = useState('')
const { login, isLoading, error, clearError } = useLogin()
const tenantSlug = useMemo(() => {
if (typeof window === 'undefined') {
return null
}
return getTenantSlugFromHost(window.location.hostname)
}, [])
const showEmailLogin = !tenantSlug

View File

@@ -14,9 +14,6 @@ export function Component() {
const { login, isLoading, error, clearError } = useLogin()
const tenantSlug = useMemo(() => {
if (typeof window === 'undefined') {
return null
}
return getTenantSlugFromHost(window.location.hostname)
}, [])
const rootLoginHref = useMemo(() => {
@@ -33,10 +30,6 @@ export function Component() {
return
}
if (typeof window === 'undefined') {
return
}
const targetUrl = buildRootTenantUrl('/root-login')
if (window.location.href === targetUrl) {
return
@@ -89,9 +82,7 @@ export function Component() {
variant="primary"
className="w-full"
onClick={() => {
if (typeof window !== 'undefined') {
window.location.href = rootLoginHref
}
window.location.href = rootLoginHref
}}
>
Go to root portal

View File

@@ -30,9 +30,8 @@ function App({ url }: { url?: string }) {
setCurrentPath(path)
setIsSidebarOpen(false) // 导航后关闭侧边栏
// 在实际应用中,这里会更新浏览器历史记录
if (typeof window !== 'undefined') {
window.history.pushState({}, '', path)
}
window.history.pushState({}, '', path)
},
[setCurrentPath, setIsSidebarOpen],
)