react-icons/fi#FiSettings TypeScript Examples
The following examples show how to use
react-icons/fi#FiSettings.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Navigation.tsx From bluebubbles-server with Apache License 2.0 | 6 votes |
LinkItems: Array<LinkItemProps> = [
{ name: 'Home', icon: FiHome, to: '/' },
{ name: 'Devices', icon: FiMonitor, to: '/devices' },
{ name: 'Contacts', icon: BsPersonCircle, to: '/contacts' },
{ name: 'Debug & Logs', icon: AiOutlineBug, to: '/logs' },
{ name: 'Google FCM', icon: BiNotification, to: '/fcm' },
{ name: 'API & Webhooks', icon: AiOutlineApi, to: '/webhooks' },
{ name: 'Guides & Links', icon: BsBook, to: '/guides' },
{ name: 'Settings', icon: FiSettings, to: '/settings' }
]
Example #2
Source File: DmChat.tsx From meshtastic-web with GNU General Public License v3.0 | 6 votes |
DmChat = ({
node,
selectedIndex,
setSelectedIndex,
}: DmChatProps): JSX.Element => {
return (
<SidebarItem
key={node.num}
selected={node.num === selectedIndex}
setSelected={(): void => {
setSelectedIndex(node.num);
}}
actions={<IconButton nested icon={<FiSettings />} />}
>
<div className="flex dark:text-white">
<div className="m-auto">
<Hashicon value={node.num.toString()} size={32} />
</div>
</div>
<div className="my-auto mr-auto font-semibold dark:text-white">
{node.user?.longName ?? 'Unknown'}
</div>
</SidebarItem>
);
}
Example #3
Source File: index.tsx From meshtastic-web with GNU General Public License v3.0 | 5 votes |
Layout = ({
title,
icon,
sidebarContents,
children,
}: LayoutProps): JSX.Element => {
const [settingsOpen, setSettingsOpen] = useState(false);
const route = useRoute();
const tabs: Omit<TabProps, 'activeLeft' | 'activeRight'>[] = [
{
title: 'Messages',
icon: <FiMessageCircle />,
link: routes.messages().link,
active: route.name === 'messages',
},
{
title: 'Map',
icon: <RiRoadMapLine />,
link: routes.map().link,
active: route.name === 'map',
},
{
title: 'Extensions',
icon: <VscExtensions />,
link: routes.extensions().link,
active: route.name === 'extensions',
},
];
return (
<div className="relative flex w-full overflow-hidden bg-white dark:bg-secondaryDark">
<div className="flex flex-grow">
<Sidebar settingsOpen={settingsOpen} setSettingsOpen={setSettingsOpen}>
<div className="bg-white px-1 pt-1 drop-shadow-md dark:bg-primaryDark">
<div className="flex h-10 gap-1">
<div className="my-auto">
<IconButton icon={icon} />
</div>
<div className="my-auto text-lg font-medium dark:text-white">
{title}
</div>
</div>
</div>
<div className="flex flex-col gap-2">{sidebarContents}</div>
</Sidebar>
</div>
<ErrorBoundary FallbackComponent={ErrorFallback}>
<div className="flex h-full w-full flex-col bg-gray-300 dark:bg-secondaryDark">
<div className="flex w-full bg-white pt-1 dark:bg-primaryDark">
<div className="z-10 -mr-2 h-8">
<IconButton
className="m-1"
icon={<FiSettings />}
onClick={(): void => {
setSettingsOpen(!settingsOpen);
}}
active={settingsOpen}
/>
</div>
<Tabs tabs={tabs} />
</div>
<div className="flex flex-grow">{children}</div>
</div>
</ErrorBoundary>
</div>
);
}
Example #4
Source File: index.tsx From dxvote with GNU Affero General Public License v3.0 | 4 votes |
Header = observer(() => {
const NavItem = withRouter(
({ route, history, children }: NavItemProps & RouteComponentProps) => {
return (
<div
style={{ cursor: 'pointer' }}
onClick={() => {
history.push(route);
}}
>
{' '}
{children}{' '}
</div>
);
}
);
const {
context: { providerStore, blockchainStore, configStore, daoStore },
} = useContext();
const { active, account } = providerStore.getActiveWeb3React();
const isTestingEnv = !window?.location?.href?.includes('dxvote.eth');
const networkName = configStore.getActiveChainName();
const { userRep, totalSupply } =
active && blockchainStore.initialLoadComplete
? daoStore.getRepAt(account, providerStore.getCurrentBlockNumber())
: { userRep: bnum(0), totalSupply: bnum(0) };
const repPercentage = active
? userRep.times(100).div(totalSupply).toFixed(4)
: bnum(0);
// const votingMachines = configStore.getNetworkContracts().votingMachines;
// const votingMachineTokens = _.uniq(
// Object.keys(votingMachines).map((votingMachineAddress, i) =>
// configStore
// .getTokensOfNetwork()
// .find(
// token => token.address === votingMachines[votingMachineAddress].token
// )
// )
// );
return (
<NavWrapper>
<NavSection>
<NavItem route={`/${networkName}/proposals`}>
<MenuItem>
<img alt="dxdao" src={dxdaoIcon} />
{isTestingEnv && <WarningDev>Testing Environment</WarningDev>}
</MenuItem>
</NavItem>
</NavSection>
{!active ? (
<NavSection>
<Web3ConnectStatus text="Connect Wallet" />
<NavItem route={`/config`}>
<a>
<FiSettings style={{ margin: '0px 10px', color: '#616161' }} />
</a>
</NavItem>
</NavSection>
) : blockchainStore.initialLoadComplete ? (
<NavSection>
{account && active && (
<>
{/* {useBalances(
account
? votingMachineTokens.map(votingMachineToken => ({
assetAddress: votingMachineToken.address,
fromAddress: account,
}))
: []
).map((votingMachineTokenBalance, i) => {
return (
<ItemBox key={i}>
{formatCurrency(
normalizeBalance(votingMachineTokenBalance)
)}{' '}
{votingMachineTokens[i].symbol}{' '}
</ItemBox>
);
})} */}
{repPercentage.toString() !== 'NaN' && (
<ItemBox> {repPercentage.toString()} % REP </ItemBox>
)}
</>
)}
<Web3ConnectStatus text="Connect Wallet" />
<NavItem route={`/${networkName}/info`}>
<a>
<FiBarChart2 style={{ margin: '0px 10px', color: '#616161' }} />
</a>
</NavItem>
<NavItem route={`/config`}>
<a>
<FiSettings style={{ margin: '0px 10px', color: '#616161' }} />
</a>
</NavItem>
{account && (
<NavItem route={`/${networkName}/user/${account}`}>
<a>
<FiUser style={{ margin: '0px 10px', color: '#616161' }} />
</a>
</NavItem>
)}
</NavSection>
) : (
<NavSection>
<Web3ConnectStatus text="Connect Wallet" />
<NavItem route={`/config`}>
<a>
<FiSettings style={{ margin: '0px 10px', color: '#616161' }} />
</a>
</NavItem>
</NavSection>
)}
</NavWrapper>
);
})
Example #5
Source File: GitHubSiteLayout.tsx From pagely with MIT License | 4 votes |
SidebarLayout: React.FC<{
activeTab: 'code' | 'setup' | 'settings';
title?: string;
}> = ({ activeTab, title, ...props }) => {
const { emailAddresses, profileImageUrl, fullName, firstName } = useUser();
const { signOut } = useClerk();
const router = useRouter();
const { data } = useClerkSWR<ghSites>(
`/api/getSiteData/github/?siteId=${router.query.siteId}`
);
return (
<div>
<div className='block lg:hidden'>
<DashboardNav />
<Head>
<title>
{title ||
data?.siteName +
' - ' +
activeTab.charAt(0).toUpperCase() +
activeTab.slice(1) +
' | ' +
'Pagely'}
</title>
</Head>
</div>
<div className='lg:flex'>
{/* <div className='sticky top-0 overflow-y-hidden'> */}
<div
style={{ position: 'sticky' }}
className='absolute top-0 h-screen left-0 px-10 py-5 bg-gray-50 w-[20vw] border-r hidden flex-col justify-between lg:flex'>
<div>
<Link href='/dashboard'>
<a>
<small className='text-gray-700 hover:text-gray-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-gray-700'>
{' '}
{'<'}- Go back
</small>
</a>
</Link>
<ul className='mt-10'>
<li
className={`my-2 rounded ${
activeTab === 'setup' ? ' bg-gray-200' : ' hover:bg-gray-300'
}`}>
<Link href={`/github-site/${data?.id}`}>
<a className='block px-3 py-2 my-2 rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-gray-700'>
{' '}
<GoInbox className='relative inline-block bottom-[2px]' />{' '}
Setup
</a>
</Link>
</li>
<li
className={`my-2 rounded ${
activeTab === 'code' ? ' bg-gray-200' : ' hover:bg-gray-300'
}`}>
<Link href={`/github-site/${data?.id}/code`}>
<a className='block px-3 py-2 my-2 rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-gray-700'>
{' '}
<BiCode className='relative inline-block bottom-[2px]' />{' '}
Code injection
</a>
</Link>
</li>
<li
className={`my-2 rounded ${
activeTab === 'settings'
? ' bg-gray-200'
: ' hover:bg-gray-300'
}`}>
<Link href={`/github-site/${data?.id}/settings`}>
<a className='block px-3 py-2 my-2 rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-gray-700'>
{' '}
<FiSettings className='relative inline-block bottom-[2px]' />{' '}
Settings
</a>
</Link>
</li>
</ul>
</div>
<ProfileDropdown
emailAddresses={emailAddresses}
profileImageUrl={profileImageUrl}
fullName={fullName}
firstName={firstName}
signOut={signOut}
/>
</div>
<div className='mx-10 mt-20'>{props.children}</div>
</div>
<Toaster />
</div>
);
}
Example #6
Source File: SidebarLayout.tsx From pagely with MIT License | 4 votes |
SidebarLayout: React.FC<{
activeTab: 'code' | 'setup' | 'pages' | 'settings' | 'seo';
title?: string;
}> = ({ activeTab, title, ...props }) => {
const { emailAddresses, profileImageUrl, fullName, firstName } = useUser();
const { signOut } = useClerk();
const router = useRouter();
const { data } = useClerkSWR<notionSites>(
`/api/getSiteData/notion/?siteId=${router.query.notionId}`
);
return (
<div>
<div className='block lg:hidden'>
<DashboardNav />
<Head>
<title>
{title ||
data?.siteName +
' - ' +
activeTab.charAt(0).toUpperCase() +
activeTab.slice(1) +
' | ' +
'Pagely'}
</title>
</Head>
</div>
<div className='lg:flex'>
{/* <div className='sticky top-0 overflow-y-hidden'> */}
<div
style={{ position: 'sticky' }}
className='absolute top-0 h-screen left-0 px-10 py-5 bg-gray-50 w-[20vw] border-r hidden flex-col justify-between lg:flex'>
<div>
<Link href='/dashboard'>
<a>
<small className='text-gray-700 hover:text-gray-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-gray-700'>
{' '}
{'<'}- Go back
</small>
</a>
</Link>
<ul className='mt-10'>
<li
className={`my-2 rounded ${
activeTab === 'setup' ? ' bg-gray-200' : ' hover:bg-gray-300'
}`}>
<Link href={'/notion-site/' + data?.id}>
<a className='block px-3 py-2 my-2 rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-gray-700'>
{' '}
<GoInbox className='relative inline-block bottom-[2px]' />{' '}
Setup
</a>
</Link>
</li>
<li
className={`my-2 rounded ${
activeTab === 'seo' ? ' bg-gray-200' : ' hover:bg-gray-300'
}`}>
<Link href={`/notion-site/${data?.id}/seo`}>
<a className='block px-3 py-2 my-2 rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-gray-700'>
{' '}
<BiSearchAlt className='relative inline-block bottom-[2px]' />{' '}
SEO
</a>
</Link>
</li>
<li
className={`my-2 rounded ${
activeTab === 'code' ? ' bg-gray-200' : ' hover:bg-gray-300'
}`}>
<Link href={`/notion-site/${data?.id}/code`}>
<a className='block px-3 py-2 my-2 rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-gray-700'>
{' '}
<BiCode className='relative inline-block bottom-[2px]' />{' '}
Code injection
</a>
</Link>
</li>
<li
className={`my-2 rounded ${
activeTab === 'pages' ? ' bg-gray-200' : ' hover:bg-gray-300'
}`}>
<Link href={`/notion-site/${data?.id}/pages`}>
<a className='block px-3 py-2 my-2 rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-gray-700'>
{' '}
<HiOutlineNewspaper className='relative inline-block bottom-[2px]' />{' '}
Pages
</a>
</Link>
</li>
<li
className={`my-2 rounded ${
activeTab === 'settings'
? ' bg-gray-200'
: ' hover:bg-gray-300'
}`}>
<Link href={`/notion-site/${data?.id}/settings`}>
<a className='block px-3 py-2 my-2 rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-gray-700'>
{' '}
<FiSettings className='relative inline-block bottom-[2px]' />{' '}
Settings
</a>
</Link>
</li>
</ul>
</div>
<ProfileDropdown
emailAddresses={emailAddresses}
profileImageUrl={profileImageUrl}
fullName={fullName}
firstName={firstName}
signOut={signOut}
/>
</div>
<div className='mx-10 mt-20'>{props.children}</div>
</div>
<Toaster />
</div>
);
}
Example #7
Source File: index.tsx From jsonschema-editor-react with Apache License 2.0 | 4 votes |
SchemaArray: React.FunctionComponent<SchemaArrayProps> = (
props: React.PropsWithChildren<SchemaArrayProps>
) => {
const { schemaState, isReadOnly } = props;
const state = useState(schemaState.items as JSONSchema7);
const isReadOnlyState = useState(isReadOnly);
const { length } = state.path.filter((name) => name !== "properties");
const tagPaddingLeftStyle = {
paddingLeft: `${20 * (length + 1)}px`,
};
const onCloseAdvanced = (): void => {
localState.isAdvancedOpen.set(false);
};
const showadvanced = (): void => {
localState.isAdvancedOpen.set(true);
};
const focusRef = React.createRef<HTMLElement>();
const localState = useState({
isAdvancedOpen: false,
});
return (
<>
<Flex
direction="row"
wrap="nowrap"
className="array-item"
mt={2}
mr={5}
style={tagPaddingLeftStyle}
>
<Input
key="Items"
isDisabled
value="Items"
size="sm"
flexShrink={1}
margin={2}
variant="outline"
/>
<Checkbox isDisabled margin={2} colorScheme="blue" />
<Select
variant="outline"
isDisabled={isReadOnlyState.value}
value={state.type.value as JSONSchema7TypeName}
size="sm"
margin={2}
placeholder="Choose data type"
onChange={(evt: React.ChangeEvent<HTMLSelectElement>) => {
const newSchema = handleTypeChange(
evt.target.value as JSONSchema7TypeName,
false
);
state.set(newSchema as JSONSchema7);
}}
>
{SchemaTypes.map((item, index) => {
return (
<option key={String(index)} value={item}>
{item}
</option>
);
})}
</Select>
<Input
value={state.title.value}
isDisabled={isReadOnlyState.value}
size="sm"
margin={2}
variant="outline"
placeholder="Add Title"
onChange={(evt: React.ChangeEvent<HTMLInputElement>) => {
state.title.set(evt.target.value);
}}
/>
<Input
value={state.description.value}
isDisabled={isReadOnlyState.value}
size="sm"
margin={2}
variant="outline"
placeholder="Add Description"
onChange={(evt: React.ChangeEvent<HTMLInputElement>) => {
state.description.set(evt.target.value);
}}
/>
<Tooltip
hasArrow
aria-label="Advanced Settings"
label="Advanced Settings"
placement="top"
>
<IconButton
isRound
isDisabled={isReadOnlyState.value}
size="sm"
mt={2}
mb={2}
ml={1}
variant="link"
colorScheme="blue"
fontSize="16px"
icon={<FiSettings />}
aria-label="Advanced Settings"
onClick={() => {
showadvanced();
}}
/>
</Tooltip>
{state.type.value === "object" && (
<Tooltip
hasArrow
aria-label="Add Child Node"
label="Add Child Node"
placement="top"
>
<IconButton
isRound
isDisabled={isReadOnlyState.value}
size="sm"
mt={2}
mb={2}
mr={2}
variant="link"
colorScheme="green"
fontSize="16px"
icon={<IoIosAddCircleOutline />}
aria-label="Add Child Node"
onClick={() => {
const fieldName = `field_${random()}`;
(state.properties as State<{
[key: string]: JSONSchema7;
}>)[fieldName].set(getDefaultSchema(DataType.string));
}}
/>
</Tooltip>
)}
</Flex>
{state.type?.value === "object" && (
<SchemaObject isReadOnly={isReadOnlyState} schemaState={state} />
)}
{state.type?.value === "array" && (
<SchemaArray isReadOnly={isReadOnlyState} schemaState={state} />
)}
<Modal
isOpen={localState.isAdvancedOpen.get()}
finalFocusRef={focusRef}
size="lg"
onClose={onCloseAdvanced}
>
<ModalOverlay />
<ModalContent>
<ModalHeader textAlign="center">Advanced Schema Settings</ModalHeader>
<ModalBody>
<AdvancedSettings itemStateProp={state} />
</ModalBody>
<ModalFooter>
<Button
colorScheme="blue"
variant="ghost"
mr={3}
onClick={onCloseAdvanced}
>
Close
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</>
);
}
Example #8
Source File: index.tsx From jsonschema-editor-react with Apache License 2.0 | 4 votes |
SchemaItem: React.FunctionComponent<SchemaItemProps> = (
props: React.PropsWithChildren<SchemaItemProps>
) => {
const {
name,
itemStateProp,
showadvanced,
required,
parentStateProp,
isReadOnly,
} = props;
// const itemState = useState(itemStateProp);
const parentState = useState(parentStateProp);
const parentStateOrNull: State<JSONSchema7> | undefined = parentState.ornull;
const propertiesOrNull:
| State<{
[key: string]: JSONSchema7Definition;
}>
| undefined = parentStateOrNull.properties.ornull;
const nameState = useState(name);
const isReadOnlyState = useState(isReadOnly);
const itemState = useState(
(parentStateProp.properties as State<{
[key: string]: JSONSchema7;
}>).nested(nameState.value)
);
const { length } = parentState.path.filter((name) => name !== "properties");
const tagPaddingLeftStyle = {
paddingLeft: `${20 * (length + 1)}px`,
};
const isRequired = required
? required.length > 0 && required.includes(name)
: false;
const toast = useToast();
// Debounce callback
const debounced = useDebouncedCallback(
// function
(newValue: string) => {
// Todo: make toast for duplicate properties
if (propertiesOrNull && propertiesOrNull[newValue].value) {
toast({
title: "Duplicate Property",
description: "Property already exists!",
status: "error",
duration: 1000,
isClosable: true,
position: "top",
});
} else {
const oldName = name;
const proptoupdate = newValue;
const newobj = renameKeys(
{ [oldName]: proptoupdate },
parentState.properties.value
);
parentStateOrNull.properties.set(JSON.parse(JSON.stringify(newobj)));
}
},
// delay in ms
1000
);
if (!itemState.value) {
return <></>;
}
return (
<div>
<Flex
alignContent="space-evenly"
direction="row"
wrap="nowrap"
className="schema-item"
style={tagPaddingLeftStyle}
>
<Input
isDisabled={isReadOnlyState.value}
defaultValue={nameState.value}
size="sm"
margin={2}
variant="outline"
placeholder="Enter property name"
onChange={(evt: React.ChangeEvent<HTMLInputElement>) => {
debounced(evt.target.value);
}}
/>
<Checkbox
isDisabled={isReadOnlyState.value}
isChecked={isRequired}
margin={2}
colorScheme="blue"
onChange={(evt: React.ChangeEvent<HTMLInputElement>) => {
if (!evt.target.checked && required.includes(name)) {
(parentState.required as State<string[]>)[
required.indexOf(name)
].set(none);
} else {
parentState.required.merge([name]);
}
}}
/>
<Select
isDisabled={false}
variant="outline"
value={itemState.type.value}
size="sm"
margin={2}
placeholder="Choose data type"
onChange={(evt: React.ChangeEvent<HTMLSelectElement>) => {
const newSchema = handleTypeChange(
evt.target.value as JSONSchema7TypeName,
false
);
itemState.set(newSchema as JSONSchema7);
}}
>
{SchemaTypes.map((item, index) => {
return (
<option key={String(index)} value={item}>
{item}
</option>
);
})}
</Select>
<Input
isDisabled={isReadOnlyState.value}
value={itemState.title.value || ""}
size="sm"
margin={2}
variant="outline"
placeholder="Add Title"
onChange={(evt: React.ChangeEvent<HTMLInputElement>) => {
itemState.title.set(evt.target.value);
}}
/>
<Input
isDisabled={isReadOnlyState.value}
value={itemState.description.value || ""}
size="sm"
margin={2}
variant="outline"
placeholder="Add Description"
onChange={(evt: React.ChangeEvent<HTMLInputElement>) => {
itemState.description.set(evt.target.value);
}}
/>
{itemState.type.value !== "object" && itemState.type.value !== "array" && (
<Tooltip
hasArrow
aria-label="Advanced Settings"
label="Advanced Settings"
placement="top"
>
<IconButton
isRound
isDisabled={isReadOnlyState.value}
size="sm"
mt={2}
mb={2}
ml={1}
variant="link"
colorScheme="blue"
fontSize="16px"
icon={<FiSettings />}
aria-label="Advanced Settings"
onClick={() => {
showadvanced(name);
}}
/>
</Tooltip>
)}
<Tooltip
hasArrow
aria-label="Remove Node"
label="Remove Node"
placement="top"
>
<IconButton
isRound
isDisabled={isReadOnlyState.value}
size="sm"
mt={2}
mb={2}
ml={1}
variant="link"
colorScheme="red"
fontSize="16px"
icon={<AiOutlineDelete />}
aria-label="Remove Node"
onClick={() => {
const updatedState = deleteKey(
nameState.value,
JSON.parse(JSON.stringify(parentState.properties.value))
);
parentState.properties.set(updatedState);
}}
/>
</Tooltip>
{itemState.type?.value === "object" ? (
<DropPlus
isDisabled={isReadOnlyState.value}
parentStateProp={parentState}
itemStateProp={itemStateProp}
/>
) : (
<Tooltip
hasArrow
aria-label="Add Sibling Node"
label="Add Sibling Node"
placement="top"
>
<IconButton
isRound
isDisabled={isReadOnlyState.value}
size="sm"
mt={2}
mb={2}
mr={2}
variant="link"
colorScheme="green"
fontSize="16px"
icon={<IoIosAddCircleOutline />}
aria-label="Add Sibling Node"
onClick={() => {
if (propertiesOrNull) {
const fieldName = `field_${random()}`;
propertiesOrNull
?.nested(fieldName)
.set(getDefaultSchema(DataType.string) as JSONSchema7);
}
}}
/>
</Tooltip>
)}
</Flex>
{itemState.type?.value === "object" && (
<SchemaObject isReadOnly={isReadOnlyState} schemaState={itemState} />
)}
{itemState.type?.value === "array" && (
<SchemaArray isReadOnly={isReadOnlyState} schemaState={itemState} />
)}
</div>
);
}
Example #9
Source File: Settings.tsx From Twenty48 with GNU General Public License v3.0 | 4 votes |
Settings: React.FC = () => {
const version = packJson['version']
const [theme, setTheme] = useRecoilState<ThemeType>(ThemeState)
const [anchorEl, setAnchorEl] = useState<Element | null | undefined>(null)
const [isCacheClear, setIsCacheClear] = useState(() => {
if (
localStorage.getItem(BESTSCORE) ||
localStorage.getItem(GAMESTATE) ||
localStorage.getItem(THEME)
) {
return false
}
return true
})
const cacheClearText = isCacheClear ? 'Cache is Clear' : 'Clear Cache'
useEffect(() => {
localStorage.setItem(THEME, theme)
}, [theme])
const removeLocalStorage = (): void => {
localStorage.removeItem(THEME)
localStorage.removeItem(GAMESTATE)
localStorage.removeItem(BESTSCORE)
setIsCacheClear(true)
}
const setSelectedTheme = (
e: React.ChangeEvent<{ name?: string; value: unknown }>,
): void => {
setTheme(e.target.value as ThemeType)
}
const getPopoverBody = (): React.ReactElement => {
return (
<div className={`popover-body popover-body-${theme}`}>
<div className="settings-item center">
<h3 onClick={removeLocalStorage}>{cacheClearText}</h3>
</div>
<Divider />
<div className="settings-item">
<h3>Theme:</h3>
<div className="center-item">
{theme === ThemeType.DARK ? (
<GiMoonBats size="22px" className="theme-icon" />
) : (
<GiUbisoftSun size="22px" className="theme-icon" />
)}
<FormControl className="no-decoration">
<NativeSelect
value={theme}
className={`select-${theme}`}
onChange={setSelectedTheme}
>
{Object.values(ThemeType).map((type, idx) => {
return (
<option key={idx} value={type}>
{type}
</option>
)
})}
</NativeSelect>
</FormControl>
</div>
</div>
<Divider />
<div className="settings-item">
<h3>Version:</h3>
<h4 className="center-item">{version}</h4>
</div>
<Divider />
<div className="settings-item ">
<h3>Made with:</h3>
<img src={logo} className="react-icon" />
</div>
</div>
)
}
return (
<>
<div>
<FiSettings
id="settings-cog"
className="settings-cog"
size="30px"
onClick={(e): void => setAnchorEl(e.currentTarget)}
/>
</div>
{/* Popover component: hidden until above button click */}
<Popover
open={anchorEl !== null}
anchorEl={anchorEl}
onClose={(): void => setAnchorEl(null)}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'center',
}}
>
{getPopoverBody()}
</Popover>
</>
)
}
Example #10
Source File: ChannelChat.tsx From meshtastic-web with GNU General Public License v3.0 | 4 votes |
ChannelChat = ({
channel,
selectedIndex,
setSelectedIndex,
}: ChannelChatProps): JSX.Element => {
const myNodeNum = useAppSelector(
(state) => state.meshtastic.radio.hardware,
).myNodeNum;
const nodes = useAppSelector((state) => state.meshtastic.nodes).filter(
(node) => node.data.num !== myNodeNum,
);
const chats = useAppSelector((state) => state.meshtastic.chats);
const channels = useAppSelector(
(state) => state.meshtastic.radio.channels,
).filter((ch) => ch.role !== Protobuf.Channel_Role.DISABLED);
return (
<SidebarItem
key={channel.index}
selected={channel.index === selectedIndex}
setSelected={(): void => {
setSelectedIndex(channel.index);
}}
actions={<IconButton nested icon={<FiSettings />} />}
>
<Tooltip
content={
channel.settings?.name.length
? channel.settings.name
: `CH: ${channel.index}`
}
>
<div className="flex h-8 w-8 rounded-full bg-gray-300 dark:bg-primaryDark dark:text-white">
<div className="m-auto">
{channel.role === Protobuf.Channel_Role.PRIMARY ? (
<MdPublic />
) : (
<p>
{channel.settings?.name.length
? channel.settings.name.substring(0, 3).toUpperCase()
: `CH: ${channel.index}`}
</p>
)}
</div>
</div>
</Tooltip>
{chats[channel.index]?.messages.length ? (
<>
<div className="mx-2 flex h-8">
{[
...new Set(
chats[channel.index]?.messages.flatMap(({ message }) => [
message.packet.from,
]),
),
]
.sort()
.map((nodeId) => {
return (
<Tooltip
key={nodeId}
content={
nodes.find((node) => node.data.num === nodeId)?.data.user
?.longName ?? 'UNK'
}
>
<div className="flex h-full">
<m.div
whileHover={{ scale: 1.1 }}
className="my-auto -ml-2"
>
<Hashicon value={nodeId.toString()} size={20} />
</m.div>
</div>
</Tooltip>
);
})}
</div>
<div className="my-auto ml-auto text-xs font-semibold dark:text-gray-400">
{chats[channel.index].messages.length ? (
<TimeAgo datetime={chats[channel.index].lastInterraction} />
) : (
<div>No messages</div>
)}
</div>
</>
) : (
<div className="my-auto dark:text-white">No messages</div>
)}
</SidebarItem>
);
}