Skip to content

Commit

Permalink
Merge pull request #8981 from ForumMagnum/ea-people-directory
Browse files Browse the repository at this point in the history
[EA] People directory
  • Loading branch information
oetherington committed Apr 25, 2024
2 parents a3a9a37 + d44d05a commit 13a5544
Show file tree
Hide file tree
Showing 67 changed files with 2,806 additions and 138 deletions.
8 changes: 8 additions & 0 deletions packages/lesswrong/components/common/ForumIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,10 @@ import ArrowRightOutlineIcon from "@heroicons/react/24/outline/PaperAirplaneIcon
import ArrowCircleIcon from "@heroicons/react/20/solid/ArrowPathRoundedSquareIcon";
import FunnelIcon from "@heroicons/react/24/outline/FunnelIcon";
import BarsArrowDown from "@heroicons/react/24/outline/BarsArrowDownIcon";
import ViewColumnsIcon from "@heroicons/react/24/outline/ViewColumnsIcon";
import InformationCircleIcon from '@heroicons/react/24/solid/InformationCircleIcon';
import ArrowDownOnSquareIcon from '@heroicons/react/24/outline/ArrowDownOnSquareIcon';
import ChevronUpDownIcon from "@heroicons/react/24/outline/ChevronUpDownIcon";
import MuiVolumeUpIcon from "@material-ui/icons/VolumeUp";
import MuiBookmarkIcon from "@material-ui/icons/Bookmark";
import MuiBookmarkBorderIcon from "@material-ui/icons/BookmarkBorder";
Expand Down Expand Up @@ -181,6 +183,7 @@ export type ForumIconName =
"ThickChevronLeft" |
"ThickChevronRight" |
"ThickChevronDown" |
"ChevronUpDown" |
"NarrowArrowDown" |
"Plus" |
"Check" |
Expand Down Expand Up @@ -217,6 +220,7 @@ export type ForumIconName =
"Voted" |
"InfoCircle" |
"BarsArrowDown" |
"ViewColumns" |
"LightbulbChat" |
"VoteBallot" |
"Import" |
Expand Down Expand Up @@ -273,6 +277,7 @@ const ICONS: ForumOptions<Record<ForumIconName, IconComponent>> = {
ThickChevronLeft: ThickChevronLeftIcon,
ThickChevronRight: ThickChevronRightIcon,
ThickChevronDown: ThickChevronDownIcon,
ChevronUpDown: ChevronUpDownIcon,
NarrowArrowDown: ArrowLongDown,
Plus: PlusIcon,
PlusSmall: PlusSmallIcon,
Expand Down Expand Up @@ -309,6 +314,7 @@ const ICONS: ForumOptions<Record<ForumIconName, IconComponent>> = {
Voted: VotedIcon,
InfoCircle: InformationCircleIcon,
BarsArrowDown: BarsArrowDown,
ViewColumns: ViewColumnsIcon,
LightbulbChat: LightbulbChatIcon,
VoteBallot: MuiVoteIcon,
Import: ArrowDownOnSquareIcon,
Expand Down Expand Up @@ -363,6 +369,7 @@ const ICONS: ForumOptions<Record<ForumIconName, IconComponent>> = {
ThickChevronLeft: ThickChevronLeftIcon,
ThickChevronRight: ThickChevronRightIcon,
ThickChevronDown: ThickChevronDownIcon,
ChevronUpDown: ChevronUpDownIcon,
NarrowArrowDown: ArrowLongDown,
Plus: PlusIcon,
PlusSmall: PlusSmallIcon,
Expand Down Expand Up @@ -399,6 +406,7 @@ const ICONS: ForumOptions<Record<ForumIconName, IconComponent>> = {
Voted: VotedIcon,
InfoCircle: InformationCircleIcon,
BarsArrowDown: BarsArrowDown,
ViewColumns: ViewColumnsIcon,
LightbulbChat: LightbulbChatIcon,
VoteBallot: MuiVoteIcon,
Import: ArrowDownOnSquareIcon,
Expand Down
25 changes: 18 additions & 7 deletions packages/lesswrong/components/common/HorizScrollBlock.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import React, { ReactNode, useCallback, useEffect, useRef, useState } from 'react';
import { Components, registerComponent } from "../../lib/vulcan-lib";
import { registerComponent } from "../../lib/vulcan-lib";
import classNames from 'classnames';

export const SCROLL_INDICATOR_SIZE = 13;

const styles = (theme: ThemeType): JssStyles => ({
scrollIndicatorWrapper: {
display: "block",
position: "relative",
maxWidth: "100% !important",

paddingLeft: 13,
paddingRight: 13,
paddingLeft: SCROLL_INDICATOR_SIZE,
paddingRight: SCROLL_INDICATOR_SIZE,
},

scrollIndicator: {
Expand Down Expand Up @@ -70,8 +72,10 @@ const styles = (theme: ThemeType): JssStyles => ({
},
})

const HorizScrollBlock = ({children, classes}: {
const HorizScrollBlock = ({children, className, contentsClassName, classes}: {
children: ReactNode
className?: string,
contentsClassName?: string,
classes: ClassesType,
}) => {
const scrollableContentsRef = useRef<HTMLDivElement>(null);
Expand All @@ -92,7 +96,7 @@ const HorizScrollBlock = ({children, classes}: {
updateScrollBounds();
}, [updateScrollBounds]);

return <div className={classes.scrollIndicatorWrapper}>
return <div className={classNames(classes.scrollIndicatorWrapper, className)}>
<div
className={classNames(
classes.scrollIndicator, classes.scrollIndicatorLeft,
Expand All @@ -104,7 +108,10 @@ const HorizScrollBlock = ({children, classes}: {
}}
/>
<div
className={classes.scrollableContents} ref={scrollableContentsRef} onScroll={updateScrollBounds}>
className={classNames(classes.scrollableContents, contentsClassName)}
ref={scrollableContentsRef}
onScroll={updateScrollBounds}
>
{children}
</div>
<div
Expand All @@ -123,7 +130,11 @@ const HorizScrollBlock = ({children, classes}: {
</div>
}

const HorizScrollBlockComponent = registerComponent('HorizScrollBlock', HorizScrollBlock, {styles});
const HorizScrollBlockComponent = registerComponent(
'HorizScrollBlock',
HorizScrollBlock,
{styles, stylePriority: -1},
);

declare global {
interface ComponentTypes {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useLocation } from '../../../lib/routeUtil';
import { MenuTabRegular } from './menuTabs';
import { forumSelect } from '../../../lib/forumTypeUtils';
import { isFriendlyUI } from '../../../themes/forumTheme';
import { useCurrentUser } from '../withUser';

export const iconWidth = 30

Expand All @@ -14,7 +15,7 @@ const iconTransform = forumSelect({
default: undefined,
});

const styles = (theme: ThemeType): JssStyles => ({
const styles = (theme: ThemeType) => ({
selected: {
'& $icon': {
opacity: 1,
Expand All @@ -25,7 +26,12 @@ const styles = (theme: ThemeType): JssStyles => ({
},
},
menuItem: {
width: 190,
width: isFriendlyUI ? 210 : 190,
},
desktopOnly: {
[theme.breakpoints.down("xs")]: {
display: "none !important",
},
},
navButton: {
'&:hover': {
Expand Down Expand Up @@ -91,19 +97,35 @@ const styles = (theme: ThemeType): JssStyles => ({
tooltip: {
maxWidth: isFriendlyUI ? 190 : undefined,
},
})
flag: {
padding: "2px 4px",
marginLeft: 10,
fontSize: 11,
fontWeight: 600,
lineHeight: "110%",
letterSpacing: "0.33px",
textTransform: "uppercase",
background: theme.palette.primary.main,
borderRadius: theme.borderRadius.small,
color: theme.palette.text.alwaysWhite,
},
});

export type TabNavigationItemProps = {
tab: MenuTabRegular,
onClick?: (event: React.MouseEvent<HTMLAnchorElement>) => void,
className?: string,
classes: ClassesType,
classes: ClassesType<typeof styles>,
}

const TabNavigationItem = ({tab, onClick, className, classes}: TabNavigationItemProps) => {
const { TabNavigationSubItem, LWTooltip, MenuItemLink } = Components
const { pathname } = useLocation()

const {pathname} = useLocation();
const currentUser = useCurrentUser();

if (tab.betaOnly && !currentUser?.beta) {
return null;
}

// Due to an issue with using anchor tags, we use react-router links, even for
// external links, we just use window.open to actuate the link.
const externalLink = /https?:\/\//.test(tab.link);
Expand All @@ -122,6 +144,7 @@ const TabNavigationItem = ({tab, onClick, className, classes}: TabNavigationItem
? tab.selectedIconComponent ?? tab.iconComponent
: tab.iconComponent;

const { TabNavigationSubItem, LWTooltip, MenuItemLink } = Components;
return <LWTooltip
placement='right-start'
title={tab.tooltip || ''}
Expand All @@ -138,6 +161,7 @@ const TabNavigationItem = ({tab, onClick, className, classes}: TabNavigationItem
[classes.navButton]: !tab.subItem,
[classes.subItemOverride]: tab.subItem,
[classes.selected]: isSelected,
[classes.desktopOnly]: tab.desktopOnly,
})}
disableTouchRipple
>
Expand All @@ -156,6 +180,7 @@ const TabNavigationItem = ({tab, onClick, className, classes}: TabNavigationItem
{tab.title}
</span>
}
{tab.flag && <span className={classes.flag}>{tab.flag}</span>}
</MenuItemLink>
</LWTooltip>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,12 @@ import TakeActionIcon from "@heroicons/react/24/outline/HeartIcon";
import TakeActionSelectedIcon from "@heroicons/react/24/solid/HeartIcon";
import EventsIcon from "@heroicons/react/24/outline/CalendarIcon";
import EventsSelectedIcon from "@heroicons/react/24/solid/CalendarIcon";
import GroupsIcon from "@heroicons/react/24/outline/UsersIcon";
import GroupsSelectedIcon from "@heroicons/react/24/solid/UsersIcon";
import GroupsIcon from "@heroicons/react/24/outline/UserGroupIcon";
import GroupsSelectedIcon from "@heroicons/react/24/solid/UserGroupIcon";
import {
PeopleDirectoryIcon,
PeopleDirectorySelectedIcon,
} from '../../icons/peopleDirectoryIcon';

// The sidebar / bottom bar of the Forum contain 10 or so similar tabs, unique to each Forum. The
// tabs can appear in
Expand Down Expand Up @@ -86,7 +90,10 @@ export type MenuTabRegular = {
showOnMobileStandalone?: boolean
showOnCompressed?: boolean
subItem?: boolean,
loggedOutOnly?: boolean
loggedOutOnly?: boolean,
flag?: string,
desktopOnly?: boolean,
betaOnly?: boolean,
}

type MenuTab = MenuTabDivider | MenuTabCustomComponent | MenuTabRegular
Expand Down Expand Up @@ -292,6 +299,18 @@ export const menuTabs: ForumOptions<Array<MenuTab>> = {
${taggingNamePluralSetting.get()} in EA and collects posts tagged with those ${taggingNamePluralSetting.get()}.`,
showOnMobileStandalone: true,
showOnCompressed: true,
}, {
id: 'peopleDirectory',
title: 'People directory',
link: '/people-directory',
iconComponent: PeopleDirectoryIcon,
selectedIconComponent: PeopleDirectorySelectedIcon,
tooltip: 'Search and filter Forum users',
showOnMobileStandalone: true,
showOnCompressed: true,
flag: "beta",
desktopOnly: true,
betaOnly: true,
}, {
id: 'takeAction',
title: 'Take action',
Expand All @@ -311,7 +330,7 @@ export const menuTabs: ForumOptions<Array<MenuTab>> = {
showOnCompressed: true
}, {
id: 'community',
title: 'Groups & people',
title: 'Groups',
link: communityPath,
iconComponent: GroupsIcon,
selectedIconComponent: GroupsSelectedIcon,
Expand Down
7 changes: 5 additions & 2 deletions packages/lesswrong/components/common/useClickableCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,18 @@ export type ClickableCellProps = {
} & ({
href: string,
onClick?: never,
openInNewTab?: boolean,
} | {
href?: never,
onClick: (e: MouseEvent<HTMLDivElement>) => void,
openInNewTab?: never,
});

export const useClickableCell = ({
ignoreLinks,
href,
onClick,
openInNewTab,
}: ClickableCellProps) => {
const navigate = useNavigate();
// Note that we only trigger this event if an href is provided
Expand All @@ -42,9 +45,9 @@ export const useClickableCell = ({
window.open(href, "_blank");
} else {
captureEvent();
navigate(href);
navigate(href, {openInNewTab});
}
}, [navigate, ignoreLinks, href, onClick, captureEvent]);
}, [navigate, ignoreLinks, href, onClick, openInNewTab, captureEvent]);

return {
onClick: wrappedOnClick,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Components, registerComponent } from '../../../lib/vulcan-lib';
import React, { useEffect, useRef, useState } from 'react';
import { useCurrentUser } from '../../common/withUser';
import { userGetProfileUrl } from '../../../lib/collections/users/helpers';
import { SOCIAL_MEDIA_PROFILE_FIELDS, userGetProfileUrl } from '../../../lib/collections/users/helpers';
import { useLocation } from '../../../lib/routeUtil';
import ArrowBack from '@material-ui/icons/ArrowBack'
import pick from 'lodash/pick';
import { CAREER_STAGES, SOCIAL_MEDIA_PROFILE_FIELDS } from '../../../lib/collections/users/schema';
import { CAREER_STAGES } from '../../../lib/collections/users/schema';
import Input from '@material-ui/core/Input';
import { useGoogleMaps } from '../../form-components/LocationFormComponent';
import { pickBestReverseGeocodingResult } from '../../../lib/geocoding';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import React from "react";
import { registerComponent, Components } from "../../../lib/vulcan-lib";
import { Link } from "../../../lib/reactRouterWrapper";
import {
SocialMediaProfileField,
SOCIAL_MEDIA_PROFILE_FIELDS,
CAREER_STAGES,
} from "../../../lib/collections/users/schema";
import { CAREER_STAGES } from "../../../lib/collections/users/schema";
import { SOCIAL_MEDIA_PROFILE_FIELDS, SocialMediaProfileField } from "../../../lib/collections/users/helpers";
import { communityPath } from "../../../lib/routes";

const styles = (theme: ThemeType): JssStyles => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import React from 'react';
import { Components, registerComponent } from '../../lib/vulcan-lib';
import Input from '@material-ui/core/Input';
import InputAdornment from '@material-ui/core/InputAdornment';
import { SocialMediaSiteName } from '../icons/SocialMediaIcon';
import type { SocialMediaProfileField } from '../../lib/collections/users/schema';
import type { SocialMediaProfileField } from '../../lib/collections/users/helpers';

const styles = (theme: ThemeType): JssStyles => ({
root: {
Expand Down
13 changes: 9 additions & 4 deletions packages/lesswrong/components/hooks/useInitiateConversation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useMulti } from "../../lib/crud/withMulti";
import { isAF } from "../../lib/instanceSettings";
import { useCurrentUser } from "../common/withUser";
import { useMessages } from "../common/withMessages";
import { useTracking } from "../../lib/analyticsEvents";

/**
* Hook to initiate a conversation with a user. This get's the existing conversation (first conversation
Expand All @@ -12,6 +13,10 @@ import { useMessages } from "../common/withMessages";
* by the hook
*/
export const useInitiateConversation = (props?: { includeModerators?: boolean }) => {
const {captureEvent} = useTracking({
eventType: "initiateConversation",
eventProps: props,
});
const { includeModerators = false } = props || {};

const currentUser = useCurrentUser();
Expand Down Expand Up @@ -53,10 +58,10 @@ export const useInitiateConversation = (props?: { includeModerators?: boolean })

const conversation = results?.[0];

const initiateConversation = useCallback(
(userIds: string[]) => setUserIds(userIds?.length ? userIds : null),
[]
);
const initiateConversation = useCallback((userIds: string[]) => {
setUserIds(userIds?.length ? userIds : null);
captureEvent();
}, [captureEvent]);

return {
conversation,
Expand Down
Loading

0 comments on commit 13a5544

Please sign in to comment.