mirror of
https://github.com/w-okada/voice-changer.git
synced 2025-02-02 16:23:58 +03:00
・モデルキャッシュ対応
・upkey対応 ・モデル一覧追加
This commit is contained in:
parent
b8640f1f5a
commit
14c73a71d2
@ -13,6 +13,7 @@ import { AppRootProvider, useAppRoot } from "./001_provider/001_AppRootProvider"
|
|||||||
import { useIndexedDB } from "@dannadori/voice-changer-client-js";
|
import { useIndexedDB } from "@dannadori/voice-changer-client-js";
|
||||||
import { Demo } from "./components/demo/010_Demo";
|
import { Demo } from "./components/demo/010_Demo";
|
||||||
import { useMessageBuilder } from "./hooks/useMessageBuilder";
|
import { useMessageBuilder } from "./hooks/useMessageBuilder";
|
||||||
|
import { removeDB as webDBRemove } from "@dannadori/voice-changer-js";
|
||||||
|
|
||||||
library.add(fas, far, fab);
|
library.add(fas, far, fab);
|
||||||
|
|
||||||
@ -57,6 +58,7 @@ const AppStateWrapper = () => {
|
|||||||
|
|
||||||
const onClearCacheClicked = async () => {
|
const onClearCacheClicked = async () => {
|
||||||
await removeDB();
|
await removeDB();
|
||||||
|
await webDBRemove();
|
||||||
location.reload();
|
location.reload();
|
||||||
};
|
};
|
||||||
const onReloadClicked = () => {
|
const onReloadClicked = () => {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ClientState, WebModelSlot } from "@dannadori/voice-changer-client-js";
|
import { ClientState, WebModelSlot } from "@dannadori/voice-changer-client-js";
|
||||||
import { VoiceChangerJSClientConfig, VoiceChangerJSClient, ProgressUpdateType, ProgreeeUpdateCallbcckInfo } from "@dannadori/voice-changer-js";
|
import { VoiceChangerJSClientConfig, VoiceChangerJSClient, ProgressUpdateType, ProgreeeUpdateCallbcckInfo, VoiceChangerType, InputLengthKey } from "@dannadori/voice-changer-js";
|
||||||
import { useEffect, useMemo, useRef, useState } from "react";
|
import { useEffect, useMemo, useRef, useState } from "react";
|
||||||
|
|
||||||
export type UseWebInfoProps = {
|
export type UseWebInfoProps = {
|
||||||
@ -30,9 +30,94 @@ export type WebInfoState = {
|
|||||||
progressLoadVCModel: number;
|
progressLoadVCModel: number;
|
||||||
progressWarmup: number;
|
progressWarmup: number;
|
||||||
webModelslot: WebModelSlot;
|
webModelslot: WebModelSlot;
|
||||||
|
upkey: number;
|
||||||
};
|
};
|
||||||
export type WebInfoStateAndMethod = WebInfoState & {
|
export type WebInfoStateAndMethod = WebInfoState & {
|
||||||
loadVoiceChanagerModel: () => Promise<void>;
|
loadVoiceChanagerModel: () => Promise<void>;
|
||||||
|
setUpkey: (upkey: number) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const ModelSampleRateStr = {
|
||||||
|
"40k": "40k",
|
||||||
|
"32k": "32k",
|
||||||
|
} as const;
|
||||||
|
type ModelSampleRateStr = (typeof ModelSampleRateStr)[keyof typeof ModelSampleRateStr];
|
||||||
|
|
||||||
|
const noF0ModelUrl: { [modelType in VoiceChangerType]: { [inputLength in InputLengthKey]: { [sampleRate in ModelSampleRateStr]: string } } } = {
|
||||||
|
rvcv1: {
|
||||||
|
"24000": {
|
||||||
|
"40k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_40k_nof0_24000.bin",
|
||||||
|
"32k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_32k_nof0_24000.bin",
|
||||||
|
},
|
||||||
|
"16000": {
|
||||||
|
"40k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_40k_nof0_16000.bin",
|
||||||
|
"32k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_32k_nof0_16000.bin",
|
||||||
|
},
|
||||||
|
"12000": {
|
||||||
|
"40k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_40k_nof0_12000.bin",
|
||||||
|
"32k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_32k_nof0_12000.bin",
|
||||||
|
},
|
||||||
|
"8000": {
|
||||||
|
"40k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_40k_nof0_8000.bin",
|
||||||
|
"32k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_32k_nof0_8000.bin",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rvcv2: {
|
||||||
|
"24000": {
|
||||||
|
"40k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_40k_nof0_24000.bin",
|
||||||
|
"32k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_32k_nof0_24000.bin",
|
||||||
|
},
|
||||||
|
"16000": {
|
||||||
|
"40k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_40k_nof0_16000.bin",
|
||||||
|
"32k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_32k_nof0_16000.bin",
|
||||||
|
},
|
||||||
|
"12000": {
|
||||||
|
"40k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_40k_nof0_12000.bin",
|
||||||
|
"32k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_32k_nof0_12000.bin",
|
||||||
|
},
|
||||||
|
"8000": {
|
||||||
|
"40k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_40k_nof0_8000.bin",
|
||||||
|
"32k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_32k_nof0_8000.bin",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const f0ModelUrl: { [modelType in VoiceChangerType]: { [inputLength in InputLengthKey]: { [sampleRate in ModelSampleRateStr]: string } } } = {
|
||||||
|
rvcv1: {
|
||||||
|
"24000": {
|
||||||
|
"40k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_40k_f0_24000.bin",
|
||||||
|
"32k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_32k_f0_24000.bin",
|
||||||
|
},
|
||||||
|
"16000": {
|
||||||
|
"40k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_40k_f0_16000.bin",
|
||||||
|
"32k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_32k_f0_16000.bin",
|
||||||
|
},
|
||||||
|
"12000": {
|
||||||
|
"40k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_40k_f0_12000.bin",
|
||||||
|
"32k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_32k_f0_12000.bin",
|
||||||
|
},
|
||||||
|
"8000": {
|
||||||
|
"40k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_40k_f0_8000.bin",
|
||||||
|
"32k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_32k_f0_8000.bin",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rvcv2: {
|
||||||
|
"24000": {
|
||||||
|
"40k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_40k_f0_24000.bin",
|
||||||
|
"32k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_32k_f0_24000.bin",
|
||||||
|
},
|
||||||
|
"16000": {
|
||||||
|
"40k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_40k_f0_16000.bin",
|
||||||
|
"32k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_32k_f0_16000.bin",
|
||||||
|
},
|
||||||
|
"12000": {
|
||||||
|
"40k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_40k_f0_12000.bin",
|
||||||
|
"32k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_32k_f0_12000.bin",
|
||||||
|
},
|
||||||
|
"8000": {
|
||||||
|
"40k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_40k_f0_8000.bin",
|
||||||
|
"32k": "https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_32k_f0_8000.bin",
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_32k_f0_8000.bin
|
// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_32k_f0_8000.bin
|
||||||
@ -75,29 +160,37 @@ export type WebInfoStateAndMethod = WebInfoState & {
|
|||||||
// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_40k_nof0_16000.bin
|
// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_40k_nof0_16000.bin
|
||||||
// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_40k_nof0_24000.bin
|
// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_40k_nof0_24000.bin
|
||||||
|
|
||||||
const InitialVoiceChangerConfig: VoiceChangerConfig = {
|
|
||||||
config: {
|
|
||||||
voiceChangerType: "rvcv1",
|
|
||||||
inputLength: "24000",
|
|
||||||
baseUrl: window.location.origin,
|
|
||||||
inputSamplingRate: 48000,
|
|
||||||
outputSamplingRate: 48000,
|
|
||||||
},
|
|
||||||
// modelUrl: `${window.location.origin}/models/rvcv1_amitaro_v1_32k_nof0_24000.bin`,
|
|
||||||
modelUrl: `https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_32k_nof0_24000.bin`,
|
|
||||||
progressCallback: null,
|
|
||||||
portrait: `${window.location.origin}/models/amitaro.png`,
|
|
||||||
name: "あみたろ",
|
|
||||||
termOfUse: "https://huggingface.co/wok000/vcclient_model/raw/main/rvc/amitaro_contentvec_256/term_of_use.txt",
|
|
||||||
f0: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useWebInfo = (props: UseWebInfoProps): WebInfoStateAndMethod => {
|
export const useWebInfo = (props: UseWebInfoProps): WebInfoStateAndMethod => {
|
||||||
const [voiceChangerConfig, setVoiceChangerConfig] = useState<VoiceChangerConfig>(InitialVoiceChangerConfig);
|
const voiceChangerType: VoiceChangerType = "rvcv1";
|
||||||
|
const inputLength: InputLengthKey = "24000";
|
||||||
|
const useF0 = false;
|
||||||
|
const sampleRate: ModelSampleRateStr = "40k";
|
||||||
|
let modelUrl;
|
||||||
|
if (useF0) {
|
||||||
|
modelUrl = f0ModelUrl[voiceChangerType][inputLength][sampleRate];
|
||||||
|
} else {
|
||||||
|
modelUrl = noF0ModelUrl[voiceChangerType][inputLength][sampleRate];
|
||||||
|
}
|
||||||
|
const [voiceChangerConfig, setVoiceChangerConfig] = useState<VoiceChangerConfig>({
|
||||||
|
config: {
|
||||||
|
voiceChangerType: voiceChangerType,
|
||||||
|
inputLength: inputLength,
|
||||||
|
baseUrl: window.location.origin,
|
||||||
|
inputSamplingRate: 48000,
|
||||||
|
outputSamplingRate: 48000,
|
||||||
|
},
|
||||||
|
modelUrl: modelUrl,
|
||||||
|
progressCallback: null,
|
||||||
|
portrait: `${window.location.origin}/models/amitaro.png`,
|
||||||
|
name: "あみたろ",
|
||||||
|
termOfUse: "https://huggingface.co/wok000/vcclient_model/raw/main/rvc/amitaro_contentvec_256/term_of_use.txt",
|
||||||
|
f0: false,
|
||||||
|
});
|
||||||
const [webModelLoadingState, setWebModelLoadingState] = useState<WebModelLoadingState>(WebModelLoadingState.none);
|
const [webModelLoadingState, setWebModelLoadingState] = useState<WebModelLoadingState>(WebModelLoadingState.none);
|
||||||
const [progressLoadPreprocess, setProgressLoadPreprocess] = useState<number>(0);
|
const [progressLoadPreprocess, setProgressLoadPreprocess] = useState<number>(0);
|
||||||
const [progressLoadVCModel, setProgressLoadVCModel] = useState<number>(0);
|
const [progressLoadVCModel, setProgressLoadVCModel] = useState<number>(0);
|
||||||
const [progressWarmup, setProgressWarmup] = useState<number>(0);
|
const [progressWarmup, setProgressWarmup] = useState<number>(0);
|
||||||
|
const [upkey, setUpkey] = useState<number>(0);
|
||||||
const voiceChangerJSClient = useRef<VoiceChangerJSClient>();
|
const voiceChangerJSClient = useRef<VoiceChangerJSClient>();
|
||||||
|
|
||||||
const webModelslot: WebModelSlot = useMemo(() => {
|
const webModelslot: WebModelSlot = useMemo(() => {
|
||||||
@ -145,9 +238,7 @@ export const useWebInfo = (props: UseWebInfoProps): WebInfoStateAndMethod => {
|
|||||||
|
|
||||||
// worm up
|
// worm up
|
||||||
setWebModelLoadingState("warmup");
|
setWebModelLoadingState("warmup");
|
||||||
const warmupResult = await voiceChangerJSClient.current.checkResponseTime((progress: number) => {
|
const warmupResult = await voiceChangerJSClient.current.checkResponseTime();
|
||||||
console.log(`Recieve Progress: ${progress}`);
|
|
||||||
});
|
|
||||||
console.log("warmup result", warmupResult);
|
console.log("warmup result", warmupResult);
|
||||||
|
|
||||||
// check time
|
// check time
|
||||||
@ -159,12 +250,21 @@ export const useWebInfo = (props: UseWebInfoProps): WebInfoStateAndMethod => {
|
|||||||
const audioF32 = new Float32Array(data.buffer);
|
const audioF32 = new Float32Array(data.buffer);
|
||||||
const res = await voiceChangerJSClient.current!.convert(audioF32);
|
const res = await voiceChangerJSClient.current!.convert(audioF32);
|
||||||
const audio = new Uint8Array(res[0].buffer);
|
const audio = new Uint8Array(res[0].buffer);
|
||||||
console.log("RESPONSE!", res[1]);
|
if (res[1]) {
|
||||||
|
console.log("RESPONSE!", res[1]);
|
||||||
|
}
|
||||||
return audio;
|
return audio;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
setWebModelLoadingState("ready");
|
setWebModelLoadingState("ready");
|
||||||
};
|
};
|
||||||
|
useEffect(() => {
|
||||||
|
if (!voiceChangerJSClient.current) {
|
||||||
|
console.log("setupkey", voiceChangerJSClient.current);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
voiceChangerJSClient.current.setUpkey(upkey);
|
||||||
|
}, [upkey]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
voiceChangerConfig,
|
voiceChangerConfig,
|
||||||
@ -173,6 +273,8 @@ export const useWebInfo = (props: UseWebInfoProps): WebInfoStateAndMethod => {
|
|||||||
progressLoadVCModel,
|
progressLoadVCModel,
|
||||||
progressWarmup,
|
progressWarmup,
|
||||||
webModelslot,
|
webModelslot,
|
||||||
|
upkey,
|
||||||
loadVoiceChanagerModel,
|
loadVoiceChanagerModel,
|
||||||
|
setUpkey,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -4,6 +4,7 @@ import { useAppRoot } from "../../../001_provider/001_AppRootProvider";
|
|||||||
import { useAppState } from "../../../001_provider/001_AppStateProvider";
|
import { useAppState } from "../../../001_provider/001_AppStateProvider";
|
||||||
import { useIndexedDB } from "@dannadori/voice-changer-client-js";
|
import { useIndexedDB } from "@dannadori/voice-changer-client-js";
|
||||||
import { useMessageBuilder } from "../../../hooks/useMessageBuilder";
|
import { useMessageBuilder } from "../../../hooks/useMessageBuilder";
|
||||||
|
import { removeDB as webDBRemove } from "@dannadori/voice-changer-js";
|
||||||
|
|
||||||
export type HeaderAreaProps = {
|
export type HeaderAreaProps = {
|
||||||
mainTitle: string;
|
mainTitle: string;
|
||||||
@ -119,6 +120,7 @@ export const HeaderArea = (props: HeaderAreaProps) => {
|
|||||||
const onClearSettingClicked = async () => {
|
const onClearSettingClicked = async () => {
|
||||||
await clearSetting();
|
await clearSetting();
|
||||||
await removeItem(INDEXEDDB_KEY_AUDIO_OUTPUT);
|
await removeItem(INDEXEDDB_KEY_AUDIO_OUTPUT);
|
||||||
|
await webDBRemove();
|
||||||
location.reload();
|
location.reload();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,14 +1,20 @@
|
|||||||
import React, { useMemo } from "react";
|
import React, { useMemo } from "react";
|
||||||
import { useAppState } from "../../../001_provider/001_AppStateProvider";
|
import { useAppState } from "../../../001_provider/001_AppStateProvider";
|
||||||
import { useGuiState } from "../001_GuiStateProvider";
|
import { useGuiState } from "../001_GuiStateProvider";
|
||||||
|
import { useAppRoot } from "../../../001_provider/001_AppRootProvider";
|
||||||
|
|
||||||
export type TuningAreaProps = {};
|
export type TuningAreaProps = {};
|
||||||
|
|
||||||
export const TuningArea = (_props: TuningAreaProps) => {
|
export const TuningArea = (_props: TuningAreaProps) => {
|
||||||
const { serverSetting } = useAppState();
|
const { appGuiSettingState } = useAppRoot();
|
||||||
const { beatriceJVSSpeakerId, setBeatriceJVSSpeakerPitch, beatriceJVSSpeakerPitch } = useGuiState();
|
const { serverSetting, webInfoState } = useAppState();
|
||||||
|
const { setBeatriceJVSSpeakerPitch, beatriceJVSSpeakerPitch } = useGuiState();
|
||||||
|
const webEdition = appGuiSettingState.edition.indexOf("web") >= 0;
|
||||||
|
|
||||||
const selected = useMemo(() => {
|
const selected = useMemo(() => {
|
||||||
|
if (webEdition) {
|
||||||
|
return webInfoState.webModelslot;
|
||||||
|
}
|
||||||
if (serverSetting.serverSetting.modelSlotIndex == undefined) {
|
if (serverSetting.serverSetting.modelSlotIndex == undefined) {
|
||||||
return;
|
return;
|
||||||
} else if (serverSetting.serverSetting.modelSlotIndex == "Beatrice-JVS") {
|
} else if (serverSetting.serverSetting.modelSlotIndex == "Beatrice-JVS") {
|
||||||
@ -17,7 +23,7 @@ export const TuningArea = (_props: TuningAreaProps) => {
|
|||||||
} else {
|
} else {
|
||||||
return serverSetting.serverSetting.modelSlots[serverSetting.serverSetting.modelSlotIndex];
|
return serverSetting.serverSetting.modelSlots[serverSetting.serverSetting.modelSlotIndex];
|
||||||
}
|
}
|
||||||
}, [serverSetting.serverSetting.modelSlotIndex, serverSetting.serverSetting.modelSlots]);
|
}, [serverSetting.serverSetting.modelSlotIndex, serverSetting.serverSetting.modelSlots, webEdition]);
|
||||||
|
|
||||||
const tuningArea = useMemo(() => {
|
const tuningArea = useMemo(() => {
|
||||||
if (!selected) {
|
if (!selected) {
|
||||||
@ -57,9 +63,18 @@ export const TuningArea = (_props: TuningAreaProps) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentTuning = serverSetting.serverSetting.tran;
|
let currentTuning;
|
||||||
|
if (webEdition) {
|
||||||
|
currentTuning = webInfoState.upkey;
|
||||||
|
} else {
|
||||||
|
currentTuning = serverSetting.serverSetting.tran;
|
||||||
|
}
|
||||||
const tranValueUpdatedAction = async (val: number) => {
|
const tranValueUpdatedAction = async (val: number) => {
|
||||||
await serverSetting.updateServerSettings({ ...serverSetting.serverSetting, tran: val });
|
if (webEdition) {
|
||||||
|
webInfoState.setUpkey(val);
|
||||||
|
} else {
|
||||||
|
await serverSetting.updateServerSettings({ ...serverSetting.serverSetting, tran: val });
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -85,7 +100,7 @@ export const TuningArea = (_props: TuningAreaProps) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}, [serverSetting.serverSetting, serverSetting.updateServerSettings, selected]);
|
}, [serverSetting.serverSetting, serverSetting.updateServerSettings, selected, webEdition, webInfoState.upkey]);
|
||||||
|
|
||||||
return tuningArea;
|
return tuningArea;
|
||||||
};
|
};
|
||||||
|
@ -137,6 +137,8 @@ export const CharacterArea = (_props: CharacterAreaProps) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
throw new Error("invalid webModelLoadingState");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
|
Loading…
Reference in New Issue
Block a user