mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-07-18 00:55:50 +00:00
Enhancement: Show username in VOD cards.
This commit is contained in:
parent
30246a4d49
commit
38f5156ca6
3 changed files with 30 additions and 8 deletions
|
|
@ -19,8 +19,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
### Added
|
||||
|
||||
- Connection cards on the Stats page now show the **username** of the connected user in a new User column (between IP Address and Connected). The username is resolved from the user store using the `user_id` stored in Redis client metadata; unauthenticated connections display "Anonymous". (Closes #766, Closes #586)
|
||||
- `ip_address` and `user_id` were not included in the client info returned by `get_detailed_channel_info()` despite being available in the Redis hash. Both fields are now extracted and returned.
|
||||
- Connection cards on the Stats page now show the **username** of the connected user. For live channel connections a new User column appears between IP Address and Connected; for VOD connections the username is shown inline next to the IP address in the Client summary row. The username is resolved from the user store using the `user_id` stored in Redis client metadata. (Closes #766, Closes #586)
|
||||
- `ip_address` and `user_id` were not included in the client info returned by `get_detailed_channel_info()` despite being available in the Redis hash. Both fields are now extracted and returned. `user_id` is now also included in the VOD stats response.
|
||||
- Donate button added to the sidebar footer. A heart icon links to the project's Open Collective page, visible in both expanded and collapsed states. Hovering shows a "Support Dispatcharr" tooltip. The version string is also now clickable to copy it to the clipboard.
|
||||
- User stream limits: administrators can now set a maximum number of concurrent streams per user account. When a user reaches their limit, the system can automatically terminate an existing stream to free a slot based on configurable rules. Limit enforcement applies to both live channels and VOD. (Closes #544)
|
||||
- Each user account has a new **Stream Limit** field (0 = unlimited) configurable from the user edit form in Settings → Users.
|
||||
|
|
|
|||
|
|
@ -949,6 +949,7 @@ class VODStatsView(View):
|
|||
'm3u_profile': m3u_profile_info,
|
||||
'client_id': client_id,
|
||||
'client_ip': combined_data.get('client_ip', 'Unknown'),
|
||||
'user_id': combined_data.get('user_id', '0'),
|
||||
'user_agent': combined_data.get('client_user_agent', 'Unknown'),
|
||||
'connected_at': combined_data.get('created_at'),
|
||||
'last_activity': combined_data.get('last_activity'),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// Format duration for content length
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import logo from '../../images/logo.png';
|
||||
import {
|
||||
ActionIcon,
|
||||
|
|
@ -38,6 +38,7 @@ import {
|
|||
getMovieDisplayTitle,
|
||||
getMovieSubtitle,
|
||||
} from '../../utils/cards/VodConnectionCardUtils.js';
|
||||
import useUsersStore from '../../store/users.jsx';
|
||||
|
||||
const ClientDetails = ({ connection, connectionStartTime }) => {
|
||||
return (
|
||||
|
|
@ -142,7 +143,10 @@ const ClientDetails = ({ connection, connectionStartTime }) => {
|
|||
};
|
||||
|
||||
const ConnectionProgress = ({ connection, durationSecs }) => {
|
||||
const { totalTime, currentTime, percentage } = calculateProgress(connection, durationSecs);
|
||||
const { totalTime, currentTime, percentage } = calculateProgress(
|
||||
connection,
|
||||
durationSecs
|
||||
);
|
||||
return totalTime > 0 ? (
|
||||
<Stack gap="xs" mt="sm">
|
||||
<Group justify="space-between" align="center">
|
||||
|
|
@ -172,6 +176,14 @@ const ConnectionProgress = ({ connection, durationSecs }) => {
|
|||
const VodConnectionCard = ({ vodContent, stopVODClient }) => {
|
||||
const { fullDateTimeFormat } = useDateTimeFormat();
|
||||
const [isClientExpanded, setIsClientExpanded] = useState(false);
|
||||
const users = useUsersStore((s) => s.users);
|
||||
const usersMap = useMemo(() => {
|
||||
const map = {};
|
||||
users.forEach((u) => {
|
||||
map[String(u.id)] = u.username;
|
||||
});
|
||||
return map;
|
||||
}, [users]);
|
||||
const [, setUpdateTrigger] = useState(0); // Force re-renders for progress updates
|
||||
|
||||
// Get metadata from the VOD content
|
||||
|
|
@ -377,13 +389,12 @@ const VodConnectionCard = ({ vodContent, stopVODClient }) => {
|
|||
</Group>
|
||||
|
||||
{/* Progress bar - show current position in content */}
|
||||
{connection &&
|
||||
metadata.duration_secs &&
|
||||
{connection && metadata.duration_secs && (
|
||||
<ConnectionProgress
|
||||
connection={connection}
|
||||
durationSecs={metadata.duration_secs}
|
||||
/>
|
||||
}
|
||||
)}
|
||||
|
||||
{/* Client information section - collapsible like channel cards */}
|
||||
{connection && (
|
||||
|
|
@ -403,11 +414,21 @@ const VodConnectionCard = ({ vodContent, stopVODClient }) => {
|
|||
>
|
||||
<Group gap={8}>
|
||||
<Text size="sm" fw={500} color="dimmed">
|
||||
Client:
|
||||
Client IP:
|
||||
</Text>
|
||||
<Text size="sm" ff={'monospace'}>
|
||||
{connection.client_ip || 'Unknown IP'}
|
||||
</Text>
|
||||
{usersMap[String(connection.user_id)] && (
|
||||
<>
|
||||
<Text size="sm" c="dimmed">
|
||||
User:
|
||||
</Text>
|
||||
<Text size="sm">
|
||||
{usersMap[String(connection.user_id)]}
|
||||
</Text>
|
||||
</>
|
||||
)}
|
||||
</Group>
|
||||
|
||||
<Group gap={8}>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue