parent
b8967c6653
commit
7cee1da98b
|
@ -30,7 +30,7 @@
|
||||||
"description": "First tip displayed in the sidebar",
|
"description": "First tip displayed in the sidebar",
|
||||||
"context": "Visible in the sidebar"
|
"context": "Visible in the sidebar"
|
||||||
},
|
},
|
||||||
"tip1": "Löschen Sie Nachrichten durch Doppeltippen",
|
"tip1": "Lösche Nachrichten durch Doppeltippen",
|
||||||
"@tip1": {
|
"@tip1": {
|
||||||
"description": "Second tip displayed in the sidebar",
|
"description": "Second tip displayed in the sidebar",
|
||||||
"context": "Visible in the sidebar"
|
"context": "Visible in the sidebar"
|
||||||
|
@ -65,6 +65,11 @@
|
||||||
"description": "Text displayed when an image is not valid",
|
"description": "Text displayed when an image is not valid",
|
||||||
"context": "Visible in the chat view"
|
"context": "Visible in the chat view"
|
||||||
},
|
},
|
||||||
|
"imageOnlyConversation": "Nur Bild Unterhaltung",
|
||||||
|
"@imageOnlyConversation": {
|
||||||
|
"description": "Title, if 'Generate Title' is executed on a conversation with no text messages",
|
||||||
|
"context": "Visible in the chat view"
|
||||||
|
},
|
||||||
"messageInputPlaceholder": "Nachricht",
|
"messageInputPlaceholder": "Nachricht",
|
||||||
"@messageInputPlaceholder": {
|
"@messageInputPlaceholder": {
|
||||||
"description": "Placeholder text for message input",
|
"description": "Placeholder text for message input",
|
||||||
|
|
|
@ -65,6 +65,11 @@
|
||||||
"description": "Text displayed when an image is not valid",
|
"description": "Text displayed when an image is not valid",
|
||||||
"context": "Visible in the chat view"
|
"context": "Visible in the chat view"
|
||||||
},
|
},
|
||||||
|
"imageOnlyConversation": "Image Only Conversation",
|
||||||
|
"@imageOnlyConversation": {
|
||||||
|
"description": "Title, if 'Generate Title' is executed on a conversation with no text messages",
|
||||||
|
"context": "Visible in the chat view"
|
||||||
|
},
|
||||||
"messageInputPlaceholder": "Message",
|
"messageInputPlaceholder": "Message",
|
||||||
"@messageInputPlaceholder": {
|
"@messageInputPlaceholder": {
|
||||||
"description": "Placeholder text for message input",
|
"description": "Placeholder text for message input",
|
||||||
|
|
|
@ -567,6 +567,11 @@ class _MainAppState extends State<MainApp> {
|
||||||
color: Colors.grey[200]!,
|
color: Colors.grey[200]!,
|
||||||
width: 1))))));
|
width: 1))))));
|
||||||
},
|
},
|
||||||
|
imageMessageBuilder: (p0, {required messageWidth}) {
|
||||||
|
return SizedBox(
|
||||||
|
width: 160.0,
|
||||||
|
child: MarkdownBody(data: ""));
|
||||||
|
},
|
||||||
disableImageGallery: true,
|
disableImageGallery: true,
|
||||||
// keyboardDismissBehavior:
|
// keyboardDismissBehavior:
|
||||||
// ScrollViewKeyboardDismissBehavior.onDrag,
|
// ScrollViewKeyboardDismissBehavior.onDrag,
|
||||||
|
@ -641,9 +646,14 @@ class _MainAppState extends State<MainApp> {
|
||||||
content: jsonDecode(jsonEncode(messages[i]))["text"],
|
content: jsonDecode(jsonEncode(messages[i]))["text"],
|
||||||
images: (images.isNotEmpty) ? images : null));
|
images: (images.isNotEmpty) ? images : null));
|
||||||
} else {
|
} else {
|
||||||
images.add(base64.encode(
|
var uri =
|
||||||
await File(jsonDecode(jsonEncode(messages[i]))["uri"])
|
jsonDecode(jsonEncode(messages[i]))["uri"] as String;
|
||||||
.readAsBytes()));
|
String content =
|
||||||
|
(uri.startsWith("data:image/png;base64,"))
|
||||||
|
? uri.removePrefix("data:image/png;base64,")
|
||||||
|
: base64.encode(await File(uri).readAsBytes());
|
||||||
|
uri = uri.removePrefix("data:image/png;base64,");
|
||||||
|
images.add(content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -757,6 +767,10 @@ class _MainAppState extends State<MainApp> {
|
||||||
void setTitle() async {
|
void setTitle() async {
|
||||||
List<Map<String, String>> history = [];
|
List<Map<String, String>> history = [];
|
||||||
for (var i = 0; i < messages.length; i++) {
|
for (var i = 0; i < messages.length; i++) {
|
||||||
|
if (jsonDecode(jsonEncode(messages[i]))["text"] ==
|
||||||
|
null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
history.add({
|
history.add({
|
||||||
"role": (messages[i].author == user)
|
"role": (messages[i].author == user)
|
||||||
? "user"
|
? "user"
|
||||||
|
@ -776,7 +790,8 @@ class _MainAppState extends State<MainApp> {
|
||||||
);
|
);
|
||||||
var title = generated.response!
|
var title = generated.response!
|
||||||
.replaceAll("*", "")
|
.replaceAll("*", "")
|
||||||
.replaceAll("_", "");
|
.replaceAll("_", "")
|
||||||
|
.trim();
|
||||||
var tmp = (prefs!.getStringList("chats") ?? []);
|
var tmp = (prefs!.getStringList("chats") ?? []);
|
||||||
for (var i = 0; i < tmp.length; i++) {
|
for (var i = 0; i < tmp.length; i++) {
|
||||||
if (jsonDecode((prefs!.getStringList("chats") ??
|
if (jsonDecode((prefs!.getStringList("chats") ??
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
import 'main.dart';
|
import 'main.dart';
|
||||||
|
|
||||||
|
import 'package:dartx/dartx.dart';
|
||||||
import 'package:ollama_dart/ollama_dart.dart' as llama;
|
import 'package:ollama_dart/ollama_dart.dart' as llama;
|
||||||
// ignore: depend_on_referenced_packages
|
// ignore: depend_on_referenced_packages
|
||||||
import 'package:flutter_chat_types/flutter_chat_types.dart' as types;
|
import 'package:flutter_chat_types/flutter_chat_types.dart' as types;
|
||||||
|
@ -157,7 +159,7 @@ void setModel(BuildContext context, Function setState) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void saveChat(String uuid, Function setState) {
|
void saveChat(String uuid, Function setState) async {
|
||||||
int index = -1;
|
int index = -1;
|
||||||
for (var i = 0; i < (prefs!.getStringList("chats") ?? []).length; i++) {
|
for (var i = 0; i < (prefs!.getStringList("chats") ?? []).length; i++) {
|
||||||
if (jsonDecode((prefs!.getStringList("chats") ?? [])[i])["uuid"] == uuid) {
|
if (jsonDecode((prefs!.getStringList("chats") ?? [])[i])["uuid"] == uuid) {
|
||||||
|
@ -167,10 +169,24 @@ void saveChat(String uuid, Function setState) {
|
||||||
if (index == -1) return;
|
if (index == -1) return;
|
||||||
List<Map<String, String>> history = [];
|
List<Map<String, String>> history = [];
|
||||||
for (var i = 0; i < messages.length; i++) {
|
for (var i = 0; i < messages.length; i++) {
|
||||||
history.add({
|
if ((jsonDecode(jsonEncode(messages[i])) as Map).containsKey("text")) {
|
||||||
"role": (messages[i].author == user) ? "user" : "assistant",
|
history.add({
|
||||||
"content": jsonDecode(jsonEncode(messages[i]))["text"]
|
"role": (messages[i].author == user) ? "user" : "assistant",
|
||||||
});
|
"content": jsonDecode(jsonEncode(messages[i]))["text"]
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
var uri = jsonDecode(jsonEncode(messages[i]))["uri"] as String;
|
||||||
|
String content = (uri.startsWith("data:image/png;base64,"))
|
||||||
|
? uri.removePrefix("data:image/png;base64,")
|
||||||
|
: base64.encode(await File(uri).readAsBytes());
|
||||||
|
history.add({
|
||||||
|
"role": (messages[i].author == user) ? "user" : "assistant",
|
||||||
|
"type": "image",
|
||||||
|
"name": (messages[i] as types.ImageMessage).name,
|
||||||
|
"size": (messages[i] as types.ImageMessage).size.toString(),
|
||||||
|
"content": content
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (messages.isEmpty && uuid == chatUuid) {
|
if (messages.isEmpty && uuid == chatUuid) {
|
||||||
for (var i = 0; i < (prefs!.getStringList("chats") ?? []).length; i++) {
|
for (var i = 0; i < (prefs!.getStringList("chats") ?? []).length; i++) {
|
||||||
|
@ -236,12 +252,24 @@ void loadChat(String uuid, Function setState) {
|
||||||
jsonDecode((prefs!.getStringList("chats") ?? [])[index])["messages"]);
|
jsonDecode((prefs!.getStringList("chats") ?? [])[index])["messages"]);
|
||||||
for (var i = 0; i < history.length; i++) {
|
for (var i = 0; i < history.length; i++) {
|
||||||
if (history[i]["role"] != "system") {
|
if (history[i]["role"] != "system") {
|
||||||
messages.insert(
|
if ((history[i] as Map).containsKey("type") &&
|
||||||
0,
|
history[i]["type"] == "image") {
|
||||||
types.TextMessage(
|
messages.insert(
|
||||||
author: (history[i]["role"] == "user") ? user : assistant,
|
0,
|
||||||
id: const Uuid().v4(),
|
types.ImageMessage(
|
||||||
text: history[i]["content"]));
|
author: (history[i]["role"] == "user") ? user : assistant,
|
||||||
|
id: const Uuid().v4(),
|
||||||
|
name: history[i]["name"],
|
||||||
|
size: int.parse(history[i]["size"]),
|
||||||
|
uri: "data:image/png;base64,${history[i]["content"]}"));
|
||||||
|
} else {
|
||||||
|
messages.insert(
|
||||||
|
0,
|
||||||
|
types.TextMessage(
|
||||||
|
author: (history[i]["role"] == "user") ? user : assistant,
|
||||||
|
id: const Uuid().v4(),
|
||||||
|
text: history[i]["content"]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
model = jsonDecode((prefs!.getStringList("chats") ?? [])[index])["model"];
|
model = jsonDecode((prefs!.getStringList("chats") ?? [])[index])["model"];
|
||||||
|
@ -325,11 +353,29 @@ Future<String> prompt(BuildContext context,
|
||||||
[])[i])["uuid"] ==
|
[])[i])["uuid"] ==
|
||||||
uuid) {
|
uuid) {
|
||||||
try {
|
try {
|
||||||
var history = jsonDecode(
|
List history = [];
|
||||||
jsonDecode((prefs!
|
var tmp = jsonDecode(jsonDecode(
|
||||||
.getStringList(
|
(prefs!.getStringList(
|
||||||
"chats") ??
|
"chats") ??
|
||||||
[])[i])["messages"]);
|
[])[i])["messages"]);
|
||||||
|
for (var j = 0;
|
||||||
|
j < tmp.length;
|
||||||
|
j++) {
|
||||||
|
if (tmp[j]["text"] == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
history.add(tmp[j]["text"]);
|
||||||
|
}
|
||||||
|
if (history.isEmpty) {
|
||||||
|
controller
|
||||||
|
.text = AppLocalizations
|
||||||
|
.of(context)!
|
||||||
|
.imageOnlyConversation;
|
||||||
|
setLocalState(() {
|
||||||
|
loading = false;
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final generated =
|
final generated =
|
||||||
await llama.OllamaClient(
|
await llama.OllamaClient(
|
||||||
|
@ -345,7 +391,8 @@ Future<String> prompt(BuildContext context,
|
||||||
);
|
);
|
||||||
var title = generated.response!
|
var title = generated.response!
|
||||||
.replaceAll("*", "")
|
.replaceAll("*", "")
|
||||||
.replaceAll("_", "");
|
.replaceAll("_", "")
|
||||||
|
.trim();
|
||||||
controller.text = title;
|
controller.text = title;
|
||||||
setLocalState(() {
|
setLocalState(() {
|
||||||
loading = false;
|
loading = false;
|
||||||
|
|
Loading…
Reference in New Issue