Improve UX of "Allow other protocols" option

This commit is contained in:
Younes Aassila 2025-02-09 15:12:29 +01:00
parent 6df1cc7638
commit 2cba7c1509
No known key found for this signature in database
3 changed files with 58 additions and 59 deletions

View File

@ -27,7 +27,7 @@ export function getProxyInfoFromUrl(
let port: number | undefined = undefined; let port: number | undefined = undefined;
if (lastIndexOfColon === -1) { if (lastIndexOfColon === -1) {
host = hostname; host = hostname;
port = !type ? 3128 : DEFAULT_PORTS[type]; // Default port port = type ? DEFAULT_PORTS[type] : 3128; // Default port
} else { } else {
host = hostname.substring(0, lastIndexOfColon); host = hostname.substring(0, lastIndexOfColon);
port = Number(hostname.substring(lastIndexOfColon + 1, hostname.length)); port = Number(hostname.substring(lastIndexOfColon + 1, hostname.length));

View File

@ -28,7 +28,7 @@ type ListOptions = {
getPromptPlaceholder(insertMode: InsertMode): string; getPromptPlaceholder(insertMode: InsertMode): string;
isAddAllowed(text: string): AllowedResult; isAddAllowed(text: string): AllowedResult;
isEditAllowed(text: string): AllowedResult; isEditAllowed(text: string): AllowedResult;
onEdit?(text: string): void; onChange?(oldText: string | undefined, newText: string): void;
focusPrompt: boolean; focusPrompt: boolean;
hidePromptMarker: boolean; hidePromptMarker: boolean;
insertMode: InsertMode; insertMode: InsertMode;
@ -162,12 +162,6 @@ function main() {
} }
return [true]; return [true];
}, },
isEditAllowed(text) {
if (!/^[a-z0-9_]+$/i.test(text)) {
return [false, `'${text}' is not a valid channel name`];
}
return [true];
},
}); });
whitelistSubscriptionsCheckboxElement.checked = whitelistSubscriptionsCheckboxElement.checked =
store.state.whitelistChannelSubscriptions; store.state.whitelistChannelSubscriptions;
@ -183,50 +177,21 @@ function main() {
if (store.state.optimizedProxiesEnabled) if (store.state.optimizedProxiesEnabled)
optimizedProxiesInputElement.checked = true; optimizedProxiesInputElement.checked = true;
else normalProxiesInputElement.checked = true; else normalProxiesInputElement.checked = true;
const onProxyTypeChange = () => { const onProxyModeChange = () => {
store.state.optimizedProxiesEnabled = optimizedProxiesInputElement.checked; store.state.optimizedProxiesEnabled = optimizedProxiesInputElement.checked;
if (isChromium && store.state.chromiumProxyActive) { if (isChromium && store.state.chromiumProxyActive) {
updateProxySettings(); updateProxySettings();
} }
updateProxyUsage(); updateProxyUsage();
}; };
optimizedProxiesInputElement.addEventListener("change", onProxyTypeChange); optimizedProxiesInputElement.addEventListener("change", onProxyModeChange);
normalProxiesInputElement.addEventListener("change", onProxyTypeChange); normalProxiesInputElement.addEventListener("change", onProxyModeChange);
listInit(optimizedProxiesListElement, "optimizedProxies", { loadProxiesLists();
getPromptPlaceholder: insertMode => {
if (insertMode == "prepend") return "Enter a proxy URL… (Primary)";
return "Enter a proxy URL… (Fallback)";
},
isAddAllowed: isOptimizedProxyUrlAllowed,
isEditAllowed: isOptimizedProxyUrlAllowed,
onEdit() {
if (isChromium && store.state.chromiumProxyActive) {
updateProxySettings();
}
},
hidePromptMarker: true,
insertMode: "both",
});
listInit(normalProxiesListElement, "normalProxies", {
getPromptPlaceholder: insertMode => {
if (insertMode == "prepend") return "Enter a proxy URL… (Primary)";
return "Enter a proxy URL… (Fallback)";
},
isAddAllowed: isNormalProxyUrlAllowed,
isEditAllowed: isNormalProxyUrlAllowed,
onEdit() {
if (isChromium && store.state.chromiumProxyActive) {
updateProxySettings();
}
},
hidePromptMarker: true,
insertMode: "both",
});
otherProtocolsCheckboxElement.checked = store.state.allowOtherProxyProtocols; otherProtocolsCheckboxElement.checked = store.state.allowOtherProxyProtocols;
otherProtocolsCheckboxElement.addEventListener("change", () => { otherProtocolsCheckboxElement.addEventListener("change", () => {
store.state.allowOtherProxyProtocols = store.state.allowOtherProxyProtocols =
otherProtocolsCheckboxElement.checked; otherProtocolsCheckboxElement.checked;
location.reload(); loadProxiesLists();
}); });
// Ad log // Ad log
adLogEnabledCheckboxElement.checked = store.state.adLogEnabled; adLogEnabledCheckboxElement.checked = store.state.adLogEnabled;
@ -313,6 +278,37 @@ function updateProxyUsage() {
} }
} }
function loadProxiesLists() {
listInit(optimizedProxiesListElement, "optimizedProxies", {
getPromptPlaceholder: insertMode => {
if (insertMode == "prepend") return "Enter a proxy URL… (Primary)";
return "Enter a proxy URL… (Fallback)";
},
isAddAllowed: isOptimizedProxyUrlAllowed,
onChange() {
if (isChromium && store.state.chromiumProxyActive) {
updateProxySettings();
}
},
hidePromptMarker: true,
insertMode: "both",
});
listInit(normalProxiesListElement, "normalProxies", {
getPromptPlaceholder: insertMode => {
if (insertMode == "prepend") return "Enter a proxy URL… (Primary)";
return "Enter a proxy URL… (Fallback)";
},
isAddAllowed: isNormalProxyUrlAllowed,
onChange() {
if (isChromium && store.state.chromiumProxyActive) {
updateProxySettings();
}
},
hidePromptMarker: true,
insertMode: "both",
});
}
function isOptimizedProxyUrlAllowed(url: string): AllowedResult { function isOptimizedProxyUrlAllowed(url: string): AllowedResult {
const urlLower = url.toLowerCase(); const urlLower = url.toLowerCase();
@ -348,7 +344,10 @@ function isOptimizedProxyUrlAllowed(url: string): AllowedResult {
if (url.includes("://")) { if (url.includes("://")) {
const [protocol] = url.split("://", 1); const [protocol] = url.split("://", 1);
if (!store.state.allowOtherProxyProtocols) { if (!store.state.allowOtherProxyProtocols) {
return [false, "Proxy URLs must not contain a protocol (e.g. 'http://')"]; return [
false,
"Proxy URLs are not allowed to contain a protocol (e.g. 'http://')",
];
} else if (!["http", "https", "socks", "socks4"].includes(protocol)) { } else if (!["http", "https", "socks", "socks4"].includes(protocol)) {
return [false, `'${protocol}' is not a supported protocol`]; return [false, `'${protocol}' is not a supported protocol`];
} }
@ -416,6 +415,7 @@ function listInit(
storeKey: StoreStringArrayKey, storeKey: StoreStringArrayKey,
options: Partial<ListOptions> = {} options: Partial<ListOptions> = {}
) { ) {
listElement.innerHTML = ""; // Reset list element.
const listOptions: ListOptions = { ...DEFAULT_LIST_OPTIONS, ...options }; const listOptions: ListOptions = { ...DEFAULT_LIST_OPTIONS, ...options };
for (const text of store.state[storeKey]) { for (const text of store.state[storeKey]) {
_listAppend(listElement, storeKey, text, { _listAppend(listElement, storeKey, text, {
@ -475,18 +475,19 @@ function _listAppend(
return console.error(`Item '${text}' not found in '${storeKey}' array`); return console.error(`Item '${text}' not found in '${storeKey}' array`);
const textInput = e.target as HTMLInputElement; const textInput = e.target as HTMLInputElement;
const oldText = text;
const newText = textInput.value.trim(); const newText = textInput.value.trim();
// Remove item if text is empty. // Remove item if text is empty.
if (newText === "") { if (newText === "") {
store.state[storeKey].splice(itemIndex, 1); store.state[storeKey].splice(itemIndex, 1);
listItem.remove(); listItem.remove();
if (options.onEdit) options.onEdit(newText); if (options.onChange) options.onChange(oldText, newText);
return; return;
} }
// Check if text is valid. // Check if text is valid.
const [allowed, error] = options.isEditAllowed(newText); const [allowed, error] = options.isAddAllowed(newText);
if (!allowed) { if (!allowed) {
alert(error || "You cannot edit this item"); alert(error || "You cannot add this item");
textInput.value = text; textInput.value = text;
return; return;
} }
@ -495,7 +496,7 @@ function _listAppend(
textInput.placeholder = options.getItemPlaceholder(newText); textInput.placeholder = options.getItemPlaceholder(newText);
textInput.value = newText; // Update text in case it was trimmed. textInput.value = newText; // Update text in case it was trimmed.
text = newText; // Update current text variable. text = newText; // Update current text variable.
if (options.onEdit) options.onEdit(newText); if (options.onChange) options.onChange(oldText, newText);
}); });
listItem.append(textInput); listItem.append(textInput);
@ -550,7 +551,7 @@ function _listPrompt(
if (options.insertMode === "prepend") newArray.unshift(text); if (options.insertMode === "prepend") newArray.unshift(text);
else newArray.push(text); else newArray.push(text);
store.state[storeKey] = newArray; store.state[storeKey] = newArray;
if (options.onEdit) options.onEdit(text); if (options.onChange) options.onChange(undefined, text);
listItem.remove(); listItem.remove();
_listAppend(listElement, storeKey, text, options); _listAppend(listElement, storeKey, text, options);

View File

@ -209,24 +209,22 @@
id="other-protocols-checkbox" id="other-protocols-checkbox"
/> />
<label for="other-protocols-checkbox"> <label for="other-protocols-checkbox">
Allow the use of other protocols for proxies Allow the use of other protocols
</label> </label>
<span class="tag">For advanced users only</span>
<br /> <br />
<small> <small>
By default, only HTTP proxies are allowed. Enabling this option This option allows you to use protocols other than HTTP.
will allow the use of other protocols like HTTPS, SOCKS4, and </small>
SOCKS5. <br />
<small>
Supported protocols are HTTPS (<code>https://</code>), SOCKS4
(<code>socks4://</code>), and SOCKS5 (<code>socks://</code>).
</small> </small>
<br /> <br />
<small> <small>
To provide a protocol, use the format To provide a protocol, use the format
<code>protocol://hostname:port</code>. Available protocols are <code>protocol://hostname:port</code>.
<code>http</code>, <code>https</code>, <code>socks</code>, and
<code>socks4</code>.
</small>
<br />
<small>
<b>ONLY ENABLE THIS OPTION IF YOU KNOW WHAT YOU ARE DOING</b>.
</small> </small>
</li> </li>
</ul> </ul>