Merge branch 'main' of https://github.com/JHubi1/ollama-app
This commit is contained in:
commit
4d63da801c
|
@ -12,6 +12,11 @@ on:
|
|||
required: true
|
||||
default: false
|
||||
type: boolean
|
||||
buildLinuxX64:
|
||||
description: Build for Linux x64
|
||||
required: true
|
||||
default: false
|
||||
type: boolean
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
|
@ -45,6 +50,9 @@ jobs:
|
|||
echo $'storePassword=${{ secrets.ANDROID_KEYSTORE_PASSPHRASE }}\nkeyPassword=${{ secrets.ANDROID_KEYSTORE_PASSPHRASE }}\nkeyAlias=upload\nstoreFile=upload-keystore.jks\n' > ./android/key.properties
|
||||
echo "${{ secrets.ANDROID_KEYSTORE }}" > ./android/app/upload-keystore.jks.asc
|
||||
gpg -d --passphrase "${{ secrets.ANDROID_KEYSTORE_PASSPHRASE }}" --batch ./android/app/upload-keystore.jks.asc > ./android/app/upload-keystore.jks
|
||||
- name: Get flutter version
|
||||
id: get_flutter_version
|
||||
uses: its404/get-flutter-version@v1.0.0
|
||||
- name: Disabling flutter analytics
|
||||
run: flutter config --no-analytics
|
||||
- name: Running build
|
||||
|
@ -52,15 +60,13 @@ jobs:
|
|||
run: flutter build apk --obfuscate --split-debug-info=build/debugAndroid
|
||||
- name: Preparing files
|
||||
run: |
|
||||
cp build/app/outputs/flutter-apk/app-release.apk build/app/outputs/flutter-apk/ollama.apk
|
||||
cp build/app/outputs/flutter-apk/app-release.apk.sha1 build/app/outputs/flutter-apk/ollama.apk.sha1
|
||||
cp build/app/outputs/flutter-apk/app-release.apk build/app/outputs/flutter-apk/ollama-android-v${{ steps.get_flutter_version.outputs.version_number }}.apk
|
||||
- name: Uploading APK
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ollama-android
|
||||
path: |
|
||||
build/app/outputs/flutter-apk/ollama.apk
|
||||
build/app/outputs/flutter-apk/ollama.apk.sha1
|
||||
build/app/outputs/flutter-apk/ollama-android-v${{ steps.get_flutter_version.outputs.version_number }}.apk
|
||||
build-windows-x64:
|
||||
name: Building for Windows x64
|
||||
if: ${{ github.event.inputs.buildWindowsX64 == 'true' }}
|
||||
|
@ -88,12 +94,43 @@ jobs:
|
|||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ollama-windows-x64
|
||||
path: build\windows\x64\runner\ollama-v${{ steps.get_flutter_version.outputs.version_number }}-x64.exe
|
||||
path: build\windows\x64\runner\ollama-windows-x64-v${{ steps.get_flutter_version.outputs.version_number }}.exe
|
||||
build-linux-x64:
|
||||
name: Building for Linux
|
||||
if: ${{ github.event.inputs.buildLinuxX64 == 'true' }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: analyze
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: subosito/flutter-action@v2
|
||||
with:
|
||||
flutter-version: 3.22.1
|
||||
- name: Get flutter version
|
||||
id: get_flutter_version
|
||||
uses: its404/get-flutter-version@v1.0.0
|
||||
- name: Disabling flutter analytics
|
||||
run: flutter config --no-analytics
|
||||
- name: Installing linux dependencies
|
||||
run: |
|
||||
sudo apt-get install ninja-build
|
||||
sudo apt-get install build-essential libgtk-3-dev
|
||||
- name: Running build
|
||||
id: compile
|
||||
run: flutter build linux --obfuscate --split-debug-info=build/debugLinux
|
||||
- name: Creating archive
|
||||
run: |
|
||||
cd build/linux/x64/release/bundle
|
||||
tar -czf ollama-linux-x64-v${{ steps.get_flutter_version.outputs.version_number }}.tar.gz *
|
||||
- name: Uploading archive
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ollama-linux-x64
|
||||
path: build/linux/x64/release/bundle/ollama-linux-x64-v${{ steps.get_flutter_version.outputs.version_number }}.tar.gz
|
||||
bundle:
|
||||
name: Creating bundle
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ always() }}
|
||||
needs: [build-android, build-windows-x64]
|
||||
needs: [build-android, build-windows-x64, build-linux-x64]
|
||||
steps:
|
||||
- name: Adding builds
|
||||
uses: actions/download-artifact@v4
|
||||
|
@ -105,4 +142,4 @@ jobs:
|
|||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ollama
|
||||
path: ./
|
||||
path: ./
|
|
@ -2,7 +2,8 @@
|
|||
<application
|
||||
android:label="Ollama"
|
||||
android:name="${applicationName}"
|
||||
android:icon="@mipmap/ic_launcher">
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:enableOnBackInvokedCallback="true">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
arb-dir: lib/l10n
|
||||
template-arb-file: app_en.arb
|
||||
preferred-supported-locales: en
|
||||
output-localization-file: app_localizations.dart
|
||||
untranslated-messages-file: untranslated_messages.json
|
||||
|
|
|
@ -544,6 +544,11 @@
|
|||
"description": "Text displayed as description for export chats button",
|
||||
"context": "Visible in the settings view"
|
||||
},
|
||||
"settingsExportChatsSuccess": "Chats exported successfully",
|
||||
"@settingsExportChatsSuccess": {
|
||||
"description": "Text displayed when chats are exported successfully",
|
||||
"context": "Visible in the settings view"
|
||||
},
|
||||
"settingsImportChats": "Import chats",
|
||||
"@settingsImportChats": {
|
||||
"description": "Text displayed as description for import chats button",
|
||||
|
@ -660,9 +665,9 @@
|
|||
"description": "Text displayed as description for report issue button",
|
||||
"context": "Visible in the settings view"
|
||||
},
|
||||
"settingsMainDeveloper": "Main Developer",
|
||||
"@settingsMainDeveloper": {
|
||||
"description": "Text displayed as description for main developer button",
|
||||
"settingsLicenses": "Licenses",
|
||||
"@settingsLicenses": {
|
||||
"description": "Text displayed as description for licenses button",
|
||||
"context": "Visible in the settings view"
|
||||
},
|
||||
"settingsVersion": "Ollama App v{version}",
|
||||
|
|
101
lib/main.dart
101
lib/main.dart
|
@ -1261,79 +1261,44 @@ class _MainAppState extends State<MainApp> {
|
|||
],
|
||||
),
|
||||
imageBuilder: (uri, title, alt) {
|
||||
Widget errorImage = InkWell(
|
||||
onTap: () {
|
||||
selectionHaptic();
|
||||
ScaffoldMessenger.of(context)
|
||||
.showSnackBar(SnackBar(
|
||||
content: Text(
|
||||
AppLocalizations.of(
|
||||
context)!
|
||||
.notAValidImage),
|
||||
showCloseIcon: true));
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius
|
||||
.circular(8),
|
||||
color: Theme.of(context)
|
||||
.brightness ==
|
||||
Brightness.light
|
||||
? Colors.white
|
||||
: Colors.black),
|
||||
padding:
|
||||
const EdgeInsets.only(
|
||||
left: 100,
|
||||
right: 100,
|
||||
top: 32),
|
||||
child: const Image(
|
||||
image: AssetImage(
|
||||
"assets/logo512error.png"))));
|
||||
if (uri.isAbsolute) {
|
||||
return Image.network(
|
||||
uri.toString(), errorBuilder:
|
||||
(context, error,
|
||||
stackTrace) {
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
selectionHaptic();
|
||||
ScaffoldMessenger.of(
|
||||
context)
|
||||
.showSnackBar(SnackBar(
|
||||
content: Text(
|
||||
AppLocalizations.of(
|
||||
context)!
|
||||
.notAValidImage),
|
||||
showCloseIcon:
|
||||
true));
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius
|
||||
.circular(
|
||||
8),
|
||||
color: Theme.of(context)
|
||||
.brightness ==
|
||||
Brightness
|
||||
.light
|
||||
? Colors.white
|
||||
: Colors.black),
|
||||
padding:
|
||||
const EdgeInsets
|
||||
.only(
|
||||
left: 100,
|
||||
right: 100,
|
||||
top: 32),
|
||||
child: const Image(
|
||||
image: AssetImage(
|
||||
"assets/logo512error.png"))));
|
||||
return errorImage;
|
||||
});
|
||||
} else {
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
selectionHaptic();
|
||||
ScaffoldMessenger.of(
|
||||
context)
|
||||
.showSnackBar(SnackBar(
|
||||
content: Text(
|
||||
AppLocalizations.of(
|
||||
context)!
|
||||
.notAValidImage),
|
||||
showCloseIcon:
|
||||
true));
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius
|
||||
.circular(8),
|
||||
color: Theme.of(context)
|
||||
.brightness ==
|
||||
Brightness
|
||||
.light
|
||||
? Colors.white
|
||||
: Colors.black),
|
||||
padding:
|
||||
const EdgeInsets.only(
|
||||
left: 100,
|
||||
right: 100,
|
||||
top: 32),
|
||||
child: const Image(
|
||||
image: AssetImage(
|
||||
"assets/logo512error.png"))));
|
||||
return errorImage;
|
||||
}
|
||||
},
|
||||
styleSheet: (p0.author == user)
|
||||
|
@ -1535,7 +1500,9 @@ class _MainAppState extends State<MainApp> {
|
|||
: null
|
||||
: () {
|
||||
selectionHaptic();
|
||||
if (!chatAllowed || model == null) return;
|
||||
if (!chatAllowed || model == null) {
|
||||
return;
|
||||
}
|
||||
if (desktopFeature()) {
|
||||
FilePicker.platform
|
||||
.pickFiles(type: FileType.image)
|
||||
|
|
|
@ -123,13 +123,37 @@ class _ScreenSettingsAboutState extends State<ScreenSettingsAbout> {
|
|||
mode: LaunchMode.inAppBrowserView,
|
||||
Uri.parse("$repoUrl/issues"));
|
||||
}),
|
||||
button(AppLocalizations.of(context)!.settingsMainDeveloper,
|
||||
Icons.developer_board_rounded, () {
|
||||
button(AppLocalizations.of(context)!.settingsLicenses,
|
||||
Icons.gavel_rounded, () {
|
||||
selectionHaptic();
|
||||
launchUrl(
|
||||
mode: LaunchMode.inAppBrowserView,
|
||||
Uri.parse(
|
||||
repoUrl.substring(0, repoUrl.lastIndexOf('/'))));
|
||||
String legal = "Copyright 2024 JHubi1";
|
||||
Widget icon = const Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: ImageIcon(AssetImage("assets/logo512.png"),
|
||||
size: 48),
|
||||
);
|
||||
if (desktopFeature()) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return Dialog(
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(28),
|
||||
child: LicensePage(
|
||||
applicationName: "Ollama App",
|
||||
applicationVersion: currentVersion,
|
||||
applicationIcon: icon,
|
||||
applicationLegalese: legal),
|
||||
));
|
||||
});
|
||||
} else {
|
||||
showLicensePage(
|
||||
context: context,
|
||||
applicationName: "Ollama App",
|
||||
applicationVersion: currentVersion,
|
||||
applicationIcon: icon,
|
||||
applicationLegalese: legal);
|
||||
}
|
||||
}),
|
||||
const SizedBox(height: 16)
|
||||
]),
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import 'dart:io';
|
||||
import 'dart:convert';
|
||||
// ignore: avoid_web_libraries_in_flutter
|
||||
import 'dart:html' as html;
|
||||
import 'package:universal_html/html.dart' as html;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
@ -14,6 +13,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|||
|
||||
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:file_selector/file_selector.dart' as file_selector;
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:dynamic_color/dynamic_color.dart';
|
||||
|
||||
|
@ -50,6 +50,7 @@ class _ScreenSettingsExportState extends State<ScreenSettingsExport> {
|
|||
var content =
|
||||
jsonEncode(prefs!.getStringList("chats") ?? []);
|
||||
if (kIsWeb) {
|
||||
// web fallback
|
||||
final bytes = utf8.encode(content);
|
||||
final blob = html.Blob([bytes]);
|
||||
final url = html.Url.createObjectUrlFromBlob(blob);
|
||||
|
@ -65,18 +66,34 @@ class _ScreenSettingsExportState extends State<ScreenSettingsExport> {
|
|||
html.document.body!.children.remove(anchor);
|
||||
html.Url.revokeObjectUrl(url);
|
||||
} else {
|
||||
var path = await FilePicker.platform.saveFile(
|
||||
type: FileType.custom,
|
||||
allowedExtensions: ["json"],
|
||||
fileName: name,
|
||||
bytes: utf8.encode(jsonEncode(
|
||||
prefs!.getStringList("chats") ?? [])));
|
||||
String? path = "";
|
||||
try {
|
||||
path = (await file_selector
|
||||
.getSaveLocation(acceptedTypeGroups: [
|
||||
const file_selector.XTypeGroup(
|
||||
label: "Ollama App File", extensions: ["json"])
|
||||
], suggestedName: name))
|
||||
?.path;
|
||||
} catch (_) {
|
||||
path = await FilePicker.platform.saveFile(
|
||||
type: FileType.custom,
|
||||
allowedExtensions: ["json"],
|
||||
fileName: name,
|
||||
bytes: utf8.encode(jsonEncode(
|
||||
prefs!.getStringList("chats") ?? [])));
|
||||
}
|
||||
selectionHaptic();
|
||||
if (path == null) return;
|
||||
if (desktopFeature()) {
|
||||
File(path).writeAsString(content);
|
||||
}
|
||||
}
|
||||
// ignore: use_build_context_synchronously
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
// ignore: use_build_context_synchronously
|
||||
content: Text(AppLocalizations.of(context)!
|
||||
.settingsExportChatsSuccess),
|
||||
showCloseIcon: true));
|
||||
}),
|
||||
allowMultipleChats
|
||||
? button(
|
||||
|
@ -104,30 +121,54 @@ class _ScreenSettingsExportState extends State<ScreenSettingsExport> {
|
|||
TextButton(
|
||||
onPressed: () async {
|
||||
selectionHaptic();
|
||||
FilePickerResult? result =
|
||||
await FilePicker.platform
|
||||
.pickFiles(
|
||||
type: FileType.custom,
|
||||
allowedExtensions: [
|
||||
"json"
|
||||
]);
|
||||
if (result == null) {
|
||||
// ignore: use_build_context_synchronously
|
||||
Navigator.of(context).pop();
|
||||
return;
|
||||
}
|
||||
|
||||
String content;
|
||||
try {
|
||||
File file = File(
|
||||
result.files.single.path!);
|
||||
if (kIsWeb) {
|
||||
throw Exception(
|
||||
"web must use file picker");
|
||||
}
|
||||
file_selector.XFile? result =
|
||||
await file_selector.openFile(
|
||||
acceptedTypeGroups: [
|
||||
const file_selector
|
||||
.XTypeGroup(
|
||||
label:
|
||||
"Ollama App File",
|
||||
extensions: ["json"])
|
||||
]);
|
||||
if (result == null) {
|
||||
// ignore: use_build_context_synchronously
|
||||
Navigator.of(context).pop();
|
||||
return;
|
||||
}
|
||||
content =
|
||||
await file.readAsString();
|
||||
await result.readAsString();
|
||||
} catch (_) {
|
||||
content = utf8.decode(result
|
||||
.files
|
||||
.single
|
||||
.bytes as List<int>);
|
||||
FilePickerResult? result =
|
||||
await FilePicker.platform
|
||||
.pickFiles(
|
||||
type:
|
||||
FileType.custom,
|
||||
allowedExtensions: [
|
||||
"json"
|
||||
]);
|
||||
if (result == null) {
|
||||
// ignore: use_build_context_synchronously
|
||||
Navigator.of(context).pop();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
File file = File(result
|
||||
.files.single.path!);
|
||||
content =
|
||||
await file.readAsString();
|
||||
} catch (_) {
|
||||
// web fallback
|
||||
content = utf8.decode(result
|
||||
.files
|
||||
.single
|
||||
.bytes as List<int>);
|
||||
}
|
||||
}
|
||||
List<dynamic> tmpHistory =
|
||||
jsonDecode(content);
|
||||
|
|
|
@ -95,14 +95,10 @@ class _ScreenSettingsVoiceState extends State<ScreenSettingsVoice> {
|
|||
: !(permissionBluetooth && permissionRecord)
|
||||
? AppLocalizations.of(context)!
|
||||
.settingsVoicePermissionNot
|
||||
: !(prefs!.getBool(
|
||||
"voiceModeEnabled") ??
|
||||
false)
|
||||
? AppLocalizations.of(context)!
|
||||
.settingsVoiceNotEnabled
|
||||
: AppLocalizations.of(context)!
|
||||
.settingsVoiceNotSupported,
|
||||
: AppLocalizations.of(context)!
|
||||
.settingsVoiceNotSupported,
|
||||
Icons.info_rounded, () {
|
||||
selectionHaptic();
|
||||
if (permissionLoading) return;
|
||||
if (!(permissionBluetooth && permissionRecord)) {
|
||||
void load() async {
|
||||
|
@ -139,7 +135,6 @@ class _ScreenSettingsVoiceState extends State<ScreenSettingsVoice> {
|
|||
} else if (!voiceLanguageOptions.contains(
|
||||
(prefs!.getString("voiceLanguage") ??
|
||||
"en_US"))) {
|
||||
selectionHaptic();
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!
|
||||
.settingsVoiceTtsNotSupportedDescription),
|
||||
|
|
|
@ -79,6 +79,9 @@ Future<String> getTitleAi(List history) async {
|
|||
.replaceAll("_", "")
|
||||
.replaceAll("\n", " ")
|
||||
.trim();
|
||||
while (title.contains(" ")) {
|
||||
title = title.replaceAll(" ", " ");
|
||||
}
|
||||
return title;
|
||||
}
|
||||
|
||||
|
@ -169,58 +172,58 @@ Future<String> send(String value, BuildContext context, Function setState,
|
|||
baseUrl: "$host/api");
|
||||
|
||||
try {
|
||||
if ((prefs!.getString("requestType") ?? "stream") == "stream") {
|
||||
final stream = client
|
||||
.generateChatCompletionStream(
|
||||
request: llama.GenerateChatCompletionRequest(
|
||||
model: model!,
|
||||
messages: history,
|
||||
keepAlive: int.parse(prefs!.getString("keepAlive") ?? "300")),
|
||||
)
|
||||
.timeout(const Duration(seconds: 30));
|
||||
if ((prefs!.getString("requestType") ?? "stream") == "stream") {
|
||||
final stream = client
|
||||
.generateChatCompletionStream(
|
||||
request: llama.GenerateChatCompletionRequest(
|
||||
model: model!,
|
||||
messages: history,
|
||||
keepAlive: int.parse(prefs!.getString("keepAlive") ?? "300")),
|
||||
)
|
||||
.timeout(const Duration(seconds: 30));
|
||||
|
||||
await for (final res in stream) {
|
||||
text += (res.message?.content ?? "");
|
||||
for (var i = 0; i < messages.length; i++) {
|
||||
if (messages[i].id == newId) {
|
||||
messages.removeAt(i);
|
||||
break;
|
||||
await for (final res in stream) {
|
||||
text += (res.message?.content ?? "");
|
||||
for (var i = 0; i < messages.length; i++) {
|
||||
if (messages[i].id == newId) {
|
||||
messages.removeAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (chatAllowed) return "";
|
||||
// if (text.trim() == "") {
|
||||
// throw Exception();
|
||||
// }
|
||||
messages.insert(
|
||||
0, types.TextMessage(author: assistant, id: newId, text: text));
|
||||
if (onStream != null) {
|
||||
onStream(text, false);
|
||||
}
|
||||
setState(() {});
|
||||
heavyHaptic();
|
||||
}
|
||||
} else {
|
||||
llama.GenerateChatCompletionResponse request;
|
||||
request = await client
|
||||
.generateChatCompletion(
|
||||
request: llama.GenerateChatCompletionRequest(
|
||||
model: model!,
|
||||
messages: history,
|
||||
keepAlive: int.parse(prefs!.getString("keepAlive") ?? "300")),
|
||||
)
|
||||
.timeout(const Duration(seconds: 30));
|
||||
if (chatAllowed) return "";
|
||||
// if (text.trim() == "") {
|
||||
// if (request.message!.content.trim() == "") {
|
||||
// throw Exception();
|
||||
// }
|
||||
messages.insert(
|
||||
0, types.TextMessage(author: assistant, id: newId, text: text));
|
||||
if (onStream != null) {
|
||||
onStream(text, false);
|
||||
}
|
||||
0,
|
||||
types.TextMessage(
|
||||
author: assistant, id: newId, text: request.message!.content));
|
||||
text = request.message!.content;
|
||||
setState(() {});
|
||||
heavyHaptic();
|
||||
}
|
||||
} else {
|
||||
llama.GenerateChatCompletionResponse request;
|
||||
request = await client
|
||||
.generateChatCompletion(
|
||||
request: llama.GenerateChatCompletionRequest(
|
||||
model: model!,
|
||||
messages: history,
|
||||
keepAlive: int.parse(prefs!.getString("keepAlive") ?? "300")),
|
||||
)
|
||||
.timeout(const Duration(seconds: 30));
|
||||
if (chatAllowed) return "";
|
||||
// if (request.message!.content.trim() == "") {
|
||||
// throw Exception();
|
||||
// }
|
||||
messages.insert(
|
||||
0,
|
||||
types.TextMessage(
|
||||
author: assistant, id: newId, text: request.message!.content));
|
||||
text = request.message!.content;
|
||||
setState(() {});
|
||||
heavyHaptic();
|
||||
}
|
||||
} catch (e) {
|
||||
for (var i = 0; i < messages.length; i++) {
|
||||
if (messages[i].id == newId) {
|
||||
|
|
|
@ -216,12 +216,8 @@ void setModel(BuildContext context, Function setState) {
|
|||
? ((MediaQuery.of(context)
|
||||
.platformBrightness ==
|
||||
Brightness.light)
|
||||
? themeLight()
|
||||
.colorScheme
|
||||
.secondary
|
||||
: themeDark()
|
||||
.colorScheme
|
||||
.secondary)
|
||||
? themeLight().colorScheme.secondary
|
||||
: themeDark().colorScheme.secondary)
|
||||
: null,
|
||||
labelStyle: (usedIndex == index &&
|
||||
!(prefs?.getBool(
|
||||
|
@ -245,12 +241,8 @@ void setModel(BuildContext context, Function setState) {
|
|||
: (MediaQuery.of(context)
|
||||
.platformBrightness ==
|
||||
Brightness.light)
|
||||
?themeLight()
|
||||
.colorScheme
|
||||
.primary
|
||||
: themeDark()
|
||||
.colorScheme
|
||||
.primary,
|
||||
? themeLight().colorScheme.primary
|
||||
: themeDark().colorScheme.primary,
|
||||
onSelected: (bool selected) {
|
||||
selectionHaptic();
|
||||
if (addIndex == index) {
|
||||
|
@ -539,7 +531,11 @@ Future<String> prompt(BuildContext context,
|
|||
uuid) {
|
||||
try {
|
||||
var title = await getTitleAi(
|
||||
await getHistory());
|
||||
jsonDecode(jsonDecode(
|
||||
(prefs!.getStringList(
|
||||
"chats") ??
|
||||
[])[
|
||||
i])["messages"]));
|
||||
controller.text = title;
|
||||
setLocalState(() {
|
||||
loading = false;
|
||||
|
|
|
@ -54,10 +54,20 @@ void resetSystemNavigation(BuildContext context,
|
|||
});
|
||||
}
|
||||
|
||||
ThemeData themeModifier(ThemeData theme) {
|
||||
return theme.copyWith(
|
||||
// https://docs.flutter.dev/platform-integration/android/predictive-back#set-up-your-app
|
||||
pageTransitionsTheme: const PageTransitionsTheme(
|
||||
builders: <TargetPlatform, PageTransitionsBuilder>{
|
||||
TargetPlatform.android: PredictiveBackPageTransitionsBuilder(),
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
ThemeData themeLight() {
|
||||
if (!(prefs?.getBool("useDeviceTheme") ?? false) ||
|
||||
colorSchemeLight == null) {
|
||||
return ThemeData.from(
|
||||
return themeModifier(ThemeData.from(
|
||||
colorScheme: const ColorScheme(
|
||||
brightness: Brightness.light,
|
||||
primary: Colors.black,
|
||||
|
@ -67,15 +77,15 @@ ThemeData themeLight() {
|
|||
error: Colors.red,
|
||||
onError: Colors.white,
|
||||
surface: Colors.white,
|
||||
onSurface: Colors.black));
|
||||
onSurface: Colors.black)));
|
||||
} else {
|
||||
return ThemeData.from(colorScheme: colorSchemeLight!);
|
||||
return themeModifier(ThemeData.from(colorScheme: colorSchemeLight!));
|
||||
}
|
||||
}
|
||||
|
||||
ThemeData themeDark() {
|
||||
if (!(prefs?.getBool("useDeviceTheme") ?? false) || colorSchemeDark == null) {
|
||||
return ThemeData.from(
|
||||
return themeModifier(ThemeData.from(
|
||||
colorScheme: const ColorScheme(
|
||||
brightness: Brightness.dark,
|
||||
primary: Colors.white,
|
||||
|
@ -85,9 +95,9 @@ ThemeData themeDark() {
|
|||
error: Colors.red,
|
||||
onError: Colors.black,
|
||||
surface: Colors.black,
|
||||
onSurface: Colors.white));
|
||||
onSurface: Colors.white)));
|
||||
} else {
|
||||
return ThemeData.from(colorScheme: colorSchemeDark!);
|
||||
return themeModifier(ThemeData.from(colorScheme: colorSchemeDark!));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
94
pubspec.lock
94
pubspec.lock
|
@ -81,6 +81,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: charcode
|
||||
sha256: fb98c0f6d12c920a02ee2d998da788bca066ca5f148492b7085ee23372b12306
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.1"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -101,10 +109,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: cross_file
|
||||
sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32"
|
||||
sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.4+1"
|
||||
version: "0.3.4+2"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -213,10 +221,34 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: file_picker
|
||||
sha256: "29c90806ac5f5fb896547720b73b17ee9aed9bba540dc5d91fe29f8c5745b10a"
|
||||
sha256: "167bb619cdddaa10ef2907609feb8a79c16dfa479d3afaf960f8e223f754bf12"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.0.3"
|
||||
version: "8.1.2"
|
||||
file_selector:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: file_selector
|
||||
sha256: "5019692b593455127794d5718304ff1ae15447dea286cdda9f0db2a796a1b828"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
file_selector_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_android
|
||||
sha256: "77f23eb5916fd0875946720d1f286f809a28a867d4882db6ac2cf053e2d5f7c6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.1+6"
|
||||
file_selector_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_ios
|
||||
sha256: "38ebf91ecbcfa89a9639a0854ccaed8ab370c75678938eebca7d34184296f0bb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.3"
|
||||
file_selector_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -241,6 +273,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.6.2"
|
||||
file_selector_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_web
|
||||
sha256: c4c0ea4224d97a60a7067eca0c8fd419e708ff830e0c83b11a48faf566cec3e7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.4+2"
|
||||
file_selector_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -377,10 +417,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: http
|
||||
sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938"
|
||||
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
version: "1.2.2"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -409,10 +449,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_for_web
|
||||
sha256: "5d6eb13048cd47b60dbf1a5495424dea226c5faf3950e20bf8120a58efb5b5f3"
|
||||
sha256: "65d94623e15372c5c51bebbcb820848d7bcb323836e12dfdba60b5d3a8b39e50"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.4"
|
||||
version: "3.0.5"
|
||||
image_picker_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -577,18 +617,18 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: package_info_plus
|
||||
sha256: b93d8b4d624b4ea19b0a5a208b2d6eff06004bc3ce74c06040b120eeadd00ce0
|
||||
sha256: a75164ade98cb7d24cfd0a13c6408927c6b217fa60dee5a7ff5c116a58f28918
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.0.0"
|
||||
version: "8.0.2"
|
||||
package_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_info_plus_platform_interface
|
||||
sha256: f49918f3433a3146047372f9d4f1f847511f2acd5cd030e1f44fe5a50036b70e
|
||||
sha256: ac1f4a4847f1ade8e6a87d1f39f5d7c67490738642e2542f559ec38c37489a66
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
version: "3.0.1"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -761,10 +801,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_web
|
||||
sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a"
|
||||
sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.0"
|
||||
version: "2.2.1"
|
||||
shared_preferences_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -898,6 +938,22 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.2"
|
||||
universal_html:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: universal_html
|
||||
sha256: "56536254004e24d9d8cfdb7dbbf09b74cf8df96729f38a2f5c238163e3d58971"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.4"
|
||||
universal_io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: universal_io
|
||||
sha256: "1722b2dcc462b4b2f3ee7d188dad008b6eb4c40bbd03a3de451d82c78bba9aad"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.2"
|
||||
url_launcher:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -950,10 +1006,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_web
|
||||
sha256: "8d9e750d8c9338601e709cd0885f95825086bd8b642547f26bda435aade95d8a"
|
||||
sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.1"
|
||||
version: "2.3.3"
|
||||
url_launcher_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1014,10 +1070,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
|
||||
sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.1"
|
||||
version: "1.0.0"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1036,4 +1092,4 @@ packages:
|
|||
version: "1.0.4"
|
||||
sdks:
|
||||
dart: ">=3.4.0 <4.0.0"
|
||||
flutter: ">=3.19.0"
|
||||
flutter: ">=3.22.0"
|
||||
|
|
|
@ -28,6 +28,7 @@ dependencies:
|
|||
restart_app: ^1.2.1
|
||||
flutter_markdown: ^0.7.1
|
||||
file_picker: ^8.0.3
|
||||
file_selector: ^1.0.3
|
||||
bitsdojo_window: ^0.1.6
|
||||
install_referrer: ^1.2.1
|
||||
package_info_plus: ^8.0.0
|
||||
|
@ -40,6 +41,7 @@ dependencies:
|
|||
datetime_loop: ^1.2.0
|
||||
dynamic_color: ^1.7.0
|
||||
volume_controller: ^2.0.7
|
||||
universal_html: ^2.2.4
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
|
@ -32,18 +32,18 @@ void main() async {
|
|||
|
||||
// ----------
|
||||
|
||||
await execute('Windows x64', flutterExecutable, [
|
||||
'build',
|
||||
'windows',
|
||||
'--obfuscate',
|
||||
'--split-debug-info=build\\debugWindows'
|
||||
]);
|
||||
// await execute('Windows x64', flutterExecutable, [
|
||||
// 'build',
|
||||
// 'windows',
|
||||
// '--obfuscate',
|
||||
// '--split-debug-info=build\\debugWindows'
|
||||
// ]);
|
||||
|
||||
await execute(
|
||||
'Windows x64 installer',
|
||||
'iscc.exe',
|
||||
['windows_installer/x64.iss', '/qp', '/dAppVersion=$version'],
|
||||
" > Inno Setup is not installed. Please install it from https://www.jrsoftware.org/isdl.php#stable\n Then add the Inno Setup directory to your PATH environment variable.");
|
||||
// await execute(
|
||||
// 'Windows x64 installer',
|
||||
// 'iscc.exe',
|
||||
// ['windows_installer/x64.iss', '/qp', '/dAppVersion=$version'],
|
||||
// " > Inno Setup is not installed. Please install it from https://www.jrsoftware.org/isdl.php#stable\n Then add the Inno Setup directory to your PATH environment variable.");
|
||||
|
||||
// ----------
|
||||
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
"settingsTemporaryFixesNoFixes",
|
||||
"settingsVoiceTtsNotSupported",
|
||||
"settingsVoiceTtsNotSupportedDescription",
|
||||
"settingsVoiceNotEnabled"
|
||||
"settingsVoiceNotEnabled",
|
||||
"settingsExportChatsSuccess",
|
||||
"settingsLicenses"
|
||||
],
|
||||
|
||||
"it": [
|
||||
|
@ -36,7 +38,9 @@
|
|||
"settingsTemporaryFixesNoFixes",
|
||||
"settingsVoiceTtsNotSupported",
|
||||
"settingsVoiceTtsNotSupportedDescription",
|
||||
"settingsVoiceNotEnabled"
|
||||
"settingsVoiceNotEnabled",
|
||||
"settingsExportChatsSuccess",
|
||||
"settingsLicenses"
|
||||
],
|
||||
|
||||
"tr": [
|
||||
|
@ -56,7 +60,9 @@
|
|||
"settingsTemporaryFixesNoFixes",
|
||||
"settingsVoiceTtsNotSupported",
|
||||
"settingsVoiceTtsNotSupportedDescription",
|
||||
"settingsVoiceNotEnabled"
|
||||
"settingsVoiceNotEnabled",
|
||||
"settingsExportChatsSuccess",
|
||||
"settingsLicenses"
|
||||
],
|
||||
|
||||
"zh": [
|
||||
|
@ -76,6 +82,8 @@
|
|||
"settingsTemporaryFixesNoFixes",
|
||||
"settingsVoiceTtsNotSupported",
|
||||
"settingsVoiceTtsNotSupportedDescription",
|
||||
"settingsVoiceNotEnabled"
|
||||
"settingsVoiceNotEnabled",
|
||||
"settingsExportChatsSuccess",
|
||||
"settingsLicenses"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
; Script generated by the Inno Setup Script Wizard.
|
||||
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
|
||||
|
||||
; #define AppVersion "1.0.1"
|
||||
;#define AppVersion "1.0.1"
|
||||
|
||||
#define AppName "Ollama App"
|
||||
#define AppPublisher "JHubi1"
|
||||
|
@ -27,7 +27,7 @@ UninstallDisplayName={#AppName}
|
|||
|
||||
DefaultDirName={autopf}\OllamaApp
|
||||
OutputDir=build\windows\{#AppArchitectures}\runner
|
||||
OutputBaseFilename=ollama-v{#AppVersion}-{#AppArchitectures}
|
||||
OutputBaseFilename=ollama-windows-{#AppArchitectures}-v{#AppVersion}
|
||||
|
||||
AppSupportURL=https://github.com/JHubi1/ollama-app/issues
|
||||
AppUpdatesURL=https://github.com/JHubi1/ollama-app/releases
|
||||
|
|
|
@ -28,7 +28,7 @@ UninstallDisplayName={#AppName}
|
|||
|
||||
DefaultDirName={autopf}\OllamaApp
|
||||
OutputDir=build\windows\{#AppArchitectures}\runner
|
||||
OutputBaseFilename=ollama-v{#AppVersion}-{#AppArchitectures}
|
||||
OutputBaseFilename=ollama-windows-{#AppArchitectures}-v{#AppVersion}
|
||||
|
||||
AppSupportURL=https://github.com/JHubi1/ollama-app/issues
|
||||
AppUpdatesURL=https://github.com/JHubi1/ollama-app/releases
|
||||
|
|
Loading…
Reference in New Issue