@@ -9,6 +9,8 @@ import useDirDetection from '@/hooks/use-dir-detection'
99
1010const TOPBAR_AD_STORAGE_KEY = 'topbar_ad_closed'
1111const HOURS_TO_HIDE = 24
12+ const TOPBAR_AD_CACHE_KEY = 'topbar_ad_cache'
13+ const CACHE_DURATION = 10 * 60 * 1000 // 10 minutes
1214
1315interface TopbarAdConfig {
1416 enabled : boolean
@@ -25,6 +27,12 @@ interface TopbarAdConfig {
2527 }
2628}
2729
30+ interface CachedAdData {
31+ config : TopbarAdConfig | null
32+ timestamp : number
33+ is404 : boolean
34+ }
35+
2836
2937export default function TopbarAd ( ) {
3038 const { i18n } = useTranslation ( )
@@ -40,6 +48,25 @@ export default function TopbarAd() {
4048 const [ iconError , setIconError ] = useState ( false )
4149
4250 useEffect ( ( ) => {
51+ const getCached = ( ) : CachedAdData | null => {
52+ try {
53+ const cached = localStorage . getItem ( TOPBAR_AD_CACHE_KEY )
54+ if ( ! cached ) return null
55+ return JSON . parse ( cached )
56+ } catch {
57+ return null
58+ }
59+ }
60+
61+ const setCache = ( config : TopbarAdConfig | null , is404 : boolean ) : void => {
62+ try {
63+ const data : CachedAdData = { config, timestamp : Date . now ( ) , is404 }
64+ localStorage . setItem ( TOPBAR_AD_CACHE_KEY , JSON . stringify ( data ) )
65+ } catch {
66+ // Silently fail
67+ }
68+ }
69+
4370 const checkShouldFetch = ( ) => {
4471 const closedTimestamp = localStorage . getItem ( TOPBAR_AD_STORAGE_KEY )
4572
@@ -59,6 +86,23 @@ export default function TopbarAd() {
5986 return
6087 }
6188
89+ // Check cache first
90+ const cached = getCached ( )
91+ if ( cached && Date . now ( ) - cached . timestamp < CACHE_DURATION ) {
92+ // Use cached data if still valid
93+ if ( cached . is404 ) {
94+ // If it's a 404 cache, don't fetch and set config to null
95+ setConfig ( null )
96+ setIsLoading ( false )
97+ return
98+ } else {
99+ // Use cached successful response
100+ setConfig ( cached . config )
101+ setIsLoading ( false )
102+ return
103+ }
104+ }
105+
62106 const loadConfig = async ( ) => {
63107 try {
64108 const githubApiUrl = 'https://api.github.com/repos/pasarguard/ads/contents/config'
@@ -74,15 +118,28 @@ export default function TopbarAd() {
74118 Array . from ( binaryString , ( char ) => '%' + ( '00' + char . charCodeAt ( 0 ) . toString ( 16 ) ) . slice ( - 2 ) ) . join ( '' )
75119 )
76120 const data = JSON . parse ( utf8String )
121+ setCache ( data , false )
77122 setConfig ( data )
78123 } else {
124+ setCache ( null , false )
79125 setConfig ( null )
80126 }
81127 } else {
128+ // Cache 404 errors
129+ if ( response . status === 404 ) {
130+ setCache ( null , true )
131+ } else {
132+ setCache ( null , false )
133+ }
82134 setConfig ( null )
83135 }
84136 } catch ( error ) {
85- setConfig ( null )
137+ // On error, use cached data if available, otherwise set to null
138+ if ( cached && ! cached . is404 ) {
139+ setConfig ( cached . config )
140+ } else {
141+ setConfig ( null )
142+ }
86143 } finally {
87144 setIsLoading ( false )
88145 }
0 commit comments