Browse Source

Robot now can answer a question.

pull/6/head
Sun 4 years ago
parent
commit
b913131d07
  1. 2
      Cargo.toml
  2. 171
      assets/answers/chinese_simplified.txt
  3. 171
      assets/answers/english.txt
  4. 51
      lib/apps/assistant/answer.dart
  5. 7
      lib/apps/assistant/message.dart
  6. 18
      lib/apps/assistant/models.dart
  7. 13
      lib/apps/assistant/page.dart
  8. 2
      pubspec.yaml
  9. 31
      src/apps/assistant/models.rs
  10. 8
      src/apps/assistant/rpc.rs

2
Cargo.toml

@ -21,7 +21,7 @@ panic = 'abort' @@ -21,7 +21,7 @@ panic = 'abort'
[dependencies]
log = "0.4"
rand = "0.7"
rand = "0.8"
simplelog = "0.8"
image = "0.23"
base64 = "0.13"

171
assets/answers/chinese_simplified.txt

@ -0,0 +1,171 @@ @@ -0,0 +1,171 @@
需要一个相当大的努力
从现在开始 一年也没有关系
绝对不是
接受改变你的日常行为
似乎已经是真实的了
采用一个冒险的态度
允许你选择先休息一下
小心谨慎的靠近
你还是问问爸爸吧
你还是问问妈妈吧
援助会让你成功进步
避免第一个解决方案
被人肯定
更慷慨
耐心点
实际一点吧
打赌
耐心的等待
合作将会是关键
考虑一下这个机会
数到10;再问
以后处理
当然
早点做到这一点
在这个时候不要问太多了
不要担心
不要迫于压力太快
别傻了
不要赌
不用怀疑了
不要忘记有乐趣
不要陷入你的感情
不要犹豫
不要忽视显而易见的
不要过分
不要等待
别浪费时间了
怀疑
尽情体验
要解决
探讨其俏皮的好奇心
完成其他事情的第一
专注你的家庭生活
遵循别人的引导
遵循专家的建议
履行你自己的义务
按照你的意愿
温柔的坚持就是胜利
获得更清晰的视野
把它写下来
给它你的一切
如果是,做的很好;如果不是,就不要这么做;
如果你按我说的做
如果你不反抗
调查研究,然后享受它!
这不可能失败
这可能是特别的
这是肯定的
这不是重要的
这是非常重要
这是你不会忘记的
这肯定会让事情变得有趣
这是不确定的
是值得的麻烦
这可能已经是木已成舟
这可能很难,但你会发现它的价值
这个似乎放心
这将影响别人看你
这将是一种享受
这会带来好运
这将会创造一个扰乱
这仍然是不可预测的
它会支持你的
这将更好地专注于自己的工作
这是不明智的
它会让你付出代价
这是一个不错的时间安排
会很棒的
这是不值得的斗争
是你走的时候
保持开放的心态
不要让别人知道
笑一下
离开旧的解决方案
过去的事就让它过去吧
仔细聆听;那么你就会知道
列出原因
为什么不列出原因
也许
不幸的是极有可能的
继续前行
从来没有
没有
不管是什么
如果你不孤单
现在你可以
只做一次
其他人将取决于你的选择
注重细节
也许,当你老了
为突发事件做好准备
按下关闭
须以较宽松的步伐
有时候选择太多,就代表着无从选择!
重新考虑你的方法
相关的问题可能的浮出水面
保持灵活
删除你自己的障碍物
重新确定优先次序什么是重要的
尊重规则
保存你的精力
寻找更多的选择
设定优先等级是一个必要的过程!
很快就会解决它
转移你的焦点
说出来吧
令人震惊的事件可能发生的
冒险一试
负责
花更多的时间来决定
告诉别人它对你意味着什么
那将是浪费钱
那是脱离你的控制
答案就在你的后院
答案可能会在另一种语言
最好的解决办法可能不是明显的
机会不会很快再来
情况将很快发生改变
结果会是好的
情况不明
与另一种情况有潜在的联系
有充分的理由保持乐观
没有保证
会有障碍要克服
这是一个很好的时机,来制定新计划
为了确保能作出最佳决策,需要保持冷静
相信自己的直觉
相信你的原始思想
尝试一种更不太可能的解决方案
不宜在这个时候
毫无疑问
无论如何你可以提升
运用你的想象力
等一等
等待一个更好的机会
看看会发生什么
注意你的节奏
不管你做什么,结果将持久
可以
是的,但不要强迫
你一定有支持
你太近的看了
你可能觉得自己无法妥协
你真的不在乎
你知道现在比以前更好
你可能会反对
你可能会放弃其他的东西
你必须
你现在必须行动
你会发现一切你需要知道的
你将需要适应
你不会失望的
你会很高兴你做了
你会得到最后的决定
你将不得不妥协
你将不得不补回来
您需要了解更多信息
你需要考虑其他办法
你需要主动出击
你会后悔的
你的行动将会改善

171
assets/answers/english.txt

@ -0,0 +1,171 @@ @@ -0,0 +1,171 @@
A Substantial Effort Will Be Required
A Year From Now It Won't Matter
Absolutely Not
Accept A Change To Your Routine
Act As Though It Is Already Real
Adopt An Adventurous Attitude
Allow Yoursele To Rest First
Approach Cautiously
Ask Your Father
Ask Your Mother
Assistance Would Make Your Progress A Success
Avoid The First Solution
Be Delightfully Sure Of It
Be More Generous
Be Patient
Be Practical
Bet On It
Better To Wait
Collaboration Will Be The Key
Consider It An Opportunity
Count To 10; Ask Again
Deal With It Later
Definitely
Do It Early
Don't Ask For Any More At This Time
Don't Be Concerned
Don't Be Pressured Into Acting Too Quickly
Don't Be Ridiculous
Don't Bet On It
Don't Doubt It
Don't Forget To Have Fun
Don't Get Caught Up In Your Emotions
Don't Hesitate
Don't Ignore The Obvious
Don't Overdo It
Don't Wait
Don't Waste Your Time
Doubt It
Enjoy The Experience
Expect To Settle
Explore It With Playful Curiosity
Finish Something Else First
Focus On Your Home Life
Follow Someone Else's Lead
Follow The Advice Of Experts
Follow Through On Your Obligations
Follow Through With Your Good Intentions
Gentle Persistence Will Pay Off
Get A Clearer View
Get It In Writing
Give It All You've Got
If It's Done Well; If Not, Don't Do It At All
If You Do As You're Told
If You Don't Resist
Investigate And Then Enjoy It
It Cannot Fail
It Could Be Extraordinary
It Is Certain
It Is Not Significant
It Is Significant
It Is Something You Won't Forget
It Is Sure To Make Things Interesting
It Is Uncertain
It Is Worth The Trouble
It May Already Be A Done Deal
It May Be Difficult But You Will Find Value In It
It Seems Assured
It Will Affect How Others See You
It Will Be A Pleasure
It Will Bring Good Luck
It Will Create A Stir
It Will Remain Unpredictable
It Will Sustain You
It Would Be Better To Focus On Your Work
It Would Be Inadvisable
It'll Cost You
It's A Good Time To Make Plans
It's Gonna Be Great
It's Not Worth A Struggle
It's Time For You To Go
Keep An Open Mind
Keep It To Yourself
Laugh About It
Leave Behind Old Solutions
Let It Go
Listen More Carefully; Then You Will Know
Make A List Of Why
Make A List Of Why Not
Maybe
Mishaps Are Highly Probable
Move On
Never
No
No Matter What
Not If You're Alone
Now You Can
Only Do It Once
Others Will Depend On Your Choices
Pay Attention To The Details
Perhaps, When You're Older
Prepare For The Unexpected
Press For Closure
Proceed At A More Relaxed Pace
Realize That Too Many Choices Is As Difficult As Too Few
Reconsider Your Approach
Related Issues May Surface
Remain Flexible
Remove Your Own Obstacles
Reprioritize What Is Important
Respect The Rules
Save Your Energy
Seek Out More Options
Setting Priorities Will Be A Necessary Part Of The Process
Settle It Soon
Shift Your Focus
Speak Up About It
Startling Events May Occur As A Result
Take A Chance
Take Charge
Take More Time To Decide
Tell Someone What It Means To You
That Would Be A Waste Of Money
That's Out Of Your Control
The Answer Is In Your Backyard
The Answer May Come To You In Another Language
The Best Solution May Not Be The Obvious One
The Chance Will Not Come Again Soon
The Circumstances Will Change Very Quickly
The Outcome Will Be Positive
The Situation Is Unclear
There Is A Substantial Link To Another Situation
There Is Good Reason To Be Optimistic
There Is No Guarantee
There Will Be Obstacles To Overcome
This Is A Good Time To Make A New Plan
To Ensure The Best Decision, Be Calm
Trust Your Intuition
Trust Your Original Thought
Try A More Unlikely Solution
Unfavorable At This Time
Unquestionably
Upgrade Any Way You Can
Use Your Imagination
Wait
Wait For A Better Offer
Watch And See What Happens
Watch Your Step As You Go
Whatever You Do The Results Will Be Lasting
Yes
Yes,But Don't Force It
You Are Sure To Have Support
You Are Too Close To See
You Could Find Yourself Unable To Compromise
You Don't Really Care
You Know Better Now Than Ever Before
You May Have Opposition
You May Have To Drop Other Things
You Must
You Must Act Now
You Will Find Out Everything You'll Need To Know
You Will Need To Accommodate
You Will Not Be Disappointed
You'll Be Happy You Did
You'll Get The Final Word
You'll Have To Compromise
You'll Have To Make It Up As You Go
You'll Need More Information
You'll Need To Consider Other Ways
You'll Need To Take The Initiative
You'll Regret It
Your Actions Will Improve Thin

51
lib/apps/assistant/answer.dart

@ -0,0 +1,51 @@ @@ -0,0 +1,51 @@
import 'dart:async';
import 'dart:ui';
import 'package:flutter/services.dart' show rootBundle;
enum AnswerLang {
CHINESE_SIMPLIFIED,
ENGLISH,
}
final ANSWER_LANGS = [
AnswerLang.ENGLISH,
AnswerLang.CHINESE_SIMPLIFIED,
];
final _langCache = Map<AnswerLang, List<dynamic>>();
String _getAnswerLangName(AnswerLang lang) {
switch (lang) {
case AnswerLang.CHINESE_SIMPLIFIED:
return 'chinese_simplified';
case AnswerLang.ENGLISH:
return 'english';
default:
return 'english';
}
}
Future<List<String>> loadAnswers(Locale locale) async {
AnswerLang lang = AnswerLang.ENGLISH;
switch (locale) {
case Locale('en'):
lang = AnswerLang.ENGLISH;
break;
case Locale('zh'):
lang = AnswerLang.CHINESE_SIMPLIFIED;
break;
default:
lang = AnswerLang.ENGLISH;
break;
}
if (_langCache.containsKey(lang)) {
return _langCache[lang];
} else {
final rawWords = await rootBundle.loadString('assets/answers/${_getAnswerLangName(lang)}.txt');
final result = rawWords.split('\n').map((s) => s.trim()).where((s) => s.isNotEmpty).toList(growable: false);
_langCache[lang] = result;
return result;
}
}

7
lib/apps/assistant/message.dart

@ -20,8 +20,9 @@ import 'package:esse/apps/assistant/models.dart'; @@ -20,8 +20,9 @@ import 'package:esse/apps/assistant/models.dart';
class AssistantMessage extends StatelessWidget {
final String name;
final Message message;
final List<String> answers;
const AssistantMessage({Key key, this.name, this.message}): super(key: key);
const AssistantMessage({Key key, this.name, this.message, this.answers}): super(key: key);
Widget _showText(context, color, isDesktop, content, isMe) {
final width = MediaQuery.of(context).size.width * 0.6;
@ -339,6 +340,10 @@ class AssistantMessage extends StatelessWidget { @@ -339,6 +340,10 @@ class AssistantMessage extends StatelessWidget {
return _showContact(context, lang, color, content);
} else if (type == MessageType.Record) {
return _showRecord(content);
} else if (type == MessageType.Answer) {
final index = int.parse(content);
final value = this.answers != null && this.answers.length > index ? this.answers[index] : content;
return _showText(context, color, isDesktop, value, isMe);
}
return _showText(context, color, isDesktop, content, isMe);
}

18
lib/apps/assistant/models.dart

@ -8,6 +8,7 @@ enum MessageType { @@ -8,6 +8,7 @@ enum MessageType {
Contact,
Emoji,
Record,
Answer,
}
// use 00-99
@ -26,6 +27,8 @@ extension MessageTypeExtension on MessageType { @@ -26,6 +27,8 @@ extension MessageTypeExtension on MessageType {
return 4;
case MessageType.Record:
return 5;
case MessageType.Answer:
return 6;
default:
return 0;
}
@ -45,6 +48,8 @@ extension MessageTypeExtension on MessageType { @@ -45,6 +48,8 @@ extension MessageTypeExtension on MessageType {
return MessageType.Emoji;
case 5:
return MessageType.Record;
case 6:
return MessageType.Answer;
default:
return MessageType.String;
}
@ -95,19 +100,6 @@ class Message { @@ -95,19 +100,6 @@ class Message {
}
}
String shortShow() {
switch (this.q_type) {
case MessageType.Image:
return '[IMAGE]';
case MessageType.Record:
return '[RECORD]';
case MessageType.Contact:
return '[CONTACT CARD]';
default:
return this.q_content;
}
}
Message.fromList(List params) {
this.id = params[0];
this.q_type = MessageTypeExtension.fromInt(params[1]);

13
lib/apps/assistant/page.dart

@ -11,11 +11,13 @@ import 'package:esse/widgets/shadow_dialog.dart'; @@ -11,11 +11,13 @@ import 'package:esse/widgets/shadow_dialog.dart';
import 'package:esse/widgets/audio_recorder.dart';
import 'package:esse/widgets/user_info.dart';
import 'package:esse/global.dart';
import 'package:esse/options.dart';
import 'package:esse/apps/chat/provider.dart';
import 'package:esse/apps/assistant/models.dart';
import 'package:esse/apps/assistant/provider.dart';
import 'package:esse/apps/assistant/message.dart';
import 'package:esse/apps/assistant/answer.dart';
class AssistantPage extends StatefulWidget {
const AssistantPage({Key key}) : super(key: key);
@ -32,12 +34,16 @@ class _AssistantPageState extends State<AssistantPage> { @@ -32,12 +34,16 @@ class _AssistantPageState extends State<AssistantPage> {
bool menuShow = false;
bool recordShow = false;
String _recordName;
List<String> answers;
@override
initState() {
super.initState();
Future.delayed(Duration.zero, () {
Future.delayed(Duration.zero, () async {
Provider.of<AssistantProvider>(context, listen: false).actived();
final options = context.read<Options>();
this.answers = await loadAnswers(options.locale);
setState(() {});
});
textFocus.addListener(() {
if (textFocus.hasFocus) {
@ -65,7 +71,9 @@ class _AssistantPageState extends State<AssistantPage> { @@ -65,7 +71,9 @@ class _AssistantPageState extends State<AssistantPage> {
return;
}
context.read<AssistantProvider>().create(MessageType.String, textController.text);
final value = textController.text.trim();
final a_type = (value.endsWith('?') || value.endsWith('')) ? MessageType.Answer : MessageType.String;
context.read<AssistantProvider>().create(a_type, textController.text);
setState(() {
textController.text = '';
@ -267,6 +275,7 @@ class _AssistantPageState extends State<AssistantPage> { @@ -267,6 +275,7 @@ class _AssistantPageState extends State<AssistantPage> {
itemBuilder: (BuildContext context, index) => AssistantMessage(
name: 'esse',
message: recentMessages[recentMessageKeys[index]],
answers: this.answers,
)
)),
Container(

2
pubspec.yaml

@ -91,6 +91,8 @@ flutter: @@ -91,6 +91,8 @@ flutter:
- assets/mnemonic/japanese.txt
- assets/mnemonic/korean.txt
- assets/mnemonic/spanish.txt
- assets/answers/chinese_simplified.txt
- assets/answers/english.txt
# fonts:
# - family: 'Noto'
# fonts:

31
src/apps/assistant/models.rs

@ -1,3 +1,4 @@ @@ -1,3 +1,4 @@
use rand::Rng;
use std::path::PathBuf;
use std::time::{SystemTime, UNIX_EPOCH};
use tdn::types::{
@ -18,6 +19,7 @@ pub(crate) enum MessageType { @@ -18,6 +19,7 @@ pub(crate) enum MessageType {
Contact,
Emoji,
Record,
Answer,
}
impl MessageType {
@ -29,6 +31,7 @@ impl MessageType { @@ -29,6 +31,7 @@ impl MessageType {
MessageType::Contact => 3,
MessageType::Emoji => 4,
MessageType::Record => 5,
MessageType::Answer => 6,
}
}
@ -40,29 +43,29 @@ impl MessageType { @@ -40,29 +43,29 @@ impl MessageType {
3 => MessageType::Contact,
4 => MessageType::Emoji,
5 => MessageType::Record,
6 => MessageType::Answer,
_ => MessageType::String,
}
}
pub async fn handle(
&self,
self,
base: &PathBuf,
mgid: &GroupId,
content: String,
) -> std::result::Result<String, tdn::types::rpc::RpcError> {
match self {
MessageType::String => Ok(content),
) -> std::result::Result<Message, tdn::types::rpc::RpcError> {
let (q_type, q_raw, a_type, a_raw) = match self {
MessageType::Image => {
let bytes = read_file(&PathBuf::from(content)).await?;
let image_name = write_image(base, &mgid, &bytes).await?;
Ok(image_name)
(self, image_name.clone(), MessageType::Image, image_name)
}
MessageType::File => {
let file_path = PathBuf::from(content);
let bytes = read_file(&file_path).await?;
let old_name = file_path.file_name()?.to_str()?;
let filename = write_file(base, mgid, old_name, &bytes).await?;
Ok(filename)
(self, filename.clone(), MessageType::File, filename)
}
MessageType::Contact => {
let cid: i64 = content.parse().map_err(|_e| new_io_error("id error"))?;
@ -70,16 +73,22 @@ impl MessageType { @@ -70,16 +73,22 @@ impl MessageType {
let contact = Friend::get_id(&db, cid)??;
db.close()?;
let tmp_name = contact.name.replace(";", "-;");
Ok(format!(
let raw = format!(
"{};;{};;{}",
tmp_name,
contact.gid.to_hex(),
contact.addr.to_hex()
))
);
(self, raw.clone(), MessageType::Contact, raw)
}
MessageType::Record => Ok(content),
MessageType::Emoji => Ok(content),
}
MessageType::Answer => {
let a_raw = format!("{}", rand::thread_rng().gen_range(0..171));
(MessageType::String, content, MessageType::Answer, a_raw)
}
_ => (self.clone(), content.clone(), self, content),
};
Ok(Message::new(q_type, q_raw, a_type, a_raw))
}
}

8
src/apps/assistant/rpc.rs

@ -56,13 +56,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -56,13 +56,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
let q_content = params[1].as_str()?.to_string();
let base = state.layer.read().await.base().clone();
let q_raw = q_type.handle(&base, &gid, q_content).await?;
// echo
let a_type = q_type.clone();
let a_content = q_raw.clone();
let mut msg = Message::new(q_type, q_raw, a_type, a_content);
let mut msg = q_type.handle(&base, &gid, q_content).await?;
let db = assistant_db(state.layer.read().await.base(), &gid)?;
msg.insert(&db)?;
db.close()?;

Loading…
Cancel
Save