Updated readme, fixed translation

This commit is contained in:
JHubi1 2024-05-28 21:57:33 +02:00
parent 0e9c5f036c
commit 7268741c89
No known key found for this signature in database
GPG Key ID: 7BF82570CBBBD050
7 changed files with 180 additions and 4 deletions

105
README.md
View File

@ -1,5 +1,106 @@
# Ollama App
A modern and easy-to-use client for Ollama. Currently, not production-ready.
A modern and easy-to-use client for Ollama. Have the greatest experience while keeping everything private and in your local network.
> Important: This app does not host a Ollama server on device, but rather connects to one and plays with it.
| ![](assets/screenshots/img1_framed.png) | ![](assets/screenshots/img2_framed.png) | ![](assets/screenshots/img3_framed.png) | ![](assets/screenshots/img4_framed.png) |
|-|-|-|-|
> Important: This app does not host a Ollama server on device, but rather connects to one and uses its api endpoint.
- [Ollama App](#ollama-app)
- [Initial Setup](#initial-setup)
- [Side Menu](#side-menu)
- [Model Selector](#model-selector)
- [Multimodal Model Input](#multimodal-model-input)
- [Multilingual Interface](#multilingual-interface)
- [Custom Builds](#custom-builds)
- [Actually Building](#actually-building)
## Initial Setup
After installing the app and opening it for the first time, you'll encounter this popup:
![set host dialog](assets/screenshots/other/s01.png)
In this dialog, you have to enter the base URL of your instance. The port is required, except for the port number matching the protocol (443 for HTTPS or 80 for HTTP).
This address will be checked, so no worry about entering the wrong one. The disadvantage of this is that your server has to be running even if you don't want to chat with it at that moment. The checkup only happens on initial setup for now. If you move your server or the server goes down and you try to send a message to it, there is a chance of the app crashing. Don't worry, just go into the side menu and click the settings button to change it.
That's it, you can now just chat. Enter a message into the box at the bottom and click the send icon.
## Side Menu
The button on the top left opens the menu. In it, you have two options for now: `New Chat` and `Settings`. The first option clears the chat (-> creates a new one), and the second one reopens the host dialog from the initial start of the app to adapt to changing hosts.
![side menu](assets/screenshots/other/s02.png)
Note: The same effect as the `New Chat` option has the button on the top right of the main screen.
## Model Selector
You can access the model selector by tapping on the `<selector>` text in the top middle or the name of the currently selected model in the same spot. Then you'll get the following bottom sheet:
![model selector](assets/screenshots/other/s03.png)
This will display all the models currently installed in your Ollama server instance.
Models with an image-like icon next to them allow multimodal input. The one shown in the image, `llava`, supports exactly that.
The models with a star next to them are recommended models. They have been selected by me (hehe) to be listed as that. Read more under [Custom Builds](#custom-builds).
The `Add Model` button does nothing at the moment, it just opens a dialog that lists steps on how to add a model to an instance. For safety reasons I didn't add the ability to add a model directly via name in the app.
## Multimodal Model Input
Ollama App supports multimodal models, models with support input via an image.
After selecting one in the model selector, a new icon appears at the bottom left of the message bar; a camera icon. Clicking on it reveals the following bottom sheet:
![attachment dialog](assets/screenshots/other/s04.png)
Select one of them, take your photo and it'll get added to the chat. You can also add multiple.
Even though the images will appear in the chat already after sending, they won't be submitted to the AI until a new text message is sent.
## Multilingual Interface
I integrated support for multiple languages into the Ollama App. Currently available are:
- English
- German
Your language isn't one of them? Reach out to me and I'll give you access to my Crowdin project.
## Custom Builds
Now comes the interesting part. I built this app in a way you can easily create custom builds. Currently, there are these values that can be customized:
```
// use host or not, if false dialog is shown
const useHost = false;
// host of ollama, must be accessible from the client, without trailing slash
const fixedHost = "http://example.com:1144";
// use model or not, if false selector is shown
const useModel = false;
// model name as string, must be valid ollama model!
const fixedModel = "gemma";
// recommended models, shown with as star in model selector
const recommendedModels = ["gemma", "llama3"];
```
They can be found at the top of `lib/main.dart`. `useHost` and `useModel` decide whether you want `fixedHost` and `fixedModel` to control anything. `fixedHost` and `fixedModel` decide about the value that has to be used. That can be practical in case you try to create an app specific to your instance.
The last one, `recommendedModels`, is a list of models that will be listed as recommended in the [Model Selector](#model-selector). They are more like personal preferences. If empty, no model will be preferred.
### Actually Building
But how do you create a custom build?
First, follow [the Flutter installation guide](https://docs.flutter.dev/get-started/install) by selecting Android as the first app type. Then follow [these steps](https://docs.flutter.dev/deployment/android#signing-the-app) till you have your custom `key.properties`. Place it into the `android` folder at the root of the project.
If you're running on Windows, just double-click on `scripts/build.bat` and wait till the process is done. Don't worry, there'll be a lot of Kotlin errors in the terminal. You can safely ignore them, the build will be fine.
If you're not running Windows, open the file `scripts/build.bat` in a text editor and copy the command starting with `flutter` after the `call` command in a terminal window. Again, don't worry about the Kotlin errors.
In both cases, you'll now find your APK in `build/app/outputs/apk/release/app-release.apk` (don't blame me for that, it's a flutter thing).

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -1,3 +1,78 @@
{
"@@locale": "de"
"@@locale": "de",
"appTitle": "Ollama",
"@appTitle": {
"description": "Title of the application",
"context": "Visible in the side bar"
},
"optionSettings": "Einstellungen",
"@optionSettings": {
"description": "Text displayed for settings option",
"context": "Visible in the side bar"
},
"optionNewChat": "Neuer Chat",
"@optionNewChat": {
"description": "Text displayed for new chat option",
"context": "Visible in the side bar"
},
"takeImage": "Bild Aufnehmen",
"@takeImage": {
"description": "Text displayed for take image button",
"context": "Visible in attachment menu"
},
"uploadImage": "Bild Hochladen",
"@uploadImage": {
"description": "Text displayed for image upload button",
"context": "Visible in attachment menu"
},
"messageInputPlaceholder": "Nachricht",
"@messageInputPlaceholder": {
"description": "Placeholder text for message input",
"context": "Visible in the chat view"
},
"noModelSelected": "Kein Modell ausgewählt",
"@noModelSelected": {
"description": "Text displayed when no model is selected",
"context": "Visible in the chat view"
},
"hostDialogTitle": "Host Festlegen",
"@hostDialogTitle": {
"description": "Title of the host dialog",
"context": "Visible in the host dialog"
},
"hostDialogDescription": "Gebe den Host des Ollama-Servers ein. Dies wird validiert und kann später in den Einstellungen geändert werden.",
"@hostDialogDescription": {
"description": "Description of the host dialog",
"context": "Visible in the host dialog"
},
"hostDialogErrorInvalidHost": "Der Host konnte nicht validiert werden, bitte versuche es erneut. Entweder ist er nicht erreichbar oder es handelt sich nicht um eine gültige Ollama-Serverinstanz.",
"@hostDialogErrorInvalidHost": {
"description": "Error message displayed when the host is invalid",
"context": "Visible in the host dialog"
},
"hostDialogErrorInvalidUrl": "Die URL ist ungültig. Versuche, sie erneut zu überprüfen.",
"@hostDialogErrorInvalidUrl": {
"description": "Error message displayed when the URL is invalid",
"context": "Visible in the host dialog"
},
"hostDialogSave": "Host Speichern",
"@hostDialogSave": {
"description": "Text displayed for save host button, should be capitalized",
"context": "Visible in the host dialog"
},
"noSelectedModel": "<selektor>",
"@noSelectedModel": {
"description": "Text displayed when no model is selected",
"context": "Visible in the chat view, opens the model dialog when clicked"
},
"modelDialogAddModel": "Modell hinzufügen",
"@modelDialogAddModel": {
"description": "Text displayed for add model button",
"context": "Visible in the model dialog"
},
"modelDialogAddSteps": "Um ein neues Modell hinzuzufügen, besuche ollama.com auf deinem Computer, suche nach einem Modell, das dir gefällt, kopieren den Befehl und füge ihn in ein neues Terminalfenster ein. Warten, bis der Download abgeschlossen ist, dies kann eine Weile dauern. Sobald dieser abgeschlossen ist, öffne diesen Selektor erneut und finden dein neu hinzugefügtes Modell.",
"@modelDialogAddSteps": {
"description": "Steps to add a new model",
"context": "Visible in the model dialog"
}
}

View File

@ -481,7 +481,7 @@ class _MainAppState extends State<MainApp> {
backgroundColor:
(themeDark ?? ThemeData.dark()).colorScheme.surface,
primaryColor: (themeDark ?? ThemeData.dark()).colorScheme.primary.withAlpha(40),
attachmentButtonIcon: const Icon(Icons.file_upload_rounded),
attachmentButtonIcon: const Icon(Icons.add_a_photo_rounded),
sendButtonIcon: const Icon(Icons.send_rounded),
inputBackgroundColor: (themeDark ?? ThemeData()).colorScheme.onSurface.withAlpha(40),
inputTextColor: (themeDark ?? ThemeData()).colorScheme.onSurface,