diff --git a/src/App.tsx b/src/App.tsx index a9e196d..dc63ee9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,21 +1,35 @@ import React from 'react'; -import { HashRouter as Router, Switch, Route, Link } from 'react-router-dom'; +import { HashRouter as Router, Switch, Route } from 'react-router-dom'; import { QueryClient, QueryClientProvider } from 'react-query'; +import { Helmet } from 'react-helmet-async'; import './styles/App.global.css'; import Layout from './components/layout/Layout'; import PlaylistList from './components/playlist/PlaylistList'; import PlaylistView from './components/playlist/PlaylistView'; import Settings from './components/settings/Settings'; +import NowPlayingView from './components/player/NowPlayingView'; +import Player from './components/player/Player'; +import Login from './components/settings/Login'; const queryClient = new QueryClient(); const App = () => { + if (!localStorage.getItem('server')) { + return ; + } + return ( + + sonicd + + + + @@ -29,6 +43,7 @@ const App = () => { + ); }; diff --git a/src/components/settings/Login.tsx b/src/components/settings/Login.tsx new file mode 100644 index 0000000..326e375 --- /dev/null +++ b/src/components/settings/Login.tsx @@ -0,0 +1,124 @@ +import React, { useState } from 'react'; +import md5 from 'md5'; +import randomstring from 'randomstring'; + +import { + Button, + Icon, + Container, + Header, + Content, + Panel, + Form, + FormGroup, + ControlLabel, + FormControl, + ButtonToolbar, + Alert, +} from 'rsuite'; +import axios from 'axios'; +import '../../styles/Settings.global.css'; + +const Login = () => { + const [serverName, setServerName] = useState( + localStorage.getItem('server') || '' + ); + const [userName, setUserName] = useState(''); + const [password, setPassword] = useState(''); + + const handleConnect = async () => { + console.log({ + serverName, + userName, + password, + }); + + const salt = randomstring.generate({ length: 16, charset: 'alphanumeric' }); + const hash = md5(password + salt); + + try { + const testConnection = await axios.get( + `${serverName}/rest/getUsers?v=1.15.0&c=sonicd&f=json&u=${userName}&s=${salt}&t=${hash}` + ); + + // Since a valid request will return a 200 response, we need to check that there + // are no additional failures reported by the server + if (testConnection.data['subsonic-response'].status === 'failed') { + Alert.error(testConnection.data['subsonic-response'].error.message); + return; + } + } catch (err) { + Alert.error(`Error validating server hostname: ${err.message}`); + return; + } + + localStorage.setItem('server', serverName); + localStorage.setItem('username', userName); + localStorage.setItem('salt', salt); + localStorage.setItem('hash', hash); + window.location.reload(); + }; + + const handleDisconnect = () => { + localStorage.removeItem('server'); + localStorage.removeItem('username'); + localStorage.removeItem('salt'); + localStorage.removeItem('hash'); + window.location.reload(); + }; + + return ( + +
+ + +
+ + *sonic Server + setServerName(e)} + /> + + + Username + setUserName(e)} + /> + + + + Password + setPassword(e)} + /> + + + + + + + + +
+
+
+ + ); +}; + +export default Login;