Enhancement: 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.

This commit is contained in:
SergeantPanda 2026-03-26 21:16:18 -05:00
parent af54366d76
commit 8e9a6285a4
2 changed files with 58 additions and 14 deletions

View file

@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- 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.
- TLS and mutual TLS (mTLS) support for Redis and PostgreSQL connections in modular deployments. Supports encrypted connections, server certificate verification (Redis: on/off; PostgreSQL: verify-full, verify-ca, require), CA certificate configuration, and client certificate authentication. Configured via environment variables in the docker compose file. Includes startup validation for certificate paths and TLS/URL scheme conflicts, and a read-only Connection Security panel in System Settings. (Closes #950) — Thanks [@CodeBormen](https://github.com/CodeBormen)
- Status filter for M3U group and VOD category filter modals: A new **All / Enabled / Disabled** segmented control is now shown alongside the text search input in the Live, VOD - Movies, and VOD - Series tabs of the M3U Group Filter modal. The status filter works in combination with the text search and also scopes the "Select Visible" / "Deselect Visible" buttons so they only act on the currently visible subset. (Closes #312)

View file

@ -1,12 +1,7 @@
import React, { useRef, useState, useMemo } from 'react';
import { Link, useLocation } from 'react-router-dom';
import { copyToClipboard } from '../utils';
import {
Copy,
LogOut,
ChevronDown,
ChevronRight,
} from 'lucide-react';
import { Copy, LogOut, ChevronDown, ChevronRight, Heart } from 'lucide-react';
import { getOrderedNavItems } from '../config/navigation';
import {
Avatar,
@ -19,6 +14,7 @@ import {
ActionIcon,
AppShellNavbar,
ScrollArea,
Tooltip,
} from '@mantine/core';
import logo from '../images/logo.png';
import useChannelsStore from '../store/channels';
@ -29,6 +25,21 @@ import { USER_LEVELS } from '../constants';
import UserForm from './forms/User';
import NotificationCenter from './NotificationCenter';
const DonateButton = ({ tooltipPosition = 'top' }) => (
<Tooltip label="Support Dispatcharr" position={tooltipPosition}>
<ActionIcon
component="a"
href="https://opencollective.com/dispatcharr/contribute"
target="_blank"
rel="noopener noreferrer"
variant="transparent"
color="pink"
>
<Heart size={20} />
</ActionIcon>
</Tooltip>
);
const NavLink = ({ item, isActive, collapsed }) => {
const IconComponent = item.icon;
return (
@ -328,24 +339,56 @@ const Sidebar = ({ collapsed, toggleDrawer, drawerWidth, miniDrawerWidth }) => {
{!collapsed && (
<Group
gap="xs"
wrap="nowrap"
style={{ padding: '0 16px 16px', justifyContent: 'space-between' }}
>
<Text size="xs" c="dimmed">
v{appVersion?.version || '0.0.0'}
{appVersion?.timestamp ? `-${appVersion.timestamp}` : ''}
</Text>
{isAuthenticated && <NotificationCenter />}
<Tooltip
label={`v${appVersion?.version || '0.0.0'}${appVersion?.timestamp ? `-${appVersion.timestamp}` : ''}`}
position="top"
>
<Text
size="xs"
c="dimmed"
style={{
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
minWidth: 0,
flex: 1,
cursor: 'pointer',
}}
onClick={() =>
copyToClipboard(
`v${appVersion?.version || '0.0.0'}${appVersion?.timestamp ? `-${appVersion.timestamp}` : ''}`,
{
successTitle: 'Copied',
successMessage: 'Version copied to clipboard',
}
)
}
>
v{appVersion?.version || '0.0.0'}
{appVersion?.timestamp ? `-${appVersion.timestamp}` : ''}
</Text>
</Tooltip>
<Group gap="xs" wrap="nowrap">
<DonateButton />
{isAuthenticated && <NotificationCenter />}
</Group>
</Group>
)}
{collapsed && isAuthenticated && (
{collapsed && (
<Box
style={{
padding: '0 16px 16px',
display: 'flex',
justifyContent: 'center',
flexDirection: 'column',
alignItems: 'center',
gap: 8,
}}
>
<NotificationCenter />
{isAuthenticated && <NotificationCenter />}
<DonateButton tooltipPosition="right" />
</Box>
)}