mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-06-20 13:00:39 +00:00
feat: refactor website icon handling by moving utility functions to a dedicated module
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
|||||||
preloadWebsiteIcon,
|
preloadWebsiteIcon,
|
||||||
subscribeWebsiteIconStatus,
|
subscribeWebsiteIconStatus,
|
||||||
} from '@/lib/website-icon-cache';
|
} from '@/lib/website-icon-cache';
|
||||||
|
import { firstCipherUri, hostFromUri, websiteIconUrl } from '@/lib/website-utils';
|
||||||
|
|
||||||
const ICON_LOAD_ROOT_MARGIN = '180px 0px';
|
const ICON_LOAD_ROOT_MARGIN = '180px 0px';
|
||||||
|
|
||||||
@@ -17,29 +18,6 @@ interface WebsiteIconProps {
|
|||||||
fallback?: ComponentChildren;
|
fallback?: ComponentChildren;
|
||||||
}
|
}
|
||||||
|
|
||||||
function firstCipherUri(cipher: Cipher): string {
|
|
||||||
const uris = cipher.login?.uris || [];
|
|
||||||
for (const uri of uris) {
|
|
||||||
const raw = uri.decUri || uri.uri || '';
|
|
||||||
if (raw.trim()) return raw.trim();
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
function hostFromUri(uri: string): string {
|
|
||||||
if (!uri.trim()) return '';
|
|
||||||
try {
|
|
||||||
const normalized = /^https?:\/\//i.test(uri) ? uri : `https://${uri}`;
|
|
||||||
return new URL(normalized).hostname || '';
|
|
||||||
} catch {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function websiteIconUrl(host: string): string {
|
|
||||||
return `/icons/${encodeURIComponent(host)}/icon.png?fallback=404`;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function WebsiteIcon(props: WebsiteIconProps) {
|
export default function WebsiteIcon(props: WebsiteIconProps) {
|
||||||
const host = useMemo(() => hostFromUri(firstCipherUri(props.cipher)), [props.cipher]);
|
const host = useMemo(() => hostFromUri(firstCipherUri(props.cipher)), [props.cipher]);
|
||||||
const src = host ? websiteIconUrl(host) : '';
|
const src = host ? websiteIconUrl(host) : '';
|
||||||
|
|||||||
@@ -148,28 +148,7 @@ export function toBooleanFieldValue(raw: string): boolean {
|
|||||||
return v === '1' || v === 'true' || v === 'yes' || v === 'on';
|
return v === '1' || v === 'true' || v === 'yes' || v === 'on';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function firstCipherUri(cipher: Cipher): string {
|
export { firstCipherUri, hostFromUri, websiteIconUrl } from '@/lib/website-utils';
|
||||||
const uris = cipher.login?.uris || [];
|
|
||||||
for (const uri of uris) {
|
|
||||||
const raw = uri.decUri || uri.uri || '';
|
|
||||||
if (raw.trim()) return raw.trim();
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function hostFromUri(uri: string): string {
|
|
||||||
if (!uri.trim()) return '';
|
|
||||||
try {
|
|
||||||
const normalized = /^https?:\/\//i.test(uri) ? uri : `https://${uri}`;
|
|
||||||
return new URL(normalized).hostname || '';
|
|
||||||
} catch {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function websiteIconUrl(host: string): string {
|
|
||||||
return `/icons/${encodeURIComponent(host)}/icon.png?fallback=404`;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createEmptyLoginUri(): VaultDraftLoginUri {
|
export function createEmptyLoginUri(): VaultDraftLoginUri {
|
||||||
return { uri: '', match: null, originalUri: '', extra: {} };
|
return { uri: '', match: null, originalUri: '', extra: {} };
|
||||||
|
|||||||
@@ -118,7 +118,9 @@ export default function useVaultSendActions(options: UseVaultSendActionsOptions)
|
|||||||
if (options?.includeFolders) {
|
if (options?.includeFolders) {
|
||||||
tasks.push(Promise.resolve(refetchFolders()));
|
tasks.push(Promise.resolve(refetchFolders()));
|
||||||
}
|
}
|
||||||
void Promise.all(tasks).catch(() => undefined);
|
void Promise.all(tasks).catch((err) => {
|
||||||
|
console.warn('Background vault sync failed:', err);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
async function decryptAndPatch(encrypted: Cipher) {
|
async function decryptAndPatch(encrypted: Cipher) {
|
||||||
|
|||||||
@@ -72,7 +72,6 @@ export function preloadWebsiteIcon(host: string, src: string): Promise<WebsiteIc
|
|||||||
record.promise = new Promise<WebsiteIconStatus>((resolve) => {
|
record.promise = new Promise<WebsiteIconStatus>((resolve) => {
|
||||||
const img = new Image();
|
const img = new Image();
|
||||||
img.decoding = 'async';
|
img.decoding = 'async';
|
||||||
img.loading = 'eager';
|
|
||||||
img.referrerPolicy = 'no-referrer';
|
img.referrerPolicy = 'no-referrer';
|
||||||
img.onload = () => {
|
img.onload = () => {
|
||||||
markWebsiteIconLoaded(host);
|
markWebsiteIconLoaded(host);
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import type { Cipher } from './types';
|
||||||
|
|
||||||
|
export function firstCipherUri(cipher: Cipher): string {
|
||||||
|
const uris = cipher.login?.uris || [];
|
||||||
|
for (const uri of uris) {
|
||||||
|
const raw = uri.decUri || uri.uri || '';
|
||||||
|
if (raw.trim()) return raw.trim();
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function hostFromUri(uri: string): string {
|
||||||
|
if (!uri.trim()) return '';
|
||||||
|
try {
|
||||||
|
const normalized = /^https?:\/\//i.test(uri) ? uri : `https://${uri}`;
|
||||||
|
return new URL(normalized).hostname || '';
|
||||||
|
} catch {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function websiteIconUrl(host: string): string {
|
||||||
|
return `/icons/${encodeURIComponent(host)}/icon.png?fallback=404`;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user