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:
parent
168c1bdbbb
commit
aba444ec8b
14 changed files with 134 additions and 23 deletions
|
@ -8,6 +8,7 @@
|
||||||
"button.share": "share",
|
"button.share": "share",
|
||||||
"button.copy": "copy",
|
"button.copy": "copy",
|
||||||
"button.import": "import",
|
"button.import": "import",
|
||||||
|
"button.continue": "continue",
|
||||||
|
|
||||||
"reset.title": "reset all settings?",
|
"reset.title": "reset all settings?",
|
||||||
"reset.body": "are you sure you want to reset all settings? this action is immediate and irreversible.",
|
"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",
|
"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."
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
"page.download": "downloading",
|
"page.download": "downloading",
|
||||||
"page.advanced": "advanced",
|
"page.advanced": "advanced",
|
||||||
"page.debug": "debug information",
|
"page.debug": "debug information",
|
||||||
|
"page.processing": "processing",
|
||||||
|
|
||||||
"section.general": "general",
|
"section.general": "general",
|
||||||
"section.save": "save",
|
"section.save": "save",
|
||||||
|
@ -103,5 +104,9 @@
|
||||||
"advanced.data": "settings data",
|
"advanced.data": "settings data",
|
||||||
"advanced.reset": "reset all settings",
|
"advanced.reset": "reset all settings",
|
||||||
"advanced.import": "import",
|
"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."
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
import DialogBackdropClose from "$components/dialog/DialogBackdropClose.svelte";
|
import DialogBackdropClose from "$components/dialog/DialogBackdropClose.svelte";
|
||||||
|
|
||||||
export let id: string;
|
export let id: string;
|
||||||
|
export let dismissable = true;
|
||||||
|
|
||||||
let dialogParent: HTMLDialogElement;
|
let dialogParent: HTMLDialogElement;
|
||||||
|
|
||||||
|
@ -32,5 +33,5 @@
|
||||||
|
|
||||||
<dialog id="dialog-{id}" bind:this={dialogParent} class:closing class:open>
|
<dialog id="dialog-{id}" bind:this={dialogParent} class:closing class:open>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
<DialogBackdropClose closeFunc={close} />
|
<DialogBackdropClose closeFunc={dismissable ? close : () => {}} />
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
export let id: string;
|
export let id: string;
|
||||||
export let items: Optional<DialogPickerItem[]> = undefined;
|
export let items: Optional<DialogPickerItem[]> = undefined;
|
||||||
export let buttons: Optional<DialogButton[]> = undefined;
|
export let buttons: Optional<DialogButton[]> = undefined;
|
||||||
|
export let dismissable = true;
|
||||||
|
|
||||||
let dialogDescription = "dialog.picker.description.";
|
let dialogDescription = "dialog.picker.description.";
|
||||||
|
|
||||||
|
@ -30,7 +31,7 @@
|
||||||
let close: () => void;
|
let close: () => void;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<DialogContainer {id} bind:close>
|
<DialogContainer {id} {dismissable} bind:close>
|
||||||
<div
|
<div
|
||||||
class="dialog-body picker-dialog"
|
class="dialog-body picker-dialog"
|
||||||
class:three-columns={items && items.length <= 3}
|
class:three-columns={items && items.length <= 3}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
export let id: string;
|
export let id: string;
|
||||||
export let url: string;
|
export let url: string;
|
||||||
export let bodyText: string = "";
|
export let bodyText: string = "";
|
||||||
|
export let dismissable = true;
|
||||||
|
|
||||||
let close: () => void;
|
let close: () => void;
|
||||||
|
|
||||||
|
@ -31,7 +32,7 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<DialogContainer {id} bind:close>
|
<DialogContainer {id} {dismissable} bind:close>
|
||||||
<div class="dialog-body popup-body">
|
<div class="dialog-body popup-body">
|
||||||
<div class="meowbalt-container">
|
<div class="meowbalt-container">
|
||||||
<Meowbalt emotion="question" />
|
<Meowbalt emotion="question" />
|
||||||
|
|
|
@ -17,11 +17,12 @@
|
||||||
export let bodyText = "";
|
export let bodyText = "";
|
||||||
export let bodySubText = "";
|
export let bodySubText = "";
|
||||||
export let buttons: Optional<DialogButton[]> = undefined;
|
export let buttons: Optional<DialogButton[]> = undefined;
|
||||||
|
export let dismissable = true;
|
||||||
|
|
||||||
let close: () => void;
|
let close: () => void;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<DialogContainer {id} bind:close>
|
<DialogContainer {id} {dismissable} bind:close>
|
||||||
<div class="dialog-body small-dialog" class:meowbalt-visible={meowbalt}>
|
<div class="dialog-body small-dialog" class:meowbalt-visible={meowbalt}>
|
||||||
{#if meowbalt}
|
{#if meowbalt}
|
||||||
<div class="meowbalt-container">
|
<div class="meowbalt-container">
|
||||||
|
|
|
@ -1,33 +1,94 @@
|
||||||
import { get } from "svelte/store";
|
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 { CobaltAPIResponse } from "$lib/types/api";
|
||||||
import type { Optional } from "$lib/types/generic";
|
import type { Optional } from "$lib/types/generic";
|
||||||
|
|
||||||
const apiURL = "https://api.cobalt.tools";
|
|
||||||
|
|
||||||
const request = async (url: string) => {
|
const request = async (url: string) => {
|
||||||
const saveSettings = get(settings).save;
|
const saveSettings = get(settings).save;
|
||||||
|
|
||||||
const request = {
|
const request = {
|
||||||
url,
|
url,
|
||||||
|
|
||||||
isAudioOnly: saveSettings.downloadMode === "audio",
|
downloadMode: saveSettings.downloadMode,
|
||||||
isAudioMuted: saveSettings.downloadMode === "mute",
|
|
||||||
aFormat: saveSettings.audioFormat,
|
|
||||||
isTTFullAudio: saveSettings.tiktokFullAudio,
|
|
||||||
dubLang: saveSettings.youtubeDubBrowserLang,
|
|
||||||
|
|
||||||
vCodec: saveSettings.youtubeVideoCodec,
|
audioFormat: saveSettings.audioFormat,
|
||||||
vQuality: saveSettings.videoQuality,
|
tiktokFullAudio: saveSettings.tiktokFullAudio,
|
||||||
|
youtubeDubBrowserLang: saveSettings.youtubeDubBrowserLang,
|
||||||
|
|
||||||
filenamePattern: saveSettings.filenameStyle,
|
youtubeVideoCodec: saveSettings.youtubeVideoCodec,
|
||||||
|
videoQuality: saveSettings.videoQuality,
|
||||||
|
|
||||||
|
filenameStyle: saveSettings.filenameStyle,
|
||||||
disableMetadata: saveSettings.disableMetadata,
|
disableMetadata: saveSettings.disableMetadata,
|
||||||
|
|
||||||
twitterGif: saveSettings.twitterGif,
|
twitterGif: saveSettings.twitterGif,
|
||||||
tiktokH265: saveSettings.tiktokH265,
|
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",
|
method: "POST",
|
||||||
redirect: "manual",
|
redirect: "manual",
|
||||||
body: JSON.stringify(request),
|
body: JSON.stringify(request),
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { createDialog } from "$lib/dialogs";
|
||||||
import type { DialogInfo } from "$lib/types/dialog";
|
import type { DialogInfo } from "$lib/types/dialog";
|
||||||
|
|
||||||
export const openSavingDialog = (url: string, body: string | void) => {
|
export const openSavingDialog = (url: string, body: string | void) => {
|
||||||
let dialogData: DialogInfo = {
|
const dialogData: DialogInfo = {
|
||||||
type: "saving",
|
type: "saving",
|
||||||
id: "saving",
|
id: "saving",
|
||||||
url
|
url
|
||||||
|
|
|
@ -4,6 +4,7 @@ const variables = {
|
||||||
HOST: env.PUBLIC_HOST,
|
HOST: env.PUBLIC_HOST,
|
||||||
PLAUSIBLE_HOST: env.PUBLIC_PLAUSIBLE_HOST,
|
PLAUSIBLE_HOST: env.PUBLIC_PLAUSIBLE_HOST,
|
||||||
PLAUSIBLE_ENABLED: env.PUBLIC_HOST && env.PUBLIC_PLAUSIBLE_HOST,
|
PLAUSIBLE_ENABLED: env.PUBLIC_HOST && env.PUBLIC_PLAUSIBLE_HOST,
|
||||||
|
DEFAULT_API: env.PUBLIC_DEFAULT_API,
|
||||||
}
|
}
|
||||||
|
|
||||||
const donate = {
|
const donate = {
|
||||||
|
@ -20,5 +21,7 @@ const donate = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export { donate };
|
const apiURL = "https://api.cobalt.tools";
|
||||||
|
|
||||||
|
export { donate, apiURL };
|
||||||
export default variables;
|
export default variables;
|
||||||
|
|
|
@ -28,7 +28,11 @@ const defaultSettings: CobaltSettings = {
|
||||||
youtubeDubBrowserLang: false,
|
youtubeDubBrowserLang: false,
|
||||||
},
|
},
|
||||||
privacy: {
|
privacy: {
|
||||||
disableAnalytics: false
|
disableAnalytics: false,
|
||||||
|
},
|
||||||
|
processing: {
|
||||||
|
allowDefaultOverride: false,
|
||||||
|
seenOverrideWarning: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ export type DialogPickerItem = {
|
||||||
|
|
||||||
type Dialog = {
|
type Dialog = {
|
||||||
id: string,
|
id: string,
|
||||||
|
dismissable?: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
type SmallDialog = Dialog & {
|
type SmallDialog = Dialog & {
|
||||||
|
|
|
@ -22,9 +22,14 @@ type CobaltSettingsAdvanced = {
|
||||||
};
|
};
|
||||||
|
|
||||||
type CobaltSettingsPrivacy = {
|
type CobaltSettingsPrivacy = {
|
||||||
disableAnalytics: boolean
|
disableAnalytics: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type CobaltSettingsProcessing = {
|
||||||
|
allowDefaultOverride: boolean,
|
||||||
|
seenOverrideWarning: boolean,
|
||||||
|
}
|
||||||
|
|
||||||
type CobaltSettingsSave = {
|
type CobaltSettingsSave = {
|
||||||
audioFormat: typeof audioFormatOptions[number],
|
audioFormat: typeof audioFormatOptions[number],
|
||||||
disableMetadata: boolean,
|
disableMetadata: boolean,
|
||||||
|
@ -44,7 +49,8 @@ export type CurrentCobaltSettings = {
|
||||||
advanced: CobaltSettingsAdvanced,
|
advanced: CobaltSettingsAdvanced,
|
||||||
appearance: CobaltSettingsAppearance,
|
appearance: CobaltSettingsAppearance,
|
||||||
save: CobaltSettingsSave,
|
save: CobaltSettingsSave,
|
||||||
privacy: CobaltSettingsPrivacy
|
privacy: CobaltSettingsPrivacy,
|
||||||
|
processing: CobaltSettingsProcessing,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type CobaltSettings = CurrentCobaltSettings;
|
export type CobaltSettings = CurrentCobaltSettings;
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
import IconSettingsBolt from "@tabler/icons-svelte/IconSettingsBolt.svelte";
|
import IconSettingsBolt from "@tabler/icons-svelte/IconSettingsBolt.svelte";
|
||||||
import IconBug from "@tabler/icons-svelte/IconBug.svelte";
|
import IconBug from "@tabler/icons-svelte/IconBug.svelte";
|
||||||
import IconLock from "@tabler/icons-svelte/IconLock.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";
|
import IconArrowLeft from "@tabler/icons-svelte/IconArrowLeft.svelte";
|
||||||
|
|
||||||
|
@ -129,6 +130,13 @@
|
||||||
</SettingsNavSection>
|
</SettingsNavSection>
|
||||||
|
|
||||||
<SettingsNavSection>
|
<SettingsNavSection>
|
||||||
|
<SettingsNavTab
|
||||||
|
tabName="processing"
|
||||||
|
tabLink="processing"
|
||||||
|
iconColor="gray"
|
||||||
|
>
|
||||||
|
<IconCloudNetwork />
|
||||||
|
</SettingsNavTab>
|
||||||
<SettingsNavTab
|
<SettingsNavTab
|
||||||
tabName="advanced"
|
tabName="advanced"
|
||||||
tabLink="advanced"
|
tabLink="advanced"
|
||||||
|
|
15
web/src/routes/settings/processing/+page.svelte
Normal file
15
web/src/routes/settings/processing/+page.svelte
Normal 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>
|
Loading…
Reference in a new issue