mirror of
https://github.com/mickael-kerjean/filestash.git
synced 2025-11-02 20:23:32 +08:00
refactoring (login): simplify code + lint
This commit is contained in:
@ -1,111 +1,74 @@
|
||||
import React from 'react';
|
||||
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
|
||||
import React, { useState, useEffect } from "react";
|
||||
|
||||
import './connectpage.scss';
|
||||
import { Session } from '../model/';
|
||||
import { Container, NgIf, NgShow, Loader, Notification, ErrorPage } from '../components/';
|
||||
import { ForkMe, PoweredByFilestash, Form } from './connectpage/';
|
||||
import { cache, notify, urlParams } from '../helpers/';
|
||||
import "./connectpage.scss";
|
||||
import { Session } from "../model/";
|
||||
import { Container, NgShow, Loader, ErrorPage } from "../components/";
|
||||
import { ForkMe, PoweredByFilestash, Form } from "./connectpage/";
|
||||
import { cache, notify, urlParams } from "../helpers/";
|
||||
|
||||
import { Alert } from '../components/';
|
||||
function ConnectPageComponent({ error, history }) {
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const _GET = urlParams();
|
||||
|
||||
@ErrorPage
|
||||
export class ConnectPage extends React.Component {
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state = {
|
||||
loading: true,
|
||||
doing_a_third_party_login: false
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
const urlData = urlParams();
|
||||
const get_params = Object.keys(urlData);
|
||||
if(get_params.length === 0){
|
||||
return;
|
||||
}else if(get_params.length === 1 && !!urlData["next"]){
|
||||
return;
|
||||
}
|
||||
|
||||
if(!urlData.type){
|
||||
urlData.type = urlData.state;
|
||||
}
|
||||
this.setState({
|
||||
doing_a_third_party_login: true,
|
||||
loading: true
|
||||
}, () => this.authenticate(urlData));
|
||||
}
|
||||
|
||||
authenticate(params){
|
||||
Session.authenticate(params)
|
||||
const authenticate = (formData) => {
|
||||
return Session.authenticate(formData)
|
||||
.then(Session.currentUser)
|
||||
.then((user) => {
|
||||
if(location.search.indexOf("?next=") === 0){
|
||||
location = urlParams()["next"];
|
||||
if (formData["next"]) {
|
||||
location = formData["next"];
|
||||
return;
|
||||
}
|
||||
let url = "/files/";
|
||||
let path = user.home;
|
||||
if(path){
|
||||
path = path.replace(/^\/?(.*?)\/?$/, "$1");
|
||||
if(path !== ""){
|
||||
url += path + "/";
|
||||
}
|
||||
if (user["home"]) {
|
||||
user["home"] = user["home"].replace(/^\/?(.*?)\/?$/, "$1").trim();
|
||||
if (user["home"] !== "") url = `${url}${user["home"]}/`;
|
||||
}
|
||||
cache.destroy();
|
||||
this.props.history.push(url);
|
||||
})
|
||||
.catch((err) => {
|
||||
this.setState({loading: false});
|
||||
notify.send(err, "error");
|
||||
history.push(url);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
onFormSubmit(data){
|
||||
if("oauth2" in data){
|
||||
this.setState({loading: true});
|
||||
Session.oauth2(data.oauth2).then((url) => {
|
||||
const onFormSubmit = (formData) => {
|
||||
if ("oauth2" in formData) {
|
||||
setIsLoading(true);
|
||||
Session.oauth2(formData["oauth2"]).then((url) => {
|
||||
window.location.href = url;
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.setState({
|
||||
loading: true
|
||||
}, () => this.authenticate(data));
|
||||
}
|
||||
setIsLoading(true);
|
||||
authenticate({ ..._GET, ...formData }).catch((err) => {
|
||||
setIsLoading(false);
|
||||
notify.send(err, "error");
|
||||
});
|
||||
};
|
||||
|
||||
setLoading(value){
|
||||
if(this.state.doing_a_third_party_login !== true){
|
||||
this.setState({loading: value});
|
||||
const onFormChangeLoadingState = (onOrOff) => {
|
||||
if (_GET["state"]) return; // Don't do anything when using oauth2
|
||||
setIsLoading(onOrOff);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (_GET["state"]) {
|
||||
authenticate({ ..._GET, type: _GET["state"] })
|
||||
.catch((err) => error(err));
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
onError(err){
|
||||
this.props.error(err);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="component_page_connect">
|
||||
<NgIf cond={window.CONFIG["fork_button"]}>
|
||||
<ForkMe repo="https://github.com/mickael-kerjean/filestash" />
|
||||
</NgIf>
|
||||
<Container maxWidth="565px">
|
||||
<NgIf cond={this.state.loading === true}>
|
||||
<Loader/>
|
||||
</NgIf>
|
||||
<NgShow cond={this.state.loading === false}>
|
||||
<ReactCSSTransitionGroup transitionName="form" transitionLeave={false} transitionEnter={false} transitionAppear={true} transitionAppearTimeout={500}>
|
||||
<Form onLoadingChange={this.setLoading.bind(this)}
|
||||
onError={this.onError.bind(this)}
|
||||
onSubmit={this.onFormSubmit.bind(this)} />
|
||||
</ReactCSSTransitionGroup>
|
||||
<ReactCSSTransitionGroup transitionName="remember" transitionLeave={false} transitionEnter={false} transitionAppear={true} transitionAppearTimeout={5000}>
|
||||
<PoweredByFilestash />
|
||||
</ReactCSSTransitionGroup>
|
||||
return (
|
||||
<div className="component_page_connect">
|
||||
{ window.CONFIG["fork_button"] && <ForkMe /> }
|
||||
<Container maxWidth="565px">
|
||||
{ isLoading && <Loader /> }
|
||||
<NgShow cond={!isLoading}>
|
||||
<Form onLoadingChange={onFormChangeLoadingState}
|
||||
onError={error}
|
||||
onSubmit={onFormSubmit} />
|
||||
{ window.CONFIG["fork_button"] && <PoweredByFilestash /> }
|
||||
</NgShow>
|
||||
</Container>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
</Container>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export const ConnectPage = ErrorPage(ConnectPageComponent);
|
||||
|
||||
@ -5,3 +5,19 @@
|
||||
.dark-mode .component_page_connect{
|
||||
background: var(--dark-mode-bg-color);
|
||||
}
|
||||
|
||||
/* PAGE ANIMATION */
|
||||
@keyframes PageConnectionPoweredBy {
|
||||
from { transform: translateY(2px); opacity: 0;}
|
||||
to {transform: translateY(0); opacity: 1; }
|
||||
}
|
||||
@keyframes PageConnectionForm {
|
||||
from { transform: scale(0.99); }
|
||||
to {transform: scale(1); }
|
||||
}
|
||||
.component_poweredbyfilestash, .component_page_connect .component_page_connection_form {
|
||||
animation-duration: 0.3s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
.component_poweredbyfilestash { animation-name: PageConnectionPoweredBy; animation-delay: 0.2s; opacity: 0; }
|
||||
.component_page_connect .component_page_connection_form { animation-name: PageConnectionForm; }
|
||||
|
||||
@ -1,41 +1,33 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Container, Card, NgIf, Input, Button, Textarea, FormBuilder } from "../../components/";
|
||||
import { gid, settings_get, settings_put, createFormBackend, FormObjToJSON, nop } from "../../helpers/";
|
||||
import { Session, Backend } from "../../model/";
|
||||
import { Card, Button, FormBuilder } from "../../components/";
|
||||
import {
|
||||
settings_get, settings_put, createFormBackend, FormObjToJSON, nop,
|
||||
} from "../../helpers/";
|
||||
import { Backend } from "../../model/";
|
||||
import { t } from "../../locales/";
|
||||
import "./form.scss";
|
||||
|
||||
export function Form({
|
||||
onLoadingChange = nop, onError = nop, onSubmit = nop
|
||||
onLoadingChange = nop, onError = nop, onSubmit = nop,
|
||||
}) {
|
||||
const [selectedTab, setSelectedTab] = useState(function(){
|
||||
const [enabledBackends, setEnabledBackends] = useState([]);
|
||||
const [selectedTab, setSelectedTab] = useState(function() { // TODO: buggy
|
||||
const connLength = window.CONFIG["connections"].length;
|
||||
if(connLength < 4) return 0;
|
||||
else if(connLength < 5) return 1;
|
||||
if (connLength < 4) return 0;
|
||||
else if (connLength < 5) return 1;
|
||||
return 2;
|
||||
}());
|
||||
const [enabledBackends, setEnabledBackends] = useState([]);
|
||||
const _marginTop = () => {
|
||||
let size = 300;
|
||||
const $screen = document.querySelector(".login-form");
|
||||
if($screen) size = $screen.offsetHeight;
|
||||
|
||||
size = Math.round((document.body.offsetHeight - size) / 2);
|
||||
if(size < 0) return 0;
|
||||
if(size > 150) return 150;
|
||||
return size;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const select = settings_get("login_tab");
|
||||
if(select !== null && select < window.CONFIG["connections"].length){
|
||||
if (select !== null && select < window.CONFIG["connections"].length) {
|
||||
setSelectedTab(select);
|
||||
}
|
||||
Backend.all().then((backend) => {
|
||||
onLoadingChange(false)
|
||||
onLoadingChange(false);
|
||||
setEnabledBackends(window.CONFIG["connections"].reduce((acc, conn) => {
|
||||
const f = createFormBackend(backend, conn);
|
||||
if(Object.keys(f).length > 0){
|
||||
if (Object.keys(f).length > 0) {
|
||||
acc.push(f);
|
||||
}
|
||||
return acc;
|
||||
@ -52,70 +44,82 @@ export function Form({
|
||||
};
|
||||
const onSubmitForm = (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const data = () => {
|
||||
const formData = FormObjToJSON((() => {
|
||||
const tmp = enabledBackends[selectedTab];
|
||||
return tmp[Object.keys(tmp)[0]];
|
||||
};
|
||||
const dataToBeSubmitted = JSON.parse(JSON.stringify(FormObjToJSON(data())));
|
||||
delete dataToBeSubmitted.image;
|
||||
delete dataToBeSubmitted.label;
|
||||
delete dataToBeSubmitted.advanced;
|
||||
onSubmit(dataToBeSubmitted);
|
||||
})());
|
||||
delete formData.image;
|
||||
delete formData.label;
|
||||
delete formData.advanced;
|
||||
onSubmit(formData);
|
||||
};
|
||||
const onTypeChange = (tabn) => {
|
||||
setSelectedTab(tabn);
|
||||
};
|
||||
|
||||
return (
|
||||
<Card style={{marginTop: _marginTop()+"px"}} className="no-select component_page_connection_form">
|
||||
<NgIf cond={ window.CONFIG["connections"].length > 1 }>
|
||||
<div role="navigation" className={"buttons "+((window.innerWidth < 600) ? "scroll-x" : "")}>
|
||||
{
|
||||
enabledBackends.map((backend, i) => {
|
||||
const key = Object.keys(backend)[0];
|
||||
if(!backend[key]) return null;
|
||||
return (
|
||||
<Button key={"menu-"+i} className={i === selectedTab ? "active primary" : ""} onClick={() => onTypeChange(i)}>
|
||||
{ backend[key].label.value }
|
||||
</Button>
|
||||
);
|
||||
})
|
||||
}
|
||||
const renderForm = ($input, props, struct, onChange) => {
|
||||
if (struct.type === "image") {
|
||||
return (
|
||||
<div className="center">
|
||||
{ $input }
|
||||
</div>
|
||||
</NgIf>
|
||||
);
|
||||
} else if (struct.enabled === true) {
|
||||
return null;
|
||||
} else if (struct.label === "advanced") {
|
||||
return (
|
||||
<label style={{ color: "rgba(0,0,0,0.4)" }}>
|
||||
{ $input }
|
||||
{ t("Advanced") }
|
||||
</label>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<label htmlFor={props.params["id"]}
|
||||
className={"no-select input_type_" + props.params["type"]}>
|
||||
<div>
|
||||
{ $input }
|
||||
</div>
|
||||
</label>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Card style={{ marginTop: `${_centerThis()}px` }}
|
||||
className="no-select component_page_connection_form">
|
||||
{
|
||||
enabledBackends.length > 1 && (
|
||||
<div role="navigation"
|
||||
className={`buttons ${((window.innerWidth < 600) ? "scroll-x" : "")}`}>
|
||||
{
|
||||
enabledBackends.map((backend, i) => {
|
||||
const key = Object.keys(backend)[0];
|
||||
if (!backend[key]) return null; // TODO: this shouldn't be needed
|
||||
return (
|
||||
<Button
|
||||
key={`menu-${i}`}
|
||||
className={i === selectedTab ? "active primary" : ""}
|
||||
onClick={() => onTypeChange(i)}
|
||||
>
|
||||
{ backend[key].label.value }
|
||||
</Button>
|
||||
);
|
||||
})
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
<div>
|
||||
<form onSubmit={(e) => onSubmitForm(e)} autoComplete="off" autoCapitalize="off" spellCheck="false" autoCorrect="off">
|
||||
<form onSubmit={(e) => onSubmitForm(e)} autoComplete="off" autoCapitalize="off"
|
||||
spellCheck="false" autoCorrect="off">
|
||||
{
|
||||
enabledBackends.map((form, i) => {
|
||||
const key = Object.keys(form)[0];
|
||||
if(!form[key]) return null;
|
||||
else if(selectedTab !== i) return null;
|
||||
if (!form[key]) return null; // TODO: this shouldn't be needed
|
||||
else if (selectedTab !== i) return null;
|
||||
return (
|
||||
<FormBuilder form={form[key]} onChange={onFormChange} key={"form"+i}
|
||||
render={ ($input, props, struct, onChange) => {
|
||||
if(struct.type === "image"){
|
||||
return (
|
||||
<div className="center">
|
||||
{ $input }
|
||||
</div>
|
||||
);
|
||||
} else if(struct.enabled === true){
|
||||
return null;
|
||||
} else if(struct.label === "advanced") return (
|
||||
<label style={{color: "rgba(0,0,0,0.4)"}}>
|
||||
{ $input }
|
||||
{ t("Advanced") }
|
||||
</label>
|
||||
);
|
||||
return (
|
||||
<label htmlFor={props.params["id"]} className={"no-select input_type_" + props.params["type"]}>
|
||||
<div>
|
||||
{ $input }
|
||||
</div>
|
||||
</label>
|
||||
);
|
||||
}} />
|
||||
render={renderForm} />
|
||||
);
|
||||
})
|
||||
}
|
||||
@ -123,159 +127,16 @@ export function Form({
|
||||
</form>
|
||||
</div>
|
||||
</Card>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const _centerThis = () => {
|
||||
let size = 300;
|
||||
const $screen = document.querySelector(".login-form");
|
||||
if ($screen) size = $screen.offsetHeight;
|
||||
|
||||
export class FormOld extends React.Component {
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state = {
|
||||
select: function(){
|
||||
const connLength = window.CONFIG["connections"].length;
|
||||
if(connLength < 4) return 0;
|
||||
else if(connLength < 5) return 1;
|
||||
return 2;
|
||||
}(),
|
||||
backends_enabled: []
|
||||
};
|
||||
|
||||
const select = settings_get("login_tab");
|
||||
if(select !== null && select < window.CONFIG["connections"].length){ this.state.select = select; }
|
||||
this.rerender = () => this.setState({_refresh: !this.state._refresh});
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
window.addEventListener("resize", this.rerender);
|
||||
Backend.all().then((backend) => {
|
||||
this.props.onLoadingChange(false);
|
||||
this.setState({
|
||||
backends_available: backend,
|
||||
backends_enabled: window.CONFIG["connections"].reduce((acc, conn) => {
|
||||
const f = createFormBackend(backend, conn);
|
||||
if(Object.keys(f).length > 0){
|
||||
acc.push(f);
|
||||
}
|
||||
return acc;
|
||||
}, [])
|
||||
}, () => this.publishState(this.props));
|
||||
}).catch((err) => this.props.onError(err));
|
||||
}
|
||||
|
||||
componentWillUnmount(){
|
||||
settings_put("login_tab", this.state.select);
|
||||
window.removeEventListener("resize", this.rerender);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(props){
|
||||
if(JSON.stringify(props.credentials) !== JSON.stringify(this.props.credentials)){
|
||||
this.publishState(props);
|
||||
}
|
||||
}
|
||||
|
||||
publishState(props){
|
||||
for(let key in props.credentials){
|
||||
this.state.backends_enabled = this.state.backends_enabled.map((backend) => {
|
||||
const b = backend[Object.keys(backend)[0]];
|
||||
if(b["type"].value + "_" + b["label"].value === key){
|
||||
for(let k in b){
|
||||
if(props.credentials[key][k]){
|
||||
b[k].value = props.credentials[key][k];
|
||||
}
|
||||
}
|
||||
}
|
||||
return backend;
|
||||
});
|
||||
}
|
||||
this.setState({backends_enabled: this.state.backends_enabled});
|
||||
}
|
||||
|
||||
onSubmit(e){
|
||||
e.preventDefault();
|
||||
const data = () => {
|
||||
const tmp = this.state.backends_enabled[this.state.select];
|
||||
return tmp[Object.keys(tmp)[0]];
|
||||
};
|
||||
const dataToBeSubmitted = JSON.parse(JSON.stringify(FormObjToJSON(data())));
|
||||
const key = dataToBeSubmitted["type"] + "_" + dataToBeSubmitted["label"];
|
||||
delete dataToBeSubmitted.image;
|
||||
delete dataToBeSubmitted.label;
|
||||
delete dataToBeSubmitted.advanced;
|
||||
this.props.credentials[key] = dataToBeSubmitted;
|
||||
this.props.onSubmit(dataToBeSubmitted, this.props.credentials);
|
||||
}
|
||||
|
||||
onTypeChange(n){
|
||||
this.setState({select: n});
|
||||
}
|
||||
|
||||
render() {
|
||||
const _marginTop = () => {
|
||||
let size = 300;
|
||||
const $screen = document.querySelector(".login-form");
|
||||
if($screen) size = $screen.offsetHeight;
|
||||
|
||||
size = Math.round((document.body.offsetHeight - size) / 2);
|
||||
if(size < 0) return 0;
|
||||
if(size > 150) return 150;
|
||||
return size;
|
||||
};
|
||||
return (
|
||||
<Card style={{marginTop: _marginTop()+"px"}} className="no-select component_page_connection_form">
|
||||
<NgIf cond={ window.CONFIG["connections"].length > 1 }>
|
||||
<div role="navigation" className={"buttons "+((window.innerWidth < 600) ? "scroll-x" : "")}>
|
||||
{
|
||||
this.state.backends_enabled.map((backend, i) => {
|
||||
const key = Object.keys(backend)[0];
|
||||
if(!backend[key]) return null;
|
||||
return (
|
||||
<Button key={"menu-"+i} className={i === this.state.select ? "active primary" : ""} onClick={this.onTypeChange.bind(this, i)}>
|
||||
{ backend[key].label.value }
|
||||
</Button>
|
||||
);
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</NgIf>
|
||||
<div>
|
||||
<form onSubmit={this.onSubmit.bind(this)} autoComplete="off" autoCapitalize="off" spellCheck="false" autoCorrect="off">
|
||||
{
|
||||
this.state.backends_enabled.map((form, i) => {
|
||||
const key = Object.keys(form)[0];
|
||||
if(!form[key]) return null;
|
||||
else if(this.state.select !== i) return null;
|
||||
return (
|
||||
<FormBuilder form={form[key]} onChange={this.rerender.bind(this)} key={"form"+i}
|
||||
render={ ($input, props, struct, onChange) => {
|
||||
if(struct.type === "image"){
|
||||
return (
|
||||
<div className="center">
|
||||
{ $input }
|
||||
</div>
|
||||
);
|
||||
} else if(struct.enabled === true){
|
||||
return null;
|
||||
} else if(struct.label === "advanced") return (
|
||||
<label style={{color: "rgba(0,0,0,0.4)"}}>
|
||||
{ $input }
|
||||
{ t("Advanced") }
|
||||
</label>
|
||||
);
|
||||
return (
|
||||
<label htmlFor={props.params["id"]} className={"no-select input_type_" + props.params["type"]}>
|
||||
<div>
|
||||
{ $input }
|
||||
</div>
|
||||
</label>
|
||||
);
|
||||
}} />
|
||||
);
|
||||
})
|
||||
}
|
||||
<Button theme="emphasis">{ t("CONNECT") }</Button>
|
||||
</form>
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
}
|
||||
size = Math.round((document.body.offsetHeight - size) / 2);
|
||||
if (size < 0) return 0;
|
||||
if (size > 150) return 150;
|
||||
return size;
|
||||
};
|
||||
|
||||
@ -67,16 +67,6 @@
|
||||
}
|
||||
|
||||
|
||||
.component_rememberme.remember-appear{
|
||||
opacity: 0;
|
||||
transform: translateX(40px);
|
||||
}
|
||||
.component_rememberme.remember-appear.remember-appear-active{
|
||||
opacity: 1;
|
||||
transform: translateX(0px);
|
||||
transition: all 0.3s ease-out;
|
||||
transition-delay: 0.5s;
|
||||
}
|
||||
|
||||
.scroll-x{
|
||||
overflow-x: auto!important;
|
||||
|
||||
Reference in New Issue
Block a user