customize profile css

This commit is contained in:
f0x 2022-09-12 20:50:51 +02:00
parent ca25d4c570
commit 0a4b1f79de
7 changed files with 37 additions and 31 deletions

View file

@ -36,7 +36,7 @@ module.exports = function Login({error}) {
let currentDomain = window.location.origin;
Promise.try(() => {
console.log("trying", currentDomain);
return dispatch(api.instance.fetch(currentDomain));
return dispatch(api.instance.fetchWithoutStore(currentDomain));
}).then(() => {
if (instanceFieldRef.current.length == 0) { // user hasn't started typing yet
dispatch(setInstance(currentDomain));
@ -51,7 +51,7 @@ module.exports = function Login({error}) {
function tryInstance() {
let domain = instanceFieldRef.current;
Promise.try(() => {
return dispatch(api.instance.fetch(domain)).catch((e) => {
return dispatch(api.instance.fetchWithoutStore(domain)).catch((e) => {
// TODO: clearer error messages for common errors
console.log(e);
throw e;

View file

@ -40,7 +40,6 @@ const nav = {
entries: {
"Profile": require("./user/profile.js"),
"Settings": require("./user/settings.js"),
"Customization": require("./user/customization.js")
}
},
"Admin": {
@ -76,6 +75,9 @@ function App() {
return dispatch(api.oauth.tokenize(code));
}
}
}).then(() => {
// Fetch current instance info
return dispatch(api.instance.fetch());
}).then(() => {
// Check currently stored auth token for validity if available
if (loginState == "callback" || loginState == "login") {

View file

@ -22,7 +22,7 @@ const Promise = require("bluebird");
const { isPlainObject } = require("is-plain-object");
const { APIError } = require("../errors");
const { setInstanceInfo } = require("../../redux/reducers/instances").actions;
const { setInstanceInfo, setNamedInstanceInfo } = require("../../redux/reducers/instances").actions;
const oauth = require("../../redux/reducers/oauth").actions;
function apiCall(method, route, payload, type="json") {
@ -95,7 +95,7 @@ function getCurrentUrl() {
return `${window.location.origin}${window.location.pathname}`;
}
function fetchInstance(domain) {
function fetchInstanceWithoutStore(domain) {
return function(dispatch, getState) {
return Promise.try(() => {
let lookup = getState().instances.info[domain];
@ -113,7 +113,20 @@ function fetchInstance(domain) {
return apiCall("GET", "/api/v1/instance")(dispatch, () => fakeState);
}).then((json) => {
if (json && json.uri) { // TODO: validate instance json more?
dispatch(setInstanceInfo([domain, json]));
dispatch(setNamedInstanceInfo([domain, json]));
return json;
}
});
};
}
function fetchInstance() {
return function(dispatch, _getState) {
return Promise.try(() => {
return dispatch(apiCall("GET", "/api/v1/instance"));
}).then((json) => {
if (json && json.uri) {
dispatch(setInstanceInfo(json));
return json;
}
});
@ -122,6 +135,7 @@ function fetchInstance(domain) {
module.exports = {
instance: {
fetchWithoutStore: fetchInstanceWithoutStore,
fetch: fetchInstance
},
oauth: require("./oauth")({apiCall, getCurrentUrl}),

View file

@ -64,7 +64,7 @@ module.exports = function ({ apiCall }) {
};
},
updateProfile: function updateProfile() {
const formKeys = ["display_name", "locked", "source"];
const formKeys = ["display_name", "locked", "source", "custom_css"];
const renamedKeys = [["note", "source.note"]];
const fileKeys = ["header", "avatar"];

View file

@ -26,9 +26,12 @@ module.exports = createSlice({
info: {},
},
reducers: {
setInstanceInfo: (state, {payload}) => {
setNamedInstanceInfo: (state, {payload}) => {
let [key, info] = payload;
state.info[key] = info;
},
setInstanceInfo: (state, {payload}) => {
state.current = payload;
}
}
});

View file

@ -1,23 +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";
module.exports = function UserCustomization() {
return "user customization";
};

View file

@ -31,6 +31,9 @@ const user = require("../redux/reducers/user").actions;
module.exports = function UserProfile() {
const dispatch = Redux.useDispatch();
const account = Redux.useSelector(state => state.user.profile);
const instance = Redux.useSelector(state => state.instances.current);
const allowCustomCSS = instance.configuration.accounts.allow_custom_css;
const { onTextChange, onCheckChange, onFileChange } = formFields(dispatch, user.setProfileVal, account);
@ -106,6 +109,13 @@ module.exports = function UserProfile() {
<label htmlFor="locked">Manually approve follow requests?</label>
<input id="locked" type="checkbox" checked={account.locked} onChange={onCheckChange("locked")} />
</div>
{ !allowCustomCSS ? null :
<div className="labelinput">
<label htmlFor="customcss">Custom CSS</label>
<textarea className="mono" id="customcss" value={account.custom_css} onChange={onTextChange("custom_css")}/>
<a href="https://docs.gotosocial.org/en/latest/user_guide/custom_css" target="_blank" className="moreinfolink" rel="noreferrer">Learn more about custom CSS (opens in a new tab)</a>
</div>
}
<Submit onClick={submit} label="Save profile info" errorMsg={errorMsg} statusMsg={statusMsg} />
</div>
);