mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 21:15:32 +09:00
fix(app): show the server avatar on message notifications (#1879)
This commit is contained in:
1 parent
e21544eac2
commit
5821a68816
5 files changed
+47
-14
No files matched your search
@@ -248,7 +248,7 @@ export const useRovingFocusList = <T extends HTMLElement>(options: UseRovingFocu
|
|||||||
}, [node, enabled, getCachedFocusableElements]);
|
}, [node, enabled, getCachedFocusableElements]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!node || !restoreFocusOnWindowFocus || !enabled) return;
|
if (!node || !restoreFocusOnWindowFocus || !enabled) return;
|
||||||
const handleWindowFocus = () => {
|
const handleWindowFocused = () => {
|
||||||
const {focusableSelector: selector, manageTabIndex: manage} = latestOptionsRef.current;
|
const {focusableSelector: selector, manageTabIndex: manage} = latestOptionsRef.current;
|
||||||
const focusable = manage
|
const focusable = manage
|
||||||
? getCachedFocusableElements(node, selector, true)
|
? getCachedFocusableElements(node, selector, true)
|
||||||
@@ -265,9 +265,9 @@ export const useRovingFocusList = <T extends HTMLElement>(options: UseRovingFocu
|
|||||||
target.focus();
|
target.focus();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
window.addEventListener('focus', handleWindowFocus);
|
window.addEventListener('focus', handleWindowFocused);
|
||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener('focus', handleWindowFocus);
|
window.removeEventListener('focus', handleWindowFocused);
|
||||||
};
|
};
|
||||||
}, [node, restoreFocusOnWindowFocus, enabled, getCachedFocusableElements]);
|
}, [node, restoreFocusOnWindowFocus, enabled, getCachedFocusableElements]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -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<User, 'id' | 'avatar'>, 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);
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import Authentication from '@app/features/auth/state/Authentication';
|
import Authentication from '@app/features/auth/state/Authentication';
|
||||||
import * as RouterUtils from '@app/features/navigation/utils/RouterUtils';
|
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 {SoundType} from '@app/features/notification/utils/SoundUtils';
|
||||||
import type {NotificationAlertOptions} from '@app/features/platform/notifications/NotificationAlertOptions';
|
import type {NotificationAlertOptions} from '@app/features/platform/notifications/NotificationAlertOptions';
|
||||||
import {getNotificationAlertOptions} 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 {getElectronAPI, hasUnavailableElectronNativeContext, isDesktop} from '@app/features/ui/utils/NativeUtils';
|
||||||
import {isInstalledIOSPwa, isInstalledPwa, isMobileOrTablet} from '@app/features/ui/utils/PwaUtils';
|
import {isInstalledIOSPwa, isInstalledPwa, isMobileOrTablet} from '@app/features/ui/utils/PwaUtils';
|
||||||
import Users from '@app/features/user/state/Users';
|
import Users from '@app/features/user/state/Users';
|
||||||
import * as AvatarUtils from '@app/features/user/utils/AvatarUtils';
|
|
||||||
import type {I18n} from '@lingui/core';
|
import type {I18n} from '@lingui/core';
|
||||||
import {msg} from '@lingui/core/macro';
|
import {msg} from '@lingui/core/macro';
|
||||||
|
|
||||||
@@ -126,12 +126,13 @@ const requestBrowserPermission = async (): Promise<PermissionResult> => {
|
|||||||
return 'denied';
|
return 'denied';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getCurrentUserAvatar = (): string | null => {
|
const getCurrentUserAvatar = (): string | null => {
|
||||||
const currentUserId = Authentication.currentUserId;
|
const currentUserId = Authentication.currentUserId;
|
||||||
if (!currentUserId) return null;
|
if (!currentUserId) return null;
|
||||||
const currentUser = Users.getUser(currentUserId);
|
const currentUser = Users.getUser(currentUserId);
|
||||||
if (!currentUser) return null;
|
if (!currentUser) return null;
|
||||||
return AvatarUtils.getUserNotificationAvatarURL(currentUser);
|
return getNotificationIconURL(currentUser);
|
||||||
};
|
};
|
||||||
|
|
||||||
async function handleDeniedPermission(i18n: I18n): Promise<void> {
|
async function handleDeniedPermission(i18n: I18n): Promise<void> {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import * as MessageUtils from '@app/features/messaging/utils/MessageUtils';
|
|||||||
import Navigation from '@app/features/navigation/state/Navigation';
|
import Navigation from '@app/features/navigation/state/Navigation';
|
||||||
import SelectedChannel from '@app/features/navigation/state/SelectedChannel';
|
import SelectedChannel from '@app/features/navigation/state/SelectedChannel';
|
||||||
import {buildMessageNotificationBody} from '@app/features/notification/utils/MessageNotificationPreview';
|
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 NotificationUtils from '@app/features/notification/utils/NotificationUtils';
|
||||||
import * as PushSubscriptionService from '@app/features/platform/push/PushSubscriptionService';
|
import * as PushSubscriptionService from '@app/features/platform/push/PushSubscriptionService';
|
||||||
import {IS_DEV} from '@app/features/platform/types/Env';
|
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 type {User} from '@app/features/user/models/User';
|
||||||
import UserGuildSettings from '@app/features/user/state/UserGuildSettings';
|
import UserGuildSettings from '@app/features/user/state/UserGuildSettings';
|
||||||
import Users from '@app/features/user/state/Users';
|
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 * as NicknameUtils from '@app/features/user/utils/NicknameUtils';
|
||||||
import {FAVORITES_GUILD_ID as ME} from '@fluxer/constants/src/AppConstants';
|
import {FAVORITES_GUILD_ID as ME} from '@fluxer/constants/src/AppConstants';
|
||||||
import {ChannelTypes, MessageFlags, MessageTypes} from '@fluxer/constants/src/ChannelConstants';
|
import {ChannelTypes, MessageFlags, MessageTypes} from '@fluxer/constants/src/ChannelConstants';
|
||||||
@@ -283,10 +283,7 @@ class NotificationState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private markNotified(key: string): void {
|
private markNotified(key: string): void {
|
||||||
const newCache = new LRUCache<string, boolean>({max: CACHE_SIZE});
|
this.notifiedMessageIds.set(key, true);
|
||||||
this.notifiedMessageIds.forEach((value, k) => newCache.set(k, value));
|
|
||||||
newCache.set(key, true);
|
|
||||||
this.notifiedMessageIds = newCache;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private claimNotification(key: string): boolean {
|
private claimNotification(key: string): boolean {
|
||||||
@@ -357,7 +354,7 @@ class NotificationState {
|
|||||||
title,
|
title,
|
||||||
subtitle,
|
subtitle,
|
||||||
body,
|
body,
|
||||||
icon: AvatarUtils.getUserNotificationAvatarURL(user),
|
icon: getNotificationIconURL(user, channel.guildId),
|
||||||
url: notificationUrl,
|
url: notificationUrl,
|
||||||
playSound: false,
|
playSound: false,
|
||||||
});
|
});
|
||||||
@@ -447,7 +444,7 @@ class NotificationState {
|
|||||||
this.unreadMessageBadgeEnabled = enabled;
|
this.unreadMessageBadgeEnabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleWindowFocus({focused}: {focused: boolean}): void {
|
handleWindowFocused({focused}: {focused: boolean}): void {
|
||||||
this.focused = focused;
|
this.focused = focused;
|
||||||
if (focused) {
|
if (focused) {
|
||||||
const channelId = SelectedChannel.currentChannelId;
|
const channelId = SelectedChannel.currentChannelId;
|
||||||
@@ -524,7 +521,7 @@ class NotificationState {
|
|||||||
id: cacheKey,
|
id: cacheKey,
|
||||||
title,
|
title,
|
||||||
body,
|
body,
|
||||||
icon: AvatarUtils.getUserNotificationAvatarURL(user),
|
icon: getNotificationIconURL(user),
|
||||||
url: Routes.ME,
|
url: Routes.ME,
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
logger.error('Failed to show relationship notification', {cacheKey}, error);
|
logger.error('Failed to show relationship notification', {cacheKey}, error);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import Window from '@app/features/window/state/Window';
|
|||||||
|
|
||||||
function applyFocusSideEffects(focused: boolean): void {
|
function applyFocusSideEffects(focused: boolean): void {
|
||||||
GuildReadState.handleWindowFocused();
|
GuildReadState.handleWindowFocused();
|
||||||
Notification.handleWindowFocus({focused});
|
Notification.handleWindowFocused({focused});
|
||||||
if (focused) {
|
if (focused) {
|
||||||
Idle.recordActivity();
|
Idle.recordActivity();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user