diff --git a/fluxer_app/src/features/app/hooks/useRovingFocusList.ts b/fluxer_app/src/features/app/hooks/useRovingFocusList.ts index f815a11df..7308845df 100644 --- a/fluxer_app/src/features/app/hooks/useRovingFocusList.ts +++ b/fluxer_app/src/features/app/hooks/useRovingFocusList.ts @@ -248,7 +248,7 @@ export const useRovingFocusList = (options: UseRovingFocu }, [node, enabled, getCachedFocusableElements]); useEffect(() => { if (!node || !restoreFocusOnWindowFocus || !enabled) return; - const handleWindowFocus = () => { + const handleWindowFocused = () => { const {focusableSelector: selector, manageTabIndex: manage} = latestOptionsRef.current; const focusable = manage ? getCachedFocusableElements(node, selector, true) @@ -265,9 +265,9 @@ export const useRovingFocusList = (options: UseRovingFocu target.focus(); } }; - window.addEventListener('focus', handleWindowFocus); + window.addEventListener('focus', handleWindowFocused); return () => { - window.removeEventListener('focus', handleWindowFocus); + window.removeEventListener('focus', handleWindowFocused); }; }, [node, restoreFocusOnWindowFocus, enabled, getCachedFocusableElements]); useEffect(() => { diff --git a/fluxer_app/src/features/notification/utils/NotificationIconURL.ts b/fluxer_app/src/features/notification/utils/NotificationIconURL.ts new file mode 100644 index 000000000..edba752af --- /dev/null +++ b/fluxer_app/src/features/notification/utils/NotificationIconURL.ts @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +import GuildMembers from '@app/features/member/state/GuildMembers'; +import {isDesktop} from '@app/features/ui/utils/NativeUtils'; +import type {User} from '@app/features/user/models/User'; +import * as AvatarUtils from '@app/features/user/utils/AvatarUtils'; +import type {MediaProxyImageSize} from '@fluxer/constants/src/MediaProxyImageSizes'; + +export const NATIVE_NOTIFICATION_ICON_CSS_SIZE: MediaProxyImageSize = 128; + +export function getNotificationIconURL(user: Pick, guildId?: string | null): string { + const member = guildId ? GuildMembers.getMember(guildId, user.id) : null; + const nativeIcon = isDesktop(); + if (guildId && member) { + return nativeIcon + ? AvatarUtils.getGuildMemberNotificationAvatarURL({ + guildId, + userId: user.id, + avatar: user.avatar, + memberAvatar: member.avatar, + avatarUnset: member.isAvatarUnset(), + size: NATIVE_NOTIFICATION_ICON_CSS_SIZE, + }) + : AvatarUtils.getGuildMemberDisplayAvatarURL({ + guildId, + user, + memberAvatar: member.avatar, + avatarUnset: member.isAvatarUnset(), + animated: false, + }); + } + return nativeIcon + ? AvatarUtils.getUserNotificationAvatarURL(user, NATIVE_NOTIFICATION_ICON_CSS_SIZE) + : AvatarUtils.getUserAvatarURL(user, false); +} diff --git a/fluxer_app/src/features/notification/utils/NotificationUtils.ts b/fluxer_app/src/features/notification/utils/NotificationUtils.ts index c31d88864..6ede5a078 100644 --- a/fluxer_app/src/features/notification/utils/NotificationUtils.ts +++ b/fluxer_app/src/features/notification/utils/NotificationUtils.ts @@ -2,6 +2,7 @@ import Authentication from '@app/features/auth/state/Authentication'; import * as RouterUtils from '@app/features/navigation/utils/RouterUtils'; +import {getNotificationIconURL} from '@app/features/notification/utils/NotificationIconURL'; import {SoundType} from '@app/features/notification/utils/SoundUtils'; import type {NotificationAlertOptions} from '@app/features/platform/notifications/NotificationAlertOptions'; import {getNotificationAlertOptions} from '@app/features/platform/notifications/NotificationAlertOptions'; @@ -12,7 +13,6 @@ import Sound from '@app/features/ui/state/Sound'; import {getElectronAPI, hasUnavailableElectronNativeContext, isDesktop} from '@app/features/ui/utils/NativeUtils'; import {isInstalledIOSPwa, isInstalledPwa, isMobileOrTablet} from '@app/features/ui/utils/PwaUtils'; import Users from '@app/features/user/state/Users'; -import * as AvatarUtils from '@app/features/user/utils/AvatarUtils'; import type {I18n} from '@lingui/core'; import {msg} from '@lingui/core/macro'; @@ -126,12 +126,13 @@ const requestBrowserPermission = async (): Promise => { return 'denied'; } }; + const getCurrentUserAvatar = (): string | null => { const currentUserId = Authentication.currentUserId; if (!currentUserId) return null; const currentUser = Users.getUser(currentUserId); if (!currentUser) return null; - return AvatarUtils.getUserNotificationAvatarURL(currentUser); + return getNotificationIconURL(currentUser); }; async function handleDeniedPermission(i18n: I18n): Promise { diff --git a/fluxer_app/src/features/ui/state/Notification.ts b/fluxer_app/src/features/ui/state/Notification.ts index 694d1ffcc..def132ebd 100644 --- a/fluxer_app/src/features/ui/state/Notification.ts +++ b/fluxer_app/src/features/ui/state/Notification.ts @@ -13,6 +13,7 @@ import * as MessageUtils from '@app/features/messaging/utils/MessageUtils'; import Navigation from '@app/features/navigation/state/Navigation'; import SelectedChannel from '@app/features/navigation/state/SelectedChannel'; import {buildMessageNotificationBody} from '@app/features/notification/utils/MessageNotificationPreview'; +import {getNotificationIconURL} from '@app/features/notification/utils/NotificationIconURL'; import * as NotificationUtils from '@app/features/notification/utils/NotificationUtils'; import * as PushSubscriptionService from '@app/features/platform/push/PushSubscriptionService'; import {IS_DEV} from '@app/features/platform/types/Env'; @@ -29,7 +30,6 @@ import {isInstalledPwa} from '@app/features/ui/utils/PwaUtils'; import type {User} from '@app/features/user/models/User'; import UserGuildSettings from '@app/features/user/state/UserGuildSettings'; import Users from '@app/features/user/state/Users'; -import * as AvatarUtils from '@app/features/user/utils/AvatarUtils'; import * as NicknameUtils from '@app/features/user/utils/NicknameUtils'; import {FAVORITES_GUILD_ID as ME} from '@fluxer/constants/src/AppConstants'; import {ChannelTypes, MessageFlags, MessageTypes} from '@fluxer/constants/src/ChannelConstants'; @@ -283,10 +283,7 @@ class NotificationState { } private markNotified(key: string): void { - const newCache = new LRUCache({max: CACHE_SIZE}); - this.notifiedMessageIds.forEach((value, k) => newCache.set(k, value)); - newCache.set(key, true); - this.notifiedMessageIds = newCache; + this.notifiedMessageIds.set(key, true); } private claimNotification(key: string): boolean { @@ -357,7 +354,7 @@ class NotificationState { title, subtitle, body, - icon: AvatarUtils.getUserNotificationAvatarURL(user), + icon: getNotificationIconURL(user, channel.guildId), url: notificationUrl, playSound: false, }); @@ -447,7 +444,7 @@ class NotificationState { this.unreadMessageBadgeEnabled = enabled; } - handleWindowFocus({focused}: {focused: boolean}): void { + handleWindowFocused({focused}: {focused: boolean}): void { this.focused = focused; if (focused) { const channelId = SelectedChannel.currentChannelId; @@ -524,7 +521,7 @@ class NotificationState { id: cacheKey, title, body, - icon: AvatarUtils.getUserNotificationAvatarURL(user), + icon: getNotificationIconURL(user), url: Routes.ME, }).catch((error) => { logger.error('Failed to show relationship notification', {cacheKey}, error); diff --git a/fluxer_app/src/features/window/commands/WindowCommands.ts b/fluxer_app/src/features/window/commands/WindowCommands.ts index 2be341551..d1964f992 100644 --- a/fluxer_app/src/features/window/commands/WindowCommands.ts +++ b/fluxer_app/src/features/window/commands/WindowCommands.ts @@ -7,7 +7,7 @@ import Window from '@app/features/window/state/Window'; function applyFocusSideEffects(focused: boolean): void { GuildReadState.handleWindowFocused(); - Notification.handleWindowFocus({focused}); + Notification.handleWindowFocused({focused}); if (focused) { Idle.recordActivity(); }