💄 Optimize thoughts

This commit is contained in:
2025-11-15 21:15:41 +08:00
parent 5e9341a19c
commit a9c8f49797
3 changed files with 75 additions and 76 deletions

View File

@@ -608,26 +608,30 @@ class FileListView extends HookConsumerWidget {
previewWidget = getFileIcon(file, size: 48); previewWidget = getFileIcon(file, size: 48);
break; break;
case 'text': case 'text':
previewWidget = FutureBuilder<String>( previewWidget = Container(
future: ref color: Theme.of(context).colorScheme.surfaceContainer,
.read(apiClientProvider) child: FutureBuilder<String>(
.get(uri) future: ref
.then((response) => response.data as String), .read(apiClientProvider)
builder: .get(uri)
(context, snapshot) => .then((response) => response.data as String),
snapshot.hasData builder:
? SingleChildScrollView( (context, snapshot) =>
child: Text( snapshot.hasData
snapshot.data!, ? SingleChildScrollView(
style: const TextStyle( padding: EdgeInsets.all(24),
fontSize: 8, child: Text(
fontFamily: 'monospace', snapshot.data!,
style: const TextStyle(
fontSize: 9,
fontFamily: 'monospace',
),
maxLines: 20,
overflow: TextOverflow.ellipsis,
), ),
maxLines: 20, )
overflow: TextOverflow.ellipsis, : const Center(child: CircularProgressIndicator()),
), ),
)
: const Center(child: CircularProgressIndicator()),
); );
break; break;
case 'application' when file.mimeType == 'application/pdf': case 'application' when file.mimeType == 'application/pdf':

View File

@@ -32,59 +32,36 @@ class ThoughtContent extends StatelessWidget {
// Streaming text with spinner // Streaming text with spinner
if (streamingText.isNotEmpty) { if (streamingText.isNotEmpty) {
final isStreamingError = streamingText.startsWith('Error:'); final isStreamingError = streamingText.startsWith('Error:');
return Row( return Container(
crossAxisAlignment: CrossAxisAlignment.start, padding: isStreamingError ? const EdgeInsets.all(8) : EdgeInsets.zero,
children: [ decoration:
Expanded( isStreamingError
child: Container( ? BoxDecoration(
padding: border: Border.all(
isStreamingError color: Theme.of(context).colorScheme.error,
? const EdgeInsets.all(8) width: 1,
: EdgeInsets.zero,
decoration:
isStreamingError
? BoxDecoration(
border: Border.all(
color: Theme.of(context).colorScheme.error,
width: 1,
),
borderRadius: BorderRadius.circular(8),
)
: null,
child: MarkdownTextContent(
isSelectable: true,
content: streamingText,
extraBlockSyntaxList: [ProposalBlockSyntax()],
textStyle: Theme.of(context).textTheme.bodyMedium!.copyWith(
color:
isStreamingError
? Theme.of(context).colorScheme.error
: null,
),
extraGenerators: [
ProposalGenerator(
backgroundColor:
Theme.of(context).colorScheme.secondaryContainer,
foregroundColor:
Theme.of(context).colorScheme.onSecondaryContainer,
borderColor: Theme.of(context).colorScheme.outline,
), ),
], borderRadius: BorderRadius.circular(8),
), )
), : null,
child: MarkdownTextContent(
isSelectable: true,
content: streamingText,
extraBlockSyntaxList: [ProposalBlockSyntax()],
textStyle: Theme.of(context).textTheme.bodyMedium!.copyWith(
color:
isStreamingError ? Theme.of(context).colorScheme.error : null,
), ),
const SizedBox(width: 8), extraGenerators: [
SizedBox( ProposalGenerator(
width: 16, backgroundColor:
height: 16, Theme.of(context).colorScheme.secondaryContainer,
child: CircularProgressIndicator( foregroundColor:
strokeWidth: 2, Theme.of(context).colorScheme.onSecondaryContainer,
valueColor: AlwaysStoppedAnimation<Color>( borderColor: Theme.of(context).colorScheme.outline,
Theme.of(context).colorScheme.primary,
),
), ),
), ],
], ),
); );
} }
return const SizedBox.shrink(); return const SizedBox.shrink();

View File

@@ -719,10 +719,27 @@ class ThoughtItem extends StatelessWidget {
spacing: 8, spacing: 8,
children: [ children: [
// Main content // Main content
ThoughtContent( Row(
isStreaming: isStreaming, mainAxisSize: MainAxisSize.min,
streamingText: streamingText, crossAxisAlignment: CrossAxisAlignment.end,
thought: thought, children: [
Flexible(
child: ThoughtContent(
isStreaming: isStreaming,
streamingText: streamingText,
thought: thought,
),
),
if (isStreaming && isAI)
SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(
strokeWidth: 2.5,
padding: const EdgeInsets.all(4),
),
),
],
), ),
// Reasoning chunks (streaming only) // Reasoning chunks (streaming only)
@@ -743,7 +760,10 @@ class ThoughtItem extends StatelessWidget {
), ),
// Token count and model name (for completed AI thoughts only) // Token count and model name (for completed AI thoughts only)
if (!isStreaming && isAI && thought != null) if (!isStreaming &&
isAI &&
thought != null &&
!thought!.id.startsWith('error-'))
TokenInfo(thought: thought!), TokenInfo(thought: thought!),
// Proposals (for completed AI thoughts only) // Proposals (for completed AI thoughts only)
@@ -752,8 +772,6 @@ class ThoughtItem extends StatelessWidget {
proposals: proposals, proposals: proposals,
onProposalAction: _handleProposalAction, onProposalAction: _handleProposalAction,
), ),
if (isStreaming && isAI) LinearProgressIndicator(),
], ],
), ),
), ),