mirror of
https://github.com/Sonarr/Sonarr.git
synced 2026-04-18 21:35:27 -04:00
Fixed: Truncating long text in the middle when it shouldn't be truncated
Closes #7413
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import MiddleTruncate from 'react-middle-truncate';
|
||||
import Label, { LabelProps } from 'Components/Label';
|
||||
import IconButton from 'Components/Link/IconButton';
|
||||
import Link from 'Components/Link/Link';
|
||||
import MiddleTruncate from 'Components/MiddleTruncate';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import { TagBase } from './TagInput';
|
||||
import styles from './TagInputTag.css';
|
||||
@@ -58,7 +58,7 @@ function TagInputTag<T extends TagBase>({
|
||||
tabIndex={-1}
|
||||
onPress={handleDelete}
|
||||
>
|
||||
<MiddleTruncate text={String(tag.name)} start={10} end={10} />
|
||||
<MiddleTruncate text={String(tag.name)} />
|
||||
</Link>
|
||||
|
||||
{canEdit ? (
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import useMeasure from 'Helpers/Hooks/useMeasure';
|
||||
|
||||
interface MiddleTruncateProps {
|
||||
text: string;
|
||||
}
|
||||
|
||||
function getTruncatedText(text: string, length: number) {
|
||||
return `${text.slice(0, length)}...${text.slice(text.length - length)}`;
|
||||
}
|
||||
|
||||
function MiddleTruncate({ text }: MiddleTruncateProps) {
|
||||
const [containerRef, { width: containerWidth }] = useMeasure();
|
||||
const [textRef, { width: textWidth }] = useMeasure();
|
||||
const [truncatedText, setTruncatedText] = useState(text);
|
||||
const truncatedTextRef = useRef(text);
|
||||
|
||||
useEffect(() => {
|
||||
setTruncatedText(text);
|
||||
}, [text]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!containerWidth || !textWidth) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (textWidth <= containerWidth) {
|
||||
return;
|
||||
}
|
||||
|
||||
const characterLength = textWidth / text.length;
|
||||
const charactersToRemove =
|
||||
Math.ceil(text.length - containerWidth / characterLength) + 3;
|
||||
let length = Math.ceil(text.length / 2 - charactersToRemove / 2);
|
||||
|
||||
let updatedText = getTruncatedText(text, length);
|
||||
|
||||
// Make sure if the text is still too long, we keep reducing the length
|
||||
// each time we re-run this.
|
||||
while (
|
||||
updatedText.length >= truncatedTextRef.current.length &&
|
||||
length > 10
|
||||
) {
|
||||
length--;
|
||||
updatedText = getTruncatedText(text, length);
|
||||
}
|
||||
|
||||
// Store the value in the ref so we can compare it in the next render,
|
||||
// without triggering this effect every time we change the text.
|
||||
truncatedTextRef.current = updatedText;
|
||||
setTruncatedText(updatedText);
|
||||
}, [text, truncatedTextRef, containerWidth, textWidth]);
|
||||
|
||||
return (
|
||||
<div ref={containerRef} style={{ whiteSpace: 'nowrap' }}>
|
||||
<div ref={textRef} style={{ display: 'inline-block' }}>
|
||||
{truncatedText}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default MiddleTruncate;
|
||||
+6
-6
@@ -1,9 +1,9 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import MiddleTruncate from 'react-middle-truncate';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { Tag } from 'App/State/TagsAppState';
|
||||
import Card from 'Components/Card';
|
||||
import Label from 'Components/Label';
|
||||
import MiddleTruncate from 'Components/MiddleTruncate';
|
||||
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
||||
import TagList from 'Components/TagList';
|
||||
import useModalOpenState from 'Helpers/Hooks/useModalOpenState';
|
||||
@@ -13,14 +13,14 @@ import Indexer from 'typings/Indexer';
|
||||
import ReleaseProfile from 'typings/Settings/ReleaseProfile';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import EditReleaseProfileModal from './EditReleaseProfileModal';
|
||||
import styles from './ReleaseProfileRow.css';
|
||||
import styles from './ReleaseProfileItem.css';
|
||||
|
||||
interface ReleaseProfileProps extends ReleaseProfile {
|
||||
tagList: Tag[];
|
||||
indexerList: Indexer[];
|
||||
}
|
||||
|
||||
function ReleaseProfileRow(props: ReleaseProfileProps) {
|
||||
function ReleaseProfileItem(props: ReleaseProfileProps) {
|
||||
const {
|
||||
id,
|
||||
name,
|
||||
@@ -70,7 +70,7 @@ function ReleaseProfileRow(props: ReleaseProfileProps) {
|
||||
|
||||
return (
|
||||
<Label key={item} className={styles.label} kind={kinds.SUCCESS}>
|
||||
<MiddleTruncate text={item} start={10} end={10} />
|
||||
<MiddleTruncate text={item} />
|
||||
</Label>
|
||||
);
|
||||
})}
|
||||
@@ -84,7 +84,7 @@ function ReleaseProfileRow(props: ReleaseProfileProps) {
|
||||
|
||||
return (
|
||||
<Label key={item} className={styles.label} kind={kinds.DANGER}>
|
||||
<MiddleTruncate text={item} start={10} end={10} />
|
||||
<MiddleTruncate text={item} />
|
||||
</Label>
|
||||
);
|
||||
})}
|
||||
@@ -128,4 +128,4 @@ function ReleaseProfileRow(props: ReleaseProfileProps) {
|
||||
);
|
||||
}
|
||||
|
||||
export default ReleaseProfileRow;
|
||||
export default ReleaseProfileItem;
|
||||
@@ -4,7 +4,7 @@
|
||||
}
|
||||
|
||||
.addReleaseProfile {
|
||||
composes: releaseProfile from '~./ReleaseProfileRow.css';
|
||||
composes: releaseProfile from '~./ReleaseProfileItem.css';
|
||||
|
||||
background-color: var(--cardAlternateBackgroundColor);
|
||||
color: var(--gray);
|
||||
|
||||
@@ -14,7 +14,7 @@ import createClientSideCollectionSelector from 'Store/Selectors/createClientSide
|
||||
import createTagsSelector from 'Store/Selectors/createTagsSelector';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import EditReleaseProfileModal from './EditReleaseProfileModal';
|
||||
import ReleaseProfileRow from './ReleaseProfileRow';
|
||||
import ReleaseProfileItem from './ReleaseProfileItem';
|
||||
import styles from './ReleaseProfiles.css';
|
||||
|
||||
function ReleaseProfiles() {
|
||||
@@ -59,7 +59,7 @@ function ReleaseProfiles() {
|
||||
|
||||
{items.map((item) => {
|
||||
return (
|
||||
<ReleaseProfileRow
|
||||
<ReleaseProfileItem
|
||||
key={item.id}
|
||||
tagList={tagList}
|
||||
indexerList={indexerList}
|
||||
|
||||
Reference in New Issue
Block a user