Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add changable Audio Device, bugfixes #2

Merged
merged 7 commits into from
Oct 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/@types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ export type System = {
// Settings table definition
export type Settings = {
volume: number,
audioDeviceId: string,
osuSongsDir: string,
"window.width": number,
"window.height": number,
Expand Down
9 changes: 9 additions & 0 deletions src/renderer/src/assets/css/settings/settings-dropdown.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.settings-item-container {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.settings-item-container select {
width: 50%;
}
31 changes: 31 additions & 0 deletions src/renderer/src/assets/css/settings/settings-item.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.settings-view .list .settings-item {
min-height: 40px;
width: 100%;
}

.settings-item .settings-item-container {
width: 100%;
height: 100%;
display: grid;
grid-template-columns: 80px 1fr;
gap: 4px;
overflow: hidden;
font-size: 1em;
border-radius: var(--border-radius);

transition: background-color 250ms;
}

.list:not(.drag-inside) .settings-item .settings-item-container:hover,
.settings-item.selected .settings-item-container,
[data-dragged] .settings-item-container {
background-color: rgba(var(--color-fg), var(--level-0));

transition: background-color 0ms;
}

.settings-view .list .settings-item .column {
display: flex;
flex-direction: column;
align-self: center;
}
23 changes: 23 additions & 0 deletions src/renderer/src/assets/css/settings/settings-view.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.settings-view {
display: flex;
flex-direction: column;
overflow: hidden;
}

.settings-view > :not(.no-pd) {
padding: 16px;
}

.settings-view .list {
position: relative; /* used for setting offsetParent for .settings-item elements */
display: flex;
flex-direction: column;
gap: 8px;
margin-top: 16px;
padding: 0 16px 16vw 16px;
overflow: auto;
}

.list.drag-inside {
cursor: move;
}
6 changes: 3 additions & 3 deletions src/renderer/src/components/Bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const Bar: Component<BarProps> = props => {
bar.style.setProperty("--fill-per", `${clamp(0, 1, f) * 100}%`);

if (props.setFill !== undefined) {
props.setFill(f);
props.setFill(clamp(0, 1, f));
}
});
});
Expand All @@ -42,11 +42,11 @@ const Bar: Component<BarProps> = props => {
const rect: DOMRect = bar.getBoundingClientRect();

if (isVertical(props.alignment)) {
setFill((-(evt.clientY - rect.top) / rect.height) + 1);
setFill(clamp(0, 1, (-(evt.clientY - rect.top) / rect.height) + 1));
return;
}

setFill((evt.clientX - rect.left) / rect.width);
setFill(clamp(0, 1, (evt.clientX - rect.left) / rect.width));
}

const onDown = (evt: PointerEvent) => {
Expand Down
3 changes: 2 additions & 1 deletion src/renderer/src/components/scenes/MainScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { GLOBAL_ICON_SCALE } from '../../App';
import SongDetail from '../song/SongDetail';
import QueueView from '../queue/QueueView';
import NoticeContainer from '../notice/NoticeContainer';
import SettingsView from '../settings/SettingsView';



Expand Down Expand Up @@ -49,7 +50,7 @@ export default function MainScene() {
<SongView isAllSongs={true}/>
<QueueView/>
<div>Playlists</div>
<div>Settings</div>
<SettingsView/>
</div>

<main class="center">
Expand Down
37 changes: 37 additions & 0 deletions src/renderer/src/components/settings/SettingDropdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Component, Show } from 'solid-js';

import "../../assets/css/select.css";

type SettingDropdownProps = {
label: string,
options: Map<string, () => any>, // name of option, function after clicked
disabled: false,
}

const SettingDropdown: Component<SettingDropdownProps> = props => {

const changeOption = (e: Event) => {
const option = (e.target as HTMLSelectElement).value;
const functionToCall = props.options.get(option);
if (functionToCall !== undefined) {
functionToCall();
}
}

return (
<div class="settings-item">
<div class="settings-item-container">
<label>{props.label}</label>
<Show when={props.options.size > 0} fallback={<div>Loading audio devices</div>}>
<select class="button-like select" disabled={props.disabled} onChange={changeOption}>
{
Array.from(props.options.keys()).map(option => (
<option value={option}>{option}</option>
))}
</select>
</Show>
</div>
</div>
);
}
export default SettingDropdown
42 changes: 42 additions & 0 deletions src/renderer/src/components/settings/SettingsView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import SettingDropdown from './SettingDropdown';
import "../../assets/css/settings/settings-view.css";
import "../../assets/css/settings/settings-item.css";
import { createEffect, createSignal, onMount } from 'solid-js';
import { changeAudioDevice} from '../../lib/Music';

const SettingsView = () => {
let view;

const [audioDevices, setAudioDevices] = createSignal(new Map<string, ()=>any>());

const setAudioDevicesMap = () => {
const audioMap = new Map<string, ()=>any>();
navigator.mediaDevices.enumerateDevices().then(r => {
for (const device of r) {
if (device.kind === "audiooutput") {
audioMap.set(device.label, () => changeAudioDevice(device.deviceId));
}
}
setAudioDevices(audioMap);
});
}

onMount(() => {
createEffect(setAudioDevicesMap);
})

return (
<div
ref={view}
class="settings-view"
>
<div class="list">
<SettingDropdown
disabled={false}
label={"Choose audio device"}
options={audioDevices()}/>
</div>
</div>
)
}
export default SettingsView;
20 changes: 19 additions & 1 deletion src/renderer/src/lib/Music.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,23 @@ export { timestamp };

const [volume, setVolume] = createSignal<ZeroToOne>(0.3);
export { volume, setVolume };

window.api.request("settings::get", "volume").then((v) => {
if (v.isNone) {
return;
}

setVolume(v.value);
});

window.api.request("settings::get", "audioDeviceId").then(v => {
if (v.isNone) {
return;
}

changeAudioDevice(v.value);
});


let bgPath;

const [localVolume, setLocalVolume] = createSignal<ZeroToOne>(0.5);
Expand Down Expand Up @@ -115,6 +124,15 @@ export function pause() {
player.pause();
}

export async function changeAudioDevice(deviceId: string) {
await window.api.request("settings::write", "audioDeviceId", deviceId);
if ("setSinkId" in player && typeof player.setSinkId === "function") {
player.setSinkId(deviceId);
} else {
console.error("Changing audio devices is not supported in your enviornment.");
}
}

export async function next() {
await window.api.request("queue::next");

Expand Down