Skip to content

Commit a117d31

Browse files
author
Daniel Sullivan
authored
Merge pull request #6 from daniel-sullivan/move-to-mui
Fix PWA and SNS linkage
2 parents 305c28e + c3ca3c4 commit a117d31

6 files changed

Lines changed: 533 additions & 11 deletions

File tree

frontend/dist/index.html

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>BabelBridge</title>
7+
<meta name="description" content="A modern web-based translation tool with live language identification and pluggable AI backends. Translate text seamlessly with intelligent context preservation." />
78
<meta name="color-scheme" content="light dark" />
89
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
910
<link rel="manifest" href="/manifest.json" />
@@ -12,7 +13,32 @@
1213
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
1314
<meta name="apple-mobile-web-app-title" content="BabelBridge" />
1415
<link rel="apple-touch-icon" href="/favicon.svg" />
15-
<script type="module" crossorigin src="/assets/index-CcXe80mT.js"></script>
16+
17+
<!-- Open Graph meta tags for social media previews -->
18+
<meta property="og:title" content="BabelBridge - Modern Translation Tool" />
19+
<meta property="og:description" content="A modern web-based translation tool with live language identification and pluggable AI backends. Translate text seamlessly with intelligent context preservation." />
20+
<meta property="og:type" content="website" />
21+
<meta property="og:url" content="https://babel-bridge.com" />
22+
<meta property="og:image" content="/og-image.svg" />
23+
<meta property="og:image:alt" content="BabelBridge - Modern Translation Tool with AI-powered features" />
24+
<meta property="og:image:width" content="1200" />
25+
<meta property="og:image:height" content="630" />
26+
<meta property="og:site_name" content="BabelBridge" />
27+
<meta property="og:locale" content="en_US" />
28+
29+
<!-- Twitter Card meta tags -->
30+
<meta name="twitter:card" content="summary_large_image" />
31+
<meta name="twitter:title" content="BabelBridge - Modern Translation Tool" />
32+
<meta name="twitter:description" content="A modern web-based translation tool with live language identification and pluggable AI backends. Translate text seamlessly with intelligent context preservation." />
33+
<meta name="twitter:image" content="/og-image.svg" />
34+
<meta name="twitter:image:alt" content="BabelBridge - Modern Translation Tool with AI-powered features" />
35+
36+
<!-- Additional meta tags for better SEO -->
37+
<meta name="keywords" content="translation, AI, language, translate, babel, bridge, multilingual, context, preservation" />
38+
<meta name="author" content="Daniel Sullivan" />
39+
<meta name="robots" content="index, follow" />
40+
<link rel="canonical" href="https://babel-bridge.com" />
41+
<script type="module" crossorigin src="/assets/index-CD4TOx2g.js"></script>
1642
</head>
1743
<body>
1844
<div id="root"></div>

frontend/index.html

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>BabelBridge</title>
7+
<meta name="description" content="A modern web-based translation tool with live language identification and pluggable AI backends. Translate text seamlessly with intelligent context preservation." />
78
<meta name="color-scheme" content="light dark" />
89
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
910
<link rel="manifest" href="/manifest.json" />
@@ -12,6 +13,31 @@
1213
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
1314
<meta name="apple-mobile-web-app-title" content="BabelBridge" />
1415
<link rel="apple-touch-icon" href="/favicon.svg" />
16+
17+
<!-- Open Graph meta tags for social media previews -->
18+
<meta property="og:title" content="BabelBridge - Modern Translation Tool" />
19+
<meta property="og:description" content="A modern web-based translation tool with live language identification and pluggable AI backends. Translate text seamlessly with intelligent context preservation." />
20+
<meta property="og:type" content="website" />
21+
<meta property="og:url" content="https://babelbridge.world" />
22+
<meta property="og:image" content="/og-image.svg" />
23+
<meta property="og:image:alt" content="BabelBridge - Modern Translation Tool with AI-powered features" />
24+
<meta property="og:image:width" content="1200" />
25+
<meta property="og:image:height" content="630" />
26+
<meta property="og:site_name" content="BabelBridge" />
27+
<meta property="og:locale" content="en_US" />
28+
29+
<!-- Twitter Card meta tags -->
30+
<meta name="twitter:card" content="summary_large_image" />
31+
<meta name="twitter:title" content="BabelBridge - Modern Translation Tool" />
32+
<meta name="twitter:description" content="A modern web-based translation tool with live language identification and pluggable AI backends. Translate text seamlessly with intelligent context preservation." />
33+
<meta name="twitter:image" content="/og-image.svg" />
34+
<meta name="twitter:image:alt" content="BabelBridge - Modern Translation Tool with AI-powered features" />
35+
36+
<!-- Additional meta tags for better SEO -->
37+
<meta name="keywords" content="translation, AI, language, translate, babel, bridge, multilingual, context, preservation" />
38+
<meta name="author" content="Daniel Sullivan" />
39+
<meta name="robots" content="index, follow" />
40+
<link rel="canonical" href="https://babelbridge.world" />
1541
</head>
1642
<body>
1743
<div id="root"></div>

frontend/public/manifest.json

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,38 @@
11
{
2-
"name": "BabelBridge",
2+
"name": "BabelBridge - Modern Translation Tool",
33
"short_name": "BabelBridge",
4-
"description": "A modern web-based translation tool with live language identification and pluggable AI backends",
4+
"description": "A modern web-based translation tool with live language identification and pluggable AI backends. Translate text seamlessly with intelligent context preservation.",
55
"start_url": "/",
66
"display": "standalone",
7-
"background_color": "#0f1220",
7+
"background_color": "#0f172a",
88
"theme_color": "#6366F1",
99
"orientation": "portrait-primary",
10+
"scope": "/",
11+
"lang": "en",
1012
"icons": [
1113
{
1214
"src": "/favicon.svg",
1315
"sizes": "any",
1416
"type": "image/svg+xml",
1517
"purpose": "any maskable"
18+
},
19+
{
20+
"src": "/og-image.svg",
21+
"sizes": "1200x630",
22+
"type": "image/svg+xml",
23+
"purpose": "any"
24+
}
25+
],
26+
"categories": ["productivity", "utilities", "education"],
27+
"keywords": ["translation", "AI", "language", "translate", "babel", "bridge", "multilingual"],
28+
"screenshots": [
29+
{
30+
"src": "/og-image.svg",
31+
"sizes": "1200x630",
32+
"type": "image/svg+xml",
33+
"label": "BabelBridge main interface"
1634
}
1735
],
18-
"categories": ["productivity", "utilities"],
1936
"shortcuts": [
2037
{
2138
"name": "New Translation",
@@ -30,6 +47,8 @@
3047
}
3148
]
3249
}
33-
]
50+
],
51+
"related_applications": [],
52+
"prefer_related_applications": false
3453
}
3554

frontend/public/og-image.svg

Lines changed: 73 additions & 0 deletions
Loading

frontend/src/components/AddToAppButton.tsx

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,51 @@ export function AddToAppButton() {
1111
const [deferredPrompt, setDeferredPrompt] = useState<BeforeInstallPromptEvent | null>(null)
1212
const [showIOSInstructions, setShowIOSInstructions] = useState(false)
1313
const [isInstallable, setIsInstallable] = useState(false)
14+
const [showDebugInfo, setShowDebugInfo] = useState(false)
1415

1516
useEffect(() => {
1617
const handleBeforeInstallPrompt = (e: Event) => {
17-
// Prevent the mini-infobar from appearing on mobile
18+
console.log('PWA: beforeinstallprompt event fired')
1819
e.preventDefault()
1920
setDeferredPrompt(e as BeforeInstallPromptEvent)
2021
setIsInstallable(true)
2122
}
2223

2324
const handleAppInstalled = () => {
25+
console.log('PWA: app installed')
2426
setIsInstallable(false)
2527
setDeferredPrompt(null)
2628
}
2729

2830
window.addEventListener('beforeinstallprompt', handleBeforeInstallPrompt)
2931
window.addEventListener('appinstalled', handleAppInstalled)
3032

33+
// Debug logging
34+
console.log('PWA: Component mounted, checking conditions...')
35+
console.log('PWA: isIOS =', isIOS())
36+
console.log('PWA: isInStandaloneMode =', isInStandaloneMode())
37+
console.log('PWA: hasBeforeInstallPrompt =', 'onbeforeinstallprompt' in window)
38+
console.log('PWA: hostname =', window.location.hostname)
39+
40+
// For localhost development: if no beforeinstallprompt after 2 seconds,
41+
// assume it's available for testing (but only on localhost)
42+
const isLocalhost = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1'
43+
const isDev = process.env.NODE_ENV === 'development'
44+
45+
let timeoutId: NodeJS.Timeout | null = null
46+
if (isDev && isLocalhost) {
47+
timeoutId = setTimeout(() => {
48+
if (!isInstallable && !isIOS()) {
49+
console.log('PWA: No beforeinstallprompt after 2s, enabling for localhost testing')
50+
setIsInstallable(true)
51+
}
52+
}, 2000)
53+
}
54+
3155
return () => {
3256
window.removeEventListener('beforeinstallprompt', handleBeforeInstallPrompt)
3357
window.removeEventListener('appinstalled', handleAppInstalled)
58+
if (timeoutId) clearTimeout(timeoutId)
3459
}
3560
}, [])
3661

@@ -39,8 +64,14 @@ export function AddToAppButton() {
3964
}
4065

4166
const isInStandaloneMode = () => {
42-
return window.matchMedia('(display-mode: standalone)').matches ||
43-
(window.navigator as any).standalone === true
67+
try {
68+
const matchMediaResult = window.matchMedia('(display-mode: standalone)')
69+
return (matchMediaResult && matchMediaResult.matches) ||
70+
(window.navigator as any).standalone === true
71+
} catch (e) {
72+
// Fallback for test environments or browsers without matchMedia
73+
return (window.navigator as any).standalone === true
74+
}
4475
}
4576

4677
const handleInstallClick = async () => {
@@ -59,11 +90,27 @@ export function AddToAppButton() {
5990
}
6091
}
6192

62-
// Don't show the button if already installed or not installable
63-
if (isInStandaloneMode() || (!isInstallable && !isIOS())) {
93+
// Don't show the button if already installed
94+
if (isInStandaloneMode()) {
95+
console.log('PWA: Button hidden - already in standalone mode')
6496
return null
6597
}
6698

99+
// Show button if:
100+
// 1. Actually installable (beforeinstallprompt fired), OR
101+
// 2. iOS device (can always install via Safari), OR
102+
// 3. Development mode AND localhost (for testing)
103+
const isLocalhost = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1'
104+
const isDev = process.env.NODE_ENV === 'development'
105+
const shouldShowButton = isInstallable || isIOS() || (isDev && isLocalhost)
106+
107+
if (!shouldShowButton) {
108+
console.log('PWA: Button hidden - not installable, not iOS, not dev+localhost')
109+
return null
110+
}
111+
112+
console.log('PWA: Button will show - installable:', isInstallable, 'iOS:', isIOS(), 'dev+localhost:', isDev && isLocalhost)
113+
67114
return (
68115
<>
69116
<Box

0 commit comments

Comments
 (0)