ui: UI/chat form follow ups (#26743)
* ui: split the markdown rendering setting per surface User content and thinking get their own toggle again, so turning off markdown for a message leaves reasoning blocks formatted. Both default to markdown. A stored renderContentAsRawText unfolds onto the user key and is dropped from the config. File mentions render as badges in the raw text path too, through a narrow pass over [name](file://path) that leaves everything else untouched. * ui: let the rich chat input scroll past its max height The contenteditable renderer caps its height with max-height but had no overflow rule, so a long buffer overflowed into the input area wrapper and got clipped by its overflow-hidden, leaving no way to reach the bottom of the message. The textarea renderer scrolls natively and was never affected. * ui: apply the new lint and format config * ui: move the render keys unfolding into the migration service Address review from @allozaur: the settings store no longer rewrites persisted config on load, the raw text toggle now unfolds onto the per-surface render keys in migration.service.ts, next to the other config migrations. The mention scanner flag and the directory path suffix become named constants.
This commit is contained in:
@@ -240,6 +240,7 @@ export {
|
||||
MENTION_BADGE_FOLDER_ICON_PATHS,
|
||||
getMentionBadgeIconPaths,
|
||||
getMentionBadgeLabel,
|
||||
splitMentionSegments,
|
||||
buildMentionInsertion
|
||||
} from './mention-badge';
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { abbreviateHome, lastPathSegment } from './path-display';
|
||||
import { FILE_URI_PREFIX } from '$lib/constants';
|
||||
import { DIRECTORY_PATH_SUFFIX, FILE_URI_PREFIX } from '$lib/constants';
|
||||
import {
|
||||
MENTION_BADGE_FILE_ICON_PATHS,
|
||||
MENTION_BADGE_FOLDER_ICON_PATHS
|
||||
MENTION_BADGE_FOLDER_ICON_PATHS,
|
||||
MENTION_LINK_SCAN_FLAGS
|
||||
} from '$lib/constants/mention-badge';
|
||||
import { FileMentionEntryType } from '$lib/enums';
|
||||
import type { FileMentionEntry } from '$lib/types';
|
||||
@@ -48,8 +49,45 @@ export function decodeFileLinkPath(path: string): string {
|
||||
}
|
||||
}
|
||||
|
||||
export interface MentionTextSegment {
|
||||
text: string;
|
||||
mention: { name: string; path: string } | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Split raw text into plain runs and `[name](file://path)` mentions.
|
||||
* The raw-text renderers walk these segments to draw badges without
|
||||
* handing the message to the markdown parser, so a `#` stays a `#`.
|
||||
*/
|
||||
export function splitMentionSegments(value: string): MentionTextSegment[] {
|
||||
const linkRe = fileMentionLinkRe(MENTION_LINK_SCAN_FLAGS);
|
||||
const segments: MentionTextSegment[] = [];
|
||||
|
||||
let cursor = 0;
|
||||
let match: RegExpExecArray | null;
|
||||
|
||||
while ((match = linkRe.exec(value)) !== null) {
|
||||
if (match.index > cursor) {
|
||||
segments.push({ mention: null, text: value.slice(cursor, match.index) });
|
||||
}
|
||||
|
||||
segments.push({
|
||||
mention: { name: match[1], path: decodeFileLinkPath(match[2]) },
|
||||
text: match[0]
|
||||
});
|
||||
|
||||
cursor = match.index + match[0].length;
|
||||
}
|
||||
|
||||
if (cursor < value.length) segments.push({ mention: null, text: value.slice(cursor) });
|
||||
|
||||
return segments;
|
||||
}
|
||||
|
||||
export function getMentionBadgeIconPaths(path: string): readonly string[] {
|
||||
return path.endsWith('/') ? MENTION_BADGE_FOLDER_ICON_PATHS : MENTION_BADGE_FILE_ICON_PATHS;
|
||||
return path.endsWith(DIRECTORY_PATH_SUFFIX)
|
||||
? MENTION_BADGE_FOLDER_ICON_PATHS
|
||||
: MENTION_BADGE_FILE_ICON_PATHS;
|
||||
}
|
||||
|
||||
export function getMentionBadgeLabel(
|
||||
|
||||
Reference in New Issue
Block a user