mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
TextPreview component init
This commit is contained in:
parent
130169ec8e
commit
d26ae3f428
@ -15,7 +15,7 @@ import {
|
||||
PopupView,
|
||||
PopupButton,
|
||||
StartEndView,
|
||||
TextView,
|
||||
TextPreview,
|
||||
PopupForm,
|
||||
PopupStartEndInput,
|
||||
PopupTextAreaInput,
|
||||
@ -114,7 +114,7 @@ function MapContainer({ layers, map }: { layers: LayerProps[]; map: any }) {
|
||||
{layer.itemType.show_profile_button && (
|
||||
<PopupButton url={'/item'} parameterField={'id'} text={'Profile'} />
|
||||
)}
|
||||
{layer.itemType.show_text && <TextView truncate></TextView>}
|
||||
{layer.itemType.show_text && <TextPreview></TextPreview>}
|
||||
</PopupView>
|
||||
<PopupForm>
|
||||
{layer.itemType.show_name_input && (
|
||||
|
||||
@ -6,6 +6,7 @@ import {
|
||||
PopupCheckboxInput as PlainPopupCheckboxInput,
|
||||
PopupTextAreaInput as PlainPopupTextAreaInput,
|
||||
PopupStartEndInput as PlainPopupStartEndInput,
|
||||
TextPreview as PlainTextPreview,
|
||||
} from '#components/Map/Subcomponents/ItemPopupComponents'
|
||||
|
||||
import { templateify } from './templateify'
|
||||
@ -14,6 +15,7 @@ export { PopupForm } from './PopupForm'
|
||||
export { PopupView } from './PopupView'
|
||||
|
||||
export const TextView = templateify(PlainTextView)
|
||||
export const TextPreview = templateify(PlainTextPreview)
|
||||
export const StartEndView = templateify(PlainStartEndView)
|
||||
export const PopupTextInput = templateify(PlainPopupTextInput)
|
||||
export const PopupButton = templateify(PlainPopupButton)
|
||||
|
||||
@ -0,0 +1,47 @@
|
||||
import { useAddFilterTag } from '#components/Map/hooks/useFilter'
|
||||
import { useTags } from '#components/Map/hooks/useTags'
|
||||
import { decodeTag } from '#utils/FormatTags'
|
||||
|
||||
import type { Item } from '#types/Item'
|
||||
import type { Tag } from '#types/Tag'
|
||||
|
||||
const MAX_CHARS = 100
|
||||
|
||||
/**
|
||||
* @category Map
|
||||
*/
|
||||
export const TextPreview = ({ item }: { item: Item }) => {
|
||||
const tags = useTags()
|
||||
|
||||
if (!item.text) return ''
|
||||
const s = item.text
|
||||
.replace(/`([^`]+)`/g, '$1')
|
||||
.replace(/<\/?[^>]+>/g, '') // übrige HTML
|
||||
.replace(/!\[.*?\]\(.*?\)/g, '') // Remove images
|
||||
.replace(/(`{1,3})(.*?)\1/g, '$2') // Remove inline code
|
||||
.replace(/(\*{1,2}|_{1,2})(.*?)\1/g, '$2') // Remove bold and italic
|
||||
.replace(/(#+)\s+(.*)/g, '$2') // Remove headers
|
||||
.replace(/>\s+(.*)/g, '$1') // Remove blockquotes
|
||||
.replace(/^\s*\n/gm, '\n') // Preserve empty lines
|
||||
.replace(/(\r\n|\n|\r)/gm, '\n') // Preserve line breaks
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
const HashTag = ({ children, tag, itemId }: { children: string; tag: Tag; itemId?: string }) => {
|
||||
const addFilterTag = useAddFilterTag()
|
||||
|
||||
return (
|
||||
<a
|
||||
className='hashtag'
|
||||
style={{ color: tag.color }}
|
||||
key={`${tag.name}-${itemId ?? ''}`}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
addFilterTag(tag)
|
||||
}}
|
||||
>
|
||||
{decodeTag(children)}
|
||||
</a>
|
||||
)
|
||||
}
|
||||
@ -6,32 +6,16 @@ import type { Item } from '#types/Item'
|
||||
/**
|
||||
* @category Map
|
||||
*/
|
||||
export const TextView = ({
|
||||
item,
|
||||
text,
|
||||
truncate = false,
|
||||
rawText,
|
||||
}: {
|
||||
item?: Item
|
||||
text?: string
|
||||
truncate?: boolean
|
||||
rawText?: string
|
||||
}) => {
|
||||
if (item) {
|
||||
text = item.text
|
||||
}
|
||||
|
||||
export const TextView = ({ item, rawText }: { item?: Item; rawText?: string }) => {
|
||||
let innerText = ''
|
||||
let replacedText = ''
|
||||
|
||||
if (rawText) {
|
||||
innerText = replacedText = rawText
|
||||
} else if (text) {
|
||||
innerText = text
|
||||
} else if (item) {
|
||||
innerText = item.text ?? ''
|
||||
}
|
||||
|
||||
if (innerText && truncate) innerText = truncateMarkdown(innerText, 100)
|
||||
|
||||
if (innerText) replacedText = fixUrls(innerText)
|
||||
|
||||
if (replacedText) {
|
||||
@ -42,7 +26,3 @@ export const TextView = ({
|
||||
|
||||
return <RichTextEditor defaultValue={replacedText} readOnly={true} />
|
||||
}
|
||||
|
||||
export function truncateMarkdown(markdown: string, limit: number): string {
|
||||
return markdown.slice(0, limit)
|
||||
}
|
||||
|
||||
@ -5,3 +5,4 @@ export { PopupCheckboxInput } from './PopupCheckboxInput'
|
||||
export { TextView } from './TextView'
|
||||
export { StartEndView } from './StartEndView'
|
||||
export { PopupButton } from './PopupButton'
|
||||
export { TextPreview } from './TextPreview'
|
||||
|
||||
@ -18,8 +18,8 @@ import { usePopupForm } from '#components/Map/hooks/usePopupForm'
|
||||
import { useSetSelectPosition } from '#components/Map/hooks/useSelectPosition'
|
||||
import { timeAgo } from '#utils/TimeAgo'
|
||||
|
||||
import { TextPreview } from './ItemPopupComponents'
|
||||
import { HeaderView } from './ItemPopupComponents/HeaderView'
|
||||
import { TextView } from './ItemPopupComponents/TextView'
|
||||
|
||||
import type { Item } from '#types/Item'
|
||||
|
||||
@ -101,7 +101,7 @@ export const ItemViewPopup = forwardRef((props: ItemViewPopupProps, ref: any) =>
|
||||
loading={loading}
|
||||
/>
|
||||
<div className='tw:overflow-hidden tw:max-h-64 fade'>
|
||||
{props.children ?? <TextView text={props.item.text} />}
|
||||
{props.children ?? <TextPreview item={props.item} />}
|
||||
</div>
|
||||
<div className='tw:flex tw:-mb-1 tw:flex-row tw:mr-2 tw:mt-1'>
|
||||
{infoExpanded ? (
|
||||
|
||||
@ -5,7 +5,7 @@ import type { Item } from '#types/Item'
|
||||
export const SimpleView = ({ item }: { item: Item }) => {
|
||||
return (
|
||||
<div className='tw:mt-8 tw:h-full tw:overflow-y-auto fade tw:px-6'>
|
||||
<TextView text={item.text} />
|
||||
<TextView rawText={item.text} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ import { useNavigate } from 'react-router-dom'
|
||||
|
||||
import { RichTextEditor } from '#components/Input/RichTextEditor/RichTextEditor'
|
||||
import { useUpdateItem } from '#components/Map/hooks/useItems'
|
||||
import { PopupStartEndInput, TextView } from '#components/Map/Subcomponents/ItemPopupComponents'
|
||||
import { PopupStartEndInput, TextPreview } from '#components/Map/Subcomponents/ItemPopupComponents'
|
||||
import { ActionButton } from '#components/Profile/Subcomponents/ActionsButton'
|
||||
import { LinkedItemsHeaderView } from '#components/Profile/Subcomponents/LinkedItemsHeaderView'
|
||||
import { TagsWidget } from '#components/Profile/Subcomponents/TagsWidget'
|
||||
@ -142,7 +142,7 @@ export const TabsForm = ({
|
||||
loading={loading}
|
||||
/>
|
||||
<div className='tw:overflow-y-auto tw:overflow-x-hidden tw:max-h-64 fade'>
|
||||
<TextView truncate />
|
||||
<TextPreview item={i} />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
@ -12,7 +12,11 @@ import { Link, useNavigate } from 'react-router-dom'
|
||||
import { useAppState } from '#components/AppShell/hooks/useAppState'
|
||||
import { useAddFilterTag } from '#components/Map/hooks/useFilter'
|
||||
import { useItems } from '#components/Map/hooks/useItems'
|
||||
import { StartEndView, TextView } from '#components/Map/Subcomponents/ItemPopupComponents'
|
||||
import {
|
||||
StartEndView,
|
||||
TextPreview,
|
||||
TextView,
|
||||
} from '#components/Map/Subcomponents/ItemPopupComponents'
|
||||
import { ActionButton } from '#components/Profile/Subcomponents/ActionsButton'
|
||||
import { LinkedItemsHeaderView } from '#components/Profile/Subcomponents/LinkedItemsHeaderView'
|
||||
import { TagView } from '#components/Templates/TagView'
|
||||
@ -104,9 +108,9 @@ export const TabsView = ({
|
||||
<StartEndView item={item}></StartEndView>
|
||||
</div>
|
||||
)}
|
||||
<TextView text={item.text} />
|
||||
<TextView rawText={item.text} />
|
||||
<div className='tw:h-4'></div>
|
||||
<TextView text={item.contact} />
|
||||
<TextView rawText={item.contact} />
|
||||
</div>
|
||||
{item.layer?.itemType.questlog && (
|
||||
<>
|
||||
@ -275,7 +279,7 @@ export const TabsView = ({
|
||||
loading={loading}
|
||||
/>
|
||||
<div className='tw:overflow-y-auto tw:overflow-x-hidden tw:max-h-64 fade'>
|
||||
<TextView truncate text={i.text} />
|
||||
<TextPreview item={i} />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
@ -3,7 +3,7 @@ import { useNavigate } from 'react-router-dom'
|
||||
|
||||
import { useSetSelectPosition } from '#components/Map/hooks/useSelectPosition'
|
||||
import useWindowDimensions from '#components/Map/hooks/useWindowDimension'
|
||||
import { StartEndView, TextView } from '#components/Map/Subcomponents/ItemPopupComponents'
|
||||
import { StartEndView, TextPreview } from '#components/Map/Subcomponents/ItemPopupComponents'
|
||||
import { HeaderView } from '#components/Map/Subcomponents/ItemPopupComponents/HeaderView'
|
||||
|
||||
import { DateUserInfo } from './DateUserInfo'
|
||||
@ -51,7 +51,7 @@ export const ItemCard = ({
|
||||
></HeaderView>
|
||||
<div className='tw:overflow-y-auto tw:overflow-x-hidden tw:max-h-64 fade'>
|
||||
{i.layer?.itemType.show_start_end && <StartEndView item={i}></StartEndView>}
|
||||
{i.layer?.itemType.show_text && <TextView truncate text={i.text} />}
|
||||
{i.layer?.itemType.show_text && <TextPreview item={i} />}
|
||||
</div>
|
||||
<DateUserInfo item={i}></DateUserInfo>
|
||||
</div>
|
||||
|
||||
10
package-lock.json
generated
10
package-lock.json
generated
@ -1,10 +0,0 @@
|
||||
{
|
||||
"name": "utopia-map",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "utopia-map"
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user