/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import React, {useRef, useEffect} from 'react';
import {
FlexBox,
colors,
Text,
Glyph,
styled,
FlipperPlugin,
FlexColumn,
FlipperBasePlugin,
ToggleButton,
brandColors,
Spacer,
Heading,
Client,
BaseDevice,
StaticView,
} from 'flipper';
import {BackgroundColorProperty} from 'csstype';
import {getPluginTitle} from '../../utils/pluginUtils';
export type FlipperPlugins = typeof FlipperPlugin[];
export type PluginsByCategory = [string, FlipperPlugins][];
export const ListItem = styled.div<{active?: boolean; disabled?: boolean}>(
({active, disabled}) => ({
paddingLeft: 10,
display: 'flex',
alignItems: 'center',
marginBottom: 6,
flexShrink: 0,
backgroundColor: active ? colors.macOSTitleBarIconSelected : 'none',
color: disabled
? 'rgba(0, 0, 0, 0.5)'
: active
? colors.white
: colors.macOSSidebarSectionItem,
lineHeight: '25px',
padding: '0 10px',
'&[disabled]': {
color: 'rgba(0, 0, 0, 0.5)',
},
}),
);
export function PluginIcon({
isActive,
backgroundColor,
name,
color,
}: {
isActive: boolean;
backgroundColor?: string;
name: string;
color: string;
}) {
return (
);
}
const PluginShape = styled(FlexBox)<{
backgroundColor?: BackgroundColorProperty;
}>(({backgroundColor}) => ({
marginRight: 8,
backgroundColor,
borderRadius: 3,
flexShrink: 0,
width: 18,
height: 18,
justifyContent: 'center',
alignItems: 'center',
top: '-1px',
}));
export const PluginName = styled(Text)<{isActive?: boolean; count?: number}>(
props => ({
minWidth: 0,
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
overflow: 'hidden',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
flexGrow: 1,
'::after': {
fontSize: 12,
display: props.count ? 'inline-block' : 'none',
padding: '0 8px',
lineHeight: '17px',
height: 17,
alignSelf: 'center',
content: `"${props.count}"`,
borderRadius: '999em',
color: props.isActive ? colors.macOSTitleBarIconSelected : colors.white,
backgroundColor: props.isActive
? colors.white
: colors.macOSTitleBarIconSelected,
fontWeight: 500,
},
}),
);
export function isStaticViewActive(
current: StaticView,
selected: StaticView,
): boolean {
return current && selected && current === selected;
}
export const CategoryName = styled(PluginName)({
color: colors.macOSSidebarSectionTitle,
textTransform: 'uppercase',
fontSize: '0.9em',
});
export const Plugins = styled(FlexColumn)({
flexGrow: 1,
overflow: 'auto',
});
export const PluginSidebarListItem: React.FC<{
onClick: () => void;
isActive: boolean;
plugin: typeof FlipperBasePlugin;
app?: string | null | undefined;
helpRef?: any;
provided?: any;
onFavorite?: () => void;
starred?: boolean; // undefined means: not starrable
}> = function(props) {
const {isActive, plugin, onFavorite, starred} = props;
const iconColor = getColorByApp(props.app);
const domRef = useRef(null);
useEffect(() => {
const node = domRef.current;
if (isActive && node) {
const rect = node.getBoundingClientRect();
if (rect.top < 0 || rect.bottom > document.documentElement.clientHeight) {
node.scrollIntoView();
}
}
}, [isActive]);
return (
{getPluginTitle(plugin)}
{starred !== undefined && (!starred || isActive) && (
)}
);
};
export function getColorByApp(app?: string | null): string {
let iconColor: string | undefined = (brandColors as any)[app!];
if (!iconColor) {
if (!app) {
// Device plugin
iconColor = colors.macOSTitleBarIconBlur;
} else {
const pluginColors = [
colors.seaFoam,
colors.teal,
colors.lime,
colors.lemon,
colors.orange,
colors.tomato,
colors.cherry,
colors.pink,
colors.grape,
];
iconColor = pluginColors[parseInt(app, 36) % pluginColors.length];
}
}
return iconColor;
}
export const NoDevices = () => (
Select a device to get started
);
export const NoClients = () => (
No clients connected
);
export function getFavoritePlugins(
device: BaseDevice,
client: Client,
allPlugins: FlipperPlugins,
starredPlugins: undefined | string[],
returnFavoredPlugins: boolean, // if false, unfavoried plugins are returned
): FlipperPlugins {
if (device.isArchived) {
if (!returnFavoredPlugins) {
return [];
}
// for archived plugins, all stored plugins are enabled
return allPlugins.filter(
plugin => client.plugins.indexOf(plugin.id) !== -1,
);
}
if (!starredPlugins || !starredPlugins.length) {
return returnFavoredPlugins ? [] : allPlugins;
}
return allPlugins.filter(plugin => {
const idx = starredPlugins.indexOf(plugin.id);
return idx === -1 ? !returnFavoredPlugins : returnFavoredPlugins;
});
}