Skip to content

Commit

Permalink
Major update
Browse files Browse the repository at this point in the history
- Added settings
- Added welcome dialog
- Added custom system message (kinda #4)
- Added markdown in messages
- Added streamed responses
- Completely reworked UI concept
- Multi chat support
- Added conversation titles
- Fixed #3 (visually the same)
  • Loading branch information
JHubi1 committed May 31, 2024
1 parent f9ff88f commit fa253b5
Show file tree
Hide file tree
Showing 36 changed files with 2,190 additions and 411 deletions.
48 changes: 33 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

A modern and easy-to-use client for Ollama. Have the greatest experience while keeping everything private and in your local network.

| ![](assets/screenshots/img1_framed.png) | ![](assets/screenshots/img2_framed.png) | ![](assets/screenshots/img3_framed.png) | ![](assets/screenshots/img4_framed.png) |
| ![](assets/screenshots/img1_framed.png) | ![](assets/screenshots/img2_framed.png) | ![](assets/screenshots/img3_framed.png) | ![](assets/screenshots/img6_framed.png) |
|-|-|-|-|

> Important: This app does not host a Ollama server on device, but rather connects to one and uses its api endpoint.
Expand All @@ -26,46 +26,56 @@ You'll find the latest recommended version of the Ollama App under [the releases

After installing the app and opening it for the first time, you'll encounter this popup:

![set host dialog](assets/screenshots/other/s01.png)
![welcome instructions](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).
Go through the welcome dialog one by one, you should read their content, but you don't have to.

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.
| ![initial notification](assets/screenshots/other/s02.png) | ![open side menu](assets/screenshots/other/s03.png) | ![set host dialog](assets/screenshots/other/s04.png) |
|-|-|-|

After going through that, you'll get a small snack bar notifying you that you have to set the host. For that, open the sidebar (swipe from the left to right or click the icon in the top left corner) and click on settings. There you'll find all app-related settings, you should go through them, but for the initial setup, only the first one is important.

In the bit host text field, 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). After that, click the save icon right next to the text field.

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. If you set the host once, and your server is offline, the requests will fail, but the host will stay saved if you don't change it yourself. 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 three options: `New Chat`, `Ask before Deletion` and `Set Host`. The first option clears the chat (-> creates a new one), the second one opens a new dialog that has a toggle you can toggle if you don't want to be asked or want to be asked again before deleting a chat, and the third option reopens the host dialog from the initial start of the app to adapt to changing hosts.
The button on the top left opens the menu. In it, you have two options: `New Chat` and `Settings`. The first option creates a new chat, and the second one opens the settings screen where you can change how everything works.

![side menu](assets/screenshots/other/s02.png)
Below that are all the chats. To delete one, swipe it from left to right. To rename the chat tab and hold it until a popup dialog appears. In it, you can change the title or tab the sparkle icon to let AI find one for you. This is not affected by the "generate title" setting.

Note: The same effect as the `New Chat` option has the button on the top right of the main screen.
| ![side menu](assets/screenshots/other/s03.png)| ![side menu](assets/screenshots/other/s08.png) |
|-|-|

> Note: The button on the top right corner deletes the chat. It has the same effect as swiping the chat in the sidebar.
## 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)
![model selector](assets/screenshots/other/s05.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.
The `Add` button does nothing at the moment, it just opens a snack bar listing 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:
After selecting a supported model, as describes in [Model Selector](#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)
| ![attachment dialog](assets/screenshots/other/s09.png) | ![side menu](assets/screenshots/other/s06.png) |
|-|-|

Select one of them, take your photo and it'll get added to the chat. You can also add multiple.
Select one of them, take or select 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.

Expand All @@ -85,19 +95,27 @@ Now comes the interesting part. I built this app in a way you can easily create
```
// 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";
// host of ollama, must be accessible from the client, without trailing slash, will always be accepted as valid
const fixedHost = "http://example.com:11434";
// 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"];
// allow opening of settings
const allowSettings = true;
// allow multiple chats
const allowMultipleChats = true;
```

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.
`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.

`allowSettings` will disable the settings screen. But it will also disable the welcome dialog at first startup and the ability to rename chats.

`allowMultipleChats` simply removes the `New Chat` option in the [Side Menu](#side-menu). And will load up the only available chat on app startup.

### Actually Building

Expand Down
28 changes: 19 additions & 9 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
Expand All @@ -37,9 +37,19 @@
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
<action android:name="android.intent.action.PROCESS_TEXT" />
<data android:mimeType="text/plain" />
</intent>
<!-- check if url is valid -->
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="http" />
</intent>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="https"/>
</intent>
<!-- check if url is valid end -->
</queries>
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
Binary file added assets/OllamaWelcome.zip
Binary file not shown.
Binary file added assets/OllamaWelcomeDark.zip
Binary file not shown.
Binary file added assets/logo512error.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/screenshots/img2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/screenshots/img2_framed.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/screenshots/img5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/screenshots/img5_framed.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/screenshots/img6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/screenshots/img6_framed.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/screenshots/other/s01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/screenshots/other/s02.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/screenshots/other/s03.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/screenshots/other/s04.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/screenshots/other/s05.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/screenshots/other/s06.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/screenshots/other/s07.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/screenshots/other/s08.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/screenshots/other/s09.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/welcome/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/welcome/1dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/welcome/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/welcome/2dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/welcome/3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/welcome/3dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions fastlane/metadata/android/de-DE/changelogs/v1.0.0.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
- Einstellungen hinzugefügt
- Begrüßungsdialog hinzugefügt
- Hinzugefügte benutzerdefinierte Systemnachricht
- Markdown in Nachrichten hinzugefügt
- Gestreamte Antworten hinzugefügt
- Vollständig überarbeitetes UI-Konzept
- Unterstützung für Mehrfachchats
- Konversationstitel hinzugefügt
- Fehler behoben, wenn die Modellversion nicht `latest` ist
9 changes: 9 additions & 0 deletions fastlane/metadata/android/en-US/changelogs/v1.0.0.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
- Added settings
- Added welcome dialog
- Added custom system message
- Added markdown in messages
- Added streamed responses
- Completely reworked UI concept
- Multi chat support
- Added conversation titles
- Fixed bug when model version is not `latest`
Loading

0 comments on commit fa253b5

Please sign in to comment.