From 0fee1ad8773723e3b1487f9bf77dc5125e43a26e Mon Sep 17 00:00:00 2001 From: heyngra Date: Sun, 29 Sep 2024 21:22:09 +0200 Subject: [PATCH 1/5] Fix slider out of bounds --- src/renderer/src/components/Bar.tsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/renderer/src/components/Bar.tsx b/src/renderer/src/components/Bar.tsx index 9c93732e..d95c598e 100644 --- a/src/renderer/src/components/Bar.tsx +++ b/src/renderer/src/components/Bar.tsx @@ -29,11 +29,15 @@ const Bar: Component = props => { bar.style.setProperty("--fill-per", `${clamp(0, 1, f) * 100}%`); if (props.setFill !== undefined) { - props.setFill(f); + props.setFill(clampFill(f)); } }); }); + const clampFill = (fill: number) => { + return clamp(0, 1, fill); + } + const calculateFill = (evt: PointerEvent) => { if (props.disabled === true) { return; @@ -42,11 +46,11 @@ const Bar: Component = props => { const rect: DOMRect = bar.getBoundingClientRect(); if (isVertical(props.alignment)) { - setFill((-(evt.clientY - rect.top) / rect.height) + 1); + setFill(clampFill((-(evt.clientY - rect.top) / rect.height) + 1)); return; } - setFill((evt.clientX - rect.left) / rect.width); + setFill(clampFill((evt.clientX - rect.left) / rect.width)); } const onDown = (evt: PointerEvent) => { From bb72060c9d25a967f51842bff7b5922a68d9aa3b Mon Sep 17 00:00:00 2001 From: heyngra Date: Sun, 29 Sep 2024 22:45:03 +0200 Subject: [PATCH 2/5] remove clamp function, add settings + audio device no idea if save works, but audio device changing does --- src/@types.d.ts | 1 + .../assets/css/settings/settings-dropdown.css | 9 ++++ .../src/assets/css/settings/settings-item.css | 31 +++++++++++++ .../src/assets/css/settings/settings-view.css | 23 ++++++++++ src/renderer/src/components/Bar.tsx | 10 ++--- .../src/components/scenes/MainScene.tsx | 3 +- .../components/settings/SettingDropdown.tsx | 34 +++++++++++++++ .../src/components/settings/SettingsView.tsx | 43 +++++++++++++++++++ src/renderer/src/lib/Music.ts | 14 ++++++ 9 files changed, 160 insertions(+), 8 deletions(-) create mode 100644 src/renderer/src/assets/css/settings/settings-dropdown.css create mode 100644 src/renderer/src/assets/css/settings/settings-item.css create mode 100644 src/renderer/src/assets/css/settings/settings-view.css create mode 100644 src/renderer/src/components/settings/SettingDropdown.tsx create mode 100644 src/renderer/src/components/settings/SettingsView.tsx diff --git a/src/@types.d.ts b/src/@types.d.ts index 21bd0359..d77b87c5 100644 --- a/src/@types.d.ts +++ b/src/@types.d.ts @@ -99,6 +99,7 @@ export type System = { export type Settings = { volume: number, + audioDeviceId: string, osuSongsDir: string, "window.width": number, "window.height": number, diff --git a/src/renderer/src/assets/css/settings/settings-dropdown.css b/src/renderer/src/assets/css/settings/settings-dropdown.css new file mode 100644 index 00000000..a2a937ce --- /dev/null +++ b/src/renderer/src/assets/css/settings/settings-dropdown.css @@ -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%; +} \ No newline at end of file diff --git a/src/renderer/src/assets/css/settings/settings-item.css b/src/renderer/src/assets/css/settings/settings-item.css new file mode 100644 index 00000000..242105bd --- /dev/null +++ b/src/renderer/src/assets/css/settings/settings-item.css @@ -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; +} \ No newline at end of file diff --git a/src/renderer/src/assets/css/settings/settings-view.css b/src/renderer/src/assets/css/settings/settings-view.css new file mode 100644 index 00000000..5fe49f03 --- /dev/null +++ b/src/renderer/src/assets/css/settings/settings-view.css @@ -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; +} \ No newline at end of file diff --git a/src/renderer/src/components/Bar.tsx b/src/renderer/src/components/Bar.tsx index d95c598e..23662599 100644 --- a/src/renderer/src/components/Bar.tsx +++ b/src/renderer/src/components/Bar.tsx @@ -29,15 +29,11 @@ const Bar: Component = props => { bar.style.setProperty("--fill-per", `${clamp(0, 1, f) * 100}%`); if (props.setFill !== undefined) { - props.setFill(clampFill(f)); + props.setFill(clamp(0, 1, f)); } }); }); - const clampFill = (fill: number) => { - return clamp(0, 1, fill); - } - const calculateFill = (evt: PointerEvent) => { if (props.disabled === true) { return; @@ -46,11 +42,11 @@ const Bar: Component = props => { const rect: DOMRect = bar.getBoundingClientRect(); if (isVertical(props.alignment)) { - setFill(clampFill((-(evt.clientY - rect.top) / rect.height) + 1)); + setFill(clamp(0, 1, (-(evt.clientY - rect.top) / rect.height) + 1)); return; } - setFill(clampFill((evt.clientX - rect.left) / rect.width)); + setFill(clamp(0, 1, (evt.clientX - rect.left) / rect.width)); } const onDown = (evt: PointerEvent) => { diff --git a/src/renderer/src/components/scenes/MainScene.tsx b/src/renderer/src/components/scenes/MainScene.tsx index 4ec0a10f..19d4dc1b 100644 --- a/src/renderer/src/components/scenes/MainScene.tsx +++ b/src/renderer/src/components/scenes/MainScene.tsx @@ -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'; @@ -49,7 +50,7 @@ export default function MainScene() {
Playlists
-
Settings
+
diff --git a/src/renderer/src/components/settings/SettingDropdown.tsx b/src/renderer/src/components/settings/SettingDropdown.tsx new file mode 100644 index 00000000..ddee5708 --- /dev/null +++ b/src/renderer/src/components/settings/SettingDropdown.tsx @@ -0,0 +1,34 @@ +import { Component, Show } from 'solid-js'; + +import "../../assets/css/select.css"; + +type SettingDropdownProps = { + label: string, + options: Map any>, // name of option, function after clicked + disabled: false, +} + +const settingDropdown: Component = props => { + + const changeOption = (e: Event) => { + const option = (e.target as HTMLSelectElement).value; + props.options.get(option)?.(); // this ?. magic should work + } + + return ( +
+
+ + 0} fallback={
Loading audio devices
}> + +
+
+
+ ); +} +export default settingDropdown \ No newline at end of file diff --git a/src/renderer/src/components/settings/SettingsView.tsx b/src/renderer/src/components/settings/SettingsView.tsx new file mode 100644 index 00000000..740b5233 --- /dev/null +++ b/src/renderer/src/components/settings/SettingsView.tsx @@ -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 Mapany>()); + + const setAudioDevicesMap = () => { + const audioMap = new Mapany>(); + navigator.mediaDevices.enumerateDevices().then(r => { + for (const device of r) { + if (device.kind === "audiooutput") { + audioMap.set(device.label, ()=>{changeAudioDevice(device.deviceId)}); + } + } + setAudioDevices(audioMap); + console.log(audioDevices()); + }); + } + + onMount(() => { + createEffect(setAudioDevicesMap); + }) + + return ( +
+
+ +
+
+ ) +} +export default settingsView; \ No newline at end of file diff --git a/src/renderer/src/lib/Music.ts b/src/renderer/src/lib/Music.ts index 55bebac7..12656073 100644 --- a/src/renderer/src/lib/Music.ts +++ b/src/renderer/src/lib/Music.ts @@ -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(0.5); @@ -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 +} + export async function next() { await window.api.request("queue::next"); From 23d65f24a2219433fd5253d48dfd5465ebbbd042 Mon Sep 17 00:00:00 2001 From: heyngra Date: Sun, 29 Sep 2024 23:07:32 +0200 Subject: [PATCH 3/5] apply review fixes --- src/renderer/src/components/settings/SettingDropdown.tsx | 5 ++++- src/renderer/src/components/settings/SettingsView.tsx | 2 +- src/renderer/src/lib/Music.ts | 6 +++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/renderer/src/components/settings/SettingDropdown.tsx b/src/renderer/src/components/settings/SettingDropdown.tsx index ddee5708..a2b8ff1b 100644 --- a/src/renderer/src/components/settings/SettingDropdown.tsx +++ b/src/renderer/src/components/settings/SettingDropdown.tsx @@ -12,7 +12,10 @@ const settingDropdown: Component = props => { const changeOption = (e: Event) => { const option = (e.target as HTMLSelectElement).value; - props.options.get(option)?.(); // this ?. magic should work + const functionToCall = props.options.get(option); + if (functionToCall !== undefined) { + functionToCall(); + } } return ( diff --git a/src/renderer/src/components/settings/SettingsView.tsx b/src/renderer/src/components/settings/SettingsView.tsx index 740b5233..952cb09c 100644 --- a/src/renderer/src/components/settings/SettingsView.tsx +++ b/src/renderer/src/components/settings/SettingsView.tsx @@ -14,7 +14,7 @@ const settingsView = () => { navigator.mediaDevices.enumerateDevices().then(r => { for (const device of r) { if (device.kind === "audiooutput") { - audioMap.set(device.label, ()=>{changeAudioDevice(device.deviceId)}); + audioMap.set(device.label, () => changeAudioDevice(device.deviceId)); } } setAudioDevices(audioMap); diff --git a/src/renderer/src/lib/Music.ts b/src/renderer/src/lib/Music.ts index 12656073..f2d30112 100644 --- a/src/renderer/src/lib/Music.ts +++ b/src/renderer/src/lib/Music.ts @@ -150,7 +150,11 @@ export function pause() { export async function changeAudioDevice(deviceId: string) { await window.api.request("settings::write", "audioDeviceId", deviceId); - (player as any).setSinkId(deviceId); // unsafe, but works + 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() { From 73369b6169846126bdcc89d07b5f7f9c40afe668 Mon Sep 17 00:00:00 2001 From: heyn Date: Sat, 5 Oct 2024 12:53:44 +0200 Subject: [PATCH 4/5] remove unnecessary log --- src/renderer/src/components/settings/SettingsView.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/renderer/src/components/settings/SettingsView.tsx b/src/renderer/src/components/settings/SettingsView.tsx index 952cb09c..2f94944b 100644 --- a/src/renderer/src/components/settings/SettingsView.tsx +++ b/src/renderer/src/components/settings/SettingsView.tsx @@ -18,7 +18,6 @@ const settingsView = () => { } } setAudioDevices(audioMap); - console.log(audioDevices()); }); } @@ -40,4 +39,4 @@ const settingsView = () => { ) } -export default settingsView; \ No newline at end of file +export default settingsView; From 71294316f21409c404adbc282741cd30901406d5 Mon Sep 17 00:00:00 2001 From: heyngra Date: Sat, 5 Oct 2024 22:35:04 +0200 Subject: [PATCH 5/5] change capitalization --- src/renderer/src/components/settings/SettingDropdown.tsx | 4 ++-- src/renderer/src/components/settings/SettingsView.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/renderer/src/components/settings/SettingDropdown.tsx b/src/renderer/src/components/settings/SettingDropdown.tsx index a2b8ff1b..90db9032 100644 --- a/src/renderer/src/components/settings/SettingDropdown.tsx +++ b/src/renderer/src/components/settings/SettingDropdown.tsx @@ -8,7 +8,7 @@ type SettingDropdownProps = { disabled: false, } -const settingDropdown: Component = props => { +const SettingDropdown: Component = props => { const changeOption = (e: Event) => { const option = (e.target as HTMLSelectElement).value; @@ -34,4 +34,4 @@ const settingDropdown: Component = props => { ); } -export default settingDropdown \ No newline at end of file +export default SettingDropdown \ No newline at end of file diff --git a/src/renderer/src/components/settings/SettingsView.tsx b/src/renderer/src/components/settings/SettingsView.tsx index 2f94944b..dd3aad64 100644 --- a/src/renderer/src/components/settings/SettingsView.tsx +++ b/src/renderer/src/components/settings/SettingsView.tsx @@ -4,7 +4,7 @@ import "../../assets/css/settings/settings-item.css"; import { createEffect, createSignal, onMount } from 'solid-js'; import { changeAudioDevice} from '../../lib/Music'; -const settingsView = () => { +const SettingsView = () => { let view; const [audioDevices, setAudioDevices] = createSignal(new Mapany>()); @@ -39,4 +39,4 @@ const settingsView = () => { ) } -export default settingsView; +export default SettingsView;