web: updated api endpoint & params, default instance override

- dialogs can be undismissable now (impossible to click away by pressing the bg behind it)
- added security warning about api override
- moved default api url to env
- added new processing settings page
This commit is contained in:
wukko 2024-08-04 00:43:24 +06:00
parent 168c1bdbbb
commit aba444ec8b
No known key found for this signature in database
GPG key ID: 3E30B3F26C7B4AA2
14 changed files with 134 additions and 23 deletions

View file

@ -8,6 +8,7 @@
"button.share": "share",
"button.copy": "copy",
"button.import": "import",
"button.continue": "continue",
"reset.title": "reset all settings?",
"reset.body": "are you sure you want to reset all settings? this action is immediate and irreversible.",
@ -22,5 +23,8 @@
"safety.title": "important safety notice",
"import.body": "importing unknown or corrupted files may unexpectedly alter or break cobalt functionality. only import files that you've personally exported and haven't modified. if you were asked to import this file by someone - don't do it.\n\nwe are not responsible for any harm caused by importing unknown setting files."
"import.body": "importing unknown or corrupted files may unexpectedly alter or break cobalt functionality. only import files that you've personally exported and haven't modified. if you were asked to import this file by someone - don't do it.\n\nwe are not responsible for any harm caused by importing unknown setting files.",
"api.override.title": "processing instance override",
"api.override.body": "{{ value }} is now the processing instance. if you don't trust it, press \"cancel\" and it'll be ignored.\n\nyou can change your choice later in processing settings."
}

View file

@ -6,6 +6,7 @@
"page.download": "downloading",
"page.advanced": "advanced",
"page.debug": "debug information",
"page.processing": "processing",
"section.general": "general",
"section.save": "save",
@ -103,5 +104,9 @@
"advanced.data": "settings data",
"advanced.reset": "reset all settings",
"advanced.import": "import",
"advanced.export": "export"
"advanced.export": "export",
"processing.override": "default instance override",
"processing.override.title": "use instance-provided processing server",
"processing.override.description": "cobalt will use the processing server from DEFAULT_API when this is enabled."
}

View file

@ -5,6 +5,7 @@
import DialogBackdropClose from "$components/dialog/DialogBackdropClose.svelte";
export let id: string;
export let dismissable = true;
let dialogParent: HTMLDialogElement;
@ -32,5 +33,5 @@
<dialog id="dialog-{id}" bind:this={dialogParent} class:closing class:open>
<slot></slot>
<DialogBackdropClose closeFunc={close} />
<DialogBackdropClose closeFunc={dismissable ? close : () => {}} />
</dialog>

View file

@ -16,6 +16,7 @@
export let id: string;
export let items: Optional<DialogPickerItem[]> = undefined;
export let buttons: Optional<DialogButton[]> = undefined;
export let dismissable = true;
let dialogDescription = "dialog.picker.description.";
@ -30,7 +31,7 @@
let close: () => void;
</script>
<DialogContainer {id} bind:close>
<DialogContainer {id} {dismissable} bind:close>
<div
class="dialog-body picker-dialog"
class:three-columns={items && items.length <= 3}

View file

@ -19,6 +19,7 @@
export let id: string;
export let url: string;
export let bodyText: string = "";
export let dismissable = true;
let close: () => void;
@ -31,7 +32,7 @@
}
</script>
<DialogContainer {id} bind:close>
<DialogContainer {id} {dismissable} bind:close>
<div class="dialog-body popup-body">
<div class="meowbalt-container">
<Meowbalt emotion="question" />

View file

@ -17,11 +17,12 @@
export let bodyText = "";
export let bodySubText = "";
export let buttons: Optional<DialogButton[]> = undefined;
export let dismissable = true;
let close: () => void;
</script>
<DialogContainer {id} bind:close>
<DialogContainer {id} {dismissable} bind:close>
<div class="dialog-body small-dialog" class:meowbalt-visible={meowbalt}>
{#if meowbalt}
<div class="meowbalt-container">

View file

@ -1,33 +1,94 @@
import { get } from "svelte/store";
import settings from "$lib/state/settings";
import env, { apiURL } from "$lib/env";
import { t } from "$lib/i18n/translations";
import settings, { updateSetting } from "$lib/state/settings";
import { createDialog } from "$lib/dialogs";
import type { CobaltAPIResponse } from "$lib/types/api";
import type { Optional } from "$lib/types/generic";
const apiURL = "https://api.cobalt.tools";
const request = async (url: string) => {
const saveSettings = get(settings).save;
const request = {
url,
isAudioOnly: saveSettings.downloadMode === "audio",
isAudioMuted: saveSettings.downloadMode === "mute",
aFormat: saveSettings.audioFormat,
isTTFullAudio: saveSettings.tiktokFullAudio,
dubLang: saveSettings.youtubeDubBrowserLang,
downloadMode: saveSettings.downloadMode,
vCodec: saveSettings.youtubeVideoCodec,
vQuality: saveSettings.videoQuality,
audioFormat: saveSettings.audioFormat,
tiktokFullAudio: saveSettings.tiktokFullAudio,
youtubeDubBrowserLang: saveSettings.youtubeDubBrowserLang,
filenamePattern: saveSettings.filenameStyle,
youtubeVideoCodec: saveSettings.youtubeVideoCodec,
videoQuality: saveSettings.videoQuality,
filenameStyle: saveSettings.filenameStyle,
disableMetadata: saveSettings.disableMetadata,
twitterGif: saveSettings.twitterGif,
tiktokH265: saveSettings.tiktokH265,
}
const response: Optional<CobaltAPIResponse> = await fetch(`${apiURL}/api/json`, {
if (env.DEFAULT_API && !get(settings).processing.seenOverrideWarning) {
let _actions: {
resolve: () => void;
reject: () => void;
};
const promise = new Promise<void>(
(resolve, reject) => (_actions = { resolve, reject })
).catch(() => {
return {}
});
createDialog({
id: "security-api-override",
type: "small",
icon: "warn-red",
title: get(t)("dialog.api.override.title"),
bodyText: get(t)("dialog.api.override.body", { value: env.DEFAULT_API }),
dismissable: false,
buttons: [
{
text: get(t)("dialog.button.cancel"),
main: false,
action: () => {
_actions.reject();
updateSetting({
processing: {
seenOverrideWarning: true,
},
})
},
},
{
text: get(t)("dialog.button.continue"),
color: "red",
main: true,
timeout: 5000,
action: () => {
_actions.resolve();
updateSetting({
processing: {
allowDefaultOverride: true,
seenOverrideWarning: true,
},
})
},
},
],
})
await promise;
}
let api = apiURL;
if (env.DEFAULT_API && get(settings).processing.allowDefaultOverride) {
api = env.DEFAULT_API;
}
const response: Optional<CobaltAPIResponse> = await fetch(api, {
method: "POST",
redirect: "manual",
body: JSON.stringify(request),

View file

@ -9,7 +9,7 @@ import { createDialog } from "$lib/dialogs";
import type { DialogInfo } from "$lib/types/dialog";
export const openSavingDialog = (url: string, body: string | void) => {
let dialogData: DialogInfo = {
const dialogData: DialogInfo = {
type: "saving",
id: "saving",
url

View file

@ -4,6 +4,7 @@ const variables = {
HOST: env.PUBLIC_HOST,
PLAUSIBLE_HOST: env.PUBLIC_PLAUSIBLE_HOST,
PLAUSIBLE_ENABLED: env.PUBLIC_HOST && env.PUBLIC_PLAUSIBLE_HOST,
DEFAULT_API: env.PUBLIC_DEFAULT_API,
}
const donate = {
@ -20,5 +21,7 @@ const donate = {
}
};
export { donate };
const apiURL = "https://api.cobalt.tools";
export { donate, apiURL };
export default variables;

View file

@ -28,7 +28,11 @@ const defaultSettings: CobaltSettings = {
youtubeDubBrowserLang: false,
},
privacy: {
disableAnalytics: false
disableAnalytics: false,
},
processing: {
allowDefaultOverride: false,
seenOverrideWarning: false,
}
}

View file

@ -18,6 +18,7 @@ export type DialogPickerItem = {
type Dialog = {
id: string,
dismissable?: boolean,
};
type SmallDialog = Dialog & {

View file

@ -22,9 +22,14 @@ type CobaltSettingsAdvanced = {
};
type CobaltSettingsPrivacy = {
disableAnalytics: boolean
disableAnalytics: boolean,
};
type CobaltSettingsProcessing = {
allowDefaultOverride: boolean,
seenOverrideWarning: boolean,
}
type CobaltSettingsSave = {
audioFormat: typeof audioFormatOptions[number],
disableMetadata: boolean,
@ -44,7 +49,8 @@ export type CurrentCobaltSettings = {
advanced: CobaltSettingsAdvanced,
appearance: CobaltSettingsAppearance,
save: CobaltSettingsSave,
privacy: CobaltSettingsPrivacy
privacy: CobaltSettingsPrivacy,
processing: CobaltSettingsProcessing,
};
export type CobaltSettings = CurrentCobaltSettings;

View file

@ -17,6 +17,7 @@
import IconSettingsBolt from "@tabler/icons-svelte/IconSettingsBolt.svelte";
import IconBug from "@tabler/icons-svelte/IconBug.svelte";
import IconLock from "@tabler/icons-svelte/IconLock.svelte";
import IconCloudNetwork from "@tabler/icons-svelte/IconCloudNetwork.svelte";
import IconArrowLeft from "@tabler/icons-svelte/IconArrowLeft.svelte";
@ -129,6 +130,13 @@
</SettingsNavSection>
<SettingsNavSection>
<SettingsNavTab
tabName="processing"
tabLink="processing"
iconColor="gray"
>
<IconCloudNetwork />
</SettingsNavTab>
<SettingsNavTab
tabName="advanced"
tabLink="advanced"

View file

@ -0,0 +1,15 @@
<script lang="ts">
import { t } from "$lib/i18n/translations";
import SettingsCategory from "$components/settings/SettingsCategory.svelte";
import SettingsToggle from "$components/buttons/SettingsToggle.svelte";
</script>
<SettingsCategory sectionId="override" title={$t("settings.processing.override")}>
<SettingsToggle
settingContext="processing"
settingId="allowDefaultOverride"
title={$t("settings.processing.override.title")}
description={$t("settings.processing.override.description")}
/>
</SettingsCategory>