Initial changes for total time view

This commit is contained in:
Sanidhya Singh
2025-05-05 15:39:05 +05:30
parent 54185bb221
commit f05d9fb948
4 changed files with 171 additions and 8 deletions

View File

@@ -0,0 +1,121 @@
exports.up = async function (knex) {
try {
await knex.schema.raw(`
DROP FUNCTION IF EXISTS public.fs_watch_stats_over_time(integer);
CREATE OR REPLACE FUNCTION public.fs_watch_stats_over_time(
days integer)
RETURNS TABLE("Date" date, "Count" bigint, "TotalTime" bigint, "Library" text, "LibraryID" text)
LANGUAGE 'plpgsql'
COST 100
VOLATILE PARALLEL UNSAFE
ROWS 1000
AS $BODY$
BEGIN
RETURN QUERY
SELECT
dates."Date",
COALESCE(counts."Count", 0) AS "Count",
COALESCE(counts."TotalTime", 0) AS "TotalTime",
l."Name" as "Library",
l."Id" as "LibraryID"
FROM
(SELECT generate_series(
DATE_TRUNC('day', NOW() - CAST(days || ' days' as INTERVAL)),
DATE_TRUNC('day', NOW()),
'1 day')::DATE AS "Date"
) dates
CROSS JOIN jf_libraries l
LEFT JOIN
(SELECT
DATE_TRUNC('day', a."ActivityDateInserted")::DATE AS "Date",
COUNT(*) AS "Count",
(SUM(a."PlaybackDuration") / 60)::bigint AS "TotalTime",
l."Name" as "Library"
FROM
jf_playback_activity a
JOIN jf_library_items i ON i."Id" = a."NowPlayingItemId"
JOIN jf_libraries l ON i."ParentId" = l."Id"
WHERE
a."ActivityDateInserted" BETWEEN NOW() - CAST(days || ' days' as INTERVAL) AND NOW()
GROUP BY
l."Name", DATE_TRUNC('day', a."ActivityDateInserted")
) counts
ON counts."Date" = dates."Date" AND counts."Library" = l."Name"
where l.archived=false
ORDER BY
"Date", "Library";
END;
$BODY$;
ALTER FUNCTION public.fs_watch_stats_over_time(integer)
OWNER TO "${process.env.POSTGRES_ROLE}";
`);
} catch (error) {
console.error(error);
}
};
exports.down = async function (knex) {
// try {
// await knex.schema.raw(`
// DROP FUNCTION IF EXISTS public.fs_watch_stats_over_time(integer);
// CREATE OR REPLACE FUNCTION fs_watch_stats_over_time(
// days integer
// )
// RETURNS TABLE(
// "Date" date,
// "Count" bigint,
// "Library" text
// )
// LANGUAGE 'plpgsql'
// COST 100
// VOLATILE PARALLEL UNSAFE
// ROWS 1000
// AS $BODY$
// BEGIN
// RETURN QUERY
// SELECT
// dates."Date",
// COALESCE(counts."Count", 0) AS "Count",
// l."Name" as "Library"
// FROM
// (SELECT generate_series(
// DATE_TRUNC('day', NOW() - CAST(days || ' days' as INTERVAL)),
// DATE_TRUNC('day', NOW()),
// '1 day')::DATE AS "Date"
// ) dates
// CROSS JOIN jf_libraries l
// LEFT JOIN
// (SELECT
// DATE_TRUNC('day', a."ActivityDateInserted")::DATE AS "Date",
// COUNT(*) AS "Count",
// l."Name" as "Library"
// FROM
// jf_playback_activity a
// JOIN jf_library_items i ON i."Id" = a."NowPlayingItemId"
// JOIN jf_libraries l ON i."ParentId" = l."Id"
// WHERE
// a."ActivityDateInserted" BETWEEN NOW() - CAST(days || ' days' as INTERVAL) AND NOW()
// GROUP BY
// l."Name", DATE_TRUNC('day', a."ActivityDateInserted")
// ) counts
// ON counts."Date" = dates."Date" AND counts."Library" = l."Name"
// ORDER BY
// "Date", "Library";
// END;
// $BODY$;
// ALTER FUNCTION fs_watch_stats_over_time(integer)
// OWNER TO "${process.env.POSTGRES_ROLE}";`);
// } catch (error) {
// console.error(error);
// }
};

View File

@@ -167,7 +167,9 @@
"STAT_PAGE": {
"STATISTICS": "Statistics",
"DAILY_PLAY_PER_LIBRARY": "Daily Play Count Per Library",
"PLAY_COUNT_BY": "Play Count By"
"PLAY_COUNT_BY": "Play Count By",
"COUNT_VIEW": "Total Count",
"TIME_VIEW": "Total Time"
},
"SETTINGS_PAGE": {
"SETTINGS": "Settings",

View File

@@ -143,3 +143,12 @@ input[type="number"] {
.item-name :hover {
color: var(--secondary-color) !important;
}
.pill-wrapper {
color: white;
display: flex;
border-radius: 8px;
font-size: 1.2em;
align-self: flex-end;
justify-content: center;
}

View File

@@ -1,3 +1,4 @@
import { Tabs, Tab } from "react-bootstrap";
import { useState } from "react";
import "./css/stats.css";
@@ -20,6 +21,13 @@ function Statistics() {
localStorage.setItem("PREF_STATISTICS_STAT_DAYS_INPUT", event.target.value);
};
const [activeTab, setActiveTab] = useState(localStorage.getItem(`PREF_STATISTICS_LAST_SELECTED_TAB`) ?? "tabCount");
function setTab(tabName) {
setActiveTab(tabName);
localStorage.setItem(`PREF_STATISTICS_LAST_SELECTED_TAB`, tabName);
}
const handleKeyDown = (event) => {
if (event.key === "Enter") {
if (input < 1) {
@@ -43,6 +51,17 @@ function Statistics() {
<h1>
<Trans i18nKey={"STAT_PAGE.STATISTICS"} />
</h1>
<div className="pill-wrapper">
<Tabs
activeKey={activeTab}
onSelect={setTab}
variant="pills"
className="custom-tabs"
>
<Tab eventKey="tabCount" title={<Trans i18nKey="STAT_PAGE.COUNT_VIEW" />} />
<Tab eventKey="tabTime" title={<Trans i18nKey="STAT_PAGE.TIME_VIEW" />} />
</Tabs>
</div>
<div className="date-range">
<div className="header">
<Trans i18nKey={"LAST"} />
@@ -55,14 +74,26 @@ function Statistics() {
</div>
</div>
</div>
<div>
<DailyPlayStats days={days} />
<div className="statistics-graphs">
<PlayStatsByDay days={days} />
<PlayStatsByHour days={days} />
</div>
</div>
{activeTab === "tabCount" && (
<>
<DailyPlayStats days={days} />
<div className="statistics-graphs">
<PlayStatsByDay days={days} />
<PlayStatsByHour days={days} />
</div>
</>
)}
{activeTab === "tabTime" && (
<>
<DailyPlayStats days={days} />
<div className="statistics-graphs">
<PlayStatsByDay days={days} />
<PlayStatsByHour days={days} />
</div>
</>
)}
</div>
);
}