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 2 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 @@ -99,6 +99,7 @@ export type System = {

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
34 changes: 34 additions & 0 deletions src/renderer/src/components/settings/SettingDropdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
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 => {
heyngra marked this conversation as resolved.
Show resolved Hide resolved

const changeOption = (e: Event) => {
const option = (e.target as HTMLSelectElement).value;
props.options.get(option)?.(); // this ?. magic should work
heyngra marked this conversation as resolved.
Show resolved Hide resolved
}

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
43 changes: 43 additions & 0 deletions src/renderer/src/components/settings/SettingsView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
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)});
heyngra marked this conversation as resolved.
Show resolved Hide resolved
}
}
setAudioDevices(audioMap);
console.log(audioDevices());
CaptSiro marked this conversation as resolved.
Show resolved Hide resolved
});
}

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;
14 changes: 14 additions & 0 deletions src/renderer/src/lib/Music.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@ window.api.request("settings::get", "volume")
setVolume(v.value);
});

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

changeAudioDevice(v.value);
});



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

export async function changeAudioDevice(deviceId: string) {
await window.api.request("settings::write", "audioDeviceId", deviceId);
(player as any).setSinkId(deviceId); // unsafe, but works
heyngra marked this conversation as resolved.
Show resolved Hide resolved
}

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

Expand Down