mirror of
https://github.com/Arrowar/StreamingCommunity.git
synced 2025-06-05 02:55:25 +00:00
Fix dark mode parziale e fix remove film e episode
This commit is contained in:
parent
c093687e9f
commit
29f8edf7a4
21
README.md
21
README.md
@ -1,17 +1,18 @@
|
|||||||
Per testare
|
Per testare
|
||||||
|
|
||||||
1. Installare requirements
|
0. Installare nodejs "https://nodejs.org/en/download/package-manager"
|
||||||
2. Inserire url per mongodb e creare database
|
1. Installare requirements "pip install -r "requirements.txt"
|
||||||
3. Runnare server.py
|
2. Inserire url per mongodb "https://www.mongodb.com/it-it"
|
||||||
|
3. Eseguire server.py con "python server.py"
|
||||||
4. Spostarsi su client\dashboard
|
4. Spostarsi su client\dashboard
|
||||||
5. Eseguire npm install, npm run build, npm install -g serve
|
5. Eseguire npm install, npm run build, npm install -g serve
|
||||||
|
|
||||||
Cosa da fare
|
Cosa da fare
|
||||||
- Dark mode su tutta la pagina
|
- MIgliorare dark mode.
|
||||||
- Aggiungere documentazione
|
- Aggiungere documentazione.
|
||||||
- Bottone download intera stagione
|
- Migliorare controlli.
|
||||||
- Messaggio con richiesta se scaricare le nuove stagione quando si fa il check in watchlist
|
- Aggiungere bottone per scaricare una stagione intera.
|
||||||
- Migliore player in case watch con bottone
|
- Messaggio con richiesta se scaricare le nuove stagione quando si fa il check in watchlist.
|
||||||
- Coda di download con bottone aggiungere alla coda (complessa)
|
- Migliore player in case watch con bottone.
|
||||||
|
- Coda di download con bottone aggiungere alla coda.
|
||||||
...
|
...
|
@ -8,12 +8,21 @@
|
|||||||
gap: 20px;
|
gap: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-results-container {
|
||||||
|
background-color: var(--background-color);
|
||||||
|
color: var(--text-color);
|
||||||
|
}
|
||||||
|
|
||||||
.search-result-item {
|
.search-result-item {
|
||||||
cursor: pointer;
|
background-color: #f0f0f0; /* Default (light mode) */
|
||||||
transition: transform 0.3s ease;
|
color: var(--text-color);
|
||||||
border-radius: 10px;
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2);
|
||||||
overflow: hidden;
|
}
|
||||||
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.search-result-item {
|
||||||
|
background-color: #1e1e1e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-result-item:hover {
|
.search-result-item:hover {
|
||||||
|
@ -35,11 +35,11 @@ function App() {
|
|||||||
<Router>
|
<Router>
|
||||||
<Navbar toggleTheme={toggleTheme} theme={theme} />
|
<Navbar toggleTheme={toggleTheme} theme={theme} />
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" element={<Dashboard />} />
|
<Route path="/" element={<Dashboard theme={theme} />} />
|
||||||
<Route path="/search" element={<SearchResults />} />
|
<Route path="/search" element={<SearchResults theme={theme} />} />
|
||||||
<Route path="/title/:id" element={<TitleDetail />} />
|
<Route path="/title/:id" element={<TitleDetail theme={theme} />} />
|
||||||
<Route path="/watchlist" element={<Watchlist />} />
|
<Route path="/watchlist" element={<Watchlist theme={theme} />} />
|
||||||
<Route path="/downloads" element={<Downloads />} />
|
<Route path="/downloads" element={<Downloads theme={theme} />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</Router>
|
</Router>
|
||||||
);
|
);
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { Container, Button, Form, InputGroup } from 'react-bootstrap';
|
import { Container, Button, Form, InputGroup } from 'react-bootstrap';
|
||||||
|
|
||||||
import SearchBar from './SearchBar.js';
|
import SearchBar from './SearchBar.js';
|
||||||
import { API_URL } from './ApiUrl.js';
|
import { API_URL } from './ApiUrl.js';
|
||||||
|
|
||||||
const Dashboard = () => {
|
const Dashboard = ({ theme }) => {
|
||||||
const [items, setItems] = useState([]);
|
const [items, setItems] = useState([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -26,7 +27,10 @@ const Dashboard = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container fluid className="p-4">
|
<Container fluid className="p-4" style={{
|
||||||
|
backgroundColor: theme === 'dark' ? '#121212' : '#ffffff',
|
||||||
|
color: theme === 'dark' ? '#ffffff' : '#000000'
|
||||||
|
}}>
|
||||||
<h1 className="mb-4">Dashboard</h1>
|
<h1 className="mb-4">Dashboard</h1>
|
||||||
|
|
||||||
<div className="d-flex justify-content-between align-items-center mb-4">
|
<div className="d-flex justify-content-between align-items-center mb-4">
|
||||||
@ -37,4 +41,9 @@ const Dashboard = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Dashboard.propTypes = {
|
||||||
|
toggleTheme: PropTypes.func.isRequired,
|
||||||
|
theme: PropTypes.oneOf(['light', 'dark']).isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
export default Dashboard;
|
export default Dashboard;
|
@ -1,4 +1,5 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { Container, Row, Col, Card, Button, Badge, Modal } from 'react-bootstrap';
|
import { Container, Row, Col, Card, Button, Badge, Modal } from 'react-bootstrap';
|
||||||
import { FaTrash, FaPlay } from 'react-icons/fa';
|
import { FaTrash, FaPlay } from 'react-icons/fa';
|
||||||
@ -6,7 +7,7 @@ import { Link } from 'react-router-dom';
|
|||||||
|
|
||||||
import { SERVER_PATH_URL, SERVER_DELETE_URL, API_URL } from './ApiUrl';
|
import { SERVER_PATH_URL, SERVER_DELETE_URL, API_URL } from './ApiUrl';
|
||||||
|
|
||||||
const Downloads = () => {
|
const Downloads = ({ theme }) => {
|
||||||
const [downloads, setDownloads] = useState([]);
|
const [downloads, setDownloads] = useState([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [showPlayer, setShowPlayer] = useState(false);
|
const [showPlayer, setShowPlayer] = useState(false);
|
||||||
@ -28,7 +29,7 @@ const Downloads = () => {
|
|||||||
const handleDeleteEpisode = async (id, season, episode) => {
|
const handleDeleteEpisode = async (id, season, episode) => {
|
||||||
try {
|
try {
|
||||||
await axios.delete(`${SERVER_DELETE_URL}/episode`, {
|
await axios.delete(`${SERVER_DELETE_URL}/episode`, {
|
||||||
params: { id, season, episode }
|
params: { series_id: id, season_number: season, episode_number: episode }
|
||||||
});
|
});
|
||||||
fetchDownloads(); // Refresh the list
|
fetchDownloads(); // Refresh the list
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -40,7 +41,7 @@ const Downloads = () => {
|
|||||||
const handleDeleteMovie = async (id) => {
|
const handleDeleteMovie = async (id) => {
|
||||||
try {
|
try {
|
||||||
await axios.delete(`${SERVER_DELETE_URL}/movie`, {
|
await axios.delete(`${SERVER_DELETE_URL}/movie`, {
|
||||||
params: { id }
|
params: { movie_id: id }
|
||||||
});
|
});
|
||||||
fetchDownloads(); // Refresh the list
|
fetchDownloads(); // Refresh the list
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -80,7 +81,10 @@ const Downloads = () => {
|
|||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container fluid className="p-0">
|
<Container fluid className="p-0" style={{
|
||||||
|
backgroundColor: theme === 'dark' ? '#121212' : '#ffffff',
|
||||||
|
color: theme === 'dark' ? '#ffffff' : '#000000'
|
||||||
|
}}>
|
||||||
<Container className="mt-4">
|
<Container className="mt-4">
|
||||||
<h2 className="mb-4">My Downloads</h2>
|
<h2 className="mb-4">My Downloads</h2>
|
||||||
|
|
||||||
@ -195,4 +199,9 @@ const Downloads = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Downloads.propTypes = {
|
||||||
|
toggleTheme: PropTypes.func.isRequired,
|
||||||
|
theme: PropTypes.oneOf(['light', 'dark']).isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
export default Downloads;
|
export default Downloads;
|
@ -22,7 +22,7 @@ const SearchBar = ({ onSearch }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form onSubmit={handleSearch} className="w-100">
|
<Form onSubmit={handleSearch} className="w-100" >
|
||||||
<InputGroup>
|
<InputGroup>
|
||||||
<Form.Control
|
<Form.Control
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
import { useLocation, useNavigate } from 'react-router-dom';
|
import { useLocation, useNavigate } from 'react-router-dom';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { Container, Row, Col, Card, Spinner } from 'react-bootstrap';
|
import { Container, Row, Col, Card, Spinner } from 'react-bootstrap';
|
||||||
@ -6,7 +7,7 @@ import { Container, Row, Col, Card, Spinner } from 'react-bootstrap';
|
|||||||
import SearchBar from './SearchBar.js';
|
import SearchBar from './SearchBar.js';
|
||||||
import { API_URL } from './ApiUrl.js';
|
import { API_URL } from './ApiUrl.js';
|
||||||
|
|
||||||
const SearchResults = () => {
|
const SearchResults = ({ theme }) => {
|
||||||
const [results, setResults] = useState([]);
|
const [results, setResults] = useState([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
@ -44,7 +45,10 @@ const SearchResults = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container fluid className="p-4">
|
<Container fluid className="p-4" style={{
|
||||||
|
backgroundColor: theme === 'dark' ? '#121212' : '#ffffff',
|
||||||
|
color: theme === 'dark' ? '#ffffff' : '#000000'
|
||||||
|
}}>
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<SearchBar />
|
<SearchBar />
|
||||||
</div>
|
</div>
|
||||||
@ -91,4 +95,10 @@ const SearchResults = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
SearchResults.propTypes = {
|
||||||
|
toggleTheme: PropTypes.func.isRequired,
|
||||||
|
theme: PropTypes.oneOf(['light', 'dark']).isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
export default SearchResults;
|
export default SearchResults;
|
@ -1,5 +1,6 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { Container, Row, Col, Image, Button, Dropdown, Modal, Alert } from 'react-bootstrap';
|
import { Container, Row, Col, Image, Button, Dropdown, Modal, Alert } from 'react-bootstrap';
|
||||||
import { FaDownload, FaPlay, FaPlus, FaTrash } from 'react-icons/fa';
|
import { FaDownload, FaPlay, FaPlus, FaTrash } from 'react-icons/fa';
|
||||||
@ -8,7 +9,7 @@ import SearchBar from './SearchBar.js';
|
|||||||
|
|
||||||
import { API_URL, SERVER_WATCHLIST_URL, SERVER_PATH_URL } from './ApiUrl.js';
|
import { API_URL, SERVER_WATCHLIST_URL, SERVER_PATH_URL } from './ApiUrl.js';
|
||||||
|
|
||||||
const TitleDetail = () => {
|
const TitleDetail = ({ theme }) => {
|
||||||
const [titleDetails, setTitleDetails] = useState(null);
|
const [titleDetails, setTitleDetails] = useState(null);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [selectedSeason, setSelectedSeason] = useState(1);
|
const [selectedSeason, setSelectedSeason] = useState(1);
|
||||||
@ -233,7 +234,10 @@ const TitleDetail = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container fluid className="p-0">
|
<Container fluid className="p-0" style={{
|
||||||
|
backgroundColor: theme === 'dark' ? '#121212' : '#ffffff',
|
||||||
|
color: theme === 'dark' ? '#ffffff' : '#000000'
|
||||||
|
}}>
|
||||||
<SearchBar />
|
<SearchBar />
|
||||||
|
|
||||||
{/* Background Image */}
|
{/* Background Image */}
|
||||||
@ -406,4 +410,9 @@ const TitleDetail = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TitleDetail.propTypes = {
|
||||||
|
toggleTheme: PropTypes.func.isRequired,
|
||||||
|
theme: PropTypes.oneOf(['light', 'dark']).isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
export default TitleDetail;
|
export default TitleDetail;
|
@ -1,16 +1,17 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
import { Container, Row, Col, Card, Button, Badge, Alert } from 'react-bootstrap';
|
import { Container, Row, Col, Card, Button, Badge, Alert } from 'react-bootstrap';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { FaTrash } from 'react-icons/fa';
|
import { FaTrash } from 'react-icons/fa';
|
||||||
|
|
||||||
import { SERVER_WATCHLIST_URL } from './ApiUrl';
|
import { SERVER_WATCHLIST_URL } from './ApiUrl';
|
||||||
|
|
||||||
const Watchlist = () => {
|
const Watchlist = ({ theme }) => {
|
||||||
const [watchlistItems, setWatchlistItems] = useState([]);
|
const [watchlistItems, setWatchlistItems] = useState([]);
|
||||||
const [newSeasons, setNewSeasons] = useState([]);
|
const [newSeasons, setNewSeasons] = useState([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [newSeasonsMessage, setNewSeasonsMessage] = useState(""); // Stato per il messaggio delle nuove stagioni
|
const [newSeasonsMessage, setNewSeasonsMessage] = useState("");
|
||||||
|
|
||||||
// Funzione per recuperare i dati della watchlist
|
// Funzione per recuperare i dati della watchlist
|
||||||
const fetchWatchlistData = async () => {
|
const fetchWatchlistData = async () => {
|
||||||
@ -93,7 +94,10 @@ const Watchlist = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container fluid className="p-0">
|
<Container fluid className="p-0" style={{
|
||||||
|
backgroundColor: theme === 'dark' ? '#121212' : '#ffffff',
|
||||||
|
color: theme === 'dark' ? '#ffffff' : '#000000'
|
||||||
|
}}>
|
||||||
<Container className="mt-4">
|
<Container className="mt-4">
|
||||||
<h2 className="mb-4">My Watchlist</h2>
|
<h2 className="mb-4">My Watchlist</h2>
|
||||||
|
|
||||||
@ -162,4 +166,9 @@ const Watchlist = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Watchlist.propTypes = {
|
||||||
|
toggleTheme: PropTypes.func.isRequired,
|
||||||
|
theme: PropTypes.oneOf(['light', 'dark']).isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
export default Watchlist;
|
export default Watchlist;
|
||||||
|
@ -13,5 +13,4 @@ qbittorrent-api
|
|||||||
python-qbittorrent
|
python-qbittorrent
|
||||||
googlesearch-python
|
googlesearch-python
|
||||||
pymongo
|
pymongo
|
||||||
fastapi
|
fastapi
|
||||||
pyclean
|
|
@ -449,7 +449,7 @@ async def remove_episode(series_id: int = Query(...), season_number: int = Query
|
|||||||
return {"success": True}
|
return {"success": True}
|
||||||
|
|
||||||
@app.delete("/server/delete/movie")
|
@app.delete("/server/delete/movie")
|
||||||
async def remove_movie(movie_id: int = Query(...)):
|
async def remove_movie(movie_id: str = Query(...)):
|
||||||
movie = downloads_collection.find_one({'type': 'movie', 'id': movie_id}, {'_id': 0, 'path': 1})
|
movie = downloads_collection.find_one({'type': 'movie', 'id': movie_id}, {'_id': 0, 'path': 1})
|
||||||
|
|
||||||
if not movie:
|
if not movie:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user