diff --git a/lib/components/setting.dart b/lib/components/setting.dart index cee9cbc..0498f36 100644 --- a/lib/components/setting.dart +++ b/lib/components/setting.dart @@ -2,11 +2,13 @@ import 'dart:developer'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:moyubie/components/tags_info.dart'; import 'package:moyubie/controller/chat_room.dart'; import 'package:moyubie/controller/settings.dart'; import 'package:get/get.dart'; import 'package:moyubie/repository/chat_room.dart'; import 'package:moyubie/repository/tags.dart'; +import 'package:moyubie/utils/tag_collector.dart'; import 'package:uuid/uuid.dart'; class SettingPage extends StatefulWidget { @@ -366,6 +368,26 @@ class _SettingPageState extends State { child: const Text("Clear remote messages")), ], ), + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + const Text("AI Recommendation"), + Tooltip( + message: "Control how LLM try to guess things you love.", + child: IconButton( + iconSize: 10.0, + splashRadius: 10, + color: Theme.of(context).colorScheme.primary, + onPressed: () {}, + icon: const Icon(Icons.question_mark), + ), + ), + ], + ), + divider, + sizedBoxSpace, + TagsInfo(Get.find()), + // DEBUGGER if (kDebugMode) ...[ Row( @@ -394,18 +416,23 @@ class _SettingPageState extends State { onPressed: () { final repo = Get.find(); repo - .addNewTags(List.generate(10, (index) => Uuid().v4())) - .then((value) => log("DONE?", name: "moyubie::tags")) - .catchError((err) => log("ERROR! [$err]", name: "moyubie::tags")); + .addNewTags( + List.generate(10, (index) => Uuid().v4())) + .then((value) => + log("DONE?", name: "moyubie::tags")) + .catchError((err) => + log("ERROR! [$err]", name: "moyubie::tags")); }, child: const Text("Add some random tags for you!")), ElevatedButton( onPressed: () { final repo = Get.find(); repo - .fetchMostPopularTags(5) - .then((value) => log("DONE? [$value]", name: "moyubie::tags")) - .catchError((err) => log("ERROR! [$err]", name: "moyubie::tags")); + .fetchMostPopularTags(10) + .then((value) => + log("DONE? [$value]", name: "moyubie::tags")) + .catchError((err) => + log("ERROR! [$err]", name: "moyubie::tags")); }, child: const Text("Fetch tags of you!")), ], diff --git a/lib/components/tags_info.dart b/lib/components/tags_info.dart new file mode 100644 index 0000000..ab83c2e --- /dev/null +++ b/lib/components/tags_info.dart @@ -0,0 +1,65 @@ +import 'dart:developer'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:moyubie/utils/tag_collector.dart'; + +class TagsInfo extends StatelessWidget { + final TagCollector _coll; + final Rx?> _$tags = Rx(null); + + TagsInfo(this._coll, {super.key}); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Obx(() => SwitchListTile( + title: _coll.enabled.value + ? const Text("Tag collector is enabled.") + : const Text("Tag collector is disabled."), + subtitle: _coll.enabled.value + ? const Text( + "Once you are asking AI, we will try to get things you love, for recommending more interesting news for you.") + : const Text("We won't try to collect your interest point."), + value: _coll.enabled.value, + onChanged: (open) { + _coll.enabled.value = open; + }, + )), + const SizedBox(height: 4,), + ExpansionTile( + title: const Text("Your Interests"), + onExpansionChanged: (exp) { + if (exp && _$tags.value == null) { + _coll.repo.fetchMostPopularTags(10, waitSync: true).then((value) { + _$tags.value = value; + }); + } + }, + children: [ + Obx(() => _$tags.value == null + ? Center( + child: Container( + margin: const EdgeInsets.symmetric(vertical: 8), + child: const CircularProgressIndicator())) + : Wrap( + alignment: WrapAlignment.start, + children: _$tags.value! + .map((element) => Container( + margin: const EdgeInsets.only(left: 8), + child: ActionChip( + avatar: const Icon(Icons.tag), + label: Text(element), + onPressed: null, + ), + )) + .toList(growable: false), + )) + ]) + ], + ); + } +} diff --git a/lib/repository/tags.dart b/lib/repository/tags.dart index b7b0460..ba73a98 100644 --- a/lib/repository/tags.dart +++ b/lib/repository/tags.dart @@ -68,7 +68,7 @@ class TagsRepository { }); } - Future> fetchMostPopularTags(int limit) async { + Future> fetchMostPopularTags(int limit, {bool waitSync = false}) async { // Firt return what we have in local final db = await ChatRoomRepository().getLocalDb(); final List> maps = await db.rawQuery(''' @@ -84,7 +84,7 @@ class TagsRepository { // Then start async task to synchronize remote to local final remoteDB = ChatRoomRepository().getMyRemoteDb(); - remoteDB.then((remoteDB_) async { + final fut = remoteDB.then((remoteDB_) async { if (remoteDB_ == null) { return; } @@ -111,6 +111,11 @@ class TagsRepository { await _addNewTags(remoteTags); }); + if (waitSync) { + await fut; + return fetchMostPopularTags(limit); + } + return localTags; } } diff --git a/lib/utils/tag_collector.dart b/lib/utils/tag_collector.dart index cde1383..279a4ae 100644 --- a/lib/utils/tag_collector.dart +++ b/lib/utils/tag_collector.dart @@ -6,14 +6,8 @@ import 'package:moyubie/controller/settings.dart'; import 'package:moyubie/repository/tags.dart'; import 'package:moyubie/utils/ai_recommend.dart'; -enum TagCollState { - Running, - Stopped -} - class TagCollector extends DisposableInterface { final TagsRepository repo; - TagCollState state; SettingsController sctl; Future? _bgTask; @@ -21,19 +15,23 @@ class TagCollector extends DisposableInterface { RxList bgErrs = RxList([]); RxInt droppedMsgs = 0.obs; + RxBool enabled = true.obs; AIContext get _ai_ctx => AIContext(api_key: sctl.openAiKey.value, model: sctl.gptModel.value); - TagCollector({required this.state, required this.repo, required this.sctl}); + TagCollector({required this.repo, required this.sctl}); factory TagCollector.create({ TagsRepository? repo, SettingsController? sctl }) { final theRepo = repo ?? Get.find(); final theSctl = sctl ?? Get.find(); - var coll = TagCollector(state: TagCollState.Running, repo: theRepo, sctl: theSctl); + var coll = TagCollector(repo: theRepo, sctl: theSctl); return coll; } void accept(String s) { + if (enabled.isFalse) { + return; + } log("Getting message $s from user.", name: "TagCollector"); _batching.add(s); if (_bgTask != null) {