mirror of
https://gitea.com/gitea/gitea-mirror.git
synced 2026-03-20 03:40:27 +00:00
Use "Enable Gravatar" but not "Disable" (#36771)
* Fix #35685 * Fix #35627 * Fix #31112 Introduce "fipped" config value type, remove unused setting variables. Make DisableGravatar=true by defult, remove useless config options from the "Install" page. The legacy config options are still kept because they are still the fallback values for the system config options. --------- Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
@@ -7,10 +7,15 @@ test('ConfigFormValueMapper', () => {
|
||||
|
||||
<!-- top-level key -->
|
||||
<input name="k1" type="checkbox" value="v-key-only" data-config-dyn-key="k1" data-config-value-json="true" data-config-value-type="boolean">
|
||||
|
||||
<input type="hidden" data-config-dyn-key="k2" data-config-value-json='"k2-val"'>
|
||||
<input name="k2">
|
||||
|
||||
<textarea name="repository.open-with.editor-apps"> a = b\n</textarea>
|
||||
|
||||
<input name="k-flipped-true" type="checkbox" data-config-value-type="flipped">
|
||||
<input name="k-flipped-false" type="checkbox" checked data-config-value-type="flipped">
|
||||
|
||||
<!-- sub key -->
|
||||
<input type="hidden" data-config-dyn-key="struct" data-config-value-json='{"SubBoolean": true, "SubTimestamp": 123456789, "OtherKey": "other-value"}'>
|
||||
<input name="struct.SubBoolean" type="checkbox" data-config-value-type="boolean">
|
||||
@@ -35,6 +40,8 @@ test('ConfigFormValueMapper', () => {
|
||||
expect(result).toEqual({
|
||||
'k1': 'true',
|
||||
'k2': '"k2-val"',
|
||||
'k-flipped-false': 'false',
|
||||
'k-flipped-true': 'true',
|
||||
'repository.open-with.editor-apps': '[{"DisplayName":"a","OpenURL":"b"}]', // TODO: OPEN-WITH-EDITOR-APP-JSON: it must match backend
|
||||
'struct': '{"SubBoolean":true,"SubTimestamp":123456780,"OtherKey":"other-value","NewKey":"new-value"}',
|
||||
});
|
||||
|
||||
@@ -6,14 +6,23 @@ import {submitFormFetchAction} from '../common-fetch-action.ts';
|
||||
|
||||
const {appSubUrl} = window.config;
|
||||
|
||||
function collectCheckboxBooleanValue(el: HTMLInputElement): boolean {
|
||||
const valType = el.getAttribute('data-config-value-type') as ConfigValueType;
|
||||
if (valType === 'boolean') return el.checked;
|
||||
if (valType === 'flipped') return !el.checked;
|
||||
requireExplicitValueType(el);
|
||||
}
|
||||
|
||||
function initSystemConfigAutoCheckbox(el: HTMLInputElement) {
|
||||
el.addEventListener('change', async () => {
|
||||
// if the checkbox is inside a form, we assume it's handled by the form submit and do not send an individual request
|
||||
if (el.closest('form')) return;
|
||||
try {
|
||||
const resp = await POST(`${appSubUrl}/-/admin/config`, {
|
||||
data: new URLSearchParams({key: el.getAttribute('data-config-dyn-key')!, value: String(el.checked)}),
|
||||
const data = new URLSearchParams({
|
||||
key: el.getAttribute('data-config-dyn-key')!,
|
||||
value: String(collectCheckboxBooleanValue(el)),
|
||||
});
|
||||
const resp = await POST(`${appSubUrl}/-/admin/config`, {data});
|
||||
const json: Record<string, any> = await resp.json();
|
||||
if (json.errorMessage) throw new Error(json.errorMessage);
|
||||
} catch (ex) {
|
||||
@@ -47,7 +56,7 @@ function extractElemConfigSubKey(el: GeneralFormFieldElement, dynKey: string): s
|
||||
|
||||
// Due to the different design between HTML form elements and the JSON struct of the config values, we need to explicitly define some types.
|
||||
// * checkbox can be used for boolean value, it can also be used for multiple values (array)
|
||||
type ConfigValueType = 'boolean' | 'string' | 'number' | 'timestamp'; // TODO: support more types like array, not used at the moment.
|
||||
type ConfigValueType = 'boolean' | 'flipped' | 'string' | 'number' | 'timestamp'; // TODO: support more types like array, not used at the moment.
|
||||
|
||||
function toDatetimeLocalValue(unixSeconds: number) {
|
||||
const d = new Date(unixSeconds * 1000);
|
||||
@@ -102,13 +111,14 @@ export class ConfigFormValueMapper {
|
||||
return true;
|
||||
}
|
||||
|
||||
collectConfigValueFromElement(el: GeneralFormFieldElement, _oldVal: any = null) {
|
||||
collectConfigValueFromElement(el: GeneralFormFieldElement) {
|
||||
let val: any;
|
||||
const valType = this.presetValueTypes[el.name];
|
||||
if (el.matches('[type="checkbox"]')) {
|
||||
if (valType !== 'boolean') requireExplicitValueType(el);
|
||||
val = el.checked;
|
||||
// oldVal: for future use when we support array value with checkbox
|
||||
// TODO: if it needs to support array values in the future,
|
||||
// it needs to iterate the "namedElems" to find all the checkboxes with the same name and collect values accordingly,
|
||||
// and set the namedElems[matchedIdx] to null to avoid duplicate processing.
|
||||
val = collectCheckboxBooleanValue(el);
|
||||
} else if (el.matches('[type="datetime-local"]')) {
|
||||
if (valType !== 'timestamp') requireExplicitValueType(el);
|
||||
val = Math.floor(new Date(el.value).getTime() / 1000) ?? 0; // NaN is fine to JSON.stringify, it becomes null.
|
||||
@@ -128,7 +138,7 @@ export class ConfigFormValueMapper {
|
||||
if (!el) continue;
|
||||
const subKey = extractElemConfigSubKey(el, dynKey);
|
||||
if (!subKey) continue; // if not match, skip
|
||||
cfgVal[subKey] = this.collectConfigValueFromElement(el, cfgVal[subKey]);
|
||||
cfgVal[subKey] = this.collectConfigValueFromElement(el);
|
||||
namedElems[idx] = null;
|
||||
}
|
||||
}
|
||||
@@ -180,6 +190,7 @@ export class ConfigFormValueMapper {
|
||||
|
||||
// now, the namedElems should only contain the config options without sub values,
|
||||
// directly store the value in formData with key as the element name, for example:
|
||||
// "foo.enabled" => "true"
|
||||
for (const el of namedElems) {
|
||||
if (!el) continue;
|
||||
const dynKey = el.name;
|
||||
|
||||
@@ -60,25 +60,6 @@ function initPreInstall() {
|
||||
}
|
||||
|
||||
// TODO: better handling of exclusive relations.
|
||||
document.querySelector<HTMLInputElement>('#offline-mode input')!.addEventListener('change', function () {
|
||||
if (this.checked) {
|
||||
document.querySelector<HTMLInputElement>('#disable-gravatar input')!.checked = true;
|
||||
document.querySelector<HTMLInputElement>('#federated-avatar-lookup input')!.checked = false;
|
||||
}
|
||||
});
|
||||
document.querySelector<HTMLInputElement>('#disable-gravatar input')!.addEventListener('change', function () {
|
||||
if (this.checked) {
|
||||
document.querySelector<HTMLInputElement>('#federated-avatar-lookup input')!.checked = false;
|
||||
} else {
|
||||
document.querySelector<HTMLInputElement>('#offline-mode input')!.checked = false;
|
||||
}
|
||||
});
|
||||
document.querySelector<HTMLInputElement>('#federated-avatar-lookup input')!.addEventListener('change', function () {
|
||||
if (this.checked) {
|
||||
document.querySelector<HTMLInputElement>('#disable-gravatar input')!.checked = false;
|
||||
document.querySelector<HTMLInputElement>('#offline-mode input')!.checked = false;
|
||||
}
|
||||
});
|
||||
document.querySelector<HTMLInputElement>('#enable-openid-signin input')!.addEventListener('change', function () {
|
||||
if (this.checked) {
|
||||
if (!document.querySelector<HTMLInputElement>('#disable-registration input')!.checked) {
|
||||
|
||||
Reference in New Issue
Block a user