[enhancement]: Support disabling MPV entirely

Supports running Feishin solely using web audio (useful for clients with problems with MPV).
Also moves save/restore queue to utils, as MPV object is now optional
This commit is contained in:
Kendall Garner 2024-02-11 13:56:29 -08:00
parent ae8fc6df13
commit f82da2e76b
No known key found for this signature in database
GPG key ID: 18D2767419676C87
10 changed files with 127 additions and 74 deletions

View file

@ -1,23 +1,36 @@
import { useEffect, useState } from 'react';
import isElectron from 'is-electron';
import { FileInput, Text, Button } from '/@/renderer/components';
import { FileInput, Text, Button, Checkbox } from '/@/renderer/components';
import { usePlaybackSettings, useSettingsStoreActions } from '/@/renderer/store';
import { PlaybackType } from '/@/renderer/types';
import { useTranslation } from 'react-i18next';
const localSettings = isElectron() ? window.electron.localSettings : null;
export const MpvRequired = () => {
const [mpvPath, setMpvPath] = useState('');
const settings = usePlaybackSettings();
const { setSettings } = useSettingsStoreActions();
const [disabled, setDisabled] = useState(false);
const { t } = useTranslation();
const handleSetMpvPath = (e: File) => {
localSettings?.set('mpv_path', e.path);
};
useEffect(() => {
const getMpvPath = async () => {
if (!localSettings) return setMpvPath('');
const mpvPath = localSettings.get('mpv_path') as string;
return setMpvPath(mpvPath);
};
const handleSetDisableMpv = (disabled: boolean) => {
setDisabled(disabled);
localSettings?.set('disable_mpv', disabled);
getMpvPath();
setSettings({
playback: { ...settings, type: disabled ? PlaybackType.WEB : PlaybackType.LOCAL },
});
};
useEffect(() => {
if (!localSettings) return setMpvPath('');
const mpvPath = localSettings.get('mpv_path') as string;
return setMpvPath(mpvPath);
}, []);
return (
@ -34,9 +47,15 @@ export const MpvRequired = () => {
</a>
</Text>
<FileInput
disabled={disabled}
placeholder={mpvPath}
onChange={handleSetMpvPath}
/>
<Text>{t('setting.disable_mpv', { context: 'description' })}</Text>
<Checkbox
label={t('setting.disableMpv')}
onChange={(e) => handleSetDisableMpv(e.currentTarget.checked)}
/>
<Button onClick={() => localSettings?.restart()}>Restart</Button>
</>
);

View file

@ -1,4 +1,4 @@
import { useState, useEffect } from 'react';
import { useMemo } from 'react';
import { Center, Group, Stack } from '@mantine/core';
import isElectron from 'is-electron';
import { useTranslation } from 'react-i18next';
@ -18,23 +18,19 @@ const localSettings = isElectron() ? window.electron.localSettings : null;
const ActionRequiredRoute = () => {
const { t } = useTranslation();
const currentServer = useCurrentServer();
const [isMpvRequired, setIsMpvRequired] = useState(false);
const isServerRequired = !currentServer;
const isCredentialRequired = false;
useEffect(() => {
const getMpvPath = async () => {
if (!localSettings) return setIsMpvRequired(false);
const mpvPath = await localSettings.get('mpv_path');
const isMpvRequired = useMemo(() => {
if (!localSettings) return false;
if (mpvPath) {
return setIsMpvRequired(false);
}
const mpvPath = localSettings.get('mpv_path');
if (mpvPath) {
return false;
}
return setIsMpvRequired(true);
};
getMpvPath();
const mpvDisabled = localSettings.get('disable_mpv');
return !mpvDisabled;
}, []);
const checks = [

View file

@ -1,7 +1,7 @@
import { useEffect, useState } from 'react';
import { SelectItem } from '@mantine/core';
import isElectron from 'is-electron';
import { Select, Slider, toast } from '/@/renderer/components';
import { Checkbox, Select, Slider, toast } from '/@/renderer/components';
import {
SettingsSection,
SettingOption,
@ -12,12 +12,15 @@ import { PlaybackType, PlayerStatus, PlaybackStyle, CrossfadeStyle } from '/@/re
import { useTranslation } from 'react-i18next';
const mpvPlayer = isElectron() ? window.electron.mpvPlayer : null;
const localSettings = isElectron() ? window.electron.localSettings : null;
const getAudioDevice = async () => {
const devices = await navigator.mediaDevices.enumerateDevices();
return (devices || []).filter((dev: MediaDeviceInfo) => dev.kind === 'audiooutput');
};
const initialDisable = (localSettings?.get('disable_mpv') as boolean | undefined) ?? false;
export const AudioSettings = () => {
const { t } = useTranslation();
const settings = usePlaybackSettings();
@ -25,6 +28,18 @@ export const AudioSettings = () => {
const status = useCurrentStatus();
const [audioDevices, setAudioDevices] = useState<SelectItem[]>([]);
const [disableMpv, setDisableMpv] = useState(initialDisable);
const handleSetDisableMpv = (disabled: boolean) => {
setDisableMpv(disabled);
localSettings?.set('disable_mpv', disabled);
if (disabled) {
setSettings({
playback: { ...settings, type: disabled ? PlaybackType.WEB : PlaybackType.LOCAL },
});
}
};
useEffect(() => {
const getAudioDevices = () => {
@ -45,6 +60,18 @@ export const AudioSettings = () => {
}, [settings.type, t]);
const audioOptions: SettingOption[] = [
{
control: (
<Checkbox
defaultChecked={disableMpv}
onChange={(e) => handleSetDisableMpv(e.currentTarget.checked)}
/>
),
description: t('setting.disableMpv', { context: 'description' }),
isHidden: !isElectron(),
note: t('common.restartRequired', { postProcess: 'sentenceCase' }),
title: t('setting.disableMpv'),
},
{
control: (
<Select
@ -71,7 +98,7 @@ export const AudioSettings = () => {
context: 'description',
postProcess: 'sentenceCase',
}),
isHidden: !isElectron(),
isHidden: !isElectron() || initialDisable || disableMpv,
note:
status === PlayerStatus.PLAYING
? t('common.playerMustBePaused', { postProcess: 'sentenceCase' })