From da79aba22731f5b286a3a74977dbcc7202e9b7cf Mon Sep 17 00:00:00 2001 From: Paul Burke Date: Wed, 17 Apr 2024 14:37:27 -0400 Subject: [PATCH] fix: avatar handling - Stops using Stamp CDN where possible - Uses Lens media snapshots --- manifest.config.ts | 2 +- src/background.ts | 10 ++-- src/lib/components/AccountChooser.svelte | 5 +- src/lib/components/ProfileHoverCard.svelte | 7 ++- src/lib/lens-service.ts | 12 +++++ src/lib/notifications/lens-notifications.ts | 17 ++----- src/lib/user/user.ts | 8 ++- src/lib/utils/lens-utils.ts | 50 +++++++++++++++---- src/lib/utils/utils.ts | 8 --- src/options/components/LensNodeSelect.svelte | 4 +- src/popup/messaging/ThreadItem.svelte | 5 +- src/popup/messaging/thread/Thread.svelte | 8 ++- .../components/CollectSettingsDialog.svelte | 3 +- 13 files changed, 80 insertions(+), 59 deletions(-) diff --git a/manifest.config.ts b/manifest.config.ts index 97ba18a..7693c99 100644 --- a/manifest.config.ts +++ b/manifest.config.ts @@ -52,6 +52,6 @@ export default defineManifest((env) => ({ keyword: 'lens', }, ...(!isProduction && { - host_permissions: ['https://api-v2-amoy.lens.dev'], + host_permissions: ['*://api-v2-amoy.lens.dev/*'], }), })); diff --git a/src/background.ts b/src/background.ts index 246508c..8e99238 100644 --- a/src/background.ts +++ b/src/background.ts @@ -1,8 +1,6 @@ import { DateTime } from 'luxon'; import type { User } from './lib/user/user'; import { - getAvatarForLensHandle, - getAvatarFromAddress, getXmtpKeys, launchThreadWindow, stripMarkdown, @@ -55,7 +53,6 @@ import { waitForTransaction, } from './lib/lens-service'; import type { - FollowNotificationFragment, NotificationFragment, ProfileFragment, PublicationMetadataFragment, @@ -65,6 +62,7 @@ import { formatHandleV2toV1, getNotificationPublication, hasMetadata, + getProfileAvatar, } from './lib/utils/lens-utils'; import { migrate } from './lib/utils/migrations'; @@ -672,9 +670,9 @@ const onMessagesAlarm = async () => { ? `${messages.length} new messages` : messages[0].content), contextMessage: 'Focalize', - iconUrl: peerProfile?.handle - ? getAvatarForLensHandle(peerProfile.handle.localName) - : getAvatarFromAddress(peerAddress) ?? getAppIconUrl(), + iconUrl: peerProfile + ? getProfileAvatar(peerProfile) + : getAppIconUrl(), silent: false, }; diff --git a/src/lib/components/AccountChooser.svelte b/src/lib/components/AccountChooser.svelte index ab717cf..c70c415 100644 --- a/src/lib/components/AccountChooser.svelte +++ b/src/lib/components/AccountChooser.svelte @@ -5,7 +5,7 @@ import LoadingSpinner from './LoadingSpinner.svelte' import ImageAvatar from '../../assets/ic_avatar.svg'; import { onLogin } from '../user/user'; - import { getAvatarForLensHandle, getAvatarFromAddress, truncateAddress } from '../utils/utils'; + import { truncateAddress } from '../utils/utils'; import DarkModeSwitch from './DarkModeSwitch.svelte'; import {darkMode} from '../stores/preferences-store'; import { getManagedProfiles, login } from '../lens-service'; @@ -13,6 +13,7 @@ import { formatHandleV2toV1 } from '../utils/lens-utils'; import { getAccounts } from '../evm/ethers-service'; import {slide} from 'svelte/transition'; + import { getProfileAvatar } from '../utils/lens-utils.js'; export let anchorNode: Node | undefined = undefined; export let showSettings = true; @@ -106,7 +107,7 @@ {#each profiles as p, index} - {@const avatarUrl = p.handle ? getAvatarForLensHandle(p.handle.fullHandle) : getAvatarFromAddress(p.ownedBy.address)} + {@const avatarUrl = getProfileAvatar(p)}
import { formatFollowerCount, - getAvatarForLensHandle, - getAvatarFromAddress, launchThreadWindow, truncateAddress, } from '../utils/utils'; import {onMount} from 'svelte'; @@ -17,6 +15,7 @@ import { cubicOut } from 'svelte/easing'; import { getMutualFollowers, getProfile } from '../lens-service'; import type { ProfileFragment, PaginatedResult } from '@lens-protocol/client'; + import { getProfileAvatar } from '../utils/lens-utils.js'; export let profile: ProfileFragment; @@ -24,7 +23,7 @@ let mutualFollows: PaginatedResult; let isMessaging = false; - $: avatarUrl = profile.handle && getAvatarForLensHandle(profile.handle.fullHandle); + $: avatarUrl = getProfileAvatar(profile, false); $: userProfileUrl = profile.handle && $nodeSearch && getNodeUrlForHandle($nodeSearch, profile.handle); $: isCurrentUserProfile = profile && profile.id === $currentUser?.profileId; @@ -184,7 +183,7 @@
{#each mutualFollows.items.slice(0,3) as mutualFollow} - Avatar {/each}
diff --git a/src/lib/lens-service.ts b/src/lib/lens-service.ts index a8374d0..40104a2 100644 --- a/src/lib/lens-service.ts +++ b/src/lib/lens-service.ts @@ -72,6 +72,18 @@ const chromeStorage = new ChromeStorageProvider(); const lensClient: LensClient = new LensClient({ environment: isMainnet ? production : development, storage: chromeStorage, + params: { + profile: { + thumbnail: { + width: '48px', + height: 'auto', + }, + cover: { + width: '512px', + height: 'auto', + }, + }, + }, }); export const isAuthenticated = (): Promise => diff --git a/src/lib/notifications/lens-notifications.ts b/src/lib/notifications/lens-notifications.ts index 40542b7..6a5a766 100644 --- a/src/lib/notifications/lens-notifications.ts +++ b/src/lib/notifications/lens-notifications.ts @@ -1,9 +1,4 @@ -import { - getAvatarForLensHandle, - getAvatarFromAddress, - stripMarkdown, - truncate, -} from '../utils/utils'; +import { stripMarkdown, truncate } from '../utils/utils'; import { type LensNode, getNodeForPublication, @@ -25,6 +20,7 @@ import { formatHandleV2toV1, getMetadataContent, getNotificationPublication, + getProfileAvatar, } from '../utils/lens-utils'; import { isCommentPublication, @@ -262,14 +258,9 @@ export const getNotificationWalletAddress = ( export const getAvatarFromNotification = ( notification: NotificationFragment -): string | null => { +): string | undefined => { const profile = getNotificationProfile(notification); - if (profile.handle) { - return getAvatarForLensHandle(profile.handle.fullHandle); - } - - const wallet = getNotificationWalletAddress(notification); - return getAvatarFromAddress(wallet); + return getProfileAvatar(profile); }; /** diff --git a/src/lib/user/user.ts b/src/lib/user/user.ts index 08881ad..9db7437 100644 --- a/src/lib/user/user.ts +++ b/src/lib/user/user.ts @@ -1,7 +1,7 @@ -import { currentUser, getUser, saveUser } from '../stores/user-store'; -import { getAvatarForLensHandle } from '../utils/utils'; +import { getUser, saveUser } from '../stores/user-store'; import { isAuthenticated } from '../lens-service'; import type { ProfileFragment } from '@lens-protocol/client'; +import { getProfileAvatar } from '../utils/lens-utils'; export type User = { address: string; @@ -20,9 +20,7 @@ export enum UserError { } export const userFromProfile = (profile: ProfileFragment): User => { - const avatarUrl = profile.handle - ? getAvatarForLensHandle(profile.handle.fullHandle) - : undefined; + const avatarUrl = getProfileAvatar(profile); return { address: profile.ownedBy.address, diff --git a/src/lib/utils/lens-utils.ts b/src/lib/utils/lens-utils.ts index 9d280e8..8f9e41e 100644 --- a/src/lib/utils/lens-utils.ts +++ b/src/lib/utils/lens-utils.ts @@ -35,11 +35,7 @@ import { PublicationSchemaId, ThreeDFormat, } from '@lens-protocol/metadata'; -import { - getAvatarForLensHandle, - getAvatarFromAddress, - truncateAddress, -} from './utils'; +import { getAvatarFromAddress, truncateAddress } from './utils'; import { getNodeUrlForHandle, LENS_NODES } from '../publications/lens-nodes'; export const hasMetadata = ( @@ -352,10 +348,46 @@ export const getProfileDisplayName = (profile: ProfileFragment): string => { return truncateAddress(profile.ownedBy.address); }; -export const getProfileAvatar = (profile: ProfileFragment): string => - profile.handle - ? getAvatarForLensHandle(profile.handle.fullHandle, 64) - : getAvatarFromAddress(profile.ownedBy.address, 64); +export const getProfileAvatar = ( + profile: ProfileFragment, + thumbnail: boolean = true +): string => { + let profileImage = undefined; + + if (profile.handle && profile.metadata?.picture) { + if (profile.metadata?.picture?.__typename === 'ImageSet') { + if ( + !profile.metadata.picture.thumbnail && + !profile.metadata.picture.optimized + ) { + profileImage = profile.metadata.picture.raw.uri; + } + profileImage = thumbnail + ? profile.metadata.picture.thumbnail?.uri + : profile.metadata.picture.optimized?.uri; + } else { + if ( + !profile.metadata.picture.image.thumbnail && + !profile.metadata.picture.image.optimized + ) { + profileImage = profile.metadata.picture.image.raw.uri; + } + profileImage = thumbnail + ? profile.metadata.picture.image.thumbnail?.uri + : profile.metadata.picture.image.optimized?.uri; + } + } + + return profileImage ?? getAvatarFromAddress(profile.ownedBy.address); +}; + +export const getAvatarForLensHandle = ( + handle: string, + size: number = 128 +): string => { + const formattedHandle = formatHandleV2toV1(handle); + return `https://cdn.stamp.fyi/avatar/${formattedHandle}?s=${size}`; +}; export const getProfileUrl = (profile: ProfileFragment): string => { if (profile.handle) { diff --git a/src/lib/utils/utils.ts b/src/lib/utils/utils.ts index e28a909..5f5e91d 100644 --- a/src/lib/utils/utils.ts +++ b/src/lib/utils/utils.ts @@ -36,14 +36,6 @@ export const isOnToolbar = async (): Promise => { return settings.isOnToolbar; }; -export const getAvatarForLensHandle = ( - handle: string, - size: number = 128 -): string => { - const formattedHandle = formatHandleV2toV1(handle); - return `https://cdn.stamp.fyi/avatar/${formattedHandle}?s=${size}`; -}; - export const getAvatarFromAddress = ( address: string, size: number = 128 diff --git a/src/options/components/LensNodeSelect.svelte b/src/options/components/LensNodeSelect.svelte index de0c2bf..6db5db6 100644 --- a/src/options/components/LensNodeSelect.svelte +++ b/src/options/components/LensNodeSelect.svelte @@ -10,10 +10,10 @@ export let preference: Writable; export let disabled = false; export let notifications = false; - export let focus: PublicationMetadataMainFocusType; + export let focus: PublicationMetadataMainFocusType | undefined = undefined; const getNodes = () => { - return LENS_NODES.filter(node => node.focus.includes(focus)); + return focus !== undefined ? LENS_NODES.filter(node => node.focus.includes(focus.valueOf())) : LENS_NODES; } let selectedNode: LensNode; diff --git a/src/popup/messaging/ThreadItem.svelte b/src/popup/messaging/ThreadItem.svelte index 69140d9..f19031c 100644 --- a/src/popup/messaging/ThreadItem.svelte +++ b/src/popup/messaging/ThreadItem.svelte @@ -2,7 +2,7 @@ //@ts-ignore import tippy from 'sveltejs-tippy'; import ImageAvatar from '../../assets/ic_avatar.svg'; - import {getAvatarForLensHandle, getAvatarFromAddress, getEnsFromAddress, truncate} from '../../lib/utils/utils'; + import {getEnsFromAddress, truncate} from '../../lib/utils/utils'; import {type CompactMessage, getPeerName, isLensThread, isUnread, type Thread} from '../../lib/xmtp-service'; import {createEventDispatcher} from 'svelte'; import {DateTime} from 'luxon'; @@ -10,6 +10,7 @@ import ProfileHoverCard from '../../lib/components/ProfileHoverCard.svelte'; import AutoRelativeTimeView from '../../lib/components/AutoRelativeTimeView.svelte'; import {getLatestMessage} from '../../lib/stores/cache-store'; + import { getProfileAvatar } from '../../lib/utils/lens-utils'; const dispatch = createEventDispatcher(); @@ -22,7 +23,7 @@ $: peerProfile = thread?.peer?.profile; $: peerAddress = thread?.peer?.profile?.ownedBy.address ?? thread?.peer?.wallet?.address!; $: unread = thread?.unread; - $: avatarUrl = peerProfile?.handle ? getAvatarForLensHandle(peerProfile.handle.fullHandle) : getAvatarFromAddress(peerAddress); + $: avatarUrl = peerProfile && getProfileAvatar(peerProfile); $: peerName = thread?.peer && getPeerName(thread, ens); const latestMessage = getLatestMessage(thread?.conversation?.topic); diff --git a/src/popup/messaging/thread/Thread.svelte b/src/popup/messaging/thread/Thread.svelte index e436e55..4b46d43 100644 --- a/src/popup/messaging/thread/Thread.svelte +++ b/src/popup/messaging/thread/Thread.svelte @@ -1,6 +1,6 @@