fix: optimized splashText working process
This commit is contained in:
parent
f921275c87
commit
051cc5b35c
4 changed files with 91 additions and 14 deletions
|
|
@ -26,6 +26,7 @@
|
|||
}
|
||||
],
|
||||
"rightSideText": "A Minecraft client clone in the browser!",
|
||||
"splashTextFallback": "GEN is cooking",
|
||||
"splashText": "https://jsonplaceholder.typicode.com/posts/1",
|
||||
"pauseLinks": [
|
||||
[
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ export type AppConfig = {
|
|||
// hideSettings?: Record<string, boolean>
|
||||
allowAutoConnect?: boolean
|
||||
splashText?: string
|
||||
splashTextFallback?: string
|
||||
pauseLinks?: Array<Array<Record<string, any>>>
|
||||
keybindings?: Record<string, any>
|
||||
defaultLanguage?: string
|
||||
|
|
|
|||
|
|
@ -4,7 +4,15 @@ import { useSnapshot } from 'valtio'
|
|||
import { haveDirectoryPicker } from '../utils'
|
||||
import { ConnectOptions } from '../connect'
|
||||
import { miscUiState } from '../globalState'
|
||||
import { isRemoteSplashText, loadRemoteSplashText } from '../utils/splashText'
|
||||
import {
|
||||
isRemoteSplashText,
|
||||
loadRemoteSplashText,
|
||||
getDisplayText,
|
||||
cacheSplashText,
|
||||
hasSourceUrlChanged,
|
||||
cacheSourceUrl,
|
||||
clearSplashCache
|
||||
} from '../utils/splashText'
|
||||
import styles from './mainMenu.module.css'
|
||||
import Button from './Button'
|
||||
import ButtonWithTooltip from './ButtonWithTooltip'
|
||||
|
|
@ -48,24 +56,46 @@ export default ({
|
|||
singleplayerAvailable = true
|
||||
}: Props) => {
|
||||
const { appConfig } = useSnapshot(miscUiState)
|
||||
const [splashText, setSplashText] = useState(appConfig?.splashText || '')
|
||||
|
||||
useEffect(() => {
|
||||
if (hasSourceUrlChanged(appConfig?.splashText)) {
|
||||
clearSplashCache()
|
||||
if (appConfig?.splashText && isRemoteSplashText(appConfig.splashText)) {
|
||||
cacheSourceUrl(appConfig.splashText)
|
||||
}
|
||||
}
|
||||
}, [appConfig?.splashText])
|
||||
|
||||
const initialSplashText = getDisplayText(appConfig?.splashText, appConfig?.splashTextFallback)
|
||||
const [splashText, setSplashText] = useState(initialSplashText)
|
||||
const [showSplash, setShowSplash] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => {
|
||||
setShowSplash(true)
|
||||
}, 100)
|
||||
return () => clearTimeout(timer)
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
const loadSplashText = async () => {
|
||||
try {
|
||||
if (appConfig?.splashText && isRemoteSplashText(appConfig.splashText)) {
|
||||
const text = await loadRemoteSplashText(appConfig.splashText)
|
||||
setSplashText(text)
|
||||
} else {
|
||||
setSplashText(appConfig?.splashText || '')
|
||||
|
||||
if (text && text.trim() !== '') {
|
||||
setSplashText(text)
|
||||
cacheSplashText(text)
|
||||
}
|
||||
} else if (appConfig?.splashText && !isRemoteSplashText(appConfig.splashText)) {
|
||||
setSplashText(appConfig.splashText)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to load splash text:', error)
|
||||
setSplashText('Error loading splash text')
|
||||
}
|
||||
}
|
||||
void loadSplashText()
|
||||
}, [appConfig?.splashText])
|
||||
}, [appConfig?.splashText, appConfig?.splashTextFallback])
|
||||
|
||||
if (!bottomRightLinks?.trim()) bottomRightLinks = undefined
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||
|
|
@ -112,7 +142,7 @@ export default ({
|
|||
<div className={styles['game-title']}>
|
||||
<div className={styles.minecraft}>
|
||||
<div className={styles.edition} />
|
||||
<span className={styles.splash}>{splashText}</span>
|
||||
{showSplash && <span className={styles.splash}>{splashText}</span>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,15 @@
|
|||
const MAX_WORDS = 5
|
||||
const HTTPS_REGEX = /^https?:\/\/[-\w@:%.+~#=]{1,256}\.[a-zA-Z\d()]{1,6}\b([-\w()@:%+.~#?&/=]*)$/
|
||||
const TIMEOUT_MS = 5000
|
||||
|
||||
const sanitizeText = (text: string): string => {
|
||||
return text.replaceAll(/<[^>]*>/g, '').replaceAll(/[^\w\s.,!?-]/g, '')
|
||||
}
|
||||
const SPLASH_CACHE_KEY = 'minecraft_splash_text_cache'
|
||||
const SPLASH_URL_KEY = 'minecraft_splash_url'
|
||||
|
||||
const limitWords = (text: string): string => {
|
||||
const words = text.split(/\s+/)
|
||||
if (words.length <= MAX_WORDS) {
|
||||
return sanitizeText(text)
|
||||
return text
|
||||
}
|
||||
return sanitizeText(words.slice(0, MAX_WORDS).join(' ') + '...')
|
||||
return words.slice(0, MAX_WORDS).join(' ') + '...'
|
||||
}
|
||||
|
||||
export const isRemoteSplashText = (text: string): boolean => {
|
||||
|
|
@ -50,3 +48,50 @@ export const loadRemoteSplashText = async (url: string): Promise<string> => {
|
|||
return 'Failed to load splash text!'
|
||||
}
|
||||
}
|
||||
|
||||
export const cacheSourceUrl = (url: string): void => {
|
||||
localStorage.setItem(SPLASH_URL_KEY, url)
|
||||
}
|
||||
|
||||
export const hasSourceUrlChanged = (newUrl?: string): boolean => {
|
||||
const cachedUrl = localStorage.getItem(SPLASH_URL_KEY)
|
||||
|
||||
if ((!cachedUrl && newUrl) || (cachedUrl && !newUrl)) {
|
||||
return true
|
||||
}
|
||||
|
||||
return cachedUrl !== newUrl
|
||||
}
|
||||
|
||||
export const clearSplashCache = (): void => {
|
||||
localStorage.removeItem(SPLASH_CACHE_KEY)
|
||||
}
|
||||
|
||||
export const getCachedSplashText = (): string | null => {
|
||||
return localStorage.getItem(SPLASH_CACHE_KEY)
|
||||
}
|
||||
|
||||
export const cacheSplashText = (text: string): void => {
|
||||
localStorage.setItem(SPLASH_CACHE_KEY, text)
|
||||
}
|
||||
|
||||
export const getDisplayText = (splashText?: string, fallbackText?: string): string => {
|
||||
const cachedText = getCachedSplashText()
|
||||
|
||||
if (cachedText) return cachedText
|
||||
|
||||
if (fallbackText) return fallbackText
|
||||
|
||||
if (splashText && isRemoteSplashText(splashText)) return ''
|
||||
|
||||
return splashText || ''
|
||||
}
|
||||
|
||||
export const getDirectDisplayText = (splashText?: string, fallbackText?: string): string => {
|
||||
|
||||
if (splashText && !isRemoteSplashText(splashText)) return splashText
|
||||
|
||||
if (fallbackText) return fallbackText
|
||||
|
||||
return ''
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue