[Refactor] Organize files.
This commit is contained in:
85
src-ui/app/others/splash_component/SplashComponent.jsx
Normal file
85
src-ui/app/others/splash_component/SplashComponent.jsx
Normal file
@@ -0,0 +1,85 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import styles from "./SplashComponent.module.scss";
|
||||
import { StartUpProgressContainer } from "./start_up_progress_container/StartUpProgressContainer";
|
||||
import { DownloadModelsContainer } from "./download_models_container/DownloadModelsContainer";
|
||||
import MegaphoneSvg from "@images/megaphone.svg?react";
|
||||
import XMarkSvg from "@images/cancel.svg?react";
|
||||
import { useWindow } from "@logics_common";
|
||||
import clsx from "clsx";
|
||||
|
||||
export const SplashComponent = () => {
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<StartUpProgressContainer />
|
||||
<DownloadModelsContainer />
|
||||
<AnnouncementsContainer />
|
||||
<CloseButtonContainer />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const SHOW_MEGAPHONE_TIME = 500;
|
||||
|
||||
const AnnouncementsContainer = () => {
|
||||
const labels = ["Check the Latest Status", "最新の状況を確認"];
|
||||
const [is_shown, setIsShown] = useState(0);
|
||||
const [currentLabelIndex, setCurrentLabelIndex] = useState(0);
|
||||
const [is_labels_active, setIsLabelsActive] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const showTimeout = setTimeout(() => {
|
||||
setIsShown(true);
|
||||
}, SHOW_MEGAPHONE_TIME);
|
||||
|
||||
const labelsTimeout = setTimeout(() => {
|
||||
setIsLabelsActive(true);
|
||||
}, SHOW_MEGAPHONE_TIME + 15000);
|
||||
|
||||
let labelInterval;
|
||||
if (is_labels_active) {
|
||||
labelInterval = setInterval(() => {
|
||||
setCurrentLabelIndex((prevIndex) => (prevIndex + 1) % labels.length);
|
||||
}, 4000);
|
||||
}
|
||||
|
||||
return () => {
|
||||
clearTimeout(showTimeout);
|
||||
clearTimeout(labelsTimeout);
|
||||
if (labelInterval) clearInterval(labelInterval);
|
||||
};
|
||||
}, [is_labels_active, labels.length]);
|
||||
|
||||
|
||||
return (
|
||||
<a
|
||||
className={clsx(styles.announcements_button_wrapper, {
|
||||
[styles.is_shown]: is_shown,
|
||||
[styles.is_labels_active]: is_labels_active,
|
||||
})}
|
||||
href="https://docs.google.com/spreadsheets/d/1_L5i-1U6PB1dnaPPTE_5uKMfqOpkLziPyRkiMLi4mqU/edit?usp=sharing"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<button className={styles.announcements_button}>
|
||||
<MegaphoneSvg className={styles.announcements_link_svg} />
|
||||
<p className={styles.announcements_label}>
|
||||
{labels[currentLabelIndex]}
|
||||
</p>
|
||||
</button>
|
||||
</a>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
// Duplicated
|
||||
const CloseButtonContainer = () => {
|
||||
const { asyncCloseApp } = useWindow();
|
||||
|
||||
return (
|
||||
<button className={styles.close_button_wrapper} onClick={asyncCloseApp}>
|
||||
<div className={styles.close_button}>
|
||||
<XMarkSvg className={styles.x_mark_svg}/>
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
104
src-ui/app/others/splash_component/SplashComponent.module.scss
Normal file
104
src-ui/app/others/splash_component/SplashComponent.module.scss
Normal file
@@ -0,0 +1,104 @@
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.announcements_button_wrapper {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease, border 0.3s ease;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
&.is_shown {
|
||||
opacity: 1;
|
||||
}
|
||||
&.is_labels_active {
|
||||
& .announcements_label {
|
||||
display: block;
|
||||
animation: appear .3s ease;
|
||||
}
|
||||
& .announcements_link_svg {
|
||||
color: var(--dark_200_color);
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
background-color: var(--dark_825_color);
|
||||
& .announcements_label {
|
||||
color: var(--dark_200_color);
|
||||
}
|
||||
& .announcements_link_svg {
|
||||
color: var(--primary_300_color);
|
||||
}
|
||||
}
|
||||
&:active {
|
||||
background-color: var(--dark_850_color);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes appear {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.announcements_button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
transition: all 0.1s ease;
|
||||
}
|
||||
|
||||
.announcements_label {
|
||||
font-size: 12px;
|
||||
color: var(--dark_400_color);
|
||||
display: none;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
.announcements_link_svg {
|
||||
width: 20px;
|
||||
color: var(--dark_600_color);
|
||||
}
|
||||
|
||||
|
||||
// Duplicated
|
||||
.close_button_wrapper {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 100%;
|
||||
transform: translate(-50%, -50%) rotate(45deg);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: end;
|
||||
width: 68px;
|
||||
aspect-ratio: 1 / 1;
|
||||
&:hover {
|
||||
background-color: var(--error_bc_color);
|
||||
& .x_mark_svg {
|
||||
color: var(--dark_200_color);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
}
|
||||
&:active {
|
||||
background-color: var(--error_bc_active_color);
|
||||
}
|
||||
transition: all 0.1s ease;
|
||||
}
|
||||
|
||||
.close_button {
|
||||
// width: 100%;
|
||||
// height: 100%;
|
||||
}
|
||||
|
||||
.x_mark_svg {
|
||||
width: 24px;
|
||||
transform: rotate(-45deg);
|
||||
color: var(--dark_700_color);
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
import styles from "./DownloadModelsContainer.module.scss";
|
||||
import vrct_logo_for_dark_mode from "@images/vrct_logo_for_dark_mode.png";
|
||||
import vrct_now_downloading from "@images/VRCT_now_downloading.png";
|
||||
|
||||
import {
|
||||
useCTranslate2WeightTypeStatus,
|
||||
useWhisperWeightTypeStatus,
|
||||
} from "@logics_configs";
|
||||
|
||||
export const DownloadModelsContainer = () => {
|
||||
const { currentCTranslate2WeightTypeStatus } = useCTranslate2WeightTypeStatus();
|
||||
const { currentWhisperWeightTypeStatus } = useWhisperWeightTypeStatus();
|
||||
|
||||
const c_translate_2 = currentCTranslate2WeightTypeStatus.data.find(d => d.id === "small");
|
||||
const whisper = currentWhisperWeightTypeStatus.data.find(d => d.id === "base");
|
||||
|
||||
if (c_translate_2.progress === null && whisper.progress === null) return null;
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.progress_container}>
|
||||
<DownloadModelsProgress progress={c_translate_2.progress} type_label="CTranslate2 Model"/>
|
||||
<DownloadModelsProgress progress={whisper.progress} type_label="Whisper Model"/>
|
||||
</div>
|
||||
<div className={styles.labels_wrapper}>
|
||||
<img src={vrct_logo_for_dark_mode} className={styles.logo_img}/>
|
||||
<img src={vrct_now_downloading} className={styles.vrct_now_downloading_img}/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
const DownloadModelsProgress = (props) => {
|
||||
if (props.progress === null) return null;
|
||||
const circular_progress = Math.floor(props.progress / 5) * 5;
|
||||
|
||||
const progress_color = generateGradientColor({
|
||||
value: circular_progress,
|
||||
colorStart: [242, 242, 242], // #f2f2f2
|
||||
colorEnd: [72, 164, 149], // #48a495
|
||||
});
|
||||
|
||||
return(
|
||||
<div className={styles.progress_bar_container}>
|
||||
<div className={styles.progress_bar_wrapper}>
|
||||
<div
|
||||
className={styles.progress_bar}
|
||||
style={{
|
||||
width: `${props.progress}%`,
|
||||
backgroundColor: progress_color,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<p className={styles.progress_label}>{`${props.type_label}: ${Math.round(props.progress)}%`}</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
const generateGradientColor = ({ value, colorStart, colorEnd }) => {
|
||||
const normalizedValue = Math.max(0, Math.min(100, value)) / 100;
|
||||
const interpolatedColor = colorStart.map((start, i) => {
|
||||
const end = colorEnd[i];
|
||||
return Math.round(start + (end - start) * normalizedValue);
|
||||
});
|
||||
const hexColor = `#${interpolatedColor.map(val => val.toString(16).padStart(2, '0')).join('')}`;
|
||||
return hexColor;
|
||||
};
|
||||
@@ -0,0 +1,64 @@
|
||||
.container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
overflow: hidden;
|
||||
background-color: var(--dark_888_color);
|
||||
}
|
||||
|
||||
.progress_container {
|
||||
position: absolute;
|
||||
top: 77%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 90%;
|
||||
gap: 6px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.labels_wrapper {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.logo_img {
|
||||
position: absolute;
|
||||
top: 42%;
|
||||
left: 50%;
|
||||
width: 280px;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
.vrct_now_downloading_img {
|
||||
position: absolute;
|
||||
bottom: 2px;
|
||||
right: 10px;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.progress_bar_container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.progress_bar_wrapper {
|
||||
background-color: var(--dark_800_color);
|
||||
}
|
||||
|
||||
$progress_ease: cubic-bezier(0, 1, 0.75, 1);
|
||||
// Duplicated
|
||||
.progress_bar {
|
||||
height: 8px;
|
||||
transition: width 0.3s $progress_ease;
|
||||
}
|
||||
|
||||
.progress_label {
|
||||
text-align: end;
|
||||
font-size: 12px;
|
||||
color: var(--dark_400_color);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import clsx from "clsx";
|
||||
import styles from "./StartUpProgressContainer.module.scss";
|
||||
|
||||
import { useInitProgress } from "@logics_common";
|
||||
import chat_white_square from "@images/chato_white_square.png";
|
||||
import vrct_explanation from "@images/vrchat_chatbox_trasnlator_transcription.png";
|
||||
import vrct_starting_up from "@images/vrct_starting_up.png";
|
||||
|
||||
export const StartUpProgressContainer = () => {
|
||||
const { currentInitProgress } = useInitProgress();
|
||||
|
||||
const progress = currentInitProgress.data;
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.progress_bar_wrapper}>
|
||||
{[...Array(4)].map((_, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={clsx(styles.progress_bar, {
|
||||
[styles.progressed]: index < progress && progress !== 0,
|
||||
})}
|
||||
>
|
||||
{index === 3
|
||||
?
|
||||
<div className={styles.chato_box}>
|
||||
<img src={chat_white_square} className={styles.chato_img}/>
|
||||
</div>
|
||||
: null
|
||||
}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className={styles.labels_wrapper}>
|
||||
<img src={vrct_starting_up} className={styles.vrct_starting_up_img}/>
|
||||
<img src={vrct_explanation} className={styles.vrct_explanation_img}/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,101 @@
|
||||
$progress_ease: cubic-bezier(0, 1, 0.75, 1);
|
||||
// Duplicated
|
||||
|
||||
.container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress_bar_wrapper {
|
||||
position: absolute;
|
||||
top: 48%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
display: flex;
|
||||
gap: 36px;
|
||||
}
|
||||
|
||||
.progress_bar {
|
||||
width: 60px;
|
||||
height: 2px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.progress_bar::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 0;
|
||||
height: 100%;
|
||||
background-color: var(--dark_200_color);
|
||||
transition: width 0.3s $progress_ease;
|
||||
}
|
||||
|
||||
.progress_bar.progressed::before {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.progress_bar:last-child::before {
|
||||
background-color: var(--primary_400_color);
|
||||
}
|
||||
|
||||
|
||||
.chato_box {
|
||||
position: relative;
|
||||
top: 0;
|
||||
transform: translateY(-100%);
|
||||
width: 100%;
|
||||
height: 8rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.chato_img {
|
||||
position: absolute;
|
||||
top: 150%;
|
||||
left: 51%;
|
||||
transform: translate(-50%, -50%) rotate(-90deg);
|
||||
width: 2.8rem;
|
||||
transition: all 0.3s $progress_ease 0.2s;
|
||||
}
|
||||
|
||||
.progress_bar.progressed .chato_img {
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%) rotate(30deg);
|
||||
animation: infinite-rotation 20s linear infinite 0.5s;
|
||||
}
|
||||
|
||||
@keyframes infinite-rotation {
|
||||
from {
|
||||
transform: translate(-50%, -50%) rotate(30deg);
|
||||
}
|
||||
to {
|
||||
transform: translate(-50%, -50%) rotate(390deg);
|
||||
}
|
||||
}
|
||||
|
||||
.labels_wrapper {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.vrct_starting_up_img {
|
||||
position: absolute;
|
||||
top: 68%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 100px;
|
||||
// transform: translate(-50%, 50%);
|
||||
}
|
||||
.vrct_explanation_img {
|
||||
position: absolute;
|
||||
bottom: 4px;
|
||||
right: 10px;
|
||||
width: 280px;
|
||||
// transform: translate(-50%, 50%);
|
||||
}
|
||||
Reference in New Issue
Block a user