@lovalingo/lovalingo 0.3.0 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -9,6 +9,7 @@ import { processPath } from '../utils/pathNormalizer';
|
|
|
9
9
|
import { LanguageSwitcher } from './LanguageSwitcher';
|
|
10
10
|
const LOCALE_STORAGE_KEY = 'Lovalingo_locale';
|
|
11
11
|
const LOADING_BG_STORAGE_PREFIX = "Lovalingo_loading_bg_color";
|
|
12
|
+
const BRANDING_STORAGE_PREFIX = "Lovalingo_branding_enabled";
|
|
12
13
|
const CRITICAL_CACHE_PREFIX = "Lovalingo_critical_v0_3";
|
|
13
14
|
export const LovalingoProvider = ({ children, apiKey: apiKeyProp, publicAnonKey, defaultLocale, locales, apiBase = 'https://leuskvkajliuzalrlwhw.supabase.co', routing = 'query', // Default to query mode (backward compatible)
|
|
14
15
|
autoPrefixLinks = true, autoApplyRules = true, switcherPosition = 'bottom-right', switcherOffsetY = 20, switcherTheme = 'dark', editMode: initialEditMode = false, editKey = 'KeyE', pathNormalization = { enabled: true }, // Enable by default
|
|
@@ -80,6 +81,21 @@ navigateRef, // For path mode routing
|
|
|
80
81
|
const exclusionsCacheRef = useRef(null);
|
|
81
82
|
const domRulesCacheRef = useRef(new Map());
|
|
82
83
|
const loadingBgStorageKey = `${LOADING_BG_STORAGE_PREFIX}:${resolvedApiKey || "anonymous"}`;
|
|
84
|
+
const brandingStorageKey = `${BRANDING_STORAGE_PREFIX}:${resolvedApiKey || "anonymous"}`;
|
|
85
|
+
const readBrandingCache = () => {
|
|
86
|
+
try {
|
|
87
|
+
const cached = (localStorage.getItem(brandingStorageKey) || "").trim();
|
|
88
|
+
if (cached === "0")
|
|
89
|
+
return false;
|
|
90
|
+
if (cached === "1")
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// ignore
|
|
95
|
+
}
|
|
96
|
+
return true;
|
|
97
|
+
};
|
|
98
|
+
const [brandingEnabled, setBrandingEnabled] = useState(readBrandingCache);
|
|
83
99
|
const prehideStateRef = useRef({
|
|
84
100
|
active: false,
|
|
85
101
|
timeoutId: null,
|
|
@@ -110,6 +126,18 @@ navigateRef, // For path mode routing
|
|
|
110
126
|
// ignore
|
|
111
127
|
}
|
|
112
128
|
}, [loadingBgStorageKey]);
|
|
129
|
+
const setCachedBrandingEnabled = useCallback((enabled) => {
|
|
130
|
+
try {
|
|
131
|
+
localStorage.setItem(brandingStorageKey, enabled === false ? "0" : "1");
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
// ignore
|
|
135
|
+
}
|
|
136
|
+
}, [brandingStorageKey]);
|
|
137
|
+
useEffect(() => {
|
|
138
|
+
setBrandingEnabled(readBrandingCache());
|
|
139
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
140
|
+
}, [brandingStorageKey]);
|
|
113
141
|
const enablePrehide = useCallback((bgColor) => {
|
|
114
142
|
if (typeof document === "undefined")
|
|
115
143
|
return;
|
|
@@ -299,14 +327,26 @@ navigateRef, // For path mode routing
|
|
|
299
327
|
return;
|
|
300
328
|
let cancelled = false;
|
|
301
329
|
(async () => {
|
|
302
|
-
const
|
|
303
|
-
if (
|
|
304
|
-
|
|
330
|
+
const bootstrap = await apiRef.current.fetchBootstrap(locale, window.location.pathname + window.location.search);
|
|
331
|
+
if (cancelled)
|
|
332
|
+
return;
|
|
333
|
+
if (bootstrap?.entitlements)
|
|
334
|
+
setEntitlements(bootstrap.entitlements);
|
|
335
|
+
if (bootstrap?.loading_bg_color)
|
|
336
|
+
setCachedLoadingBgColor(bootstrap.loading_bg_color);
|
|
337
|
+
if (bootstrap?.entitlements?.brandingRequired) {
|
|
338
|
+
setBrandingEnabled(true);
|
|
339
|
+
setCachedBrandingEnabled(true);
|
|
340
|
+
}
|
|
341
|
+
else if (typeof bootstrap?.branding_enabled === "boolean") {
|
|
342
|
+
setBrandingEnabled(bootstrap.branding_enabled);
|
|
343
|
+
setCachedBrandingEnabled(bootstrap.branding_enabled);
|
|
344
|
+
}
|
|
305
345
|
})();
|
|
306
346
|
return () => {
|
|
307
347
|
cancelled = true;
|
|
308
348
|
};
|
|
309
|
-
}, [defaultLocale, entitlements, locale]);
|
|
349
|
+
}, [defaultLocale, entitlements, locale, setCachedBrandingEnabled, setCachedLoadingBgColor]);
|
|
310
350
|
const applySeoBundle = useCallback((bundle, hreflangEnabled) => {
|
|
311
351
|
try {
|
|
312
352
|
const head = document.head;
|
|
@@ -531,6 +571,14 @@ navigateRef, // For path mode routing
|
|
|
531
571
|
setCachedLoadingBgColor(bootstrap.loading_bg_color);
|
|
532
572
|
enablePrehide(bootstrap.loading_bg_color);
|
|
533
573
|
}
|
|
574
|
+
if ((bootstrap?.entitlements || nextEntitlements)?.brandingRequired) {
|
|
575
|
+
setBrandingEnabled(true);
|
|
576
|
+
setCachedBrandingEnabled(true);
|
|
577
|
+
}
|
|
578
|
+
else if (typeof bootstrap?.branding_enabled === "boolean") {
|
|
579
|
+
setBrandingEnabled(bootstrap.branding_enabled);
|
|
580
|
+
setCachedBrandingEnabled(bootstrap.branding_enabled);
|
|
581
|
+
}
|
|
534
582
|
const exclusions = Array.isArray(bootstrap?.exclusions)
|
|
535
583
|
? bootstrap.exclusions
|
|
536
584
|
.map((row) => {
|
|
@@ -1028,7 +1076,9 @@ navigateRef, // For path mode routing
|
|
|
1028
1076
|
};
|
|
1029
1077
|
return (React.createElement(LovalingoContext.Provider, { value: contextValue },
|
|
1030
1078
|
children,
|
|
1031
|
-
React.createElement(LanguageSwitcher, { locales: allLocales, currentLocale: locale, onLocaleChange: setLocale, position: switcherPosition, offsetY: switcherOffsetY, theme: switcherTheme, branding:
|
|
1032
|
-
|
|
1033
|
-
:
|
|
1079
|
+
React.createElement(LanguageSwitcher, { locales: allLocales, currentLocale: locale, onLocaleChange: setLocale, position: switcherPosition, offsetY: switcherOffsetY, theme: switcherTheme, branding: {
|
|
1080
|
+
required: Boolean(entitlements?.brandingRequired),
|
|
1081
|
+
enabled: brandingEnabled,
|
|
1082
|
+
href: "https://lovalingo.com",
|
|
1083
|
+
} })));
|
|
1034
1084
|
};
|
|
@@ -205,7 +205,7 @@ export const LanguageSwitcher = ({ locales, currentLocale, onLocaleChange, posit
|
|
|
205
205
|
e.currentTarget.style.filter = 'brightness(1)';
|
|
206
206
|
e.currentTarget.style.transform = 'scale(1)';
|
|
207
207
|
}, "aria-label": `Switch to ${locale.toUpperCase()}`, title: locale.toUpperCase(), tabIndex: isOpen ? 0 : -1 }, LANGUAGE_FLAGS[locale] || '🏳️')))),
|
|
208
|
-
branding?.required && (React.createElement("div", { style: badgeRowStyles, "aria-label": "Lovalingo branding" },
|
|
208
|
+
(branding?.required || branding?.enabled) && (React.createElement("div", { style: badgeRowStyles, "aria-label": "Lovalingo branding" },
|
|
209
209
|
React.createElement("a", { href: branding.href || 'https://lovalingo.com', target: "_blank", rel: "noreferrer", style: badgeLinkStyles, tabIndex: isOpen ? 0 : -1, "aria-label": "Localized by Lovalingo", title: "Localized by Lovalingo" },
|
|
210
210
|
React.createElement("span", { style: {
|
|
211
211
|
width: '16px',
|
package/dist/utils/api.d.ts
CHANGED
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "0.3.
|
|
1
|
+
export declare const VERSION = "0.3.2";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = "0.3.
|
|
1
|
+
export const VERSION = "0.3.2";
|
package/package.json
CHANGED