chore: auto-commit (5 archivos)
- backend/dist/assets/index-DFLRkdHe.js - backend/dist/assets/index-DT3pghXY.js - backend/dist/assets/index-UVzY_37O.js - backend/dist/index.html - frontend/src/components/CardChatPanel.tsx Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+1318
File diff suppressed because one or more lines are too long
-1283
File diff suppressed because one or more lines are too long
-1280
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Kanban</title>
|
<title>Kanban</title>
|
||||||
<script type="module" crossorigin src="/assets/index-UVzY_37O.js"></script>
|
<script type="module" crossorigin src="/assets/index-DFLRkdHe.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-b0xjFtx2.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-b0xjFtx2.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
Avatar,
|
Avatar,
|
||||||
Badge,
|
|
||||||
Box,
|
Box,
|
||||||
Combobox,
|
Combobox,
|
||||||
FileButton,
|
FileButton,
|
||||||
@@ -20,7 +19,6 @@ import { notifications } from "@mantine/notifications";
|
|||||||
import {
|
import {
|
||||||
DragEvent,
|
DragEvent,
|
||||||
KeyboardEvent,
|
KeyboardEvent,
|
||||||
ReactNode,
|
|
||||||
useCallback,
|
useCallback,
|
||||||
useEffect,
|
useEffect,
|
||||||
useMemo,
|
useMemo,
|
||||||
@@ -78,38 +76,6 @@ function detectMention(value: string, cursor: number): MentionMatch | null {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const mentionRegex = /(^|\s)(@[a-z0-9][a-z0-9_.-]{0,63})/gi;
|
|
||||||
|
|
||||||
function renderBody(body: string, knownUsers: Map<string, User>): ReactNode {
|
|
||||||
const out: ReactNode[] = [];
|
|
||||||
let last = 0;
|
|
||||||
let key = 0;
|
|
||||||
for (const m of body.matchAll(mentionRegex)) {
|
|
||||||
const handle = m[2].slice(1).toLowerCase();
|
|
||||||
const idx = (m.index ?? 0) + m[1].length;
|
|
||||||
if (idx > last) out.push(body.slice(last, idx));
|
|
||||||
const user = knownUsers.get(handle);
|
|
||||||
if (user) {
|
|
||||||
out.push(
|
|
||||||
<Badge
|
|
||||||
key={`m${key++}`}
|
|
||||||
size="xs"
|
|
||||||
variant="light"
|
|
||||||
color={user.color || tagColor(user.username)}
|
|
||||||
style={{ verticalAlign: "middle" }}
|
|
||||||
>
|
|
||||||
@{user.username}
|
|
||||||
</Badge>,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
out.push(`@${handle}`);
|
|
||||||
}
|
|
||||||
last = idx + m[2].length;
|
|
||||||
}
|
|
||||||
if (last < body.length) out.push(body.slice(last));
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function CardChatPanel({
|
export function CardChatPanel({
|
||||||
cardId,
|
cardId,
|
||||||
users,
|
users,
|
||||||
@@ -132,7 +98,6 @@ export function CardChatPanel({
|
|||||||
const lastTypingEmitRef = useRef(0);
|
const lastTypingEmitRef = useRef(0);
|
||||||
|
|
||||||
const usersById = useMemo(() => new Map(users.map((u) => [u.id, u])), [users]);
|
const usersById = useMemo(() => new Map(users.map((u) => [u.id, u])), [users]);
|
||||||
const usersByUsername = useMemo(() => new Map(users.map((u) => [u.username.toLowerCase(), u])), [users]);
|
|
||||||
|
|
||||||
const reload = useCallback(async () => {
|
const reload = useCallback(async () => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user