mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
[feature] sound control in title bar
This commit is contained in:
@@ -11,16 +11,11 @@ import { useThemeColor } from 'renderer/hooks/use-theme-color.hook';
|
||||
import Tippy from '@tippyjs/react';
|
||||
import { useTranslation } from 'renderer/hooks/use-translation.hook';
|
||||
import { I18nService } from 'renderer/services/i18n.service';
|
||||
import { BsmRange } from '../shared/bsm-range.component';
|
||||
import { AudioPlayerService } from 'renderer/services/audio-player.service';
|
||||
|
||||
export function NavBar() {
|
||||
|
||||
const bsVersionServoce = BSVersionManagerService.getInstance();
|
||||
const audio = AudioPlayerService.getInstance();
|
||||
|
||||
const playing = useObservable(audio.playing$);
|
||||
const volume = useObservable(audio.volume$);
|
||||
const installedVersions = useObservable(bsVersionServoce.installedVersions$);
|
||||
const color = useThemeColor("first-color");
|
||||
const t = useTranslation();
|
||||
@@ -31,14 +26,8 @@ export function NavBar() {
|
||||
<nav id='nav-bar' className='z-10 flex flex-col h-full max-h-full items-center p-1 bg-light-main-color-1 dark:bg-main-color-1'>
|
||||
<BsManagerIcon className='relative aspect-square w-16 h-16 mb-3'/>
|
||||
<ol id='versions' className='w-fit max-w-[120px] relative left-[2px] grow overflow-y-hidden scrollbar-track-transparent scrollbar-thin scrollbar-thumb-rounded-full scrollbar-thumb-neutral-900 hover:overflow-y-scroll'>
|
||||
<MapsNavBarItem/>
|
||||
{playing ? (
|
||||
<div className='relative w-[calc(100%-25px)] mx-auto my-2'>
|
||||
<BsmRange min={0} max={.5} values={[volume]} step={.01} colors={[color, "#40444b"]} onChange={vals => audio.setVolume(vals[0])}/>
|
||||
</div>
|
||||
) : (
|
||||
<NavBarSpliter/>
|
||||
)}
|
||||
<MapsNavBarItem/>
|
||||
<NavBarSpliter/>
|
||||
{installedVersions && installedVersions.map((version) => <BsVersionItem key={JSON.stringify(version)} version={version}/>)}
|
||||
</ol>
|
||||
<NavBarSpliter/>
|
||||
|
||||
@@ -36,10 +36,10 @@ export function BsmRange({colorType = "first-color", values, onChange, onFinalCh
|
||||
style={{
|
||||
...props.style,
|
||||
background: getTrackBackground({
|
||||
values: values,
|
||||
values,
|
||||
colors: colors ?? ["#ccc", color, "#ccc"],
|
||||
min: min,
|
||||
max: max
|
||||
min,
|
||||
max
|
||||
}),
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -48,11 +48,14 @@ import { TwitterIcon } from "./icons/twitter-icon.component";
|
||||
import { Mee6Icon } from "./icons/mee6-icon.component";
|
||||
import { InfoIcon } from "./icons/info-icon.component";
|
||||
import { SyncIcon } from "./icons/sync-icon.component";
|
||||
import { VolumeUpIcon } from "./icons/volume-up-icon.component";
|
||||
import { VolumeOffIcon } from "./icons/volume-off-icon.component";
|
||||
import { VolumeDownIcon } from "./icons/volume-down-icon.component";
|
||||
|
||||
export type BsmIconType = BsvMapCharacteristic | (
|
||||
"settings"|"trash"|"favorite"|"folder"|"bsNote"|"check"|"three-dots"|"twitch"|"eye"|"play"|"checkCircleIcon"|"discord"|"info"|
|
||||
"terminal"|"desktop"|"oculus"|"add"|"cross"|"task"|"github"|"close"|"thumbUpFill"|"timerFill"|"pause"|"twitter"|"sync"|
|
||||
"copy"|"steam"|"edit"|"export"|"patreon"|"search"|"bsMapDifficulty"|"link"|"unlink"|"download"|"filter"|"mee6"|
|
||||
"copy"|"steam"|"edit"|"export"|"patreon"|"search"|"bsMapDifficulty"|"link"|"unlink"|"download"|"filter"|"mee6"|"volume-up"|"volume-off"|"volume-down"|
|
||||
"fr-FR-flag"|"es-ES-flag"|"en-US-flag"|"en-EN-flag"
|
||||
);
|
||||
|
||||
@@ -107,6 +110,9 @@ export const BsmIcon = memo(({className, icon, style}: {className?: string, icon
|
||||
if(icon === "mee6"){ return <Mee6Icon className={className} style={style}/> }
|
||||
if(icon === "info"){ return <InfoIcon className={className} style={style}/> }
|
||||
if(icon === "sync"){ return <SyncIcon className={className} style={style}/> }
|
||||
if(icon === "volume-up"){ return <VolumeUpIcon className={className} style={style}/> }
|
||||
if(icon === "volume-down"){ return <VolumeDownIcon className={className} style={style}/> }
|
||||
if(icon === "volume-off"){ return <VolumeOffIcon className={className} style={style}/> }
|
||||
return <TrashIcon className={className} style={style}/>
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ export function TwitterIcon(props: {className?: string, style?: CSSProperties})
|
||||
return (
|
||||
<svg className={props.className} style={props.style} viewBox="0 0 24 24" fill="currentColor">
|
||||
<g>
|
||||
<path d="M23.643 4.937c-.835.37-1.732.62-2.675.733.962-.576 1.7-1.49 2.048-2.578-.9.534-1.897.922-2.958 1.13-.85-.904-2.06-1.47-3.4-1.47-2.572 0-4.658 2.086-4.658 4.66 0 .364.042.718.12 1.06-3.873-.195-7.304-2.05-9.602-4.868-.4.69-.63 1.49-.63 2.342 0 1.616.823 3.043 2.072 3.878-.764-.025-1.482-.234-2.11-.583v.06c0 2.257 1.605 4.14 3.737 4.568-.392.106-.803.162-1.227.162-.3 0-.593-.028-.877-.082.593 1.85 2.313 3.198 4.352 3.234-1.595 1.25-3.604 1.995-5.786 1.995-.376 0-.747-.022-1.112-.065 2.062 1.323 4.51 2.093 7.14 2.093 8.57 0 13.255-7.098 13.255-13.254 0-.2-.005-.402-.014-.602.91-.658 1.7-1.477 2.323-2.41z"></path>
|
||||
<path d="M23.643 4.937c-.835.37-1.732.62-2.675.733.962-.576 1.7-1.49 2.048-2.578-.9.534-1.897.922-2.958 1.13-.85-.904-2.06-1.47-3.4-1.47-2.572 0-4.658 2.086-4.658 4.66 0 .364.042.718.12 1.06-3.873-.195-7.304-2.05-9.602-4.868-.4.69-.63 1.49-.63 2.342 0 1.616.823 3.043 2.072 3.878-.764-.025-1.482-.234-2.11-.583v.06c0 2.257 1.605 4.14 3.737 4.568-.392.106-.803.162-1.227.162-.3 0-.593-.028-.877-.082.593 1.85 2.313 3.198 4.352 3.234-1.595 1.25-3.604 1.995-5.786 1.995-.376 0-.747-.022-1.112-.065 2.062 1.323 4.51 2.093 7.14 2.093 8.57 0 13.255-7.098 13.255-13.254 0-.2-.005-.402-.014-.602.91-.658 1.7-1.477 2.323-2.41z"/>
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import { CSSProperties } from "react";
|
||||
|
||||
export function VolumeDownIcon(props: {className?: string, style?: CSSProperties}) {
|
||||
return (
|
||||
<svg className={props.className} style={props.style} xmlns="http://www.w3.org/2000/svg" viewBox="0 96 960 960" fill="currentColor">
|
||||
<path d="M229.826 702.696q-16.326 0-27.181-10.855t-10.855-27.022V487.181q0-16.167 10.855-27.101 10.855-10.935 27.181-10.935h125.949l144.928-144.928q17.978-17.819 41.268-8.123 23.29 9.695 23.29 34.978v489.697q0 25.442-23.29 35.137-23.29 9.696-41.268-8.282L355.775 702.696H229.826Zm402.101 41.029V406.942q52.196 18.971 84.24 65.609Q748.21 519.188 748.21 576q0 57.478-32.043 103.036-32.044 45.558-84.24 64.689ZM489.348 427.818l-100.573 97.24H267.703v101.884h121.072l100.573 97.907V427.818ZM377.072 576Z"/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { CSSProperties } from "react";
|
||||
|
||||
export function VolumeOffIcon(props: {className?: string, style?: CSSProperties}) {
|
||||
return (
|
||||
<svg className={props.className} style={props.style} xmlns="http://www.w3.org/2000/svg" viewBox="0 96 960 960" fill="currentColor">
|
||||
<path d="M783.037 981.102 679.261 877.246q-16.645 11.044-34.21 20.493-17.566 9.45-36.544 16.225-17.572 6.159-32.862-5.04-15.29-11.199-15.29-31.474 0-8.682 4.609-15.649 4.608-6.967 12.797-9.873 13.391-4.522 26.761-10.862 13.37-6.341 24.826-14.45L480.355 676.637v144.132q0 25.442-23.29 35.137-23.29 9.696-41.108-8.282L271.029 702.696H144.92q-16.167 0-27.022-10.855-10.855-10.855-10.855-27.022V487.181q0-16.167 10.855-27.101 10.855-10.935 27.022-10.935h109.109L68.768 263.086q-10.225-10.224-9.892-24.703.334-14.478 10.558-24.702 10.225-10.225 24.53-10.225 14.304 0 24.528 10.225l714.697 718.175q10.224 10.224 10.224 24.702 0 14.478-10.224 24.544-10.225 10.384-25.076 10.384-14.852 0-25.076-10.384Zm-174.53-745.066q105.812 39.558 170.424 131.862Q843.543 460.203 843.543 575q0 52.464-14.525 101.942-14.525 49.478-42.511 93.21l-50.152-50.63q19-32.761 28.167-69.308 9.167-36.547 9.167-75.214 0-94.776-52.888-170.696-52.888-75.921-140.33-104.986-9.319-2.905-14.717-10.637-5.399-7.732-5.399-17.29 0-19.304 15.384-30.569 15.384-11.264 32.768-4.786ZM367.739 563.572Zm285.007 72.261-92.391-92.869V411.609q47.797 22.478 75.493 66.996 27.695 44.518 27.695 97.395 0 15.558-2.739 30.576t-8.058 29.257ZM480.355 462.406 369.5 350.674l46.457-46.457q17.818-17.819 41.108-8.044 23.29 9.776 23.29 34.899v131.334Zm-75.913 265.776V600.594l-75.217-75.536H182.797v101.884h120.406l101.239 101.24Z"/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { CSSProperties } from "react";
|
||||
|
||||
export function VolumeUpIcon(props: {className?: string, style?: CSSProperties}) {
|
||||
return (
|
||||
<svg className={props.className} style={props.style} xmlns="http://www.w3.org/2000/svg" viewBox="0 96 960 960" fill="currentColor">
|
||||
<path d="M613.413 913.964q-18.051 6.478-33.101-5.08-15.051-11.558-15.051-31.434 0-9.558 5.326-17.044 5.326-7.485 14.551-10.55 86.775-32.08 140.116-106.747Q778.595 668.442 778.595 575q0-93.442-53.341-168.363-53.341-74.92-140.116-106.652-9.319-2.906-14.598-10.971t-5.279-17.623q0-19.304 15.384-30.569 15.384-11.264 32.768-4.786 105.812 39.558 170.304 131.862Q848.21 460.203 848.21 575t-64.493 207.102q-64.492 92.304-170.304 131.862ZM149.826 702.696q-16.326 0-27.181-10.855t-10.855-27.022V487.181q0-16.167 10.855-27.101 10.855-10.935 27.181-10.935h125.949l144.928-144.928q17.978-17.819 41.268-8.044 23.29 9.776 23.29 34.899v489.697q0 25.282-23.29 35.058-23.29 9.775-41.268-8.203L275.775 702.696H149.826Zm402.101 41.029V406.942q52.196 18.971 84.24 65.609Q668.21 519.188 668.21 576q0 57.478-32.043 103.036-32.044 45.558-84.24 64.689ZM409.348 427.818l-100.573 97.24H187.703v101.884h121.072l100.573 97.907V427.818ZM315.74 576Z"/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
@@ -1,13 +1,24 @@
|
||||
import { useState } from 'react';
|
||||
import { useObservable } from 'renderer/hooks/use-observable.hook';
|
||||
import { useThemeColor } from 'renderer/hooks/use-theme-color.hook';
|
||||
import { AudioPlayerService } from 'renderer/services/audio-player.service';
|
||||
import { IpcService } from 'renderer/services/ipc.service';
|
||||
import { WindowManagerService } from 'renderer/services/window-manager.service';
|
||||
import { AppWindow } from 'shared/models/window-manager/app-window.model';
|
||||
import { BsmButton } from '../shared/bsm-button.component';
|
||||
import { BsmRange } from '../shared/bsm-range.component';
|
||||
import { BsmIcon, BsmIconType } from '../svgs/bsm-icon.component';
|
||||
import './title-bar.component.css'
|
||||
|
||||
export default function TitleBar({template = "index.html"} : {template: AppWindow}) {
|
||||
|
||||
const ipcService = IpcService.getInstance();
|
||||
const windows = WindowManagerService.getInstance();
|
||||
const audio = AudioPlayerService.getInstance();
|
||||
|
||||
const volume = useObservable(audio.volume$);
|
||||
const playing = useObservable(audio.playing$);
|
||||
const color = useThemeColor("first-color");
|
||||
|
||||
const [maximized, setMaximized] = useState(false);
|
||||
|
||||
@@ -33,6 +44,12 @@ export default function TitleBar({template = "index.html"} : {template: AppWindo
|
||||
setMaximized(!maximized);
|
||||
}
|
||||
|
||||
const volumeIcon: BsmIconType = (() => {
|
||||
if(volume === 0){ return "volume-off"; }
|
||||
if(volume < 0.5){ return "volume-down"; }
|
||||
return "volume-up";
|
||||
})()
|
||||
|
||||
if(template === "index.html"){
|
||||
|
||||
return (
|
||||
@@ -42,7 +59,13 @@ export default function TitleBar({template = "index.html"} : {template: AppWindo
|
||||
<span className='text-gray-800 dark:text-gray-100 font-bold text-xs italic'>BSManager</span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="window-controls" className="h-full flex shrink-0">
|
||||
<div id="window-controls" className="h-full flex shrink-0 items-center">
|
||||
<div className='h-full text-gray-800 dark:text-gray-200 mr-2 cursor-pointer flex flex-row justify-end items-center gap-2 group'>
|
||||
<div className='shrink-0 w-0 overflow-hidden transition-all group-hover:w-16 group-hover:overflow-visible group-active:w-16 group-active:overflow-visible text-main-color-3'>
|
||||
<BsmRange min={0} max={1} step={.01} values={[volume]} colors={[color, "currentColor"]} onChange={val => audio.setVolume(val[0])}/>
|
||||
</div>
|
||||
<BsmButton className='shrink-0 h-[21px] w-[21px] aspect-square !bg-transparent flex items-start' icon={volumeIcon} withBar={false} onClick={() => audio.setVolume(0)}/>
|
||||
</div>
|
||||
<div onClick={minimizeWindow} className="text-gray-800 dark:text-gray-200 hover:bg-gray-300 dark:hover:bg-[#4F545C] cursor-pointer w-11 h-full shrink-0 flex justify-center items-center" id="min-button" >
|
||||
<svg aria-hidden="false" width="12" height="12" viewBox="0 0 12 12"><rect fill="currentColor" width="10" height="1" x="1" y="6"> </rect></svg>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user