UI Usability Fixes

* Fallback to sessionStorage if localStorage is absent
* Disable auto-correct and auto-capitalize on username field (SignIn)
* Fix SignIn component name
* Improve support for low screen widths

Co-authored-by: kasedy <kasedy@gmail.com>
This commit is contained in:
rjwats
2020-05-16 12:39:18 +01:00
committed by GitHub
parent a1f4e57a21
commit 7d3bbf4240
6 changed files with 84 additions and 99 deletions

View File

@ -7,21 +7,28 @@ export const ACCESS_TOKEN = 'access_token';
export const LOGIN_PATHNAME = 'loginPathname';
export const LOGIN_SEARCH = 'loginSearch';
/**
* Fallback to sessionStorage if localStorage is absent. WebView may not have local storage enabled.
*/
export function getStorage() {
return localStorage || sessionStorage;
}
export function storeLoginRedirect(location?: H.Location) {
if (location) {
localStorage.setItem(LOGIN_PATHNAME, location.pathname);
localStorage.setItem(LOGIN_SEARCH, location.search);
getStorage().setItem(LOGIN_PATHNAME, location.pathname);
getStorage().setItem(LOGIN_SEARCH, location.search);
}
}
export function clearLoginRedirect() {
localStorage.removeItem(LOGIN_PATHNAME);
localStorage.removeItem(LOGIN_SEARCH);
getStorage().removeItem(LOGIN_PATHNAME);
getStorage().removeItem(LOGIN_SEARCH);
}
export function fetchLoginRedirect(): H.LocationDescriptorObject {
const loginPathname = localStorage.getItem(LOGIN_PATHNAME);
const loginSearch = localStorage.getItem(LOGIN_SEARCH);
const loginPathname = getStorage().getItem(LOGIN_PATHNAME);
const loginSearch = getStorage().getItem(LOGIN_SEARCH);
clearLoginRedirect();
return {
pathname: loginPathname || `/${PROJECT_PATH}/`,
@ -33,7 +40,7 @@ export function fetchLoginRedirect(): H.LocationDescriptorObject {
* Wraps the normal fetch routene with one with provides the access token if present.
*/
export function authorizedFetch(url: RequestInfo, params?: RequestInit): Promise<Response> {
const accessToken = localStorage.getItem(ACCESS_TOKEN);
const accessToken = getStorage().getItem(ACCESS_TOKEN);
if (accessToken) {
params = params || {};
params.credentials = 'include';
@ -63,7 +70,7 @@ export function redirectingAuthorizedFetch(url: RequestInfo, params?: RequestIni
}
export function addAccessTokenParameter(url: string) {
const accessToken = localStorage.getItem(ACCESS_TOKEN);
const accessToken = getStorage().getItem(ACCESS_TOKEN);
if (!accessToken) {
return url;
}

View File

@ -8,7 +8,7 @@ import { withStyles, Theme, createStyles, WithStyles } from '@material-ui/core/s
import history from '../history'
import { VERIFY_AUTHORIZATION_ENDPOINT } from '../api';
import { ACCESS_TOKEN, authorizedFetch } from './Authentication';
import { ACCESS_TOKEN, authorizedFetch, getStorage } from './Authentication';
import { AuthenticationContext, Me } from './AuthenticationContext';
export const decodeMeJWT = (accessToken: string): Me => jwtDecode(accessToken);
@ -81,7 +81,7 @@ class AuthenticationWrapper extends React.Component<AuthenticationWrapperProps,
}
refresh = () => {
const accessToken = localStorage.getItem(ACCESS_TOKEN)
const accessToken = getStorage().getItem(ACCESS_TOKEN)
if (accessToken) {
authorizedFetch(VERIFY_AUTHORIZATION_ENDPOINT)
.then(response => {
@ -100,7 +100,7 @@ class AuthenticationWrapper extends React.Component<AuthenticationWrapperProps,
signIn = (accessToken: string) => {
try {
localStorage.setItem(ACCESS_TOKEN, accessToken);
getStorage().setItem(ACCESS_TOKEN, accessToken);
const me: Me = decodeMeJWT(accessToken);
this.setState({ context: { ...this.state.context, me } });
this.props.enqueueSnackbar(`Logged in as ${me.username}`, { variant: 'success' });
@ -111,7 +111,7 @@ class AuthenticationWrapper extends React.Component<AuthenticationWrapperProps,
}
signOut = () => {
localStorage.removeItem(ACCESS_TOKEN);
getStorage().removeItem(ACCESS_TOKEN);
this.setState({
context: {
...this.state.context,