fix: logo optimization, deprecated meta tag, and clipboard copy fallback (#306)
- Replace 2 MB favicon.svg (base64-PNG-in-SVG) with optimized 43 KB app-logo.png (256x256) - Update AppHeader and AboutModal references to use new logo - Remove SVG favicon link from index.html (PNG/ICO favicons remain) - Fix deprecated apple-mobile-web-app-capable → mobile-web-app-capable meta tag - Add clipboard copy fallback for non-secure contexts (LAN IP over HTTP) Closes #303
This commit is contained in:
+1
-2
@@ -6,7 +6,6 @@
|
||||
<title>MedAssist-ng</title>
|
||||
|
||||
<!-- Favicons -->
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png" />
|
||||
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
||||
@@ -14,7 +13,7 @@
|
||||
|
||||
<!-- Theme color -->
|
||||
<meta name="theme-color" content="#0f172a" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 1.9 MiB |
@@ -73,7 +73,7 @@ export default function AboutModal({ isOpen, onClose }: AboutModalProps) {
|
||||
</button>
|
||||
<div className="about-header">
|
||||
<div className="about-logo">
|
||||
<img src="/favicon.svg" alt="MedAssist-ng" />
|
||||
<img src="/app-logo.png" alt="MedAssist-ng" />
|
||||
</div>
|
||||
<h2>{t("about.appName", "MedAssist-ng")}</h2>
|
||||
<p className="about-tagline">{t("about.description", "Personal medication tracking and reminder app")}</p>
|
||||
|
||||
@@ -73,7 +73,7 @@ export function AppHeader({ onOpenProfile, onOpenAbout }: AppHeaderProps) {
|
||||
return (
|
||||
<header className="hero">
|
||||
<div className="hero-title">
|
||||
<img src="/favicon.svg" alt="MedAssist-ng" className="hero-logo" />
|
||||
<img src="/app-logo.png" alt="MedAssist-ng" className="hero-logo" />
|
||||
<div>
|
||||
<p className="eyebrow">{pageInfo.eyebrow}</p>
|
||||
<h1>{pageInfo.title}</h1>
|
||||
|
||||
@@ -106,10 +106,40 @@ export function useShare(): UseShareReturn {
|
||||
|
||||
const copyShareLink = useCallback(() => {
|
||||
if (shareLink) {
|
||||
navigator.clipboard.writeText(shareLink);
|
||||
setShareCopied(true);
|
||||
log.debug("[ShareDialog] Share link copied to clipboard");
|
||||
setTimeout(() => setShareCopied(false), 2000);
|
||||
if (navigator.clipboard?.writeText) {
|
||||
navigator.clipboard.writeText(shareLink).then(
|
||||
() => {
|
||||
setShareCopied(true);
|
||||
log.debug("[ShareDialog] Share link copied to clipboard");
|
||||
setTimeout(() => setShareCopied(false), 2000);
|
||||
},
|
||||
() => {
|
||||
// Clipboard API blocked (non-secure context / permissions)
|
||||
fallbackCopyToClipboard(shareLink);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
fallbackCopyToClipboard(shareLink);
|
||||
}
|
||||
}
|
||||
|
||||
function fallbackCopyToClipboard(text: string) {
|
||||
const textarea = document.createElement("textarea");
|
||||
textarea.value = text;
|
||||
textarea.style.position = "fixed";
|
||||
textarea.style.opacity = "0";
|
||||
document.body.appendChild(textarea);
|
||||
textarea.select();
|
||||
try {
|
||||
document.execCommand("copy");
|
||||
setShareCopied(true);
|
||||
log.debug("[ShareDialog] Share link copied via fallback");
|
||||
setTimeout(() => setShareCopied(false), 2000);
|
||||
} catch {
|
||||
log.warn("[ShareDialog] Clipboard copy failed — not in secure context");
|
||||
} finally {
|
||||
document.body.removeChild(textarea);
|
||||
}
|
||||
}
|
||||
}, [shareLink]);
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ describe("useShare", () => {
|
||||
mockAlert = vi.fn();
|
||||
global.alert = mockAlert;
|
||||
|
||||
mockClipboard = { writeText: vi.fn() };
|
||||
mockClipboard = { writeText: vi.fn().mockResolvedValue(undefined) };
|
||||
Object.defineProperty(navigator, "clipboard", {
|
||||
value: mockClipboard,
|
||||
writable: true,
|
||||
@@ -237,7 +237,7 @@ describe("useShare", () => {
|
||||
result.current.setShareLink("http://localhost:5173/share/test-token");
|
||||
});
|
||||
|
||||
act(() => {
|
||||
await act(async () => {
|
||||
result.current.copyShareLink();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user