class chat_gpt extends StatefulWidget { @override _chat_gptState createState() => _chat_gptState(); }

var _filteredStringList = []; var _stringList = []; int _selectedIndex = 0;

class _chat_gptState extends State<chat_gpt> { List<types.Message> _messages = []; final _user = const types.User( id: '82091008-a484-4a89-ae75-a22bf8d6f3ac', );

//从assets/prompts.json中读取数据,并转换为List<Map<String, String>> void loadprompts() async { String prompt = await rootBundle.loadString('assets/prompts.json'); _stringList = json.decode(prompt); _filteredStringList = List.from(_stringList); }

@override void initState() { super.initState(); _loadMessages(); loadprompts(); }

@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Chat with GPT'), //加入返回按鈕 leading: IconButton( icon: Icon(Icons.arrow_back), onPressed: () { //跳转到成绩页面 Navigator.push(context, MaterialPageRoute(builder: (context) { return HomePage(); })); }, ), actions: [ IconButton( icon: Icon(Icons.settings), onPressed: () { showDialog( context: context, builder: (context) { return Scaffold( appBar: AppBar( title: Text('设置'), actions: [ IconButton( icon: const Icon(Icons.search), onPressed: () { showDialog( context: context, builder: (BuildContext context) { return AlertDialog( content: FloatingActionButton( child: Icon(Icons.search), tooltip: '搜索语句', onPressed: () => showSearch( context: context, delegate: SearchPage( items: _stringList, searchLabel: '搜索语句', suggestion: Center( child: Text('查询你要注入的语句'), ), failure: Center( child: Text('什么都没找到哦 :('), ), filter: (person) => [ person['act'], person['prompt'], ], builder: (person) => ListTile( title: Text(person['act']!), subtitle: Text(person['prompt']!), onTap: () { Navigator.pop(context, person); }, ), ), ), ), ); }).then((value) { if (value != null) { setState(() { _filteredStringList = [value]; _selectedIndex = 0; }); } }); }, ), ], ), body: ListView.builder( itemCount: _filteredStringList.length, itemBuilder: (BuildContext context, int index) { String act = _filteredStringList[index]['act']!; String prompt = _filteredStringList[index]['prompt']!; return RadioListTile( title: Text('行为: $act'), subtitle: Text('语句: $prompt'), value: index, groupValue: _selectedIndex, onChanged: (int? value) { setState(() { _selectedIndex = value!; }); }, ); }, )); }); }, ), ], ), body: Chat( messages: _messages, onAttachmentPressed: _handleAttachmentPressed, onMessageTap: _handleMessageTap, onPreviewDataFetched: _handlePreviewDataFetched, onSendPressed: _handleSendPressed, showUserAvatars: true, showUserNames: true, user: _user, ), ); }

void _addMessage(types.Message message) { setState(() { _messages.insert(0, message); }); }

void _handleAttachmentPressed() { showModalBottomSheet( context: context, builder: (BuildContext context) => SafeArea( child: SizedBox( height: 144, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ TextButton( onPressed: () { Navigator.pop(context); _handleImageSelection(); }, child: const Align( alignment: AlignmentDirectional.centerStart, child: Text('Photo'), ), ), TextButton( onPressed: () { Navigator.pop(context); _handleFileSelection(); }, child: const Align( alignment: AlignmentDirectional.centerStart, child: Text('File'), ), ), TextButton( onPressed: () => Navigator.pop(context), child: const Align( alignment: AlignmentDirectional.centerStart, child: Text('Cancel'), ), ), ], ), ), ), ); }

void _handleFileSelection() async { final result = await FilePicker.platform.pickFiles( type: FileType.any, );

if (result != null && result.files.single.path != null) {
  final message = types.FileMessage(
    author: _user,
    createdAt: DateTime.now().millisecondsSinceEpoch,
    id: const Uuid().v4(),
    mimeType: lookupMimeType(result.files.single.path!),
    name: result.files.single.name,
    size: result.files.single.size,
    uri: result.files.single.path!,
  );

  _addMessage(message);
}

}

void _handleImageSelection() async { final result = await ImagePicker().pickImage( imageQuality: 70, maxWidth: 1440, source: ImageSource.gallery, );

if (result != null) {
  final bytes = await result.readAsBytes();
  final image = await decodeImageFromList(bytes);

  final message = types.ImageMessage(
    author: _user,
    createdAt: DateTime.now().millisecondsSinceEpoch,
    height: image.height.toDouble(),
    id: const Uuid().v4(),
    name: result.name,
    size: bytes.length,
    uri: result.path,
    width: image.width.toDouble(),
  );

  _addMessage(message);
}

}

void _handleMessageTap(BuildContext _, types.Message message) async { if (message is types.FileMessage) { var localPath = message.uri;

  if (message.uri.startsWith('http')) {
    try {
      final index = _messages.indexWhere((element) => element.id == message.id);
      final updatedMessage = (_messages[index] as types.FileMessage).copyWith(
        isLoading: true,
      );

      setState(() {
        _messages[index] = updatedMessage;
      });

      final client = http.Client();
      final request = await client.get(Uri.parse(message.uri));
      final bytes = request.bodyBytes;
      final documentsDir = (await getApplicationDocumentsDirectory()).path;
      localPath = '$documentsDir/${message.name}';

      if (!File(localPath).existsSync()) {
        final file = File(localPath);
        await file.writeAsBytes(bytes);
      }
    } finally {
      final index = _messages.indexWhere((element) => element.id == message.id);
      final updatedMessage = (_messages[index] as types.FileMessage).copyWith(
        isLoading: null,
      );

      setState(() {
        _messages[index] = updatedMessage;
      });
    }
  }
}

}

void _handlePreviewDataFetched( types.TextMessage message, types.PreviewData previewData, ) { final index = _messages.indexWhere((element) => element.id == message.id); final updatedMessage = (_messages[index] as types.TextMessage).copyWith( previewData: previewData, );

setState(() {
  _messages[index] = updatedMessage;
});

}

void _handleSendPressed(types.PartialText message) { final textMessage = types.TextMessage( author: _user, createdAt: DateTime.now().millisecondsSinceEpoch, id: const Uuid().v4(), text: message.text, );

_addMessage(textMessage);
print(message.text);
//打印最近20条消息
print(_messages.sublist(0, 20));

}

void _loadMessages() async { final response = await rootBundle.loadString('assets/messages.json'); final messages = (jsonDecode(response) as List).map((e) => types.Message.fromJson(e as Map<String, dynamic>)).toList();

setState(() {
  _messages = messages;
});

}

ChatGPT聊天应用 - 使用自定义指令与 AI 交谈

原文地址: https://www.cveoy.top/t/topic/lQtm 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录