Merge branch 'master' into sebas-manifest-v3-migration
This commit is contained in:
@@ -28,3 +28,11 @@ canvas#icon {
|
|||||||
div#status {
|
div#status {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[type='text'].border-danger,
|
||||||
|
.border-danger {
|
||||||
|
box-shadow: inset 0 -2px 0 @brand-danger;
|
||||||
|
&:focus {
|
||||||
|
.box-shadow(inset 0 -2px 0 @brand-danger);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,32 +1,13 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React from 'react';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { configLogout, setApiKey } from '../reducers/configReducer';
|
import { ReduxSelector } from '../types/store';
|
||||||
import { userLogout } from '../reducers/currentUser';
|
|
||||||
import { ApiKeyReducer, ReduxSelector } from '../types/store';
|
|
||||||
import { User } from '../types/user';
|
import { User } from '../types/user';
|
||||||
import apiKeyInvalid from '../utils/apiKey';
|
|
||||||
import { fetchUserData } from '../utils/user';
|
|
||||||
|
|
||||||
export default function NavBar(): JSX.Element {
|
export default function NavBar(): JSX.Element {
|
||||||
const [state, setState] = useState({
|
|
||||||
apiKey: '',
|
|
||||||
apiKeyError: '',
|
|
||||||
loading: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const dispatch = useDispatch();
|
|
||||||
|
|
||||||
const { apiKey: apiKeyFromRedux }: ApiKeyReducer = useSelector(
|
|
||||||
(selector: ReduxSelector) => selector.config,
|
|
||||||
);
|
|
||||||
const user: User | undefined = useSelector(
|
const user: User | undefined = useSelector(
|
||||||
(selector: ReduxSelector) => selector.currentUser.user,
|
(selector: ReduxSelector) => selector.currentUser.user,
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setState({ ...state, apiKey: apiKeyFromRedux });
|
|
||||||
}, [apiKeyFromRedux]);
|
|
||||||
|
|
||||||
const signedInAs = () => {
|
const signedInAs = () => {
|
||||||
if (user) {
|
if (user) {
|
||||||
return (
|
return (
|
||||||
@@ -127,50 +108,6 @@ export default function NavBar(): JSX.Element {
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
|
||||||
<div className="container-fluid">
|
|
||||||
{state.apiKeyError && (
|
|
||||||
<div className="alert alert-danger" role="alert">
|
|
||||||
{state.apiKeyError}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div className="input-group">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
className="form-control"
|
|
||||||
placeholder="API key"
|
|
||||||
value={state.apiKey}
|
|
||||||
onChange={(e) => {
|
|
||||||
const key = e.target.value;
|
|
||||||
const isApiKeyInvalid = apiKeyInvalid(key);
|
|
||||||
setState({ ...state, apiKey: key, apiKeyError: isApiKeyInvalid });
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<span className="input-group-btn">
|
|
||||||
<button
|
|
||||||
className={`btn btn-default ${state.loading ? 'disabled' : ''}`}
|
|
||||||
disabled={state.loading}
|
|
||||||
type="button"
|
|
||||||
data-loading-text="Loading..."
|
|
||||||
onClick={async () => {
|
|
||||||
if (state.apiKeyError === '' && state.apiKey !== '') {
|
|
||||||
setState({ ...state, loading: true });
|
|
||||||
await browser.storage.sync.set({ apiKey: state.apiKey });
|
|
||||||
dispatch(configLogout());
|
|
||||||
dispatch(userLogout());
|
|
||||||
dispatch(setApiKey(state.apiKey));
|
|
||||||
|
|
||||||
await fetchUserData(state.apiKey, dispatch);
|
|
||||||
setState({ ...state, loading: false });
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Save
|
|
||||||
</button>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
import React, { useRef, useState, useEffect } from 'react';
|
import React, { useRef, useState, useEffect } from 'react';
|
||||||
import config, { SuccessOrFailType } from '../config/config';
|
import config, { SuccessOrFailType } from '../config/config';
|
||||||
|
import apiKeyInvalid from '../utils/apiKey';
|
||||||
|
import { logUserIn } from '../utils/user';
|
||||||
import Alert from './Alert';
|
import Alert from './Alert';
|
||||||
import SitesList from './SitesList';
|
import SitesList from './SitesList';
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
alertText: string;
|
alertText: string;
|
||||||
alertType: SuccessOrFailType;
|
alertType: SuccessOrFailType;
|
||||||
|
apiKey: string;
|
||||||
blacklist: string;
|
blacklist: string;
|
||||||
displayAlert: boolean;
|
displayAlert: boolean;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
@@ -18,6 +21,7 @@ export default function Options(): JSX.Element {
|
|||||||
const [state, setState] = useState<State>({
|
const [state, setState] = useState<State>({
|
||||||
alertText: config.alert.success.text,
|
alertText: config.alert.success.text,
|
||||||
alertType: config.alert.success.type,
|
alertType: config.alert.success.type,
|
||||||
|
apiKey: '',
|
||||||
blacklist: '',
|
blacklist: '',
|
||||||
displayAlert: false,
|
displayAlert: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
@@ -31,6 +35,7 @@ export default function Options(): JSX.Element {
|
|||||||
|
|
||||||
const restoreSettings = async (): Promise<void> => {
|
const restoreSettings = async (): Promise<void> => {
|
||||||
const items = await browser.storage.sync.get({
|
const items = await browser.storage.sync.get({
|
||||||
|
apiKey: config.apiKey,
|
||||||
blacklist: '',
|
blacklist: '',
|
||||||
loggingStyle: config.loggingStyle,
|
loggingStyle: config.loggingStyle,
|
||||||
loggingType: config.loggingType,
|
loggingType: config.loggingType,
|
||||||
@@ -39,11 +44,12 @@ export default function Options(): JSX.Element {
|
|||||||
});
|
});
|
||||||
setState({
|
setState({
|
||||||
...state,
|
...state,
|
||||||
blacklist: items.blacklist,
|
apiKey: items.apiKey as string,
|
||||||
loggingStyle: items.loggingStyle,
|
blacklist: items.blacklist as string,
|
||||||
loggingType: items.loggingType,
|
loggingStyle: items.loggingStyle as string,
|
||||||
theme: items.theme,
|
loggingType: items.loggingType as string,
|
||||||
whitelist: items.whitelist,
|
theme: items.theme as string,
|
||||||
|
whitelist: items.whitelist as string,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -63,6 +69,7 @@ export default function Options(): JSX.Element {
|
|||||||
if (state.loading) return;
|
if (state.loading) return;
|
||||||
setState({ ...state, loading: true });
|
setState({ ...state, loading: true });
|
||||||
|
|
||||||
|
const apiKey = state.apiKey;
|
||||||
const theme = state.theme;
|
const theme = state.theme;
|
||||||
const loggingType = state.loggingType;
|
const loggingType = state.loggingType;
|
||||||
const loggingStyle = state.loggingStyle;
|
const loggingStyle = state.loggingStyle;
|
||||||
@@ -72,23 +79,26 @@ export default function Options(): JSX.Element {
|
|||||||
|
|
||||||
// Sync options with google storage.
|
// Sync options with google storage.
|
||||||
await browser.storage.sync.set({
|
await browser.storage.sync.set({
|
||||||
blacklist: blacklist,
|
apiKey,
|
||||||
loggingStyle: loggingStyle,
|
blacklist,
|
||||||
loggingType: loggingType,
|
loggingStyle,
|
||||||
theme: theme,
|
loggingType,
|
||||||
whitelist: whitelist,
|
theme,
|
||||||
|
whitelist,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set state to be newly entered values.
|
// Set state to be newly entered values.
|
||||||
setState({
|
setState({
|
||||||
...state,
|
...state,
|
||||||
blacklist: blacklist,
|
apiKey,
|
||||||
|
blacklist,
|
||||||
displayAlert: true,
|
displayAlert: true,
|
||||||
loggingStyle: loggingStyle,
|
loggingStyle,
|
||||||
loggingType: loggingType,
|
loggingType,
|
||||||
theme: theme,
|
theme,
|
||||||
whitelist: whitelist,
|
whitelist,
|
||||||
});
|
});
|
||||||
|
await logUserIn(state.apiKey);
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateBlacklistState = (sites: string) => {
|
const updateBlacklistState = (sites: string) => {
|
||||||
@@ -142,11 +152,14 @@ export default function Options(): JSX.Element {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isApiKeyValid = apiKeyInvalid(state.apiKey) === '';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="container"
|
className="container"
|
||||||
style={{
|
style={{
|
||||||
height: 515,
|
height: 590,
|
||||||
|
marginTop: 0,
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
overflowY: 'scroll',
|
overflowY: 'scroll',
|
||||||
}}
|
}}
|
||||||
@@ -156,6 +169,21 @@ export default function Options(): JSX.Element {
|
|||||||
{alert()}
|
{alert()}
|
||||||
|
|
||||||
<form className="form-horizontal">
|
<form className="form-horizontal">
|
||||||
|
<div className="form-group">
|
||||||
|
<label className="col-lg-2 control-label">API Key</label>
|
||||||
|
|
||||||
|
<div className="col-lg-10">
|
||||||
|
<input
|
||||||
|
autoFocus={true}
|
||||||
|
type="text"
|
||||||
|
className={`form-control ${isApiKeyValid ? '' : 'border-danger'}`}
|
||||||
|
placeholder="API key"
|
||||||
|
value={state.apiKey}
|
||||||
|
onChange={(e) => setState({ ...state, apiKey: e.target.value })}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className="col-lg-2 control-label">Logging style!</label>
|
<label className="col-lg-2 control-label">Logging style!</label>
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export default function WakaTime(): JSX.Element {
|
|||||||
}: ApiKeyReducer = useSelector((selector: ReduxSelector) => selector.config);
|
}: ApiKeyReducer = useSelector((selector: ReduxSelector) => selector.config);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchUserData(apiKeyFromRedux, dispatch);
|
void fetchUserData(apiKeyFromRedux, dispatch);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -5,6 +5,26 @@ import WakaTimeCore from '../core/WakaTimeCore';
|
|||||||
import { setUser } from '../reducers/currentUser';
|
import { setUser } from '../reducers/currentUser';
|
||||||
import changeExtensionState from './changeExtensionState';
|
import changeExtensionState from './changeExtensionState';
|
||||||
|
|
||||||
|
export const logUserIn = async (apiKey: string): Promise<void> => {
|
||||||
|
if (!apiKey) {
|
||||||
|
await changeExtensionState('notSignedIn');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await WakaTimeCore.checkAuth(apiKey);
|
||||||
|
const items = await browser.storage.sync.get({ loggingEnabled: config.loggingEnabled });
|
||||||
|
|
||||||
|
if (items.loggingEnabled === true) {
|
||||||
|
await changeExtensionState('allGood');
|
||||||
|
} else {
|
||||||
|
await changeExtensionState('notLogging');
|
||||||
|
}
|
||||||
|
} catch (err: unknown) {
|
||||||
|
await changeExtensionState('notSignedIn');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const fetchUserData = async (
|
export const fetchUserData = async (
|
||||||
apiKey: string,
|
apiKey: string,
|
||||||
dispatch: Dispatch<AnyAction>,
|
dispatch: Dispatch<AnyAction>,
|
||||||
@@ -18,7 +38,7 @@ export const fetchUserData = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!apiKey) {
|
if (!apiKey) {
|
||||||
await changeExtensionState('notSignedIn');
|
return changeExtensionState('notSignedIn');
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user