feat: 添加URL高亮功能,支持yxdim协议解析

This commit is contained in:
2026-03-07 18:20:01 +07:00
parent 047ea3a77a
commit a11cde5a96
3 changed files with 106 additions and 16 deletions

View File

@@ -95,6 +95,7 @@
v-if="item.type === TYPES.MSG_TEXT"
:content="item.getMessageContent()"
:messageItem="item"
:enableURLHighlight="true"
/>
<ProgressMessage
v-else-if="item.type === TYPES.MSG_IMAGE"

View File

@@ -56,21 +56,97 @@
url?: string
}
interface URLSegment {
type: string
text: string
url?: string
}
const props = withDefaults(defineProps<IProps>(), {
content: () => ({}),
messageItem: () => ({} as IMessageModel),
messageItem: () => ({}) as IMessageModel,
enableURLHighlight: false
})
const processedContent = ref<TextItem>([])
const processedContent = ref<TextItem[]>([])
const YXDIM_SCHEMA_REGEXP = /((https?|yxdim):\/\/[^\s]+)/g
function splitYxdimSchema(text: string): URLSegment[] {
if (!text) {
return []
}
const result: URLSegment[] = []
let lastIndex = 0
const matches = text.matchAll(YXDIM_SCHEMA_REGEXP)
for (const match of matches) {
const matchedText = match[0]
const startIndex = match.index ?? -1
if (startIndex < 0) {
continue
}
if (startIndex > lastIndex) {
result.push({
type: 'text',
text: text.slice(lastIndex, startIndex)
})
}
result.push({
type: 'url',
text: matchedText,
url: matchedText
})
lastIndex = startIndex + matchedText.length
}
if (!result.length) {
return [{ type: 'text', text }]
}
if (lastIndex < text.length) {
result.push({
type: 'text',
text: text.slice(lastIndex)
})
}
return result
}
function parseMessageTextWithLinks(text: string): URLSegment[] {
if (!parseTextAndValidateUrls) {
console.warn(
'parseTextAndValidateUrls not found. Please update @tencentcloud/universal-api to 2.3.7 or higher.'
)
return splitYxdimSchema(text)
}
const segments = parseTextAndValidateUrls(text)
if (!segments?.length) {
return splitYxdimSchema(text)
}
return segments
.map((segment: URLSegment) => {
if (segment.type !== 'text') {
return [segment]
}
return splitYxdimSchema(segment.text)
})
.flat()
}
watch(
() => props.messageItem,
(newValue: IMessageModel, oldValue: IMessageModel) => {
(newValue: IMessageModel, oldValue?: IMessageModel) => {
if (newValue?.ID === oldValue?.ID) {
return
}
console.log('messageItem=========', newValue)
if (props.enableURLHighlight) {
TUIReportService.reportFeature(208)
}
@@ -83,6 +159,7 @@
props.messageItem.ID
)?.getMessageContent()?.text
}
processedContent.value =
processedContent.value || props.content?.text
@@ -122,13 +199,8 @@
item.name === 'text' &&
item.text
) {
if (!parseTextAndValidateUrls) {
console.warn(
'parseTextAndValidateUrls not found. Please update @tencentcloud/universal-api to 2.3.7 or higher.'
)
return item
}
const segments = parseTextAndValidateUrls(item.text)
const segments = parseMessageTextWithLinks(item.text)
console.log('segments=========', segments)
if (segments.length) {
return segments.map(segment => ({
name: segment.type,
@@ -149,15 +221,31 @@
)
// Function to handle navigation
function navigateToUrl(url: string) {
function navigateToUrl(url?: string) {
if (url) {
if (/^https?:\/\//i.test(url)) {
TUIGlobal.open(url, '_blank')
return
}
if (/^yxdim:\/\//i.test(url)) {
if (isUniFrameWork) {
const appPath = url.replace(/^yxdim:\/\//i, '/')
TUIGlobal.navigateTo({
url: appPath
})
return
}
TUIGlobal.open(url, '_self')
return
}
if (isUniFrameWork) {
// Use UniApp navigation
TUIGlobal.navigateTo({
url: `/pages/views/webview?url=${url}` // Assuming you have a webview page to handle external URLs
url
})
} else {
// Use standard browser navigation
TUIGlobal.open(url, '_blank')
}
}

View File

@@ -57,7 +57,8 @@
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
],
"debuggable" : true
"debuggable" : true,
"schemes" : "yxdim"
},
/* ios */
"ios" : {