✨ AI Post Insight
This commit is contained in:
parent
03275b46ca
commit
38dcaa6066
@ -554,6 +554,9 @@
|
|||||||
"postImageShareAds": "Explore posts on the Solar Network",
|
"postImageShareAds": "Explore posts on the Solar Network",
|
||||||
"postShare": "Share",
|
"postShare": "Share",
|
||||||
"postShareImage": "Share via Image",
|
"postShareImage": "Share via Image",
|
||||||
|
"postGetInsight": "Get Insight",
|
||||||
|
"postGetInsightTitle": "AI Insight",
|
||||||
|
"postGetInsightDescription": "AI may make mistakes, check important information.",
|
||||||
"appInitializing": "Initializing",
|
"appInitializing": "Initializing",
|
||||||
"poweredBy": "Powered by {}",
|
"poweredBy": "Powered by {}",
|
||||||
"shareIntent": "Share",
|
"shareIntent": "Share",
|
||||||
@ -600,5 +603,6 @@
|
|||||||
"walletCurrency": {
|
"walletCurrency": {
|
||||||
"one": "{} Source Point",
|
"one": "{} Source Point",
|
||||||
"other": "{} Source Points"
|
"other": "{} Source Points"
|
||||||
}
|
},
|
||||||
|
"aiThinkingProcess": "AI Thinking Process"
|
||||||
}
|
}
|
||||||
|
@ -552,6 +552,9 @@
|
|||||||
"postImageShareAds": "来 Solar Network 探索更多有趣帖子",
|
"postImageShareAds": "来 Solar Network 探索更多有趣帖子",
|
||||||
"postShare": "分享",
|
"postShare": "分享",
|
||||||
"postShareImage": "分享帖图",
|
"postShareImage": "分享帖图",
|
||||||
|
"postGetInsight": "获取见解",
|
||||||
|
"postGetInsightTitle": "AI 见解",
|
||||||
|
"postGetInsightDescription": "AI 可能会出错,检查信息真实性。",
|
||||||
"appInitializing": "正在初始化",
|
"appInitializing": "正在初始化",
|
||||||
"poweredBy": "由 {} 提供支持",
|
"poweredBy": "由 {} 提供支持",
|
||||||
"shareIntent": "分享",
|
"shareIntent": "分享",
|
||||||
@ -598,5 +601,6 @@
|
|||||||
"walletCurrency": {
|
"walletCurrency": {
|
||||||
"one": "{} 源点",
|
"one": "{} 源点",
|
||||||
"other": "{} 源点"
|
"other": "{} 源点"
|
||||||
}
|
},
|
||||||
|
"aiThinkingProcess": "AI 思考过程"
|
||||||
}
|
}
|
||||||
|
@ -552,6 +552,9 @@
|
|||||||
"postImageShareAds": "來 Solar Network 探索更多有趣帖子",
|
"postImageShareAds": "來 Solar Network 探索更多有趣帖子",
|
||||||
"postShare": "分享",
|
"postShare": "分享",
|
||||||
"postShareImage": "分享帖圖",
|
"postShareImage": "分享帖圖",
|
||||||
|
"postGetInsight": "獲取見解",
|
||||||
|
"postGetInsightTitle": "AI 見解",
|
||||||
|
"postGetInsightDescription": "AI 可能會出錯,檢查信息真實性。",
|
||||||
"appInitializing": "正在初始化",
|
"appInitializing": "正在初始化",
|
||||||
"poweredBy": "由 {} 提供支持",
|
"poweredBy": "由 {} 提供支持",
|
||||||
"shareIntent": "分享",
|
"shareIntent": "分享",
|
||||||
@ -598,5 +601,6 @@
|
|||||||
"walletCurrency": {
|
"walletCurrency": {
|
||||||
"one": "{} 源點",
|
"one": "{} 源點",
|
||||||
"other": "{} 源點"
|
"other": "{} 源點"
|
||||||
}
|
},
|
||||||
|
"aiThinkingProcess": "AI 思考過程"
|
||||||
}
|
}
|
||||||
|
@ -552,6 +552,9 @@
|
|||||||
"postImageShareAds": "來 Solar Network 探索更多有趣帖子",
|
"postImageShareAds": "來 Solar Network 探索更多有趣帖子",
|
||||||
"postShare": "分享",
|
"postShare": "分享",
|
||||||
"postShareImage": "分享帖圖",
|
"postShareImage": "分享帖圖",
|
||||||
|
"postGetInsight": "獲取見解",
|
||||||
|
"postGetInsightTitle": "AI 見解",
|
||||||
|
"postGetInsightDescription": "AI 可能會出錯,檢查信息真實性。",
|
||||||
"appInitializing": "正在初始化",
|
"appInitializing": "正在初始化",
|
||||||
"poweredBy": "由 {} 提供支持",
|
"poweredBy": "由 {} 提供支持",
|
||||||
"shareIntent": "分享",
|
"shareIntent": "分享",
|
||||||
@ -598,5 +601,6 @@
|
|||||||
"walletCurrency": {
|
"walletCurrency": {
|
||||||
"one": "{} 源點",
|
"one": "{} 源點",
|
||||||
"other": "{} 源點"
|
"other": "{} 源點"
|
||||||
}
|
},
|
||||||
|
"aiThinkingProcess": "AI 思考過程"
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
import 'dart:convert';
|
|
||||||
import 'dart:developer';
|
|
||||||
|
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
import 'dart:developer';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math' as math;
|
import 'dart:math' as math;
|
||||||
|
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:file_saver/file_saver.dart';
|
import 'package:file_saver/file_saver.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
@ -34,6 +36,7 @@ import 'package:surface/widgets/post/post_meta_editor.dart';
|
|||||||
import 'package:surface/widgets/post/post_reaction.dart';
|
import 'package:surface/widgets/post/post_reaction.dart';
|
||||||
import 'package:surface/widgets/post/publisher_popover.dart';
|
import 'package:surface/widgets/post/publisher_popover.dart';
|
||||||
import 'package:surface/widgets/universal_image.dart';
|
import 'package:surface/widgets/universal_image.dart';
|
||||||
|
import 'package:xml/xml.dart';
|
||||||
|
|
||||||
class PostItem extends StatelessWidget {
|
class PostItem extends StatelessWidget {
|
||||||
final SnPost data;
|
final SnPost data;
|
||||||
@ -817,6 +820,22 @@ class _PostContentHeader extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
const PopupMenuDivider(),
|
const PopupMenuDivider(),
|
||||||
|
PopupMenuItem(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
const Icon(Symbols.book_4_spark),
|
||||||
|
const Gap(16),
|
||||||
|
Text('postGetInsight').tr(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => _PostGetInsightSheet(postId: data.id),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const PopupMenuDivider(),
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
onTap: onShare,
|
onTap: onShare,
|
||||||
child: Row(
|
child: Row(
|
||||||
@ -1181,3 +1200,96 @@ class _PostAbuseReportDialogState extends State<_PostAbuseReportDialog> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _PostGetInsightSheet extends StatefulWidget {
|
||||||
|
final int postId;
|
||||||
|
|
||||||
|
const _PostGetInsightSheet({required this.postId});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<_PostGetInsightSheet> createState() => _PostGetInsightSheetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PostGetInsightSheetState extends State<_PostGetInsightSheet> {
|
||||||
|
String? _response;
|
||||||
|
String? _thinkingProcess;
|
||||||
|
|
||||||
|
Future<void> _fetchResponse() async {
|
||||||
|
try {
|
||||||
|
final sn = context.read<SnNetworkProvider>();
|
||||||
|
final resp = await sn.client.get('/cgi/co/posts/${widget.postId}/insight',
|
||||||
|
options: Options(
|
||||||
|
sendTimeout: const Duration(minutes: 10),
|
||||||
|
receiveTimeout: const Duration(minutes: 10),
|
||||||
|
));
|
||||||
|
final out = resp.data['response'] as String;
|
||||||
|
final document = XmlDocument.parse(out);
|
||||||
|
_thinkingProcess = document.getElement('think')?.innerText.trim();
|
||||||
|
RegExp cleanThinkingRegExp = RegExp(r'<think>[\s\S]*?</think>');
|
||||||
|
setState(() => _response = out.replaceAll(cleanThinkingRegExp, '').trim());
|
||||||
|
} catch (err) {
|
||||||
|
if (!mounted) return;
|
||||||
|
context.showErrorDialog(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_fetchResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
const Icon(Symbols.book_4_spark, size: 24),
|
||||||
|
const Gap(16),
|
||||||
|
Text('postGetInsightTitle', style: Theme.of(context).textTheme.titleLarge).tr(),
|
||||||
|
],
|
||||||
|
).padding(horizontal: 20, top: 16, bottom: 12),
|
||||||
|
const Gap(4),
|
||||||
|
Text('postGetInsightDescription', style: Theme.of(context).textTheme.bodySmall).tr().padding(horizontal: 20),
|
||||||
|
const Gap(4),
|
||||||
|
if (_response == null)
|
||||||
|
Expanded(
|
||||||
|
child: Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
else
|
||||||
|
Expanded(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
if (_thinkingProcess != null && _thinkingProcess!.isNotEmpty)
|
||||||
|
ExpansionTile(
|
||||||
|
leading: const Icon(Symbols.info),
|
||||||
|
title: Text('aiThinkingProcess'.tr()),
|
||||||
|
tilePadding: const EdgeInsets.symmetric(horizontal: 20),
|
||||||
|
collapsedBackgroundColor: Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||||
|
minTileHeight: 32,
|
||||||
|
children: [
|
||||||
|
SelectableText(
|
||||||
|
_thinkingProcess!,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium!.copyWith(fontStyle: FontStyle.italic),
|
||||||
|
).padding(horizontal: 20, vertical: 8),
|
||||||
|
],
|
||||||
|
).padding(vertical: 8),
|
||||||
|
SelectionArea(
|
||||||
|
child: MarkdownTextContent(
|
||||||
|
content: _response!,
|
||||||
|
),
|
||||||
|
).padding(horizontal: 20, top: 8),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -8,6 +8,7 @@ import Foundation
|
|||||||
import bitsdojo_window_macos
|
import bitsdojo_window_macos
|
||||||
import connectivity_plus
|
import connectivity_plus
|
||||||
import device_info_plus
|
import device_info_plus
|
||||||
|
import file_picker
|
||||||
import file_saver
|
import file_saver
|
||||||
import file_selector_macos
|
import file_selector_macos
|
||||||
import firebase_analytics
|
import firebase_analytics
|
||||||
@ -36,6 +37,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
|||||||
BitsdojoWindowPlugin.register(with: registry.registrar(forPlugin: "BitsdojoWindowPlugin"))
|
BitsdojoWindowPlugin.register(with: registry.registrar(forPlugin: "BitsdojoWindowPlugin"))
|
||||||
ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin"))
|
ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin"))
|
||||||
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||||
|
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
|
||||||
FileSaverPlugin.register(with: registry.registrar(forPlugin: "FileSaverPlugin"))
|
FileSaverPlugin.register(with: registry.registrar(forPlugin: "FileSaverPlugin"))
|
||||||
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
||||||
FLTFirebaseAnalyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAnalyticsPlugin"))
|
FLTFirebaseAnalyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAnalyticsPlugin"))
|
||||||
|
34
pubspec.lock
34
pubspec.lock
@ -362,10 +362,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: device_info_plus
|
name: device_info_plus
|
||||||
sha256: b37d37c2f912ad4e8ec694187de87d05de2a3cb82b465ff1f65f65a2d05de544
|
sha256: e3fc9a65820fef83035af8ee8c09004a719d5d1d54e6de978fcb0d84bbeb241a
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "11.2.1"
|
version: "11.2.2"
|
||||||
device_info_plus_platform_interface:
|
device_info_plus_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -378,10 +378,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: dio
|
name: dio
|
||||||
sha256: "5598aa796bbf4699afd5c67c0f5f6e2ed542afc956884b9cd58c306966efc260"
|
sha256: "253a18bbd4851fecba42f7343a1df3a9a4c1d31a2c1b37e221086b4fa8c8dbc9"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.7.0"
|
version: "5.8.0+1"
|
||||||
dio_smart_retry:
|
dio_smart_retry:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -394,10 +394,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: dio_web_adapter
|
name: dio_web_adapter
|
||||||
sha256: "33259a9276d6cea88774a0000cfae0d861003497755969c92faa223108620dc8"
|
sha256: e485c7a39ff2b384fa1d7e09b4e25f755804de8384358049124830b04fc4f93a
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.1.0"
|
||||||
dismissible_page:
|
dismissible_page:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -490,10 +490,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: file_picker
|
name: file_picker
|
||||||
sha256: c904b4ab56d53385563c7c39d8e9fa9af086f91495dfc48717ad84a42c3cf204
|
sha256: c9943dd7d702ab4199d199bc151a2d79c86db031a02ad84566dab58c494d2adc
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.1.7"
|
version: "8.3.1"
|
||||||
file_saver:
|
file_saver:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -886,10 +886,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: go_router
|
name: go_router
|
||||||
sha256: daf3ff5570f55396b2d2c9bf8136d7db3a8acf208ac0cef92a3ae2beb9a81550
|
sha256: "9b736a9fa879d8ad6df7932cbdcc58237c173ab004ef90d8377923d7ad731eaa"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "14.7.1"
|
version: "14.7.2"
|
||||||
google_fonts:
|
google_fonts:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -1334,10 +1334,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: package_info_plus
|
name: package_info_plus
|
||||||
sha256: "739e0a5c3c4055152520fa321d0645ee98e932718b4c8efeeb51451968fe0790"
|
sha256: b15fad91c4d3d1f2b48c053dd41cb82da007c27407dc9ab5f9aa59881d0e39d4
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.1.3"
|
version: "8.1.4"
|
||||||
package_info_plus_platform_interface:
|
package_info_plus_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1710,10 +1710,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: shared_preferences
|
name: shared_preferences
|
||||||
sha256: c59819dacc6669a1165d54d2735a9543f136f9b3cec94ca65cea6ab8dffc422e
|
sha256: "688ee90fbfb6989c980254a56cb26ebe9bb30a3a2dff439a78894211f73de67a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.0"
|
version: "2.5.1"
|
||||||
shared_preferences_android:
|
shared_preferences_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -2059,10 +2059,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vector_graphics
|
name: vector_graphics
|
||||||
sha256: "27d5fefe86fb9aace4a9f8375b56b3c292b64d8c04510df230f849850d912cb7"
|
sha256: "7ed22c21d7fdcc88dd6ba7860384af438cd220b251ad65dfc142ab722fabef61"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.15"
|
version: "1.1.16"
|
||||||
vector_graphics_codec:
|
vector_graphics_codec:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -2216,7 +2216,7 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
xml:
|
xml:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: xml
|
name: xml
|
||||||
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
|
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
|
||||||
|
@ -117,6 +117,7 @@ dependencies:
|
|||||||
cached_network_image: ^3.4.1
|
cached_network_image: ^3.4.1
|
||||||
flutter_inappwebview: ^6.1.5
|
flutter_inappwebview: ^6.1.5
|
||||||
html: ^0.15.5
|
html: ^0.15.5
|
||||||
|
xml: ^6.5.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user