federation block routing

This commit is contained in:
f0x 2022-09-15 21:16:18 +02:00
parent 9fbe8f5cfd
commit 80c05825ab
7 changed files with 150 additions and 47 deletions

View file

@ -21,62 +21,108 @@
const Promise = require("bluebird");
const React = require("react");
const Redux = require("react-redux");
const {Switch, Route, Link, useRoute} = require("wouter");
const Submit = require("../components/submit");
const api = require("../lib/api");
const adminActions = require("../redux/reducers/instances").actions;
const {
TextInput,
TextArea,
File
} = require("../components/form-fields").formFields(adminActions.setAdminSettingsVal, (state) => state.instances.adminSettings);
const base = "/settings/admin/federation";
// const {
// TextInput,
// TextArea,
// File
// } = require("../components/form-fields").formFields(adminActions.setAdminSettingsVal, (state) => state.instances.adminSettings);
module.exports = function AdminSettings() {
const dispatch = Redux.useDispatch();
const instance = Redux.useSelector(state => state.instances.adminSettings);
const [loaded, setLoaded] = React.useState(false);
// const instance = Redux.useSelector(state => state.instances.adminSettings);
const { blockedInstances } = Redux.useSelector(state => state.admin);
const [errorMsg, setError] = React.useState("");
const [statusMsg, setStatus] = React.useState("");
React.useEffect(() => {
Promise.try(() => {
return dispatch(api.admin.fetchDomainBlocks());
}).then(() => {
setLoaded(true);
}).catch((e) => {
console.log(e);
});
}, []);
const [loaded, setLoaded] = React.useState(false);
function submit() {
setStatus("PATCHing");
setError("");
return Promise.try(() => {
return dispatch(api.admin.updateInstance());
}).then(() => {
setStatus("Saved!");
}).catch((e) => {
setError(e.message);
setStatus("");
});
}
React.useEffect(() => {
if (blockedInstances != undefined) {
setLoaded(true);
} else {
return Promise.try(() => {
return dispatch(api.admin.fetchDomainBlocks());
}).then(() => {
setLoaded(true);
});
}
}, []);
if (!loaded) {
return (
<div>
<h1>Federation</h1>
Loading instance blocks...
Loading...
</div>
);
}
return (
<div>
<h1>Federation</h1>
<Switch>
<Route path={`${base}/:domain`}>
<InstancePage blockedInstances={blockedInstances}/>
</Route>
<InstanceOverview blockedInstances={blockedInstances} />
</Switch>
</div>
);
};
};
function InstanceOverview({blockedInstances}) {
return (
<div>
<h1>Federation</h1>
{blockedInstances.map((entry) => {
return (
<Link key={entry.domain} to={`${base}/${entry.domain}`}>
<a>{entry.domain}</a>
</Link>
);
})}
</div>
);
}
function BackButton() {
return (
<Link to={base}>
<a className="button">&lt; back</a>
</Link>
);
}
function InstancePage({blockedInstances}) {
let [_match, {domain}] = useRoute(`${base}/:domain`);
let [status, setStatus] = React.useState("");
let [entry, setEntry] = React.useState(() => {
let entry = blockedInstances.find((a) => a.domain == domain);
if (entry == undefined) {
setStatus(`No block entry found for ${domain}, but you can create one below:`);
return {
private_comment: ""
};
} else {
return entry;
}
});
return (
<div>
{status}
<h1><BackButton/> Federation settings for: {domain}</h1>
<div>{entry.private_comment}</div>
</div>
);
}

View file

@ -22,7 +22,7 @@ const React = require("react");
const { Link, useRoute } = require("wouter");
module.exports = function NavButton({href, name}) {
const [isActive] = useRoute(href);
const [isActive] = useRoute(`${href}/:anything?`);
return (
<Link href={href}>
<a className={isActive ? "active" : ""} data-content={name}>

View file

@ -21,6 +21,7 @@
const Promise = require("bluebird");
const instance = require("../../redux/reducers/instances").actions;
const admin = require("../../redux/reducers/admin").actions;
module.exports = function ({ apiCall, getChanges }) {
return {
@ -45,6 +46,8 @@ module.exports = function ({ apiCall, getChanges }) {
return function (dispatch, _getState) {
return Promise.try(() => {
return dispatch(apiCall("GET", "/api/v1/admin/domain_blocks"));
}).then((data) => {
return dispatch(admin.setBlockedInstances(data));
});
};
}

View file

@ -24,7 +24,7 @@ const { OAUTHError, AuthenticationError } = require("../errors");
const oauth = require("../../redux/reducers/oauth").actions;
const temporary = require("../../redux/reducers/temporary").actions;
const user = require("../../redux/reducers/user").actions;
const admin = require("../../redux/reducers/admin").actions;
module.exports = function oauthAPI({ apiCall, getCurrentUrl }) {
return {
@ -103,8 +103,11 @@ module.exports = function oauthAPI({ apiCall, getCurrentUrl }) {
// no role info, try fetching an admin-only route and see if we get an error
return Promise.try(() => {
return dispatch(apiCall("GET", "/api/v1/admin/domain_blocks"));
}).then(() => {
return dispatch(oauth.setAdmin(true));
}).then((data) => {
return Promise.all([
dispatch(oauth.setAdmin(true)),
dispatch(admin.setBlockedInstances(data))
]);
}).catch(AuthenticationError, () => {
return dispatch(oauth.setAdmin(false));
}).catch((e) => {

View file

@ -64,11 +64,11 @@ module.exports = function getViews(struct) {
let url = `${base}/${urlSafe(name)}`;
if (firstRoute == undefined) {
firstRoute = `${base}/${urlSafe(name)}`;
firstRoute = url;
}
routes.push((
<Route path={url} key={url}>
panelRouterEl.push((
<Route path={`${url}/:page?`} key={url}>
<ErrorBoundary FallbackComponent={ErrorFallback} onReset={() => { }}>
{/* FIXME: implement onReset */}
<ViewComponent />
@ -87,14 +87,15 @@ module.exports = function getViews(struct) {
</Route>
);
let childrenPath = `${base}/:section`;
panelRouterEl.push(
<Route key={childrenPath} path={childrenPath}>
<Switch>
{routes}
</Switch>
</Route>
);
// let childrenPath = `${base}/:section`;
// panelRouterEl.push(...routes);
console.log(panelRouterEl);
// <Route key={childrenPath} path={childrenPath}>
// <Switch id="childrenPath-switch">
// {routes}
// </Switch>
// </Route>
// );
sidebarEl.push(
<React.Fragment key={name}>

View file

@ -36,6 +36,7 @@ const combinedReducers = combineReducers({
instances: require("./reducers/instances").reducer,
temporary: require("./reducers/temporary").reducer,
user: require("./reducers/user").reducer,
admin: require("./reducers/admin").reducer,
});
const persistedReducer = persistReducer(persistConfig, combinedReducers);

View file

@ -0,0 +1,49 @@
/*
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");
// const d = require("dotty");
function sortBlocks(blocks) {
return blocks.sort((a, b) => { // alphabetical sort
return a.domain.localeCompare(b.domain);
});
}
// function deduplicateBlocks(blocks) {
// let a = new Map();
// blocks.forEach((block) => {
// a.set(block.id, block);
// });
// return Array.from(a.values());
// }
module.exports = createSlice({
name: "admin",
initialState: {
blockedInstances: undefined,
blockedInstancesMap: {}
},
reducers: {
setBlockedInstances: (state, {payload}) => {
state.blockedInstances = sortBlocks(payload);
},
}
});