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 (
+
+
+
+
+
+
+
+
+ );
+};
+
+export default Login;