Skip to content

Commit

Permalink
show unverified tab indicator on sidebar
Browse files Browse the repository at this point in the history
  • Loading branch information
ajbura committed Aug 4, 2024
1 parent c620504 commit d9ca0e9
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 33 deletions.
31 changes: 0 additions & 31 deletions src/app/hooks/useDeviceList.js

This file was deleted.

35 changes: 35 additions & 0 deletions src/app/hooks/useDeviceList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* eslint-disable import/prefer-default-export */
import { useState, useEffect } from 'react';
import { CryptoEvent, IMyDevice } from 'matrix-js-sdk';
import { CryptoEventHandlerMap } from 'matrix-js-sdk/lib/crypto';
import { useMatrixClient } from './useMatrixClient';

export function useDeviceList() {
const mx = useMatrixClient();
const [deviceList, setDeviceList] = useState<IMyDevice[] | null>(null);

useEffect(() => {
let isMounted = true;

const updateDevices = () =>
mx.getDevices().then((data) => {
if (!isMounted) return;
setDeviceList(data.devices || []);
});
updateDevices();

const handleDevicesUpdate: CryptoEventHandlerMap[CryptoEvent.DevicesUpdated] = (users) => {
const userId = mx.getUserId();
if (userId && users.includes(userId)) {
updateDevices();
}
};

mx.on(CryptoEvent.DevicesUpdated, handleDevicesUpdate);
return () => {
mx.removeListener(CryptoEvent.DevicesUpdated, handleDevicesUpdate);
isMounted = false;
};
}, [mx]);
return deviceList;
}
12 changes: 11 additions & 1 deletion src/app/pages/client/SidebarNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,15 @@ import {
SidebarItemTooltip,
SidebarItem,
} from '../../components/sidebar';
import { DirectTab, HomeTab, SpaceTabs, InboxTab, ExploreTab, UserTab } from './sidebar';
import {
DirectTab,
HomeTab,
SpaceTabs,
InboxTab,
ExploreTab,
UserTab,
UnverifiedTab,
} from './sidebar';
import { openCreateRoom, openSearch } from '../../../client/action/navigation';

export function SidebarNav() {
Expand Down Expand Up @@ -65,6 +73,8 @@ export function SidebarNav() {
</SidebarItemTooltip>
</SidebarItem>

<UnverifiedTab />

<InboxTab />
<UserTab />
</SidebarStack>
Expand Down
24 changes: 24 additions & 0 deletions src/app/pages/client/sidebar/UnverifiedTab.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { keyframes, style } from '@vanilla-extract/css';
import { color, toRem } from 'folds';

const pushRight = keyframes({
from: {
transform: `translateX(${toRem(2)}) scale(1)`,
},
to: {
transform: 'translateX(0) scale(1)',
},
});

export const UnverifiedTab = style({
animationName: pushRight,
animationDuration: '400ms',
animationIterationCount: 30,
animationDirection: 'alternate',
});

export const UnverifiedAvatar = style({
backgroundColor: color.Critical.Container,
color: color.Critical.OnContainer,
borderColor: color.Critical.ContainerLine,
});
51 changes: 51 additions & 0 deletions src/app/pages/client/sidebar/UnverifiedTab.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from 'react';
import { Badge, color, Icon, Icons, Text } from 'folds';
import { openSettings } from '../../../../client/action/navigation';
import { isCrossVerified } from '../../../../util/matrixUtil';
import {
SidebarAvatar,
SidebarItem,
SidebarItemBadge,
SidebarItemTooltip,
} from '../../../components/sidebar';
import { useDeviceList } from '../../../hooks/useDeviceList';
import { tabText } from '../../../organisms/settings/Settings';
import { useMatrixClient } from '../../../hooks/useMatrixClient';
import * as css from './UnverifiedTab.css';

export function UnverifiedTab() {
const mx = useMatrixClient();
const deviceList = useDeviceList();
console.log(deviceList);
const unverified = deviceList?.filter(
(device) => isCrossVerified(mx, device.device_id) === false
);
console.log(unverified);

if (!unverified?.length) return null;

return (
<SidebarItem className={css.UnverifiedTab}>
<SidebarItemTooltip tooltip="Unverified Sessions">
{(triggerRef) => (
<SidebarAvatar
className={css.UnverifiedAvatar}
as="button"
ref={triggerRef}
outlined
onClick={() => openSettings(tabText.SECURITY)}
>
<Icon style={{ color: color.Critical.Main }} src={Icons.ShieldUser} />
</SidebarAvatar>
)}
</SidebarItemTooltip>
<SidebarItemBadge hasCount>
<Badge variant="Critical" size="400" fill="Solid" radii="Pill" outlined={false}>
<Text as="span" size="L400">
{unverified.length}
</Text>
</Badge>
</SidebarItemBadge>
</SidebarItem>
);
}
1 change: 1 addition & 0 deletions src/app/pages/client/sidebar/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * from './SpaceTabs';
export * from './InboxTab';
export * from './ExploreTab';
export * from './UserTab';
export * from './UnverifiedTab';
2 changes: 1 addition & 1 deletion src/util/matrixUtil.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export function isCrossVerified(mx, deviceId) {
const deviceInfo = mx.getStoredDevice(mx.getUserId(), deviceId);
const deviceTrust = crossSignInfo.checkDeviceTrust(crossSignInfo, deviceInfo, false, true);
return deviceTrust.isCrossSigningVerified();
} catch {
} catch (e) {
// device does not support encryption
return null;
}
Expand Down

0 comments on commit d9ca0e9

Please sign in to comment.