- Added assets folder to .gitignore

- disabled audio extension by default
        - turned get request into post
        - avoid background that are data url
        - changed UI name to Dynamic Audio
        - Changed Assets/Audio ui load to use $.get
        - added assets json url as field in ui, with connect button require confirm from popup.
This commit is contained in:
Tony Ribeiro 2023-08-23 18:51:41 +02:00
parent ecb4436f07
commit f23115f6b3
7 changed files with 196 additions and 136 deletions

1
.gitignore vendored
View File

@ -32,3 +32,4 @@ public/movingUI/
public/QuickReplies/
content.log
cloudflared.exe
public/assets/

View File

@ -4,7 +4,7 @@ TODO:
*/
//const DEBUG_TONY_SAMA_FORK_MODE = false
import { saveSettingsDebounced } from "../../../script.js";
import { saveSettingsDebounced, getRequestHeaders, callPopup } from "../../../script.js";
import { getContext, getApiUrl, extension_settings, doExtrasFetch, ModuleWorkerWrapper, modules } from "../../extensions.js";
export { MODULE_NAME };
@ -13,6 +13,9 @@ const DEBUG_PREFIX = "<Assets module> ";
const UPDATE_INTERVAL = 1000;
let ASSETS_JSON_URL = "https://raw.githubusercontent.com/SillyTavern/SillyTavern-Content/main/index.json"
const extensionName = "assets";
const extensionFolderPath = `scripts/extensions/${extensionName}`;
// DBG
//if (DEBUG_TONY_SAMA_FORK_MODE)
// ASSETS_JSON_URL = "https://raw.githubusercontent.com/Tony-sama/SillyTavern-Content/main/index.json"
@ -26,11 +29,15 @@ let currentAssets = {};
const defaultSettings = {
}
function loadSettings() {
function downloadAssetsList(url) {
updateCurrentAssets().then(function(){
fetch(ASSETS_JSON_URL)
fetch(url)
.then(response => response.json())
.then(json => {
availableAssets = {};
$("#assets_menu").empty();
console.debug(DEBUG_PREFIX,"Received assets dictionary", json);
for(const i of json){
@ -80,36 +87,16 @@ function loadSettings() {
}
assetTypeMenu.appendTo("#assets_menu");
}
$("#assets_menu").show();
})
.catch((error) => {
console.error(error);
toastr.error("Problem with assets URL",DEBUG_PREFIX+"Cannot get assets list")
});
});
}
$(document).ready(function () {
function addExtensionControls() {
const settingsHtml = `
<div id="audio_settings">
<div class="inline-drawer">
<div class="inline-drawer-toggle inline-drawer-header">
<b>Assets</b>
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
</div>
<div class="inline-drawer-content" id="assets_menu">
</div>
</div>
</div>
`;
$('#extensions_settings').append(settingsHtml);
}
addExtensionControls(); // No init dependencies
loadSettings(); // Depends on Extension Controls
//const wrapper = new ModuleWorkerWrapper(moduleWorker);
//setInterval(wrapper.update.bind(wrapper), UPDATE_INTERVAL);
//moduleWorker();
})
function isAssetInstalled(assetType,filename) {
for(const i of currentAssets[assetType]){
//console.debug(DEBUG_PREFIX,i,filename)
@ -124,7 +111,10 @@ async function installAsset(url, assetType, filename) {
console.debug(DEBUG_PREFIX,"Downloading ",url);
const save_path = "public/assets/"+assetType+"/"+filename;
try {
const result = await fetch(`/asset_download?url=${url}&save_path=${save_path}`);
const result = await fetch(`/asset_download?url=${url}&save_path=${save_path}`, {
method: 'POST',
headers: getRequestHeaders(),
});
let assets = result.ok ? (await result.json()) : [];
return assets;
}
@ -141,7 +131,10 @@ async function installAsset(url, assetType, filename) {
async function updateCurrentAssets() {
console.debug(DEBUG_PREFIX,"Checking installed assets...")
try {
const result = await fetch(`/get_assets`);
const result = await fetch(`/get_assets`, {
method: 'POST',
headers: getRequestHeaders(),
});
currentAssets = result.ok ? (await result.json()) : {};
}
catch (err) {
@ -152,5 +145,33 @@ async function updateCurrentAssets() {
//#############################//
// Module Worker //
// Extension load //
//#############################//
// This function is called when the extension is loaded
jQuery(async () => {
// This is an example of loading HTML from a file
const windowHtml = $(await $.get(`${extensionFolderPath}/window.html`));
const assetsJsonUrl = windowHtml.find('#assets_json_url_field');
assetsJsonUrl.val(ASSETS_JSON_URL);
const connectButton = windowHtml.find('#assets_connect_button');
connectButton.on("click", async function(){
const confirmation = await callPopup(`Are you sure you want to connect to '${assetsJsonUrl.val()}'?`, 'confirm')
if (confirmation) {
try {
console.debug(DEBUG_PREFIX,"Confimation, loading assets...");
downloadAssetsList(assetsJsonUrl.val());
} catch (error) {
console.error('Error:', error);
toastr.error(`Cannot get assets list from ${assetsJsonUrl.val()}`);
}
}
else {
console.debug(DEBUG_PREFIX,"Connection refused by user");
}
});
$('#extensions_settings').append(windowHtml);
});

View File

@ -1,3 +1,8 @@
.assets-connect-div {
display: flex;
flex-direction: row;
}
.assets-list-div i {
display: flex;
flex-direction: row;

View File

@ -0,0 +1,18 @@
<div id="assets_ui">
<div class="inline-drawer">
<div class="inline-drawer-toggle inline-drawer-header">
<b>Assets</b>
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
</div>
<div class="inline-drawer-content">
<div class="assets-connect-div">
<label for="assets_json_url_field">Assets URL
<input id="assets_json_url_field" class="flex1 heightFitContent text_pole widthNatural">
</label>
<input id="assets_connect_button" class="menu_button" value="Connect">
</div>
<div class="inline-drawer-content" id="assets_menu">
</div>
</div>
</div>
</div>

View File

@ -9,10 +9,14 @@ Ideas:
- https://codepen.io/xrocker/pen/abdKVGy
*/
import { saveSettingsDebounced } from "../../../script.js";
import { saveSettingsDebounced, getRequestHeaders } from "../../../script.js";
import { getContext, extension_settings, ModuleWorkerWrapper } from "../../extensions.js";
import {isDataURL} from "../../utils.js";
export { MODULE_NAME };
const extensionName = "audio";
const extensionFolderPath = `scripts/extensions/${extensionName}`;
const MODULE_NAME = 'Audio';
const DEBUG_PREFIX = "<Audio module> ";
const UPDATE_INTERVAL = 1000;
@ -70,7 +74,7 @@ let cooldownBGM = 0;
//#############################//
const defaultSettings = {
enabled: true,
enabled: false,
bgm_muted: false,
ambient_muted: false,
bgm_volume: 50,
@ -163,96 +167,6 @@ async function onBGMCooldownInput() {
console.debug(DEBUG_PREFIX,"UPDATED BGM cooldown to",extension_settings.audio.bgm_cooldown);
}
$(document).ready(function () {
function addExtensionControls() {
const settingsHtml = `
<div id="audio_settings">
<div class="inline-drawer">
<div class="inline-drawer-toggle inline-drawer-header">
<b>Audio</b>
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
</div>
<div class="inline-drawer-content">
<div>
<label class="checkbox_label" for="audio_enabled">
<input type="checkbox" id="audio_enabled" name="audio_enabled">
<small>Enabled</small>
</label>
<div id="audio_debug_div">
<label class="checkbox_label" for="audio_debug">
<input type="checkbox" id="audio_debug" name="audio_debug">
<small>Debug</small>
</label>
</div>
</div>
<div>
<div>
<label for="audio_character_bgm_volume_slider">Music <span id="audio_character_bgm_volume"></span></label>
<div class="mixer-div">
<div id="audio_character_bgm_mute" class="menu_button audio-mute-button">
<i class="fa-solid fa-volume-high fa-lg" id="audio_character_bgm_mute_icon"></i>
</div>
<input type="range" class ="slider" id ="audio_character_bgm_volume_slider" value = "0" maxlength ="100">
</div>
<audio id="audio_character_bgm" controls src="">
</div>
<div>
<label for="audio_ambient_volume_slider">Ambient <span id="audio_ambient_volume"></span></label>
<div class="mixer-div">
<div id="audio_character_ambient_mute" class="menu_button audio-mute-button">
<i class="fa-solid fa-volume-high fa-lg" id="audio_ambient_mute_icon"></i>
</div>
<input type="range" class ="slider" id ="audio_ambient_volume_slider" value = "0" maxlength ="100">
</div>
<audio id="audio_ambient" controls src="">
</div>
<div>
<label for="audio_bgm_cooldown">Music update cooldown (in seconds)</label>
<input id="audio_bgm_cooldown" class="text_pole wide30p">
</div>
</div>
</div>
</div>
</div>
`;
$('#extensions_settings').append(settingsHtml);
}
addExtensionControls(); // No init dependencies
loadSettings(); // Depends on Extension Controls
$("#audio_character_bgm").attr("loop",true);
$("#audio_ambient").attr("loop",true);
$("#audio_character_bgm").hide();
$("#audio_ambient").hide();
$("#audio_character_bgm_mute").on("click",onBGMMuteClick);
$("#audio_character_ambient_mute").on("click",onAmbientMuteClick);
$("#audio_enabled").on("click", onEnabledClick);
$("#audio_character_bgm_volume_slider").on("input", onBGMVolumeChange);
$("#audio_ambient_volume_slider").on("input", onAmbientVolumeChange);
$("#audio_bgm_cooldown").on("input", onBGMCooldownInput);
// DBG
$("#audio_debug").on("click",function() {
if($("#audio_debug").is(':checked')) {
$("#audio_character_bgm").show();
$("#audio_ambient").show();
}
else {
$("#audio_character_bgm").hide();
$("#audio_ambient").hide();
}
});
//
const wrapper = new ModuleWorkerWrapper(moduleWorker);
setInterval(wrapper.update.bind(wrapper), UPDATE_INTERVAL);
moduleWorker();
})
//#############################//
// API Calls //
//#############################//
@ -261,7 +175,10 @@ async function getAssetsList(type) {
console.debug(DEBUG_PREFIX, "getting assets of type",type);
try {
const result = await fetch(`/get_assets`);
const result = await fetch(`/get_assets`, {
method: 'POST',
headers: getRequestHeaders(),
});
const assets = result.ok ? (await result.json()) : {type:[]};
console.debug(DEBUG_PREFIX, "Found assets:",assets);
return assets[type];
@ -276,7 +193,10 @@ async function getCharacterBgmList(name) {
console.debug(DEBUG_PREFIX, "getting bgm list for", name);
try {
const result = await fetch(`/get_character_assets_list?name=${encodeURIComponent(name)}&assetsFolder=${CHARACTER_BGM_FOLDER}`);
const result = await fetch(`/get_character_assets_list?name=${encodeURIComponent(name)}&assetsFolder=${CHARACTER_BGM_FOLDER}`, {
method: 'POST',
headers: getRequestHeaders(),
});
let musics = result.ok ? (await result.json()) : [];
return musics;
}
@ -327,15 +247,18 @@ async function moduleWorker() {
if(custom_background !== undefined)
newBackground = custom_background
newBackground = newBackground.substring(newBackground.lastIndexOf("/")+1).replace(/\.[^/.]+$/, "").replaceAll("%20","-").replaceAll(" ","-"); // remove path and spaces
if (!isDataURL(newBackground))
{
newBackground = newBackground.substring(newBackground.lastIndexOf("/")+1).replace(/\.[^/.]+$/, "").replaceAll("%20","-").replaceAll(" ","-"); // remove path and spaces
//console.debug(DEBUG_PREFIX,"Current backgroung:",newBackground);
//console.debug(DEBUG_PREFIX,"Current backgroung:",newBackground);
if (currentBackground !== newBackground) {
currentBackground = newBackground;
if (currentBackground !== newBackground) {
currentBackground = newBackground;
console.debug(DEBUG_PREFIX,"Changing ambient audio for",currentBackground);
updateAmbient();
console.debug(DEBUG_PREFIX,"Changing ambient audio for",currentBackground);
updateAmbient();
}
}
const context = getContext();
@ -578,4 +501,48 @@ async function updateAmbient() {
audio.volume = extension_settings.audio.ambient_volume * 0.01;
audio.animate({volume: extension_settings.audio.ambient_volume * 0.01}, 2000);
});
}
}
//#############################//
// Extension load //
//#############################//
// This function is called when the extension is loaded
jQuery(async () => {
// This is an example of loading HTML from a file
const windowHtml = $(await $.get(`${extensionFolderPath}/window.html`));
$('#extensions_settings').append(windowHtml);
loadSettings();
$("#audio_character_bgm").attr("loop",true);
$("#audio_ambient").attr("loop",true);
$("#audio_character_bgm").hide();
$("#audio_ambient").hide();
$("#audio_character_bgm_mute").on("click",onBGMMuteClick);
$("#audio_character_ambient_mute").on("click",onAmbientMuteClick);
$("#audio_enabled").on("click", onEnabledClick);
$("#audio_character_bgm_volume_slider").on("input", onBGMVolumeChange);
$("#audio_ambient_volume_slider").on("input", onAmbientVolumeChange);
$("#audio_bgm_cooldown").on("input", onBGMCooldownInput);
// DBG
$("#audio_debug").on("click",function() {
if($("#audio_debug").is(':checked')) {
$("#audio_character_bgm").show();
$("#audio_ambient").show();
}
else {
$("#audio_character_bgm").hide();
$("#audio_ambient").hide();
}
});
//
const wrapper = new ModuleWorkerWrapper(moduleWorker);
setInterval(wrapper.update.bind(wrapper), UPDATE_INTERVAL);
moduleWorker();
});

View File

@ -0,0 +1,48 @@
<div id="audio_settings">
<div class="inline-drawer">
<div class="inline-drawer-toggle inline-drawer-header">
<b>Dynamic Audio</b>
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
</div>
<div class="inline-drawer-content">
<div>
<label class="checkbox_label" for="audio_enabled">
<input type="checkbox" id="audio_enabled" name="audio_enabled">
<small>Enabled</small>
</label>
<div id="audio_debug_div">
<label class="checkbox_label" for="audio_debug">
<input type="checkbox" id="audio_debug" name="audio_debug">
<small>Debug</small>
</label>
</div>
</div>
<div>
<div>
<label for="audio_character_bgm_volume_slider">Music <span id="audio_character_bgm_volume"></span></label>
<div class="mixer-div">
<div id="audio_character_bgm_mute" class="menu_button audio-mute-button">
<i class="fa-solid fa-volume-high fa-lg" id="audio_character_bgm_mute_icon"></i>
</div>
<input type="range" class ="slider" id ="audio_character_bgm_volume_slider" value = "0" maxlength ="100">
</div>
<audio id="audio_character_bgm" controls src="">
</div>
<div>
<label for="audio_ambient_volume_slider">Ambient <span id="audio_ambient_volume"></span></label>
<div class="mixer-div">
<div id="audio_character_ambient_mute" class="menu_button audio-mute-button">
<i class="fa-solid fa-volume-high fa-lg" id="audio_ambient_mute_icon"></i>
</div>
<input type="range" class ="slider" id ="audio_ambient_volume_slider" value = "0" maxlength ="100">
</div>
<audio id="audio_ambient" controls src="">
</div>
<div>
<label for="audio_bgm_cooldown">Music update cooldown (in seconds)</label>
<input id="audio_bgm_cooldown" class="text_pole wide30p">
</div>
</div>
</div>
</div>
</div>

View File

@ -5010,7 +5010,7 @@ app.post('/delete_extension', jsonParser, async (request, response) => {
*
* @returns {void}
*/
app.get('/get_assets', jsonParser, function (request, response) {
app.post('/get_assets', jsonParser, async (request, response) => {
const folderPath = path.join(directories.assets);
let output = {}
//console.info("Checking files into",folderPath);
@ -5050,7 +5050,7 @@ app.get('/get_assets', jsonParser, function (request, response) {
*
* @returns {void}
*/
app.get('/asset_download', jsonParser, function (request, response) {
app.post('/asset_download', jsonParser, async (request, response) => {
const fs = require('fs');
const { Readable } = require('stream');
const { finished } = require('stream/promises');
@ -5083,7 +5083,7 @@ app.get('/asset_download', jsonParser, function (request, response) {
*
* @returns {void}
*/
app.get('/get_character_assets_list', jsonParser, function (request, response) {
app.post('/get_character_assets_list', jsonParser, async (request, response) => {
const name = request.query.name;
const assetsFolder = request.query.assetsFolder
const folderPath = path.join(directories.characters, name, assetsFolder);