mirror of
https://github.com/umami-software/umami.git
synced 2026-02-04 04:37:11 +01:00
Merge 5413ce5d61 into 860e6390f1
This commit is contained in:
commit
d4b4230f69
4 changed files with 43 additions and 10 deletions
|
|
@ -13,6 +13,7 @@ import { X } from 'lucide-react';
|
|||
import { Avatar } from '@/components/common/Avatar';
|
||||
import { LoadingPanel } from '@/components/common/LoadingPanel';
|
||||
import { useMessages, useWebsiteSessionQuery } from '@/components/hooks';
|
||||
import { isLikelyBot } from '@/lib/botDetection';
|
||||
import { SessionActivity } from './SessionActivity';
|
||||
import { SessionData } from './SessionData';
|
||||
import { SessionInfo } from './SessionInfo';
|
||||
|
|
@ -51,7 +52,7 @@ export function SessionProfile({
|
|||
)}
|
||||
<Column gap="6">
|
||||
<Row justifyContent="center" alignItems="center" gap="6">
|
||||
<Avatar seed={data?.id} size={128} />
|
||||
<Avatar seed={data?.id} size={128} isBot={isLikelyBot(data)} />
|
||||
<Column width="360px">
|
||||
<TextField label="ID" value={data?.id} allowCopy />
|
||||
</Column>
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { Avatar } from '@/components/common/Avatar';
|
|||
import { DateDistance } from '@/components/common/DateDistance';
|
||||
import { TypeIcon } from '@/components/common/TypeIcon';
|
||||
import { useFormat, useMessages, useNavigation } from '@/components/hooks';
|
||||
import { isLikelyBot } from '@/lib/botDetection';
|
||||
|
||||
export function SessionsTable(props: DataTableProps) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
|
|
@ -15,7 +16,7 @@ export function SessionsTable(props: DataTableProps) {
|
|||
<DataColumn id="id" label={formatMessage(labels.session)} width="100px">
|
||||
{(row: any) => (
|
||||
<Link href={updateParams({ session: row.id })}>
|
||||
<Avatar seed={row.id} size={32} />
|
||||
<Avatar seed={row.id} size={32} isBot={isLikelyBot(row)} />
|
||||
</Link>
|
||||
)}
|
||||
</DataColumn>
|
||||
|
|
|
|||
|
|
@ -1,21 +1,27 @@
|
|||
import { lorelei } from '@dicebear/collection';
|
||||
import { createAvatar } from '@dicebear/core';
|
||||
import { bottts, lorelei } from '@dicebear/collection';
|
||||
import { createAvatar, type Style } from '@dicebear/core';
|
||||
import { useMemo } from 'react';
|
||||
import { getColor, getPastel } from '@/lib/colors';
|
||||
|
||||
const lib = lorelei;
|
||||
|
||||
export function Avatar({ seed, size = 128, ...props }: { seed: string; size?: number }) {
|
||||
export function Avatar({
|
||||
seed,
|
||||
size = 128,
|
||||
isBot = false,
|
||||
}: {
|
||||
seed: string;
|
||||
size?: number;
|
||||
isBot?: boolean;
|
||||
}) {
|
||||
const backgroundColor = getPastel(getColor(seed), 4);
|
||||
const style = (isBot ? bottts : lorelei) as Style<object>;
|
||||
|
||||
const avatar = useMemo(() => {
|
||||
return createAvatar(lib, {
|
||||
...props,
|
||||
return createAvatar(style, {
|
||||
seed,
|
||||
size,
|
||||
backgroundColor: [backgroundColor],
|
||||
}).toDataUri();
|
||||
}, []);
|
||||
}, [seed, isBot]);
|
||||
|
||||
return <img src={avatar} alt="Avatar" style={{ borderRadius: '100%', width: size }} />;
|
||||
}
|
||||
|
|
|
|||
25
src/lib/botDetection.ts
Normal file
25
src/lib/botDetection.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
const BOT_CITIES = [
|
||||
'Council Bluffs',
|
||||
'North Richland Hills',
|
||||
'Santa Clara',
|
||||
'Ashburn',
|
||||
'The Dalles',
|
||||
'Boardman',
|
||||
'Quincy',
|
||||
];
|
||||
|
||||
export function isLikelyBot(session: {
|
||||
city?: string;
|
||||
firstAt?: string | Date;
|
||||
lastAt?: string | Date;
|
||||
}): boolean {
|
||||
const cityMatch =
|
||||
session.city && BOT_CITIES.some(botCity => session.city?.toLowerCase() === botCity.toLowerCase());
|
||||
|
||||
const zeroDuration =
|
||||
session.firstAt &&
|
||||
session.lastAt &&
|
||||
new Date(session.firstAt).getTime() === new Date(session.lastAt).getTime();
|
||||
|
||||
return !!(cityMatch && zeroDuration);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue