mirror of
1
Fork 0

redux, whitespace changes..

This commit is contained in:
f0x 2022-09-09 20:43:55 +02:00
parent 8739608434
commit 2576e3b2d6
33 changed files with 767 additions and 1072 deletions

View File

@ -23,7 +23,8 @@
*/ */
const path = require('path'); const path = require('path');
const budoExpress = require('budo-express'); // Forked budo-express supports EventEmitter, to write bundle.js to disk in development
const budoExpress = require('@f0x52/budo-express');
const babelify = require('babelify'); const babelify = require('babelify');
const fs = require("fs"); const fs = require("fs");
const EventEmitter = require('events'); const EventEmitter = require('events');

View File

@ -9,12 +9,13 @@
"@babel/core": "^7.12.13", "@babel/core": "^7.12.13",
"@babel/preset-env": "^7.12.13", "@babel/preset-env": "^7.12.13",
"@babel/preset-react": "^7.12.13", "@babel/preset-react": "^7.12.13",
"@f0x52/budo-express": "^1.1.0",
"@reduxjs/toolkit": "^1.8.5",
"autoprefixer": "^10.4.8", "autoprefixer": "^10.4.8",
"babelify": "^10.0.0", "babelify": "^10.0.0",
"bluebird": "^3.7.2", "bluebird": "^3.7.2",
"browserify": "^17.0.0", "browserify": "^17.0.0",
"browserlist": "^1.0.1", "browserlist": "^1.0.1",
"budo-express": "^1.0.8",
"css-extract": "^2.0.0", "css-extract": "^2.0.0",
"eslint-plugin-react": "^7.24.0", "eslint-plugin-react": "^7.24.0",
"express": "^4.18.1", "express": "^4.18.1",
@ -35,7 +36,9 @@
"react": "^17.0.1", "react": "^17.0.1",
"react-dom": "^17.0.1", "react-dom": "^17.0.1",
"react-error-boundary": "^3.1.4", "react-error-boundary": "^3.1.4",
"react-redux": "^8.0.2",
"reactify": "^1.1.1", "reactify": "^1.1.1",
"redux-persist": "^6.0.0",
"uglifyify": "^5.0.2", "uglifyify": "^5.0.2",
"wouter": "^2.8.0-alpha.2" "wouter": "^2.8.0-alpha.2"
}, },

View File

@ -18,6 +18,6 @@
"use strict"; "use strict";
module.exports = function UserProfile() { module.exports = function Federation() {
return "federation"; return "federation";
}; };

View File

@ -25,9 +25,7 @@ const { Route, Switch } = require("wouter");
module.exports = function AdminPanel({oauth, routes}) { module.exports = function AdminPanel({oauth, routes}) {
return ( return (
<Switch> <Switch>
{routes.map(([path, component]) => { {routes}
return <Route key={path} path={path} component={component}/>;
})}
</Switch> </Switch>
); );
}; };

View File

@ -18,6 +18,6 @@
"use strict"; "use strict";
module.exports = function UserProfile() { module.exports = function AdminSettings() {
return "admin settings"; return "admin settings";
}; };

View File

@ -1,45 +0,0 @@
/*
GoToSocial
Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
"use strict";
const Promise = require("bluebird");
const React = require("react");
module.exports = function ErrorFallback({error, resetErrorBoundary}) {
return (
<div className="error">
<p>
{"An error occured, please report this on the "}
<a href="https://github.com/superseriousbusiness/gotosocial/issues">GoToSocial issue tracker</a>
{" or "}
<a href="https://matrix.to/#/#gotosocial-help:superseriousbusiness.org">Matrix support room</a>.
<br/>Include the details below:
</p>
<pre>
{error.name}: {error.message}
</pre>
<pre>
{error.stack}
</pre>
<p>
<button onClick={resetErrorBoundary}>Try again</button> or <a href="">refresh the page</a>
</p>
</div>
);
};

View File

@ -0,0 +1,45 @@
/*
GoToSocial
Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
"use strict";
const Promise = require("bluebird");
const React = require("react");
module.exports = function ErrorFallback({error, resetErrorBoundary}) {
return (
<div className="error">
<p>
{"An error occured, please report this on the "}
<a href="https://github.com/superseriousbusiness/gotosocial/issues">GoToSocial issue tracker</a>
{" or "}
<a href="https://matrix.to/#/#gotosocial-help:superseriousbusiness.org">Matrix support room</a>.
<br/>Include the details below:
</p>
<pre>
{error.name}: {error.message}
</pre>
<pre>
{error.stack}
</pre>
<p>
<button onClick={resetErrorBoundary}>Try again</button> or <a href="">refresh the page</a>
</p>
</div>
);
};

View File

@ -0,0 +1,23 @@
/*
GoToSocial
Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
"use strict";
module.exports = function Login() {
return (null);
};

View File

@ -0,0 +1,33 @@
/*
GoToSocial
Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
"use strict";
const React = require("react");
const { Link, useRoute } = require("wouter");
module.exports = function NavButton({href, name}) {
const [isActive] = useRoute(href);
return (
<Link href={href}>
<a className={isActive ? "active" : ""} data-content={name}>
{name}
</a>
</Link>
);
};

View File

@ -21,19 +21,21 @@
const Promise = require("bluebird"); const Promise = require("bluebird");
const React = require("react"); const React = require("react");
const ReactDom = require("react-dom"); const ReactDom = require("react-dom");
const { Link, Route, Switch, useRoute, Redirect } = require("wouter"); const Redux = require("react-redux");
const { ErrorBoundary } = require("react-error-boundary"); const { Switch } = require("wouter");
const { Provider } = require("react-redux");
const { PersistGate } = require("redux-persist/integration/react");
const Auth = require("./components/auth"); const { store, persistor } = require("./redux");
const Login = require("./components/login");
const ErrorFallback = require("./components/error"); const ErrorFallback = require("./components/error");
const oauthLib = require("./lib/oauth"); const oauthLib = require("./lib/oauth");
require("./style.css"); // require("./style.css");
const UserPanel = require("./user");
const AdminPanel = require("./admin");
// TODO: nested categories?
const nav = { const nav = {
"User": { "User": {
Component: require("./user"), Component: require("./user"),
@ -53,107 +55,40 @@ const nav = {
} }
}; };
function urlSafe(str) {
return str.toLowerCase().replace(/\s+/g, "-");
}
// TODO: nested categories?
const sidebar = [];
const panelRouter = [];
// Generate component tree from `nav` object once, as it won't change // Generate component tree from `nav` object once, as it won't change
Object.entries(nav).forEach(([name, {Component, entries}]) => { const { sidebar, panelRouter } = require("./lib/generate-views")(nav);
let base = `/settings/${urlSafe(name)}`;
let links = [];
let routes = [];
let firstRoute;
Object.entries(entries).forEach(([name, component]) => {
let url = `${base}/${urlSafe(name)}`;
if (firstRoute == undefined) {
firstRoute = `${base}/${urlSafe(name)}`;
}
routes.push([url, component]);
links.push(
<NavButton key={url} href={url} name={name} />
);
});
panelRouter.push(
<Route key={base} path={base}>
<Redirect to={firstRoute}/>
</Route>
);
let childrenPath = `${base}/:section`;
panelRouter.push(
<Route key={childrenPath} path={childrenPath}>
<ErrorBoundary FallbackComponent={ErrorFallback} onReset={() => {}}>
{/* FIXME: implement onReset */}
<Component routes={routes}/>
</ErrorBoundary>
</Route>
);
sidebar.push(
<React.Fragment key={name}>
<Link href={firstRoute}>
<a>
<h2>{name}</h2>
</a>
</Link>
<nav>
{links}
</nav>
</React.Fragment>
);
});
function NavButton({href, name}) {
const [isActive] = useRoute(href);
return (
<Link href={href}>
<a className={isActive ? "active" : ""} data-content={name}>
{name}
</a>
</Link>
);
}
function App() { function App() {
const [oauth, setOauth] = React.useState(); const { loggedIn } = Redux.useSelector((state) => state.oauth);
const [hasAuth, setAuth] = React.useState(false);
const [oauthState, _setOauthState] = React.useState(localStorage.getItem("oauth"));
React.useEffect(() => { // const [oauth, setOauth] = React.useState();
let state = localStorage.getItem("oauth"); // const [hasAuth, setAuth] = React.useState(false);
if (state != undefined) { // const [oauthState, _setOauthState] = React.useState(localStorage.getItem("oauth"));
state = JSON.parse(state);
let restoredOauth = oauthLib(state.config, state);
Promise.try(() => {
return restoredOauth.callback();
}).then(() => {
setAuth(true);
});
setOauth(restoredOauth);
}
}, [setAuth, setOauth]);
if (!hasAuth && oauth && oauth.isAuthorized()) { // React.useEffect(() => {
setAuth(true); // let state = localStorage.getItem("oauth");
} // if (state != undefined) {
// state = JSON.parse(state);
// let restoredOauth = oauthLib(state.config, state);
// Promise.try(() => {
// return restoredOauth.callback();
// }).then(() => {
// setAuth(true);
// });
// setOauth(restoredOauth);
// }
// }, [setAuth, setOauth]);
if (oauth && oauth.isAuthorized()) { // if (!hasAuth && oauth && oauth.isAuthorized()) {
// setAuth(true);
// }
if (loggedIn) {
return ( return (
<> <>
<div className="sidebar"> <div className="sidebar">
{sidebar} {sidebar}
<button className="logout" onClick={oauth.logout}>Log out</button> {/* <button className="logout" onClick={oauth.logout}>Log out</button> */}
</div> </div>
<section> <section>
<Switch> <Switch>
@ -162,15 +97,19 @@ function App() {
</section> </section>
</> </>
); );
} else if (oauthState != undefined) {
return (
<section>
processing oauth...
</section>
);
} else { } else {
return <Auth setOauth={setOauth}/>; return <Login />;
} }
} }
ReactDom.render(<React.StrictMode><App/></React.StrictMode>, document.getElementById("root")); function Main() {
return (
<Provider store={store}>
<PersistGate loading={"loading..."} persistor={persistor}>
<App />
</PersistGate>
</Provider>
);
}
ReactDom.render(<React.StrictMode><Main /></React.StrictMode>, document.getElementById("root"));

View File

@ -0,0 +1,94 @@
/*
GoToSocial
Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
"use strict";
const React = require("react");
const { Link, Route, Redirect } = require("wouter");
const { ErrorBoundary } = require("react-error-boundary");
const ErrorFallback = require("../components/error");
const NavButton = require("../components/nav-button");
function urlSafe(str) {
return str.toLowerCase().replace(/\s+/g, "-");
}
module.exports = function generateViews(struct) {
const sidebar = [];
const panelRouter = [];
Object.entries(struct).forEach(([name, {Component, entries}]) => {
let base = `/settings/${urlSafe(name)}`;
let links = [];
let routes = [];
let firstRoute;
Object.entries(entries).forEach(([name, ViewComponent]) => {
let url = `${base}/${urlSafe(name)}`;
if (firstRoute == undefined) {
firstRoute = `${base}/${urlSafe(name)}`;
}
console.log(name, ViewComponent);
routes.push((
<Route path={url} key={url}>
<ErrorBoundary FallbackComponent={ErrorFallback} onReset={() => {}}>
{/* FIXME: implement onReset */}
<ViewComponent/>
</ErrorBoundary>
</Route>
));
links.push(
<NavButton key={url} href={url} name={name} />
);
});
panelRouter.push(
<Route key={base} path={base}>
<Redirect to={firstRoute}/>
</Route>
);
let childrenPath = `${base}/:section`;
panelRouter.push(
<Route key={childrenPath} path={childrenPath}>
<Component routes={routes}/>
</Route>
);
sidebar.push(
<React.Fragment key={name}>
<Link href={firstRoute}>
<a>
<h2>{name}</h2>
</a>
</Link>
<nav>
{links}
</nav>
</React.Fragment>
);
});
return {sidebar, panelRouter};
};

View File

@ -0,0 +1,39 @@
/*
GoToSocial
Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
"use strict";
const { createStore, combineReducers } = require("redux");
const { persistStore, persistReducer } = require("redux-persist");
const persistConfig = {
key: "gotosocial-settings",
storage: require("redux-persist/lib/storage").default,
stateReconciler: require("redux-persist/lib/stateReconciler/autoMergeLevel2").default
};
const combinedReducers = combineReducers({
oauth: require("./reducers/oauth").reducer
});
const persistedReducer = persistReducer(persistConfig, combinedReducers);
const store = createStore(persistedReducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__());
const persistor = persistStore(store);
module.exports = { store, persistor };

View File

@ -0,0 +1,42 @@
/*
GoToSocial
Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
"use strict";
const {createSlice} = require("@reduxjs/toolkit");
module.exports = createSlice({
name: "oauth",
initialState: {
loggedIn: false
},
reducers: {
setInstance: (state, {payload}) => {
return {
...state,
instance: payload
};
},
setRegistration: (state, {payload}) => {
return {
...state,
}
}
}
});

View File

@ -18,6 +18,6 @@
"use strict"; "use strict";
module.exports = function UserProfile() { module.exports = function UserCustomization() {
return "user customization"; return "user customization";
}; };

View File

@ -42,10 +42,7 @@ module.exports = function UserPanel({oauth, routes}) {
return ( return (
<Switch> <Switch>
{routes.map(([path, component]) => { {routes}
console.log(component);
return <Route key={path} path={path} component={component}/>;
})}
</Switch> </Switch>
); );
}; };

View File

@ -18,6 +18,6 @@
"use strict"; "use strict";
module.exports = function UserProfile() { module.exports = function UserSettings() {
return "user settings"; return "user settings";
}; };

File diff suppressed because it is too large Load Diff