mirror of
https://github.com/BreizhHardware/Jellystat.git
synced 2026-01-18 16:27:20 +01:00
Added Media Listing to libraries
Added Media Listing to libraries Minor css changes to item cards and image constraints Minor css changes to stat cards Added api endpoint to show all items per library
This commit is contained in:
@@ -69,12 +69,11 @@ router.get("/getLibraries", async (req, res) => {
|
||||
|
||||
router.post("/getLibraryItems", async (req, res) => {
|
||||
try{
|
||||
const Id = req.headers['id'];
|
||||
|
||||
const {libraryid} = req.body;
|
||||
console.log(`ENDPOINT CALLED: /getLibraryItems: `+libraryid);
|
||||
const { rows } = await db.query(
|
||||
`SELECT * FROM jf_library_items where "ParentId"='${Id}'`
|
||||
`SELECT * FROM jf_library_items where "ParentId"='${libraryid}'`
|
||||
);
|
||||
console.log({ Id: Id });
|
||||
res.send(rows);
|
||||
|
||||
|
||||
@@ -83,7 +82,7 @@ router.post("/getLibraryItems", async (req, res) => {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
console.log(`ENDPOINT CALLED: /getLibraryItems: `);
|
||||
|
||||
});
|
||||
|
||||
router.post("/getSeasons", async (req, res) => {
|
||||
|
||||
@@ -61,7 +61,7 @@ function Row(data) {
|
||||
size="small"
|
||||
onClick={() => {if(row.results.length>1){setOpen(!open);}}}
|
||||
>
|
||||
{!open ? <AddCircleFillIcon /> : <IndeterminateCircleFillIcon />}
|
||||
{!open ? <AddCircleFillIcon opacity={row.results.length>1 ?1 : 0} cursor={row.results.length>1 ? "pointer":"default"}/> : <IndeterminateCircleFillIcon />}
|
||||
</IconButton>
|
||||
</TableCell>
|
||||
<TableCell><Link to={`/users/${row.UserId}`} className='text-decoration-none'>{row.UserName}</Link></TableCell>
|
||||
|
||||
@@ -12,13 +12,14 @@ function MoreItemCards(props) {
|
||||
const [loaded, setLoaded] = useState(false);
|
||||
const [fallback, setFallback] = useState(false);
|
||||
return (
|
||||
<div className={props.data.Type==="Episode" ? "last-card episode" : "last-card"}>
|
||||
<div className={props.data.Type==="Episode" ? "last-card episode-card" : "last-card"}>
|
||||
<Link to={`/libraries/item/${ (props.data.Type==="Episode" ? props.data.EpisodeId : props.data.Id) }`}>
|
||||
<div className={props.data.Type==="Episode" ? "last-card-banner episode" : "last-card-banner"}>
|
||||
{props.data.ImageBlurHashes && !loaded ? <Blurhash hash={props.data.ImageBlurHashes.Primary[props.data.ImageTags.Primary]} width={'100%'} height={'100%'}/> : null}
|
||||
|
||||
{fallback ?
|
||||
<img
|
||||
className="episode"
|
||||
src={
|
||||
`${
|
||||
props.base_url +
|
||||
|
||||
@@ -11,6 +11,7 @@ import LibraryGlobalStats from './library/library-stats';
|
||||
import LibraryLastWatched from './library/last-watched';
|
||||
import RecentlyPlayed from './library/recently-added';
|
||||
import LibraryActivity from './library/library-activity';
|
||||
import LibraryItems from './library/library-items';
|
||||
|
||||
import { Tabs, Tab, Button, ButtonGroup } from 'react-bootstrap';
|
||||
|
||||
@@ -90,7 +91,7 @@ function LibraryInfo() {
|
||||
<LibraryActivity LibraryId={LibraryId}/>
|
||||
</Tab>
|
||||
<Tab eventKey="tabItems" className='bg-transparent'>
|
||||
<LibraryActivity LibraryId={LibraryId}/>
|
||||
<LibraryItems LibraryId={LibraryId}/>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</div>
|
||||
|
||||
75
src/pages/components/library/library-items.js
Normal file
75
src/pages/components/library/library-items.js
Normal file
@@ -0,0 +1,75 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import axios from "axios";
|
||||
|
||||
|
||||
import MoreItemCards from "../item-info/more-items/more-items-card";
|
||||
|
||||
|
||||
import Config from "../../../lib/config";
|
||||
import "../../css/library/media-items.css";
|
||||
|
||||
function LibraryItems(props) {
|
||||
const [data, setData] = useState();
|
||||
const [config, setConfig] = useState();
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
const fetchConfig = async () => {
|
||||
try {
|
||||
const newConfig = await Config();
|
||||
setConfig(newConfig);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const itemData = await axios.post(`/api/getLibraryItems`, {
|
||||
libraryid: props.LibraryId,
|
||||
}, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${config.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
setData(itemData.data);
|
||||
console.log(itemData.data);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
if (!config) {
|
||||
fetchConfig();
|
||||
}else{
|
||||
fetchData();
|
||||
}
|
||||
|
||||
|
||||
const intervalId = setInterval(fetchData, 60000 * 5);
|
||||
return () => clearInterval(intervalId);
|
||||
}, [config, props.LibraryId]);
|
||||
|
||||
|
||||
if (!data || !config) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="last-played">
|
||||
<h1 className="my-3">Media</h1>
|
||||
<div className="media-items-container">
|
||||
{data.map((item) => (
|
||||
<MoreItemCards data={item} base_url={config.hostUrl} key={item.Id+item.SeasonNumber+item.EpisodeNumber}/>
|
||||
))}
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default LibraryItems;
|
||||
@@ -14,15 +14,15 @@ function LibraryStatComponent(props) {
|
||||
};
|
||||
|
||||
const cardBgStyle = {
|
||||
backdropFilter: 'blur(5px)',
|
||||
// backdropFilter: 'blur(5px)',
|
||||
backgroundColor: 'rgb(0, 0, 0, 0.6)',
|
||||
height:'100%',
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<Card className="stat-card" style={cardStyle}>
|
||||
<div style={cardBgStyle}>
|
||||
<Card className="stat-card rounded-3" style={cardStyle}>
|
||||
<div style={cardBgStyle} className="rounded-3">
|
||||
<Row className="h-100">
|
||||
<Col className="d-none d-lg-block stat-card-banner">
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ function ItemStatComponent(props) {
|
||||
};
|
||||
|
||||
const cardBgStyle = {
|
||||
backdropFilter: 'blur(5px)',
|
||||
backdropFilter: props.base_url ? 'blur(5px)' : 'blur(0px)',
|
||||
backgroundColor: 'rgb(0, 0, 0, 0.6)',
|
||||
height:'100%',
|
||||
};
|
||||
|
||||
@@ -64,19 +64,13 @@ function MostActiveUsers(props) {
|
||||
}, [data, config, days,props.days]);
|
||||
|
||||
|
||||
|
||||
// const handleImageError = () => {
|
||||
// setImgError(true);
|
||||
// };
|
||||
|
||||
|
||||
if (!data || data.length === 0) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<ItemStatComponent base_url={config.hostUrl} icon={<AccountCircleFillIcon color="white" size={"100%"}/>} data={data} heading={"MOST ACTIVE USERS"} units={"Plays"}/>
|
||||
<ItemStatComponent icon={<AccountCircleFillIcon color="white" size={"100%"}/>} data={data} heading={"MOST ACTIVE USERS"} units={"Plays"}/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,10 +8,8 @@
|
||||
color: white;
|
||||
margin-bottom: 20px;
|
||||
min-height: 300px;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
.last-played-container::-webkit-scrollbar {
|
||||
width: 5px; /* set scrollbar width */
|
||||
}
|
||||
@@ -42,6 +40,7 @@
|
||||
|
||||
width: 150px;
|
||||
border-radius: 8px;
|
||||
background-color: #1e1c22;
|
||||
|
||||
}
|
||||
|
||||
@@ -49,13 +48,19 @@
|
||||
.episode{
|
||||
width: 220px !important;
|
||||
height: 128px !important;
|
||||
|
||||
}
|
||||
|
||||
.episode-card{
|
||||
width: 220px !important;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
.last-card-banner {
|
||||
width: 150px;
|
||||
height: 224px;
|
||||
height: 220px;
|
||||
transition: opacity 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
|
||||
33
src/pages/css/library/media-items.css
Normal file
33
src/pages/css/library/media-items.css
Normal file
@@ -0,0 +1,33 @@
|
||||
.media-items-container {
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(150px, 150px));
|
||||
grid-gap: 20px;
|
||||
|
||||
background-color: rgb(100, 100, 100,0.2);
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
color: white;
|
||||
margin-bottom: 20px;
|
||||
min-height: 300px;
|
||||
}
|
||||
|
||||
.media-items-container::-webkit-scrollbar {
|
||||
width: 5px; /* set scrollbar width */
|
||||
}
|
||||
|
||||
.media-items-container::-webkit-scrollbar-track {
|
||||
background-color: transparent; /* set track color */
|
||||
}
|
||||
|
||||
.media-items-container::-webkit-scrollbar-thumb {
|
||||
background-color: #8888884d; /* set thumb color */
|
||||
border-radius: 5px; /* round corners */
|
||||
width: 5px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.media-items-container::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #88888883; /* set thumb color */
|
||||
}
|
||||
@@ -12,7 +12,6 @@
|
||||
color: white;
|
||||
max-width: 500px;
|
||||
max-height: 180px;
|
||||
border-radius: 8px !important;
|
||||
}
|
||||
|
||||
.stat-card-banner
|
||||
|
||||
Reference in New Issue
Block a user