Skip to content

Commit

Permalink
Merge pull request #18 from geeker-ai/prompts
Browse files Browse the repository at this point in the history
Prompts
  • Loading branch information
zmhu authored Oct 8, 2023
2 parents 44481ff + 5b5421d commit 3aac5d1
Show file tree
Hide file tree
Showing 18 changed files with 429 additions and 54 deletions.
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ Geek Chat is a cross-platform AI Client that supports MacOS, Windows, iPhone, iP

![iOS](https://img.shields.io/badge/-iOS-black?style=flat-square&logo=apple&logoColor=white) ![Android](https://img.shields.io/badge/-Android-black?style=flat-square&logo=android&logoColor=white) ![macOS](https://img.shields.io/badge/-macOS-black?style=flat-square&logo=apple&logoColor=white) ![Windows](https://img.shields.io/badge/-Windows-black?style=flat-square&logo=windows&logoColor=white) ![GitHub all releases](https://img.shields.io/github/downloads/geeker-ai/geek_chat/total)

## Install Issues
- Windows [troubleshoot-appinstaller-issues](https://learn.microsoft.com/zh-cn/windows/msix/app-installer/troubleshoot-appinstaller-issues)
- macOS [Open a Mac app from an unidentified developer](https://support.apple.com/zh-cn/guide/mac-help/mh40616/mac)

## Desktop ScreenShots

<table>
Expand Down Expand Up @@ -90,6 +94,7 @@ Geek Chat is a cross-platform AI Client that supports MacOS, Windows, iPhone, iP
- [ ] Copy button for code blocks
- [ ] Azure OpenAI API compatibility
- [ ] Chat with files.
- [ ] DALL-E3
- [ ] Chat with URLs.

## How to Contribute
Expand All @@ -108,6 +113,8 @@ Any form of contribution is welcome, including but not limited to:

Geek chat is developed using the flutter language. It can be compiled and packaged directly using the flutter command. It also supports the packaging of flutter_distributor.

Regarding flutter development using vscode and skip installing android studio, please refer to this article [Manually installing the Flutter development environment on MacOS.](https://macgeeker.com/devnotes/macos-flutter/)

iOS packaging requires a profile. Before I obtain authorization from Apple developers, if you need to package iOS, please package it by yourself.

```
Expand All @@ -116,9 +123,9 @@ flutter pub get
flutter build ipa
```

<!-- ## Star History
## Star History

[![Star History Chart](https://api.star-history.com/svg?repos=geeker-ai/geek_chat&type=Date)](https://star-history.com/#geeker-ai/geek_chat&Date) -->
[![Star History Chart](https://api.star-history.com/svg?repos=geeker-ai/geek_chat&type=Date)](https://star-history.com/#geeker-ai/geek_chat&Date)

## License
[GNU General Public License v3.0](./LICENSE)
8 changes: 6 additions & 2 deletions lib/components/main_settings_component.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'package:event_bus/event_bus.dart';
import 'package:flutter/material.dart';
import 'package:geek_chat/components/settings/bottom_sheet_switcher.dart';
import 'package:geek_chat/controller/settings.dart';
import 'package:geek_chat/models/language.dart';
import 'package:geek_chat/models/theme.dart';
import 'package:get/get.dart';

Expand All @@ -12,8 +14,8 @@ class SettingsComponent extends StatelessWidget {

List<Map<String, String>> getLanguageOptions() {
List<Map<String, String>> options = [];
for (Map<String, String> item in SettingsController.to.locales) {
options.add({'name': item['locale'] ?? '', 'title': item['name'] ?? ''});
for (LanguageModel item in SettingsController.to.locales) {
options.add({'name': item.locale, 'title': item.name});
}
return options;
}
Expand Down Expand Up @@ -96,6 +98,8 @@ class SettingsComponent extends StatelessWidget {
onTapCallback: (value) {
controller.settingsLanguage = value;
controller.saveSettings();
EventBus eventBus = Get.find();
eventBus.fire(SettingsController.to.getLocale(value));
},
),

Expand Down
81 changes: 81 additions & 0 deletions lib/components/prompt/prompt_list_component.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import 'package:event_bus/event_bus.dart';
import 'package:flutter/material.dart';
import 'package:geek_chat/controller/chat_list_controller.dart';
import 'package:geek_chat/controller/main_controller.dart';
import 'package:geek_chat/models/language.dart';
import 'package:geek_chat/models/session.dart';
import 'package:get/get.dart';
import 'package:logger/logger.dart';

// ignore: must_be_immutable
class PromptListComponent extends StatelessWidget {
PromptListComponent({super.key}) {
eventBus.on<LanguageModel>().listen((event) {
mainController.initPrompts().then((value) {
logger.d("init prompts finished!");
mainController.update();
});
});
}

ChatListController chatListController = Get.find();
MainController mainController = Get.find();
Logger logger = Get.find();
EventBus eventBus = Get.find();

@override
Widget build(BuildContext context) {
return GetBuilder<MainController>(builder: (controller) {
return ListView.builder(
padding: const EdgeInsets.only(
left: 10.0, top: 0.0, right: 20.0, bottom: 0.0),
itemCount: controller.prompts.length,
controller: ScrollController(),
itemBuilder: (BuildContext ctxt, int index) {
return Container(
padding: const EdgeInsets.only(bottom: 10),
child: Card(
elevation: 5,
child: InkWell(
onTap: () {
SessionModel sessionModel =
chatListController.createSession(
name: controller.prompts.elementAt(index).name,
prompt: controller.prompts.elementAt(index).prompt,
);
// chatListController.save();
chatListController.saveSession(sessionModel);
controller.navIndex = 0;
controller.update();
chatListController.update();
Get.toNamed('/chat', parameters: {'sid': sessionModel.sid});
},
child: Container(
padding: const EdgeInsets.all(15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
controller.prompts.elementAt(index).name,
style: const TextStyle(
fontSize: 17, fontWeight: FontWeight.bold),
),
const SizedBox(
height: 10,
),
Text(
controller.prompts.elementAt(index).prompt,
maxLines: 3,
overflow: TextOverflow.ellipsis,
softWrap: true,
)
],
),
),
),
),
);
});
});
}
}
29 changes: 29 additions & 0 deletions lib/controller/chat_list_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:geek_chat/controller/settings.dart';
import 'package:geek_chat/models/model.dart';
import 'package:geek_chat/models/session.dart';
import 'package:geek_chat/repository/sessions_repository.dart';
import 'package:geek_chat/util/functions.dart';
import 'package:get/get.dart';
import 'package:moment_dart/moment_dart.dart';
import 'package:uuid/uuid.dart';
Expand Down Expand Up @@ -68,6 +69,28 @@ class ChatListController extends GetxController {
return currentSession;
}

SessionModel createSession(
{String name = 'Untitled',
String prompt = 'You are a helpful assistant.'}) {
AiModel model = SettingsController.to.getModelByName('gpt-3.5-turbo');
currentSession = SessionModel(
sid: const Uuid().v4(),
name: name,
promptContent: prompt,
type: model.aiType.name,
modelType: model.modelType.name,
model: model.modelName,
maxContextSize: model.maxContextSize,
maxContextMsgCount: 22,
temperature: model.temperature,
maxTokens: model.maxTokens,
updated: getCurrentDateTime(),
synced: false,
status: 1);
currentSessionId = currentSession.sid;
return currentSession;
}

SessionModel getSessionBysid(String sid) {
// SessionModel? currentSession;
late SessionTable? st;
Expand All @@ -92,6 +115,12 @@ class ChatListController extends GetxController {
getSessionBysid(currentSession.sid);
}

void saveSession(SessionModel sessionModel) {
_sessionRepository.save(sessionModel.toSessionTable());
// getSessionBysid(sessionModel.sid);
sessions.insert(0, sessionModel);
}

void remove(SessionModel session) {
sessions.remove(session);
_sessionRepository.removeSession(session.sid);
Expand Down
63 changes: 63 additions & 0 deletions lib/controller/main_controller.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import 'dart:convert';

import 'package:flutter/services.dart';
import 'package:geek_chat/controller/settings.dart';
import 'package:geek_chat/models/prompts.dart';
import 'package:geek_chat/models/release.dart';
import 'package:geek_chat/repository/localstore_repository.dart';
import 'package:geek_chat/service/http_service.dart';
import 'package:geek_chat/util/functions.dart';
import 'package:get/get.dart';
import 'package:logger/logger.dart';

Expand All @@ -16,6 +20,7 @@ class ChangeLogModel {
class MainController extends GetxController {
static MainController get to => Get.find();
Logger logger = Get.find();
final LocalStoreRepository _localStoreRepository = Get.find();

@override
void onInit() {
Expand Down Expand Up @@ -69,6 +74,64 @@ class MainController extends GetxController {
});
}

bool get needRefreshPrompts {
bool needRefresh = false;
if (prompts.isEmpty) {
needRefresh = true;
return needRefresh;
}
if (promptLang == SettingsController.to.lang) {
needRefresh = false;
} else {
return false;
}
return needRefresh;
}

List<PromptModel> prompts = [];
String promptLang = '';
Future<List<PromptModel>> initPrompts() async {
prompts.clear();
// if (prompts.isNotEmpty) {
// return prompts;
// }
promptLang = SettingsController.to.lang;
int datestr = getCurrentDate();
String key = "$datestr-${SettingsController.to.lang}";
logger.d("initPrompts: $key");
String jsonStr = '';
if (key == _localStoreRepository.getPromptsLastUpdate()) {
jsonStr = _localStoreRepository.getPromptsJsonString();
logger.d("get prompts from local store");
} else {
jsonStr = await _fetchPrompts();
if (jsonStr.isNotEmpty) {
_localStoreRepository.savePrompts(jsonStr);
_localStoreRepository.updatePromptsLastUpdate(key);
}
}

if (jsonStr.isNotEmpty) {
var jsonObj = jsonDecode(jsonStr);
for (var item in jsonObj) {
prompts.add(PromptModel(
id: "${item['id']}", name: item['name'], prompt: item['prompt']));
}
}
return prompts;
// logger.d(prompts);
}

Future<String> _fetchPrompts() async {
String url = "http://capi.fucklina.com/app/prompt";
Map<String, String> headers = {
"lang": SettingsController.to.lang,
};

String responseString = await HttpClientService.getPrompts(url, headers);
return responseString;
}

Future<String> fetchReleaseInfo(List<String> urls) async {
String version = '';
for (String url in urls) {
Expand Down
42 changes: 35 additions & 7 deletions lib/controller/settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:geek_chat/models/language.dart';
import 'package:geek_chat/models/model.dart';
import 'package:geek_chat/models/settings.dart';
import 'package:geek_chat/models/theme.dart';
Expand Down Expand Up @@ -75,9 +76,15 @@ class SettingsController extends GetxController {
maxTokens: 0),
];

final List<Map<String, String>> locales = [
{'name': 'Simplified Chinese', 'locale': 'zh_Hans_CN'},
{'name': 'English', 'locale': 'en_US'}
final List<Map<String, String>> locales1 = [
{'name': 'Simplified Chinese', 'locale': 'zh_Hans_CN', 'lang': 'zh-Hans'},
{'name': 'English', 'locale': 'en_US', 'lang': 'en'}
];

final List<LanguageModel> locales = [
LanguageModel(
name: 'Simplified Chinese', locale: 'zh_Hans_CN', lang: 'zh-Hans'),
LanguageModel(name: "English", locale: 'en_US', lang: 'en')
];

final List<Map<String, String>> serverList = [
Expand Down Expand Up @@ -120,6 +127,27 @@ class SettingsController extends GetxController {
return channel;
}

LanguageModel getLocale(String locale) {
LanguageModel lm = locales[0];
for (LanguageModel languageModel in locales) {
if (languageModel.locale == locale) {
lm = languageModel;
break;
}
}
return lm;
}

String get lang {
String lang = 'en';
for (LanguageModel locale in locales) {
if (locale.locale == settings.language) {
lang = locale.lang;
}
}
return lang;
}

bool get needSettings {
logger.d("${settings.toJson()}");

Expand Down Expand Up @@ -169,13 +197,13 @@ class SettingsController extends GetxController {
}

String get locale {
String currentLocale = "${locales[0]['name']}";
String currentLocale = locales[0].name; //"${locales[0]['name']}";
// print(currentLocale);
// print(settings.language);
for (var element in locales) {
for (LanguageModel element in locales) {
// print("${element['locale']}");
if ("${element['locale']}" == settings.language) {
currentLocale = "${element['name']}";
if (element.locale == settings.language) {
currentLocale = element.name;
break;
}
}
Expand Down
Loading

0 comments on commit 3aac5d1

Please sign in to comment.