Reduce sign in errors

Summary:
A lot of the errors in our monitoring / logs are mere sign in errors. Many of them are unnecessary as they are features triggered automatically even when the user isn't logged in.

This diff improves error handling and prevents requires from being made / features from being used by introducing a `<RequireLogin>` component that will hide an underlying feature if the user isn't logged in.

This also prevents the support request form from failing after the user has filled in all details.

This also fixes an issue where mobilebuilds plugin didn't refresh after the user did log in.

From our monitoring error 1,9 and 10:

{F350458668}

Reviewed By: jknoxville

Differential Revision: D25494356

fbshipit-source-id: 95701381bb74c27b9ea9658dc4df678e5f0710e0
This commit is contained in:
Michel Weststrate
2020-12-14 01:59:50 -08:00
committed by Facebook GitHub Bot
parent 379339b03b
commit 2ad81f2c63
4 changed files with 62 additions and 7 deletions

View File

@@ -35,6 +35,8 @@ import {State as Store} from '../reducers';
import {StarOutlined} from '@ant-design/icons'; import {StarOutlined} from '@ant-design/icons';
import {Popover, Rate} from 'antd'; import {Popover, Rate} from 'antd';
import {useStore} from '../utils/useStore'; import {useStore} from '../utils/useStore';
import {isLoggedIn} from '../fb-stubs/user';
import {useValue} from 'flipper-plugin';
type PropsFromState = { type PropsFromState = {
sessionId: string | null; sessionId: string | null;
@@ -379,6 +381,7 @@ export function SandyRatingButton() {
const [isShown, setIsShown] = useState(false); const [isShown, setIsShown] = useState(false);
const [hasTriggered, setHasTriggered] = useState(false); const [hasTriggered, setHasTriggered] = useState(false);
const sessionId = useStore((store) => store.application.sessionId); const sessionId = useStore((store) => store.application.sessionId);
const loggedIn = useValue(isLoggedIn());
const triggerPopover = useCallback(() => { const triggerPopover = useCallback(() => {
if (!hasTriggered) { if (!hasTriggered) {
@@ -388,13 +391,13 @@ export function SandyRatingButton() {
}, [hasTriggered]); }, [hasTriggered]);
useEffect(() => { useEffect(() => {
if (GK.get('flipper_enable_star_ratiings') && !hasTriggered) { if (GK.get('flipper_enable_star_ratiings') && !hasTriggered && loggedIn) {
UserFeedback.getPrompt().then((prompt) => { UserFeedback.getPrompt().then((prompt) => {
setPromptData(prompt); setPromptData(prompt);
setTimeout(triggerPopover, 30000); setTimeout(triggerPopover, 30000);
}); });
} }
}, [triggerPopover, hasTriggered]); }, [triggerPopover, hasTriggered, loggedIn]);
const onClick = () => { const onClick = () => {
const willBeShown = !isShown; const willBeShown = !isShown;

View File

@@ -7,6 +7,7 @@
* @format * @format
*/ */
import {Atom, createState} from 'flipper-plugin';
import {User} from '../reducers/user'; import {User} from '../reducers/user';
export async function getUser(): Promise<User> { export async function getUser(): Promise<User> {
@@ -84,8 +85,12 @@ export async function getPreferredEditorUriScheme(): Promise<string> {
return 'vscode'; return 'vscode';
} }
export const appendAccessTokenToUrl: ( export async function appendAccessTokenToUrl(_url: URL): Promise<string> {
url: URL, throw new Error('Implement appendAccessTokenToUrl');
) => Promise<string> = async () => { }
return Promise.reject(new Error('Implement appendAccessTokenToUrl'));
}; const isLoggedInAtom = createState(false);
export function isLoggedIn(): Atom<boolean> {
return isLoggedInAtom;
}

View File

@@ -21,6 +21,7 @@ export {
internGraphGETAPIRequest, internGraphGETAPIRequest,
internGraphPOSTAPIRequest, internGraphPOSTAPIRequest,
graphQLQuery, graphQLQuery,
isLoggedIn,
} from './fb-stubs/user'; } from './fb-stubs/user';
export { export {
FlipperBasePlugin, FlipperBasePlugin,
@@ -203,3 +204,4 @@ export {default as SidebarExtensions} from './fb-stubs/LayoutInspectorSidebarExt
export {IDEFileResolver, IDEType} from './fb-stubs/IDEFileResolver'; export {IDEFileResolver, IDEType} from './fb-stubs/IDEFileResolver';
export {renderMockFlipperWithPlugin} from './test-utils/createMockFlipperWithPlugin'; export {renderMockFlipperWithPlugin} from './test-utils/createMockFlipperWithPlugin';
export {Tracked} from 'flipper-plugin'; // To be able to use it in legacy plugins export {Tracked} from 'flipper-plugin'; // To be able to use it in legacy plugins
export {RequireLogin} from './ui/components/RequireLogin';

View File

@@ -0,0 +1,45 @@
/**
* 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 {isLoggedIn} from '../../fb-stubs/user';
import {Layout, useValue} from 'flipper-plugin';
import React from 'react';
import config from '../../fb-stubs/config';
import {Alert} from 'antd';
import {LoginOutlined} from '@ant-design/icons';
export const RequireLogin: React.FC<{}> = ({children}) => {
const loggedIn = useValue(isLoggedIn());
if (!config.isFBBuild) {
return (
<Layout.Container pad>
<Alert
type="error"
message="This feature is only available in the Facebook version of Flipper"
/>
</Layout.Container>
);
}
if (!loggedIn) {
return (
<Layout.Container pad>
<Alert
type="error"
message={
<>
You are currently not logged in. Please log in using the{' '}
<LoginOutlined /> button to use this feature.
</>
}
/>
</Layout.Container>
);
}
return <>{children}</>;
};