Linkify URLs and preserve line breaks in question messages
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useState, useEffect, useCallback, useRef } from "react";
|
import { useState, useEffect, useCallback, useRef } from "react";
|
||||||
|
import { linkify } from "@/lib/linkify";
|
||||||
|
|
||||||
interface FileAttachment {
|
interface FileAttachment {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -322,7 +323,7 @@ export function QuestionSplitView({ currentUserId }: { currentUserId: string })
|
|||||||
<p className="text-xs mb-1" style={{ color: "var(--muted-foreground)" }}>
|
<p className="text-xs mb-1" style={{ color: "var(--muted-foreground)" }}>
|
||||||
{msg.author.name} · {formatDate(msg.createdAt)}
|
{msg.author.name} · {formatDate(msg.createdAt)}
|
||||||
</p>
|
</p>
|
||||||
<p style={{ color: "var(--foreground)" }}>{msg.text}</p>
|
<p style={{ color: "var(--foreground)", whiteSpace: "pre-wrap" }}>{linkify(msg.text)}</p>
|
||||||
{msg.files && msg.files.length > 0 && (
|
{msg.files && msg.files.length > 0 && (
|
||||||
<div className="flex flex-col gap-1 mt-2">
|
<div className="flex flex-col gap-1 mt-2">
|
||||||
{msg.files.map((f) => (
|
{msg.files.map((f) => (
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useState, useRef, useEffect } from "react";
|
import { useState, useRef, useEffect } from "react";
|
||||||
|
import { linkify } from "@/lib/linkify";
|
||||||
|
|
||||||
interface FileAttachment {
|
interface FileAttachment {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -140,7 +141,7 @@ export function QuestionThread({
|
|||||||
<strong style={{ color: "#323232" }}> · 🔵 новое</strong>
|
<strong style={{ color: "#323232" }}> · 🔵 новое</strong>
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
<p style={{ color: "var(--foreground)" }}>{msg.text}</p>
|
<p style={{ color: "var(--foreground)", whiteSpace: "pre-wrap" }}>{linkify(msg.text)}</p>
|
||||||
{msg.files && msg.files.length > 0 && (
|
{msg.files && msg.files.length > 0 && (
|
||||||
<div className="flex flex-col gap-1 mt-2">
|
<div className="flex flex-col gap-1 mt-2">
|
||||||
{msg.files.map((f, i) => (
|
{msg.files.map((f, i) => (
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { Fragment, type ReactNode } from "react";
|
||||||
|
|
||||||
|
const URL_RE = /(https?:\/\/[^\s<>()]+[^\s<>().,;:!?])/g;
|
||||||
|
|
||||||
|
export function linkify(text: string): ReactNode[] {
|
||||||
|
if (!text) return [];
|
||||||
|
const parts = text.split(URL_RE);
|
||||||
|
return parts.map((part, i) => {
|
||||||
|
if (URL_RE.test(part)) {
|
||||||
|
URL_RE.lastIndex = 0;
|
||||||
|
return (
|
||||||
|
<a
|
||||||
|
key={i}
|
||||||
|
href={part}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="underline break-all"
|
||||||
|
style={{ color: "var(--foreground)" }}
|
||||||
|
>
|
||||||
|
{part}
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return <Fragment key={i}>{part}</Fragment>;
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user