mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-07 04:20:12 +02:00
Update various components
This commit is contained in:
@@ -34,42 +34,29 @@ const MotionWrapper = styled(motion.div)<MotionWrapperProps>`
|
||||
|
||||
const ButtonMainVariant = css`
|
||||
padding: 0.5rem;
|
||||
background-color: var(--playerbar-btn-bg);
|
||||
background: var(--playerbar-btn-main-bg);
|
||||
border-radius: 50%;
|
||||
|
||||
svg {
|
||||
display: flex;
|
||||
fill: var(--playerbar-btn-fg);
|
||||
fill: var(--playerbar-btn-main-fg);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
background: var(--playerbar-btn-bg-hover);
|
||||
background: var(--playerbar-btn-main-bg-hover);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: var(--playerbar-btn-bg-hover);
|
||||
background: var(--playerbar-btn-main-bg-hover);
|
||||
|
||||
svg {
|
||||
fill: var(--playerbar-btn-fg-hover);
|
||||
fill: var(--playerbar-btn-main-fg-hover);
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const ButtonSecondaryVariant = css`
|
||||
padding: 0.5rem;
|
||||
|
||||
svg {
|
||||
display: flex;
|
||||
fill: var(--playerbar-btn-bg);
|
||||
stroke: var(--playerbar-btn-bg);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
svg {
|
||||
fill: var(--playerbar-btn-bg-hover);
|
||||
stroke: var(--playerbar-btn-bg-hover);
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const ButtonTertiaryVariant = css`
|
||||
@@ -81,8 +68,8 @@ const ButtonTertiaryVariant = css`
|
||||
|
||||
&:focus-visible {
|
||||
svg {
|
||||
fill: var(--playerbar-btn-bg-hover);
|
||||
stroke: var(--playerbar-btn-bg-hover);
|
||||
fill: var(--playerbar-btn-fg-hover);
|
||||
stroke: var(--playerbar-btn-fg-hover);
|
||||
}
|
||||
}
|
||||
`;
|
||||
@@ -95,6 +82,7 @@ const StyledPlayerButton = styled(UnstyledButton)<StyledPlayerButtonProps>`
|
||||
width: 100%;
|
||||
padding: 0.5rem;
|
||||
overflow: visible;
|
||||
background: var(--playerbar-btn-bg-hover);
|
||||
all: unset;
|
||||
cursor: default;
|
||||
|
||||
@@ -103,6 +91,7 @@ const StyledPlayerButton = styled(UnstyledButton)<StyledPlayerButtonProps>`
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
background: var(--playerbar-btn-bg-hover);
|
||||
outline: 1px var(--primary-color) solid;
|
||||
}
|
||||
|
||||
@@ -111,12 +100,18 @@ const StyledPlayerButton = styled(UnstyledButton)<StyledPlayerButtonProps>`
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: ${({ $isActive }) => $isActive && 'var(--primary-color)'};
|
||||
display: flex;
|
||||
fill: ${({ $isActive }) =>
|
||||
$isActive ? 'var(--primary-color)' : 'var(--playerbar-btn-fg)'};
|
||||
stroke: var(--playerbar-btn-fg);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: var(--playerbar-btn-bg-hover);
|
||||
|
||||
svg {
|
||||
fill: ${({ $isActive }) => !$isActive && 'var(--playerbar-btn-bg-hover)'};
|
||||
fill: ${({ $isActive }) =>
|
||||
$isActive ? 'var(--primary-color)' : 'var(--playerbar-btn-fg-hover)'};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,10 +2,16 @@ import { useMemo } from 'react';
|
||||
import { Stack, Group, Divider } from '@mantine/core';
|
||||
import { useDisclosure } from '@mantine/hooks';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import { RiDeleteBin2Line, RiEdit2Fill } from 'react-icons/ri';
|
||||
import { RiDeleteBin2Line, RiEdit2Fill, RiMore2Fill } from 'react-icons/ri';
|
||||
import { queryKeys } from '@/renderer/api/query-keys';
|
||||
import { Server, TaskType } from '@/renderer/api/types';
|
||||
import { Button, Switch, Text, toast } from '@/renderer/components';
|
||||
import {
|
||||
Button,
|
||||
DropdownMenu,
|
||||
Switch,
|
||||
Text,
|
||||
toast,
|
||||
} from '@/renderer/components';
|
||||
import { AddServerCredentialForm } from '@/renderer/features/servers/components/add-server-credential-form';
|
||||
import { AddServerUrlForm } from '@/renderer/features/servers/components/add-server-url-form';
|
||||
import { EditServerForm } from '@/renderer/features/servers/components/edit-server-form';
|
||||
@@ -134,14 +140,26 @@ export const ServerListItem = ({ server }: ServerListItemProps) => {
|
||||
|
||||
const handleToggleFolder = (folderId: string, enabled: boolean) => {
|
||||
if (enabled) {
|
||||
return disableServerFolder.mutate({
|
||||
query: { folderId, serverId: server.id },
|
||||
});
|
||||
return disableServerFolder.mutate(
|
||||
{
|
||||
query: { folderId, serverId: server.id },
|
||||
},
|
||||
{
|
||||
onError: (err) =>
|
||||
toast.error({ message: err?.response?.data?.error.message }),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return enableServerFolder.mutate({
|
||||
query: { folderId, serverId: server.id },
|
||||
});
|
||||
return enableServerFolder.mutate(
|
||||
{
|
||||
query: { folderId, serverId: server.id },
|
||||
},
|
||||
{
|
||||
onError: (err) =>
|
||||
toast.error({ message: err?.response?.data?.error.message }),
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -228,9 +246,23 @@ export const ServerListItem = ({ server }: ServerListItemProps) => {
|
||||
}
|
||||
/>
|
||||
{serverPermission >= ServerPermission.ADMIN && (
|
||||
<Button compact variant="subtle">
|
||||
<RiDeleteBin2Line color="var(--danger-color)" />
|
||||
</Button>
|
||||
<DropdownMenu position="right-start">
|
||||
<DropdownMenu.Target>
|
||||
<Button compact variant="subtle">
|
||||
<RiMore2Fill size={15} />
|
||||
</Button>
|
||||
</DropdownMenu.Target>
|
||||
<DropdownMenu.Dropdown>
|
||||
<DropdownMenu.Item
|
||||
disabled
|
||||
rightSection={
|
||||
<RiDeleteBin2Line color="var(--danger-color)" />
|
||||
}
|
||||
>
|
||||
Delete
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.Dropdown>
|
||||
</DropdownMenu>
|
||||
)}
|
||||
</>
|
||||
</Group>
|
||||
@@ -261,13 +293,25 @@ export const ServerListItem = ({ server }: ServerListItemProps) => {
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Button
|
||||
compact
|
||||
variant="subtle"
|
||||
onClick={() => handleDeleteCredential(credential.id)}
|
||||
>
|
||||
<RiDeleteBin2Line color="var(--danger-color)" />
|
||||
</Button>
|
||||
<DropdownMenu position="right-start">
|
||||
<DropdownMenu.Target>
|
||||
<Button compact variant="subtle">
|
||||
<RiMore2Fill size={15} />
|
||||
</Button>
|
||||
</DropdownMenu.Target>
|
||||
<DropdownMenu.Dropdown>
|
||||
<DropdownMenu.Item
|
||||
rightSection={
|
||||
<RiDeleteBin2Line color="var(--danger-color)" />
|
||||
}
|
||||
onClick={() =>
|
||||
handleDeleteCredential(credential.id)
|
||||
}
|
||||
>
|
||||
Delete
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.Dropdown>
|
||||
</DropdownMenu>
|
||||
</Group>
|
||||
</Group>
|
||||
))}
|
||||
@@ -275,7 +319,7 @@ export const ServerListItem = ({ server }: ServerListItemProps) => {
|
||||
<Button
|
||||
compact
|
||||
mt={10}
|
||||
variant="subtle"
|
||||
variant="default"
|
||||
onClick={() => addCredentialHandlers.open()}
|
||||
>
|
||||
Add credential
|
||||
@@ -307,13 +351,23 @@ export const ServerListItem = ({ server }: ServerListItemProps) => {
|
||||
}
|
||||
/>
|
||||
{serverPermission >= ServerPermission.EDITOR && (
|
||||
<Button
|
||||
compact
|
||||
variant="subtle"
|
||||
onClick={() => handleDeleteUrl(serverUrl.id)}
|
||||
>
|
||||
<RiDeleteBin2Line color="var(--danger-color)" />
|
||||
</Button>
|
||||
<DropdownMenu position="right-start">
|
||||
<DropdownMenu.Target>
|
||||
<Button compact variant="subtle">
|
||||
<RiMore2Fill size={15} />
|
||||
</Button>
|
||||
</DropdownMenu.Target>
|
||||
<DropdownMenu.Dropdown>
|
||||
<DropdownMenu.Item
|
||||
rightSection={
|
||||
<RiDeleteBin2Line color="var(--danger-color)" />
|
||||
}
|
||||
onClick={() => handleDeleteUrl(serverUrl.id)}
|
||||
>
|
||||
Delete
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.Dropdown>
|
||||
</DropdownMenu>
|
||||
)}
|
||||
</Group>
|
||||
</Group>
|
||||
@@ -323,7 +377,7 @@ export const ServerListItem = ({ server }: ServerListItemProps) => {
|
||||
<Button
|
||||
compact
|
||||
mt={10}
|
||||
variant="subtle"
|
||||
variant="default"
|
||||
onClick={() => addUrlHandlers.open()}
|
||||
>
|
||||
Add url
|
||||
@@ -349,6 +403,7 @@ export const ServerListItem = ({ server }: ServerListItemProps) => {
|
||||
<Divider my="xl" />
|
||||
<Button
|
||||
compact
|
||||
disabled
|
||||
leftIcon={<RiDeleteBin2Line />}
|
||||
size="xs"
|
||||
sx={{
|
||||
|
||||
@@ -31,15 +31,25 @@ export const ServerList = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Group mb={10} position="right">
|
||||
<Button
|
||||
compact
|
||||
disabled={!permissions.createServer}
|
||||
variant="subtle"
|
||||
onClick={handleAddServerModal}
|
||||
>
|
||||
Add server
|
||||
</Button>
|
||||
<Group
|
||||
mb={10}
|
||||
position="right"
|
||||
sx={{
|
||||
position: 'absolute',
|
||||
right: 45,
|
||||
transform: 'translateY(-35px)',
|
||||
}}
|
||||
>
|
||||
{permissions.isAdmin && (
|
||||
<Button
|
||||
autoFocus
|
||||
compact
|
||||
variant="default"
|
||||
onClick={handleAddServerModal}
|
||||
>
|
||||
Add server
|
||||
</Button>
|
||||
)}
|
||||
</Group>
|
||||
<Accordion variant="separated">
|
||||
{servers?.data?.map((s) => (
|
||||
|
||||
@@ -187,6 +187,7 @@ export const PlaybackTab = () => {
|
||||
{
|
||||
control: (
|
||||
<Switch
|
||||
aria-label="Toggle global media hotkeys"
|
||||
defaultChecked={settings.globalMediaHotkeys}
|
||||
disabled={!isElectron()}
|
||||
onChange={(e) => {
|
||||
@@ -241,6 +242,7 @@ export const PlaybackTab = () => {
|
||||
{
|
||||
control: (
|
||||
<Switch
|
||||
aria-label="Toggle skip buttons"
|
||||
defaultChecked={settings.skipButtons?.enabled}
|
||||
onChange={(e) =>
|
||||
update({
|
||||
|
||||
@@ -73,7 +73,7 @@ export const ActivityMenu = () => {
|
||||
{isTaskRunning ? (
|
||||
<StyledActivitySvg color="var(--primary-color)" size={15} />
|
||||
) : (
|
||||
<FiActivity size={15} />
|
||||
<FiActivity color="var(--titlebar-fg)" size={15} />
|
||||
)}
|
||||
</Button>
|
||||
</Popover.Target>
|
||||
|
||||
@@ -92,13 +92,8 @@ export const AppMenu = () => {
|
||||
return (
|
||||
<DropdownMenu withArrow withinPortal position="bottom" width={200}>
|
||||
<DropdownMenu.Target>
|
||||
<Button
|
||||
px={5}
|
||||
size="xs"
|
||||
sx={{ color: 'var(--titlebar-fg)' }}
|
||||
variant="subtle"
|
||||
>
|
||||
<RiMenu3Fill size={15} />
|
||||
<Button px={5} size="xs" variant="subtle">
|
||||
<RiMenu3Fill color="var(--titlebar-fg)" size={15} />
|
||||
</Button>
|
||||
</DropdownMenu.Target>
|
||||
<DropdownMenu.Dropdown>
|
||||
@@ -138,7 +133,7 @@ export const AppMenu = () => {
|
||||
<DropdownMenu.Item rightSection={<RiProfileLine />}>
|
||||
Edit profile
|
||||
</DropdownMenu.Item>
|
||||
{permissions.manageUsers && (
|
||||
{permissions.isAdmin && (
|
||||
<DropdownMenu.Item
|
||||
rightSection={<RiUserAddLine />}
|
||||
onClick={handleManageUsersModal}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import { ReactNode } from 'react';
|
||||
import { Group } from '@mantine/core';
|
||||
import styled from 'styled-components';
|
||||
import { Text } from '@/renderer/components';
|
||||
import { ActivityMenu } from '@/renderer/features/titlebar/components/activity-menu';
|
||||
import { AppMenu } from '@/renderer/features/titlebar/components/app-menu';
|
||||
import { useAuthStore } from '@/renderer/store';
|
||||
import { Font } from '@/renderer/styles';
|
||||
import { WindowControls } from '../../window-controls';
|
||||
|
||||
interface TitlebarProps {
|
||||
@@ -20,6 +18,7 @@ const TitlebarContainer = styled.div`
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: var(--titlebar-fg);
|
||||
|
||||
button {
|
||||
-webkit-app-region: no-drag;
|
||||
@@ -59,9 +58,7 @@ export const Titlebar = ({ children }: TitlebarProps) => {
|
||||
<>
|
||||
<TitlebarContainer>
|
||||
<Left>
|
||||
<Group>
|
||||
<Text font={Font.POPPINS}>Feishin</Text>
|
||||
</Group>
|
||||
<Group>Feishin</Group>
|
||||
</Left>
|
||||
<Center />
|
||||
<Right>
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
import React from 'react';
|
||||
import { Avatar, Group, Stack } from '@mantine/core';
|
||||
import { openContextModal } from '@mantine/modals';
|
||||
import { RiAdminLine, RiDeleteBin2Line, RiEdit2Line } from 'react-icons/ri';
|
||||
import {
|
||||
RiAdminLine,
|
||||
RiDeleteBin2Line,
|
||||
RiEdit2Line,
|
||||
RiMore2Fill,
|
||||
} from 'react-icons/ri';
|
||||
import { User } from '@/renderer/api/types';
|
||||
import {
|
||||
Button,
|
||||
ContextModalVars,
|
||||
Popover,
|
||||
DropdownMenu,
|
||||
Text,
|
||||
toast,
|
||||
Tooltip,
|
||||
@@ -74,75 +80,87 @@ export const UserList = () => {
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
<Group mb={10} position="right">
|
||||
<Button compact variant="default" onClick={handleAddUserModal}>
|
||||
<Group
|
||||
mb={10}
|
||||
position="right"
|
||||
sx={{
|
||||
position: 'absolute',
|
||||
right: 45,
|
||||
transform: 'translateY(-35px)',
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
autoFocus
|
||||
compact
|
||||
variant="default"
|
||||
onClick={handleAddUserModal}
|
||||
>
|
||||
Add user
|
||||
</Button>
|
||||
</Group>
|
||||
{users?.data?.map((u) => (
|
||||
<Group
|
||||
key={u.id}
|
||||
noWrap
|
||||
position="apart"
|
||||
sx={{
|
||||
'&:hover': {
|
||||
background: 'rgba(125, 125, 125, 0.1)',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Group>
|
||||
<Avatar radius="xl" />
|
||||
<Text overflow="hidden">
|
||||
{u.displayName ? u.displayName : u.username}{' '}
|
||||
{u.isAdmin && (
|
||||
<Tooltip label="Admin">
|
||||
<span>
|
||||
<RiAdminLine />
|
||||
</span>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Text>
|
||||
</Group>
|
||||
<Group>
|
||||
<Button
|
||||
compact
|
||||
disabled={!permissions.isAdmin}
|
||||
leftIcon={<RiEdit2Line />}
|
||||
variant="subtle"
|
||||
onClick={() => handleEditUserModal(u)}
|
||||
>
|
||||
Edit
|
||||
</Button>
|
||||
<Popover position="bottom-start">
|
||||
<Popover.Target>
|
||||
<Button
|
||||
compact
|
||||
disabled={!permissions.isAdmin}
|
||||
variant="subtle"
|
||||
>
|
||||
<RiDeleteBin2Line color="var(--danger-color)" size={15} />
|
||||
</Button>
|
||||
</Popover.Target>
|
||||
<Popover.Dropdown>
|
||||
<Group>
|
||||
<React.Fragment key={u.id}>
|
||||
<Group
|
||||
noWrap
|
||||
position="apart"
|
||||
sx={{
|
||||
'&:hover': {
|
||||
background: 'rgba(125, 125, 125, 0.1)',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Group>
|
||||
<Avatar radius="xl" />
|
||||
<Stack spacing="xs">
|
||||
<Text overflow="hidden">
|
||||
{u.username}
|
||||
{(u.isSuperAdmin || u.isAdmin) && (
|
||||
<Tooltip label={u.isSuperAdmin ? 'Super Admin' : 'Admin'}>
|
||||
<span>
|
||||
<RiAdminLine />
|
||||
</span>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Text>
|
||||
<Text $secondary size="xs">
|
||||
{u.displayName}
|
||||
</Text>
|
||||
</Stack>
|
||||
</Group>
|
||||
<Group>
|
||||
<Button
|
||||
compact
|
||||
disabled={!permissions.isAdmin}
|
||||
leftIcon={<RiEdit2Line />}
|
||||
variant="subtle"
|
||||
onClick={() => handleEditUserModal(u)}
|
||||
>
|
||||
Edit
|
||||
</Button>
|
||||
<DropdownMenu position="right-start">
|
||||
<DropdownMenu.Target>
|
||||
<Button
|
||||
compact
|
||||
uppercase
|
||||
sx={{
|
||||
'&:hover': {
|
||||
background: 'var(--danger-color)',
|
||||
},
|
||||
background: 'var(--danger-color)',
|
||||
}}
|
||||
disabled={!permissions.isAdmin}
|
||||
variant="subtle"
|
||||
>
|
||||
<RiMore2Fill size={15} />
|
||||
</Button>
|
||||
</DropdownMenu.Target>
|
||||
<DropdownMenu.Dropdown>
|
||||
<DropdownMenu.Item
|
||||
rightSection={
|
||||
<RiDeleteBin2Line color="var(--danger-color)" />
|
||||
}
|
||||
onClick={() => handleDeleteUser(u)}
|
||||
>
|
||||
Delete
|
||||
</Button>
|
||||
</Group>
|
||||
</Popover.Dropdown>
|
||||
</Popover>
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.Dropdown>
|
||||
</DropdownMenu>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</React.Fragment>
|
||||
))}
|
||||
</Stack>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user