mirror of https://github.com/CympleTech/ESSE.git
34 changed files with 606 additions and 17937 deletions
@ -1,171 +0,0 @@
@@ -1,171 +0,0 @@
|
||||
需要一个相当大的努力 |
||||
从现在开始 一年也没有关系 |
||||
绝对不是 |
||||
接受改变你的日常行为 |
||||
似乎已经是真实的了 |
||||
采用一个冒险的态度 |
||||
允许你选择先休息一下 |
||||
小心谨慎的靠近 |
||||
你还是问问爸爸吧 |
||||
你还是问问妈妈吧 |
||||
援助会让你成功进步 |
||||
避免第一个解决方案 |
||||
被人肯定 |
||||
更慷慨 |
||||
耐心点 |
||||
实际一点吧 |
||||
打赌 |
||||
耐心的等待 |
||||
合作将会是关键 |
||||
考虑一下这个机会 |
||||
数到10;再问 |
||||
以后处理 |
||||
当然 |
||||
早点做到这一点 |
||||
在这个时候不要问太多了 |
||||
不要担心 |
||||
不要迫于压力太快 |
||||
别傻了 |
||||
不要赌 |
||||
不用怀疑了 |
||||
不要忘记有乐趣 |
||||
不要陷入你的感情 |
||||
不要犹豫 |
||||
不要忽视显而易见的 |
||||
不要过分 |
||||
不要等待 |
||||
别浪费时间了 |
||||
怀疑 |
||||
尽情体验 |
||||
要解决 |
||||
探讨其俏皮的好奇心 |
||||
完成其他事情的第一 |
||||
专注你的家庭生活 |
||||
遵循别人的引导 |
||||
遵循专家的建议 |
||||
履行你自己的义务 |
||||
按照你的意愿 |
||||
温柔的坚持就是胜利 |
||||
获得更清晰的视野 |
||||
把它写下来 |
||||
给它你的一切 |
||||
如果是,做的很好;如果不是,就不要这么做; |
||||
如果你按我说的做 |
||||
如果你不反抗 |
||||
调查研究,然后享受它! |
||||
这不可能失败 |
||||
这可能是特别的 |
||||
这是肯定的 |
||||
这不是重要的 |
||||
这是非常重要 |
||||
这是你不会忘记的 |
||||
这肯定会让事情变得有趣 |
||||
这是不确定的 |
||||
是值得的麻烦 |
||||
这可能已经是木已成舟 |
||||
这可能很难,但你会发现它的价值 |
||||
这个似乎放心 |
||||
这将影响别人看你 |
||||
这将是一种享受 |
||||
这会带来好运 |
||||
这将会创造一个扰乱 |
||||
这仍然是不可预测的 |
||||
它会支持你的 |
||||
这将更好地专注于自己的工作 |
||||
这是不明智的 |
||||
它会让你付出代价 |
||||
这是一个不错的时间安排 |
||||
会很棒的 |
||||
这是不值得的斗争 |
||||
是你走的时候 |
||||
保持开放的心态 |
||||
不要让别人知道 |
||||
笑一下 |
||||
离开旧的解决方案 |
||||
过去的事就让它过去吧 |
||||
仔细聆听;那么你就会知道 |
||||
列出原因 |
||||
为什么不列出原因 |
||||
也许 |
||||
不幸的是极有可能的 |
||||
继续前行 |
||||
从来没有 |
||||
没有 |
||||
不管是什么 |
||||
如果你不孤单 |
||||
现在你可以 |
||||
只做一次 |
||||
其他人将取决于你的选择 |
||||
注重细节 |
||||
也许,当你老了 |
||||
为突发事件做好准备 |
||||
按下关闭 |
||||
须以较宽松的步伐 |
||||
有时候选择太多,就代表着无从选择! |
||||
重新考虑你的方法 |
||||
相关的问题可能的浮出水面 |
||||
保持灵活 |
||||
删除你自己的障碍物 |
||||
重新确定优先次序什么是重要的 |
||||
尊重规则 |
||||
保存你的精力 |
||||
寻找更多的选择 |
||||
设定优先等级是一个必要的过程! |
||||
很快就会解决它 |
||||
转移你的焦点 |
||||
说出来吧 |
||||
令人震惊的事件可能发生的 |
||||
冒险一试 |
||||
负责 |
||||
花更多的时间来决定 |
||||
告诉别人它对你意味着什么 |
||||
那将是浪费钱 |
||||
那是脱离你的控制 |
||||
答案就在你的后院 |
||||
答案可能会在另一种语言 |
||||
最好的解决办法可能不是明显的 |
||||
机会不会很快再来 |
||||
情况将很快发生改变 |
||||
结果会是好的 |
||||
情况不明 |
||||
与另一种情况有潜在的联系 |
||||
有充分的理由保持乐观 |
||||
没有保证 |
||||
会有障碍要克服 |
||||
这是一个很好的时机,来制定新计划 |
||||
为了确保能作出最佳决策,需要保持冷静 |
||||
相信自己的直觉 |
||||
相信你的原始思想 |
||||
尝试一种更不太可能的解决方案 |
||||
不宜在这个时候 |
||||
毫无疑问 |
||||
无论如何你可以提升 |
||||
运用你的想象力 |
||||
等一等 |
||||
等待一个更好的机会 |
||||
看看会发生什么 |
||||
注意你的节奏 |
||||
不管你做什么,结果将持久 |
||||
可以 |
||||
是的,但不要强迫 |
||||
你一定有支持 |
||||
你太近的看了 |
||||
你可能觉得自己无法妥协 |
||||
你真的不在乎 |
||||
你知道现在比以前更好 |
||||
你可能会反对 |
||||
你可能会放弃其他的东西 |
||||
你必须 |
||||
你现在必须行动 |
||||
你会发现一切你需要知道的 |
||||
你将需要适应 |
||||
你不会失望的 |
||||
你会很高兴你做了 |
||||
你会得到最后的决定 |
||||
你将不得不妥协 |
||||
你将不得不补回来 |
||||
您需要了解更多信息 |
||||
你需要考虑其他办法 |
||||
你需要主动出击 |
||||
你会后悔的 |
||||
你的行动将会改善 |
@ -1,171 +0,0 @@
@@ -1,171 +0,0 @@
|
||||
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 |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,133 @@
@@ -0,0 +1,133 @@
|
||||
import 'package:flutter/material.dart'; |
||||
import 'package:provider/provider.dart'; |
||||
|
||||
import 'package:esse/utils/adaptive.dart'; |
||||
import 'package:esse/utils/relative_time.dart'; |
||||
import 'package:esse/l10n/localizations.dart'; |
||||
import 'package:esse/widgets/chat_message.dart'; |
||||
import 'package:esse/widgets/chat_input.dart'; |
||||
import 'package:esse/options.dart'; |
||||
import 'package:esse/account.dart' show Language, LanguageExtension; |
||||
import 'package:esse/rpc.dart'; |
||||
|
||||
import 'package:esse/apps/primitives.dart'; |
||||
|
||||
class Message extends BaseMessage { |
||||
Message.fromList(List params) { |
||||
this.id = params[0]; |
||||
this.isMe = params[1]; |
||||
this.type = MessageTypeExtension.fromInt(params[2]); |
||||
this.content = params[3]; |
||||
this.time = RelativeTime.fromInt(params[4]); |
||||
this.isDelivery = true; |
||||
} |
||||
} |
||||
|
||||
class JarvisDetail extends StatefulWidget { |
||||
JarvisDetail({Key? key}) : super(key: key); |
||||
|
||||
@override |
||||
_JarvisDetailState createState() => _JarvisDetailState(); |
||||
} |
||||
|
||||
class _JarvisDetailState extends State<JarvisDetail> { |
||||
TextEditingController textController = TextEditingController(); |
||||
FocusNode textFocus = FocusNode(); |
||||
bool _emojiShow = false; |
||||
bool _sendShow = false; |
||||
bool _menuShow = false; |
||||
bool _recordShow = false; |
||||
String _recordName = ''; |
||||
|
||||
Language _language = Language.English; |
||||
List<String> _answers = []; |
||||
Map<int, Message> _messages = {}; |
||||
|
||||
@override |
||||
initState() { |
||||
super.initState(); |
||||
|
||||
rpc.addListener('jarvis-create', _create, false); |
||||
|
||||
textFocus.addListener(() { |
||||
if (textFocus.hasFocus) { |
||||
setState(() { |
||||
_emojiShow = false; |
||||
_menuShow = false; |
||||
_recordShow = false; |
||||
}); |
||||
} |
||||
}); |
||||
|
||||
Future.delayed(Duration.zero, () async { |
||||
this._language = LanguageExtension.fromLocale(context.read<Options>().locale); |
||||
_load(); |
||||
}); |
||||
} |
||||
|
||||
_load() async { |
||||
this._messages.clear(); |
||||
final res = await httpPost('jarvis-list', []); |
||||
if (res.isOk) { |
||||
_list(res.params); |
||||
} else { |
||||
print(res.error); |
||||
} |
||||
} |
||||
|
||||
/// list message with friend. |
||||
_list(List params) { |
||||
params.forEach((param) { |
||||
this._messages[param[0]] = Message.fromList(param); |
||||
}); |
||||
setState(() {}); |
||||
} |
||||
|
||||
/// friend send message to me. |
||||
_create(List params) { |
||||
final msg = Message.fromList(params); |
||||
this._messages[msg.id] = msg; |
||||
setState(() {}); |
||||
} |
||||
|
||||
_send(MessageType mtype, String raw) { |
||||
rpc.send('jarvis-create', [this._language.toInt(), mtype.toInt(), raw]); |
||||
} |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
final color = Theme.of(context).colorScheme; |
||||
final lang = AppLocalizations.of(context); |
||||
final isDesktop = isDisplayDesktop(context); |
||||
final recentMessageKeys = this._messages.keys.toList().reversed.toList(); |
||||
|
||||
return Scaffold( |
||||
appBar: AppBar( |
||||
automaticallyImplyLeading: false, |
||||
leading: isDesktop ? null : IconButton(icon: Icon(Icons.arrow_back), |
||||
onPressed: () => Navigator.pop(context)), |
||||
title: Text(lang.jarvis, |
||||
maxLines: 1, overflow: TextOverflow.ellipsis), |
||||
bottom: isDesktop ? PreferredSize( |
||||
child: Container(color: const Color(0x40ADB0BB), height: 1.0), |
||||
preferredSize: Size.fromHeight(1.0)): null, |
||||
), |
||||
body: Column( |
||||
children: [ |
||||
Expanded( |
||||
child: ListView.builder( |
||||
padding: EdgeInsets.symmetric(horizontal: 20.0), |
||||
itemCount: recentMessageKeys.length, |
||||
reverse: true, |
||||
itemBuilder: (BuildContext context, index) => ChatMessage( |
||||
fgid: '', |
||||
name: lang.jarvis, |
||||
message: this._messages[recentMessageKeys[index]]!, |
||||
) |
||||
)), |
||||
ChatInput(sid: 0, online: true, callback: _send, hasTransfer: false), |
||||
] |
||||
) |
||||
); |
||||
} |
||||
} |
@ -1,348 +0,0 @@
@@ -1,348 +0,0 @@
|
||||
import 'dart:io'; |
||||
|
||||
import 'package:flutter/material.dart'; |
||||
import 'package:image_save/image_save.dart'; |
||||
import 'package:permission_handler/permission_handler.dart'; |
||||
import 'package:open_file/open_file.dart'; |
||||
|
||||
import 'package:esse/l10n/localizations.dart'; |
||||
import 'package:esse/utils/adaptive.dart'; |
||||
import 'package:esse/utils/better_print.dart'; |
||||
import 'package:esse/widgets/avatar.dart'; |
||||
import 'package:esse/widgets/audio_player.dart'; |
||||
import 'package:esse/widgets/shadow_dialog.dart'; |
||||
import 'package:esse/global.dart'; |
||||
|
||||
import 'package:esse/apps/file/models.dart' show FileType, FileTypeExtension, parseFileType; |
||||
import 'package:esse/apps/jarvis/models.dart'; |
||||
|
||||
class JarvisMessage extends StatelessWidget { |
||||
final String name; |
||||
final Message message; |
||||
final List<String> answers; |
||||
|
||||
const JarvisMessage({Key? key, required this.name, required this.message, required this.answers}): super(key: key); |
||||
|
||||
Widget _showText(context, color, isDesktop, content, isMe) { |
||||
final width = MediaQuery.of(context).size.width * 0.6; |
||||
// text |
||||
return Container( |
||||
constraints: BoxConstraints(minWidth: 50, maxWidth: isDesktop ? width - 300.0 : width), |
||||
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 14.0), |
||||
decoration: BoxDecoration( |
||||
color: isMe ? Color(0xFF6174FF) : color.primaryVariant, |
||||
borderRadius: BorderRadius.circular(15.0), |
||||
), |
||||
child: Text(content, |
||||
style: TextStyle( |
||||
color: isMe ? Colors.white : Color(0xFF1C1939), |
||||
fontSize: 14.0))); |
||||
} |
||||
|
||||
Widget _showImage(context, lang, color, content) { |
||||
// image |
||||
bool imageExsit = true; |
||||
var thumImage; |
||||
final imagePath = Global.imagePath + content; |
||||
final thumPath = Global.thumbPath + content; |
||||
if (FileSystemEntity.typeSync(thumPath) == |
||||
FileSystemEntityType.notFound) { |
||||
imageExsit = false; |
||||
thumImage = AssetImage('assets/images/image_missing.png'); |
||||
} else { |
||||
thumImage = FileImage(File(thumPath)); |
||||
} |
||||
return GestureDetector( |
||||
onTap: imageExsit |
||||
? () => showShadowDialog( |
||||
context, |
||||
Icons.image_rounded, |
||||
lang.album, |
||||
Column(children: [ |
||||
Image(image: FileImage(File(imagePath)), fit: BoxFit.cover), |
||||
SizedBox(height: 15.0), |
||||
if (Platform.isAndroid || Platform.isIOS) |
||||
InkWell( |
||||
onTap: () async { |
||||
Map<Permission, PermissionStatus> statuses = await [ |
||||
Permission.storage, |
||||
].request(); |
||||
|
||||
if (statuses[Permission.storage] == PermissionStatus.granted) { |
||||
|
||||
// Save to album. |
||||
final data = await File(imagePath).readAsBytes(); |
||||
final bool? success = await ImageSave.saveImage(data, content, albumName: "ESSE"); |
||||
print(success); |
||||
|
||||
Navigator.pop(context); |
||||
} |
||||
}, |
||||
hoverColor: Colors.transparent, |
||||
child: Container( |
||||
width: 200.0, |
||||
padding: const EdgeInsets.symmetric(vertical: 10.0), |
||||
decoration: BoxDecoration( |
||||
border: Border.all(color: color.primary), |
||||
borderRadius: BorderRadius.circular(10.0)), |
||||
child: Center(child: Text(lang.download, |
||||
style: TextStyle(fontSize: 14.0, color: color.primary))), |
||||
) |
||||
), |
||||
])) |
||||
: () => {}, |
||||
child: Container( |
||||
width: imageExsit ? 120.0 : 60.0, |
||||
child: Image(image: thumImage, fit: BoxFit.cover), |
||||
)); |
||||
} |
||||
|
||||
Widget _showFile(context, lang, color, content) { |
||||
// file |
||||
bool fileExsit = true; |
||||
Widget fileImage; |
||||
final filePath = Global.filePath + content; |
||||
if (FileSystemEntity.typeSync(filePath) == |
||||
FileSystemEntityType.notFound) { |
||||
fileExsit = false; |
||||
fileImage = Image(image: AssetImage('assets/images/image_missing.png'), fit: BoxFit.cover); |
||||
} else { |
||||
final params = parseFileType(content).params(); |
||||
fileImage = Icon(params[0], color: params[1], size: 36.0); |
||||
} |
||||
return GestureDetector( |
||||
onTap: fileExsit |
||||
? () => showShadowDialog( |
||||
context, |
||||
Icons.folder_rounded, |
||||
lang.files, |
||||
Column(children: [ |
||||
Text(content), |
||||
SizedBox(height: 15.0), |
||||
Container( |
||||
height: 100.0, |
||||
child: fileImage, |
||||
), |
||||
SizedBox(height: 15.0), |
||||
InkWell( |
||||
onTap: () => OpenFile.open(filePath), |
||||
hoverColor: Colors.transparent, |
||||
child: Container( |
||||
width: 200.0, |
||||
padding: const EdgeInsets.symmetric(vertical: 10.0), |
||||
decoration: BoxDecoration( |
||||
border: Border.all(color: color.primary), |
||||
borderRadius: BorderRadius.circular(10.0)), |
||||
child: Center(child: Text(lang.open, |
||||
style: TextStyle(fontSize: 14.0, color: color.primary))), |
||||
) |
||||
), |
||||
])) |
||||
: () => {}, |
||||
child: Container( |
||||
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 15.0), |
||||
decoration: BoxDecoration( |
||||
color: const Color(0x40ADB0BB), |
||||
borderRadius: BorderRadius.circular(15.0), |
||||
), |
||||
child: Row(mainAxisSize: MainAxisSize.min, children: [ |
||||
Container( |
||||
height: 36.0, |
||||
child: fileImage, |
||||
), |
||||
Container( |
||||
padding: const EdgeInsets.only(left: 5.0), |
||||
width: 120.0, |
||||
child: Text(content, |
||||
maxLines: 1, |
||||
overflow: TextOverflow.ellipsis, |
||||
style: fileExsit |
||||
? TextStyle( |
||||
color: color.onPrimary, |
||||
fontSize: 14.0, |
||||
) |
||||
: TextStyle( |
||||
color: color.onPrimary.withOpacity(0.5), |
||||
decoration: TextDecoration.lineThrough, |
||||
fontSize: 14.0, |
||||
)), |
||||
), |
||||
]))); |
||||
} |
||||
|
||||
Widget _showRecord(content) { |
||||
final raws = Message.showRecordTime(content); |
||||
// text |
||||
return Container( |
||||
width: 120.0, |
||||
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 10.0), |
||||
decoration: BoxDecoration( |
||||
color: const Color(0x40ADB0BB), |
||||
borderRadius: BorderRadius.circular(15.0), |
||||
), |
||||
child: RecordPlayer(path: Global.recordPath + raws[1], time: raws[0]), |
||||
); |
||||
} |
||||
|
||||
Widget _showContact(context, lang, color, content) { |
||||
// contact [name, gid, addr, avatar] |
||||
final infos = Message.showContact(content); |
||||
final gid = 'EH' + infos[1].toUpperCase(); |
||||
|
||||
return GestureDetector( |
||||
onTap: () => showShadowDialog( |
||||
context, |
||||
Icons.person_rounded, |
||||
lang.contact, |
||||
Column(children: [ |
||||
Avatar(width: 100.0, name: infos[0], avatarPath: infos[3]), |
||||
const SizedBox(height: 10.0), |
||||
Text(infos[0]), |
||||
const SizedBox(height: 10.0), |
||||
const Divider(height: 1.0, color: Color(0x40ADB0BB)), |
||||
const SizedBox(height: 10.0), |
||||
_infoListTooltip(Icons.person, color.primary, gidText(gid), gidPrint(gid)), |
||||
_infoListTooltip(Icons.location_on, color.primary, addrText(infos[2]), addrPrint(infos[2])), |
||||
Container( |
||||
width: 300.0, |
||||
padding: const EdgeInsets.symmetric(vertical: 10.0), |
||||
child: Row(children: [ |
||||
Icon(Icons.turned_in, size: 20.0, color: color.primary), |
||||
const SizedBox(width: 20.0), |
||||
Expanded(child: Text(lang.fromContactCard(name))), |
||||
]), |
||||
), |
||||
const SizedBox(height: 20.0), |
||||
InkWell( |
||||
onTap: () => Navigator.pop(context), |
||||
hoverColor: Colors.transparent, |
||||
child: Container( |
||||
width: 200.0, |
||||
padding: const EdgeInsets.symmetric(vertical: 10.0), |
||||
decoration: BoxDecoration( |
||||
border: Border.all(color: color.primary), |
||||
borderRadius: BorderRadius.circular(10.0)), |
||||
child: Center( |
||||
child: Text(lang.ok, |
||||
style: TextStyle( |
||||
fontSize: 14.0, color: color.primary))), |
||||
)), |
||||
])), |
||||
child: Container( |
||||
padding: |
||||
const EdgeInsets.symmetric(vertical: 10.0, horizontal: 10.0), |
||||
width: 200.0, |
||||
decoration: BoxDecoration( |
||||
color: const Color(0x40ADB0BB), |
||||
borderRadius: BorderRadius.circular(15.0), |
||||
), |
||||
child: |
||||
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ |
||||
Row(children: [ |
||||
Avatar(width: 40.0, name: infos[0], avatarPath: infos[3]), |
||||
Container( |
||||
width: 135.0, |
||||
padding: const EdgeInsets.only(left: 10.0), |
||||
child: Column(children: [ |
||||
Text(infos[0], |
||||
maxLines: 1, |
||||
overflow: TextOverflow.ellipsis, |
||||
style: TextStyle( |
||||
color: color.onPrimary, fontSize: 16.0)), |
||||
SizedBox(height: 5.0), |
||||
Text(gidPrint(gid), |
||||
style: TextStyle(color: Colors.grey, fontSize: 12.0)), |
||||
])), |
||||
]), |
||||
SizedBox(height: 5.0), |
||||
const Divider(height: 1.0, color: Color(0x40ADB0BB)), |
||||
SizedBox(height: 3.0), |
||||
Text(lang.contactCard, |
||||
style: TextStyle(color: Colors.grey, fontSize: 10.0)), |
||||
]))); |
||||
} |
||||
|
||||
Widget _infoListTooltip(icon, color, text, short) { |
||||
return Container( |
||||
width: 300.0, |
||||
padding: const EdgeInsets.symmetric(vertical: 10.0), |
||||
child: Row( |
||||
children: [ |
||||
Icon(icon, size: 20.0, color: color), |
||||
const SizedBox(width: 20.0), |
||||
Expanded( |
||||
child: Tooltip( |
||||
message: text, |
||||
child: Text(short), |
||||
) |
||||
) |
||||
] |
||||
), |
||||
); |
||||
} |
||||
|
||||
Widget _show(context, color, lang, isDesktop, type, content, isMe) { |
||||
if (type == MessageType.String) { |
||||
return _showText(context, color, isDesktop, content, isMe); |
||||
} else if (type == MessageType.Image) { |
||||
return _showImage(context, lang, color, content); |
||||
} else if (type == MessageType.File) { |
||||
return _showFile(context, lang, color, content); |
||||
} else if (type == MessageType.Contact) { |
||||
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.length > index ? this.answers[index] : content; |
||||
return _showText(context, color, isDesktop, value, isMe); |
||||
} |
||||
return _showText(context, color, isDesktop, content, isMe); |
||||
} |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
final color = Theme.of(context).colorScheme; |
||||
final lang = AppLocalizations.of(context); |
||||
final isDesktop = isDisplayDesktop(context); |
||||
final qShow = _show(context, color, lang, isDesktop, message.qType, message.qContent, true); |
||||
final aShow = _show(context, color, lang, isDesktop, message.aType, message.aContent, false); |
||||
|
||||
return Padding( |
||||
padding: const EdgeInsets.symmetric(vertical: 5.0), |
||||
child: Column(children: [ |
||||
Row(crossAxisAlignment: CrossAxisAlignment.start, children: [ |
||||
Expanded( |
||||
child: Align( |
||||
alignment: Alignment.topRight, |
||||
child: qShow, |
||||
), |
||||
), |
||||
]), |
||||
Container( |
||||
padding: EdgeInsets.only(top: 10.0), |
||||
child: Row(children: [ |
||||
Spacer(), |
||||
Text(message.time.toString(), |
||||
style: TextStyle( |
||||
color: color.onPrimary.withOpacity(0.5), |
||||
fontSize: 12.0)), |
||||
SizedBox(width: 4.0), |
||||
Icon( |
||||
message.aContent.length == 0 ? Icons.hourglass_top : Icons.done, |
||||
size: 12.0, |
||||
color: color.primary |
||||
), |
||||
])), |
||||
const SizedBox(height: 4.0), |
||||
Row(crossAxisAlignment: CrossAxisAlignment.start, children: [ |
||||
Expanded( |
||||
child: Align( |
||||
alignment: Alignment.topLeft, |
||||
child: aShow, |
||||
), |
||||
), |
||||
]), |
||||
])); |
||||
} |
||||
} |
@ -1,116 +0,0 @@
@@ -1,116 +0,0 @@
|
||||
import 'package:esse/utils/relative_time.dart'; |
||||
import 'package:esse/global.dart'; |
||||
|
||||
enum MessageType { |
||||
String, |
||||
Image, |
||||
File, |
||||
Contact, |
||||
Emoji, |
||||
Record, |
||||
Answer, |
||||
} |
||||
|
||||
// use 00-99 |
||||
extension MessageTypeExtension on MessageType { |
||||
int toInt() { |
||||
switch (this) { |
||||
case MessageType.String: |
||||
return 0; |
||||
case MessageType.Image: |
||||
return 1; |
||||
case MessageType.File: |
||||
return 2; |
||||
case MessageType.Contact: |
||||
return 3; |
||||
case MessageType.Emoji: |
||||
return 4; |
||||
case MessageType.Record: |
||||
return 5; |
||||
case MessageType.Answer: |
||||
return 6; |
||||
default: |
||||
return 0; |
||||
} |
||||
} |
||||
|
||||
static MessageType fromInt(int s) { |
||||
switch (s) { |
||||
case 0: |
||||
return MessageType.String; |
||||
case 1: |
||||
return MessageType.Image; |
||||
case 2: |
||||
return MessageType.File; |
||||
case 3: |
||||
return MessageType.Contact; |
||||
case 4: |
||||
return MessageType.Emoji; |
||||
case 5: |
||||
return MessageType.Record; |
||||
case 6: |
||||
return MessageType.Answer; |
||||
default: |
||||
return MessageType.String; |
||||
} |
||||
} |
||||
} |
||||
|
||||
class Message { |
||||
int id = 0; |
||||
MessageType qType = MessageType.String; |
||||
String qContent = ''; |
||||
MessageType aType = MessageType.String; |
||||
String aContent = ''; |
||||
RelativeTime time = RelativeTime(); |
||||
|
||||
Message(this.qType, this.qContent); |
||||
|
||||
static List showContact(String content) { |
||||
var name = ''; |
||||
var did = ''; |
||||
var addr = ''; |
||||
|
||||
var iName = content.indexOf(';;'); |
||||
if (iName > 0) { |
||||
name = content.substring(0, iName).replaceAll('-;', ';'); |
||||
} |
||||
var raw = content.substring(iName + 2); |
||||
var iDid = raw.indexOf(';;'); |
||||
if (iDid > 0) { |
||||
did = raw.substring(0, iDid); |
||||
} |
||||
addr = raw.substring(iDid + 2); |
||||
|
||||
return [name, did, addr, Global.avatarPath + did + '.png']; |
||||
} |
||||
|
||||
static String rawRecordName(int time, String name) { |
||||
return time.toString() + '-' + name; |
||||
} |
||||
|
||||
static List showRecordTime(String content) { |
||||
final len = content.indexOf('-'); |
||||
if (len > 0) { |
||||
final time = int.parse(content.substring(0, len)); |
||||
final path = content.substring(len + 1); |
||||
return [time, path]; |
||||
} else { |
||||
return [0, content]; |
||||
} |
||||
} |
||||
|
||||
Message.fromList(List params): |
||||
this.id = params[0], |
||||
this.qType = MessageTypeExtension.fromInt(params[1]), |
||||
this.qContent = params[2], |
||||
this.aType = MessageTypeExtension.fromInt(params[3]), |
||||
this.aContent = params[4], |
||||
this.time = RelativeTime.fromInt(params[5]); |
||||
|
||||
update(List params) { |
||||
// params[0] is id. |
||||
this.aType = MessageTypeExtension.fromInt(params[1]); |
||||
this.aContent = params[2]; |
||||
} |
||||
} |
@ -1,469 +0,0 @@
@@ -1,469 +0,0 @@
|
||||
import 'package:flutter/material.dart'; |
||||
import 'package:provider/provider.dart'; |
||||
|
||||
import 'package:esse/utils/adaptive.dart'; |
||||
import 'package:esse/utils/pick_image.dart'; |
||||
import 'package:esse/utils/pick_file.dart'; |
||||
import 'package:esse/l10n/localizations.dart'; |
||||
import 'package:esse/widgets/emoji.dart'; |
||||
import 'package:esse/widgets/shadow_dialog.dart'; |
||||
import 'package:esse/widgets/audio_recorder.dart'; |
||||
import 'package:esse/widgets/show_contact.dart'; |
||||
import 'package:esse/widgets/transfer.dart'; |
||||
import 'package:esse/global.dart'; |
||||
import 'package:esse/options.dart'; |
||||
|
||||
import 'package:esse/apps/jarvis/models.dart'; |
||||
import 'package:esse/apps/jarvis/provider.dart'; |
||||
import 'package:esse/apps/jarvis/message.dart'; |
||||
import 'package:esse/apps/jarvis/answer.dart'; |
||||
|
||||
class JarvisDetail extends StatefulWidget { |
||||
const JarvisDetail({Key? key}) : super(key: key); |
||||
|
||||
@override |
||||
_JarvisDetailState createState() => _JarvisDetailState(); |
||||
} |
||||
|
||||
class _JarvisDetailState extends State<JarvisDetail> { |
||||
TextEditingController textController = TextEditingController(); |
||||
FocusNode textFocus = FocusNode(); |
||||
bool emojiShow = false; |
||||
bool sendShow = false; |
||||
bool menuShow = false; |
||||
bool recordShow = false; |
||||
String _recordName = ''; |
||||
List<String> answers = []; |
||||
|
||||
@override |
||||
initState() { |
||||
super.initState(); |
||||
Future.delayed(Duration.zero, () async { |
||||
Provider.of<JarvisProvider>(context, listen: false).actived(); |
||||
final options = context.read<Options>(); |
||||
this.answers = await loadAnswers(options.locale); |
||||
setState(() {}); |
||||
}); |
||||
textFocus.addListener(() { |
||||
if (textFocus.hasFocus) { |
||||
setState(() { |
||||
emojiShow = false; |
||||
menuShow = false; |
||||
recordShow = false; |
||||
}); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
@override |
||||
void deactivate() { |
||||
Provider.of<JarvisProvider>(context, listen: false).inactived(); |
||||
super.deactivate(); |
||||
} |
||||
|
||||
_generateRecordPath() { |
||||
this._recordName = DateTime.now().millisecondsSinceEpoch.toString() + '_jarvis.m4a'; |
||||
} |
||||
|
||||
void _sendMessage() async { |
||||
if (textController.text.length < 1) { |
||||
return; |
||||
} |
||||
|
||||
final value = textController.text.trim(); |
||||
final aType = (value.endsWith('?') || value.endsWith('?')) ? MessageType.Answer : MessageType.String; |
||||
context.read<JarvisProvider>().create(aType, textController.text); |
||||
|
||||
setState(() { |
||||
textController.text = ''; |
||||
textFocus.requestFocus(); |
||||
|
||||
emojiShow = false; |
||||
sendShow = false; |
||||
menuShow = false; |
||||
recordShow = false; |
||||
}); |
||||
} |
||||
|
||||
void _selectEmoji(value) { |
||||
textController.text += value; |
||||
} |
||||
|
||||
void _sendImage() async { |
||||
final image = await pickImage(); |
||||
if (image != null) { |
||||
context.read<JarvisProvider>().create(MessageType.Image, image); |
||||
} |
||||
setState(() { |
||||
textFocus.requestFocus(); |
||||
emojiShow = false; |
||||
sendShow = false; |
||||
menuShow = false; |
||||
recordShow = false; |
||||
}); |
||||
} |
||||
|
||||
void _sendFile() async { |
||||
final file = await pickFile(); |
||||
if (file != null) { |
||||
context.read<JarvisProvider>().create(MessageType.File, file); |
||||
} |
||||
setState(() { |
||||
textFocus.requestFocus(); |
||||
emojiShow = false; |
||||
sendShow = false; |
||||
menuShow = false; |
||||
recordShow = false; |
||||
}); |
||||
} |
||||
|
||||
void _sendRecord(int time) async { |
||||
final raw = Message.rawRecordName(time, _recordName); |
||||
context.read<JarvisProvider>().create(MessageType.Record, raw); |
||||
|
||||
setState(() { |
||||
textFocus.requestFocus(); |
||||
emojiShow = false; |
||||
sendShow = false; |
||||
menuShow = false; |
||||
recordShow = false; |
||||
}); |
||||
} |
||||
|
||||
_callback(int id) { |
||||
context.read<JarvisProvider>().create(MessageType.Contact, id.toString()); |
||||
setState(() { |
||||
textFocus.requestFocus(); |
||||
emojiShow = false; |
||||
sendShow = false; |
||||
menuShow = false; |
||||
recordShow = false; |
||||
}); |
||||
} |
||||
|
||||
void _sendContact(ColorScheme color, AppLocalizations lang) { |
||||
showShadowDialog( |
||||
context, |
||||
Icons.person_rounded, |
||||
lang.contact, |
||||
ContactList(callback: _callback, multiple: false) |
||||
); |
||||
} |
||||
|
||||
_tokenCallback(String hash, String to, String amount, String name) { |
||||
//context.read<JarvisProvider>().create(MessageType.Transfer, ""); |
||||
setState(() { |
||||
textFocus.requestFocus(); |
||||
emojiShow = false; |
||||
sendShow = false; |
||||
menuShow = false; |
||||
recordShow = false; |
||||
}); |
||||
} |
||||
|
||||
// TEST CODE. |
||||
void _sendToken(ColorScheme color, AppLocalizations lang) { |
||||
return; |
||||
showShadowDialog( |
||||
context, |
||||
Icons.paid, |
||||
lang.transfer, |
||||
Transfer(callback: _tokenCallback, to: "0xdac17f958d2ee523a2206206994597c13d831ec7"), |
||||
0.0 |
||||
); |
||||
} |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
final color = Theme.of(context).colorScheme; |
||||
final lang = AppLocalizations.of(context); |
||||
final isDesktop = isDisplayDesktop(context); |
||||
final recentMessages = context.watch<JarvisProvider>().messages; |
||||
final recentMessageKeys = recentMessages.keys.toList().reversed.toList(); |
||||
|
||||
return Scaffold( |
||||
body: SafeArea( |
||||
child: Column( |
||||
children: [ |
||||
Container( |
||||
padding: EdgeInsets.only(left: 20.0, right: 20.0, top: 10.0, bottom: 6.0), |
||||
child: Row( |
||||
children: [ |
||||
if (!isDesktop) |
||||
GestureDetector( |
||||
onTap: () { |
||||
Navigator.pop(context); |
||||
}, |
||||
child: Container( |
||||
width: 20.0, |
||||
child: |
||||
Icon(Icons.arrow_back, color: color.primary)), |
||||
), |
||||
SizedBox(width: 15.0), |
||||
Expanded( |
||||
child: Column( |
||||
crossAxisAlignment: CrossAxisAlignment.start, |
||||
children: [ |
||||
Container( |
||||
height: 20.0, |
||||
child: Text('Jarvis', |
||||
style: TextStyle(fontWeight: FontWeight.bold), |
||||
)), |
||||
SizedBox(height: 5.0), |
||||
Container( |
||||
height: 15.0, |
||||
child: Text(lang.jarvisBio, |
||||
style: TextStyle(color: color.onPrimary.withOpacity(0.5), fontSize: 12.0)) |
||||
) |
||||
], |
||||
), |
||||
), |
||||
SizedBox(width: 20.0), |
||||
GestureDetector( |
||||
onTap: () {}, |
||||
child: Container( |
||||
width: 20.0, |
||||
child: Icon(Icons.phone_rounded, |
||||
color: Color(0x26ADB0BB))), |
||||
), |
||||
SizedBox(width: 20.0), |
||||
GestureDetector( |
||||
onTap: () {}, |
||||
child: Container( |
||||
width: 20.0, |
||||
child: Icon(Icons.videocam_rounded, |
||||
color: Color(0x26ADB0BB))), |
||||
), |
||||
SizedBox(width: 20.0), |
||||
// PopupMenuButton<int>( |
||||
// shape: RoundedRectangleBorder( |
||||
// borderRadius: BorderRadius.circular(15) |
||||
// ), |
||||
// color: const Color(0xFFEDEDED), |
||||
// child: Icon(Icons.more_vert_rounded, color: color.primary), |
||||
// onSelected: (int value) { |
||||
// if (value == 1) { |
||||
// // TODO set top |
||||
// } |
||||
// }, |
||||
// itemBuilder: (context) { |
||||
// return <PopupMenuEntry<int>>[ |
||||
// _menuItem(Color(0xFF6174FF), 1, Icons.vertical_align_top_rounded, lang.cancelTop), |
||||
// ]; |
||||
// }, |
||||
// ) |
||||
] |
||||
), |
||||
), |
||||
const Divider(height: 1.0, color: Color(0x40ADB0BB)), |
||||
Expanded( |
||||
child: ListView.builder( |
||||
padding: EdgeInsets.symmetric(horizontal: 20.0), |
||||
itemCount: recentMessageKeys.length, |
||||
reverse: true, |
||||
itemBuilder: (BuildContext context, index) => JarvisMessage( |
||||
name: 'Jarvis', |
||||
message: recentMessages[recentMessageKeys[index]]!, |
||||
answers: this.answers, |
||||
) |
||||
)), |
||||
Container( |
||||
padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0), |
||||
child: Row( |
||||
children: [ |
||||
GestureDetector( |
||||
onTap: () async { |
||||
if (recordShow) { |
||||
recordShow = false; |
||||
textFocus.requestFocus(); |
||||
} else { |
||||
_generateRecordPath(); |
||||
setState(() { |
||||
menuShow = false; |
||||
emojiShow = false; |
||||
recordShow = true; |
||||
textFocus.unfocus(); |
||||
}); |
||||
} |
||||
}, |
||||
child: Container(width: 20.0, |
||||
child: Icon(Icons.mic_rounded, color: color.primary)), |
||||
), |
||||
SizedBox(width: 10.0), |
||||
Expanded( |
||||
child: Container( |
||||
height: 40, |
||||
decoration: BoxDecoration( |
||||
color: color.surface, |
||||
borderRadius: BorderRadius.circular(15.0), |
||||
), |
||||
child: TextField( |
||||
style: TextStyle(fontSize: 14.0), |
||||
textInputAction: TextInputAction.send, |
||||
onChanged: (value) { |
||||
if (value.length == 0 && sendShow) { |
||||
setState(() { |
||||
sendShow = false; |
||||
}); |
||||
} else { |
||||
if (!sendShow) { |
||||
setState(() { |
||||
sendShow = true; |
||||
}); |
||||
} |
||||
} |
||||
}, |
||||
onSubmitted: (_v) => _sendMessage(), |
||||
decoration: InputDecoration( |
||||
hintText: 'Aa', |
||||
border: InputBorder.none, |
||||
contentPadding: EdgeInsets.only( |
||||
left: 15.0, right: 15.0, bottom: 7.0), |
||||
), |
||||
controller: textController, |
||||
focusNode: textFocus, |
||||
), |
||||
), |
||||
), |
||||
SizedBox(width: 10.0), |
||||
GestureDetector( |
||||
onTap: () { |
||||
if (emojiShow) { |
||||
textFocus.requestFocus(); |
||||
} else { |
||||
setState(() { |
||||
menuShow = false; |
||||
recordShow = false; |
||||
emojiShow = true; |
||||
textFocus.unfocus(); |
||||
}); |
||||
} |
||||
}, |
||||
child: Container( |
||||
width: 20.0, |
||||
child: Icon( |
||||
emojiShow |
||||
? Icons.keyboard_rounded |
||||
: Icons.emoji_emotions_rounded, |
||||
color: color.primary)), |
||||
), |
||||
SizedBox(width: 10.0), |
||||
sendShow |
||||
? GestureDetector( |
||||
onTap: _sendMessage, |
||||
child: Container( |
||||
width: 50.0, |
||||
height: 30.0, |
||||
decoration: BoxDecoration( |
||||
color: Color(0xFF6174FF), |
||||
borderRadius: BorderRadius.circular(10.0), |
||||
), |
||||
child: Center( |
||||
child: Icon(Icons.send, color: Colors.white, size: 20.0))), |
||||
) |
||||
: GestureDetector( |
||||
onTap: () { |
||||
if (menuShow) { |
||||
textFocus.requestFocus(); |
||||
} else { |
||||
setState(() { |
||||
emojiShow = false; |
||||
recordShow = false; |
||||
menuShow = true; |
||||
textFocus.unfocus(); |
||||
}); |
||||
} |
||||
}, |
||||
child: Container( |
||||
width: 20.0, |
||||
child: Icon(Icons.add_circle_rounded, color: color.primary)), |
||||
), |
||||
], |
||||
), |
||||
), |
||||
if (emojiShow) Emoji(action: _selectEmoji), |
||||
if (recordShow) |
||||
Container( |
||||
height: 100.0, |
||||
child: AudioRecorder( |
||||
path: Global.recordPath + _recordName, onStop: _sendRecord), |
||||
), |
||||
if (menuShow) |
||||
Container( |
||||
height: 100.0, |
||||
child: Wrap( |
||||
spacing: 20.0, |
||||
runSpacing: 20.0, |
||||
alignment: WrapAlignment.center, |
||||
children: <Widget>[ |
||||
ExtensionButton( |
||||
icon: Icons.image_rounded, |
||||
text: lang.album, |
||||
action: _sendImage, |
||||
bgColor: color.surface, |
||||
iconColor: color.primary), |
||||
ExtensionButton( |
||||
icon: Icons.folder_rounded, |
||||
text: lang.file, |
||||
action: _sendFile, |
||||
bgColor: color.surface, |
||||
iconColor: color.primary), |
||||
ExtensionButton( |
||||
icon: Icons.person_rounded, |
||||
text: lang.contact, |
||||
action: () => _sendContact(color, lang), |
||||
bgColor: color.surface, |
||||
iconColor: color.primary), |
||||
ExtensionButton( |
||||
icon: Icons.paid_rounded, |
||||
text: lang.transfer, |
||||
action: () => _sendToken(color, lang), |
||||
bgColor: color.surface, |
||||
iconColor: color.primary), |
||||
], |
||||
), |
||||
) |
||||
], |
||||
) |
||||
) |
||||
); |
||||
} |
||||
} |
||||
|
||||
class ExtensionButton extends StatelessWidget { |
||||
final String text; |
||||
final IconData icon; |
||||
final VoidCallback action; |
||||
final Color bgColor; |
||||
final Color iconColor; |
||||
|
||||
const ExtensionButton({ |
||||
Key? key, |
||||
required this.icon, |
||||
required this.text, |
||||
required this.action, |
||||
required this.bgColor, |
||||
required this.iconColor, |
||||
}) : super(key: key); |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
return GestureDetector( |
||||
onTap: action, |
||||
child: Column( |
||||
crossAxisAlignment: CrossAxisAlignment.center, |
||||
mainAxisAlignment: MainAxisAlignment.center, |
||||
children: [ |
||||
Container( |
||||
padding: const EdgeInsets.all(10.0), |
||||
decoration: BoxDecoration( |
||||
color: bgColor, |
||||
borderRadius: BorderRadius.circular(15.0), |
||||
), |
||||
child: Icon(icon, color: iconColor, size: 36.0)), |
||||
SizedBox(height: 5.0), |
||||
Text(text, style: TextStyle(fontSize: 14.0)), |
||||
], |
||||
)); |
||||
} |
||||
} |
@ -1,75 +0,0 @@
@@ -1,75 +0,0 @@
|
||||
import "dart:collection"; |
||||
import 'package:flutter/material.dart'; |
||||
|
||||
import 'package:esse/rpc.dart'; |
||||
import 'package:esse/apps/jarvis/models.dart'; |
||||
|
||||
class JarvisProvider extends ChangeNotifier { |
||||
bool isActived = false; |
||||
SplayTreeMap<int, Message> messages = SplayTreeMap(); |
||||
|
||||
JarvisProvider() { |
||||
// rpc. |
||||
rpc.addListener('jarvis-list', _list, false); |
||||
rpc.addListener('jarvis-create', _create, false); |
||||
rpc.addListener('jarvis-update', _update, false); |
||||
rpc.addListener('jarvis-delete', _delete, false); |
||||
} |
||||
|
||||
actived() { |
||||
this.isActived = true; |
||||
rpc.send('jarvis-list', []); |
||||
} |
||||
|
||||
inactived() { |
||||
this.messages.clear(); |
||||
this.isActived = false; |
||||
} |
||||
|
||||
create(MessageType qType, String qContent) { |
||||
rpc.send('jarvis-create', [qType.toInt(), qContent]); |
||||
} |
||||
|
||||
/// delete a message. |
||||
delete(int id) { |
||||
this.messages.remove(id); |
||||
rpc.send('jarvis-delete', [id]); |
||||
notifyListeners(); |
||||
} |
||||
|
||||
/// list message with friend. |
||||
_list(List params) { |
||||
if (this.isActived) { |
||||
params.forEach((param) { |
||||
this.messages[param[0]] = Message.fromList(param); |
||||
}); |
||||
notifyListeners(); |
||||
} |
||||
} |
||||
|
||||
/// friend send message to me. |
||||
_create(List params) { |
||||
if (this.isActived) { |
||||
final msg = Message.fromList(params); |
||||
this.messages[msg.id] = msg; |
||||
notifyListeners(); |
||||
} |
||||
} |
||||
|
||||
_update(List params) { |
||||
if (this.isActived) { |
||||
final id = params[0]; |
||||
if (this.messages.containsKey(id)) { |
||||
this.messages[id]!.update(params); |
||||
notifyListeners(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
_delete(List params) { |
||||
if (this.isActived) { |
||||
this.messages.remove(params[0]); |
||||
notifyListeners(); |
||||
} |
||||
} |
||||
} |
@ -1,5 +1,4 @@
@@ -1,5 +1,4 @@
|
||||
mod models; |
||||
pub(crate) mod rpc; |
||||
mod rpc; |
||||
|
||||
pub(crate) use models::{Message, MessageType}; |
||||
pub(crate) use rpc::new_rpc_handler; |
||||
|
@ -1,2 +1,3 @@
@@ -1,2 +1,3 @@
|
||||
pub(crate) mod answer; |
||||
pub(crate) mod crypto; |
||||
pub(crate) mod device_status; |
||||
|
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
use tdn_did::Language; |
||||
|
||||
mod english; |
||||
mod simplified_chinese; |
||||
|
||||
pub(crate) fn load_answer(lang: &Language, index: usize) -> String { |
||||
match lang { |
||||
Language::SimplifiedChinese => simplified_chinese::WORDS[index].to_owned(), |
||||
_ => english::WORDS[index].to_owned(), |
||||
} |
||||
} |
@ -0,0 +1,173 @@
@@ -0,0 +1,173 @@
|
||||
pub const WORDS: [&str; 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", |
||||
]; |
@ -0,0 +1,173 @@
@@ -0,0 +1,173 @@
|
||||
pub const WORDS: [&str; 171] = [ |
||||
"需要一个相当大的努力", |
||||
"从现在开始 一年也没有关系", |
||||
"绝对不是", |
||||
"接受改变你的日常行为", |
||||
"似乎已经是真实的了", |
||||
"采用一个冒险的态度", |
||||
"允许你选择先休息一下", |
||||
"小心谨慎的靠近", |
||||
"你还是问问爸爸吧", |
||||
"你还是问问妈妈吧", |
||||
"援助会让你成功进步", |
||||
"避免第一个解决方案", |
||||
"被人肯定", |
||||
"更慷慨", |
||||
"耐心点", |
||||
"实际一点吧", |
||||
"打赌", |
||||
"耐心的等待", |
||||
"合作将会是关键", |
||||
"考虑一下这个机会", |
||||
"数到10;再问", |
||||
"以后处理", |
||||
"当然", |
||||
"早点做到这一点", |
||||
"在这个时候不要问太多了", |
||||
"不要担心", |
||||
"不要迫于压力太快", |
||||
"别傻了", |
||||
"不要赌", |
||||
"不用怀疑了", |
||||
"不要忘记有乐趣", |
||||
"不要陷入你的感情", |
||||
"不要犹豫", |
||||
"不要忽视显而易见的", |
||||
"不要过分", |
||||
"不要等待", |
||||
"别浪费时间了", |
||||
"怀疑", |
||||
"尽情体验", |
||||
"要解决", |
||||
"探讨其俏皮的好奇心", |
||||
"完成其他事情的第一", |
||||
"专注你的家庭生活", |
||||
"遵循别人的引导", |
||||
"遵循专家的建议", |
||||
"履行你自己的义务", |
||||
"按照你的意愿", |
||||
"温柔的坚持就是胜利", |
||||
"获得更清晰的视野", |
||||
"把它写下来", |
||||
"给它你的一切", |
||||
"如果是,做的很好;如果不是,就不要这么做;", |
||||
"如果你按我说的做", |
||||
"如果你不反抗", |
||||
"调查研究,然后享受它!", |
||||
"这不可能失败", |
||||
"这可能是特别的", |
||||
"这是肯定的", |
||||
"这不是重要的", |
||||
"这是非常重要", |
||||
"这是你不会忘记的", |
||||
"这肯定会让事情变得有趣", |
||||
"这是不确定的", |
||||
"是值得的麻烦", |
||||
"这可能已经是木已成舟", |
||||
"这可能很难,但你会发现它的价值", |
||||
"这个似乎放心", |
||||
"这将影响别人看你", |
||||
"这将是一种享受", |
||||
"这会带来好运", |
||||
"这将会创造一个扰乱", |
||||
"这仍然是不可预测的", |
||||
"它会支持你的", |
||||
"这将更好地专注于自己的工作", |
||||
"这是不明智的", |
||||
"它会让你付出代价", |
||||
"这是一个不错的时间安排", |
||||
"会很棒的", |
||||
"这是不值得的斗争", |
||||
"是你走的时候", |
||||
"保持开放的心态", |
||||
"不要让别人知道", |
||||
"笑一下", |
||||
"离开旧的解决方案", |
||||
"过去的事就让它过去吧", |
||||
"仔细聆听;那么你就会知道", |
||||
"列出原因", |
||||
"为什么不列出原因", |
||||
"也许", |
||||
"不幸的是极有可能的", |
||||
"继续前行", |
||||
"从来没有", |
||||
"没有", |
||||
"不管是什么", |
||||
"如果你不孤单", |
||||
"现在你可以", |
||||
"只做一次", |
||||
"其他人将取决于你的选择", |
||||
"注重细节", |
||||
"也许,当你老了", |
||||
"为突发事件做好准备", |
||||
"按下关闭", |
||||
"须以较宽松的步伐", |
||||
"有时候选择太多,就代表着无从选择!", |
||||
"重新考虑你的方法", |
||||
"相关的问题可能的浮出水面", |
||||
"保持灵活", |
||||
"删除你自己的障碍物", |
||||
"重新确定优先次序什么是重要的", |
||||
"尊重规则", |
||||
"保存你的精力", |
||||
"寻找更多的选择", |
||||
"设定优先等级是一个必要的过程!", |
||||
"很快就会解决它", |
||||
"转移你的焦点", |
||||
"说出来吧", |
||||
"令人震惊的事件可能发生的", |
||||
"冒险一试", |
||||
"负责", |
||||
"花更多的时间来决定", |
||||
"告诉别人它对你意味着什么", |
||||
"那将是浪费钱", |
||||
"那是脱离你的控制", |
||||
"答案就在你的后院", |
||||
"答案可能会在另一种语言", |
||||
"最好的解决办法可能不是明显的", |
||||
"机会不会很快再来", |
||||
"情况将很快发生改变", |
||||
"结果会是好的", |
||||
"情况不明", |
||||
"与另一种情况有潜在的联系", |
||||
"有充分的理由保持乐观", |
||||
"没有保证", |
||||
"会有障碍要克服", |
||||
"这是一个很好的时机,来制定新计划", |
||||
"为了确保能作出最佳决策,需要保持冷静", |
||||
"相信自己的直觉", |
||||
"相信你的原始思想", |
||||
"尝试一种更不太可能的解决方案", |
||||
"不宜在这个时候", |
||||
"毫无疑问", |
||||
"无论如何你可以提升", |
||||
"运用你的想象力", |
||||
"等一等", |
||||
"等待一个更好的机会", |
||||
"看看会发生什么", |
||||
"注意你的节奏", |
||||
"不管你做什么,结果将持久", |
||||
"可以", |
||||
"是的,但不要强迫", |
||||
"你一定有支持", |
||||
"你太近的看了", |
||||
"你可能觉得自己无法妥协", |
||||
"你真的不在乎", |
||||
"你知道现在比以前更好", |
||||
"你可能会反对", |
||||
"你可能会放弃其他的东西", |
||||
"你必须", |
||||
"你现在必须行动", |
||||
"你会发现一切你需要知道的", |
||||
"你将需要适应", |
||||
"你不会失望的", |
||||
"你会很高兴你做了", |
||||
"你会得到最后的决定", |
||||
"你将不得不妥协", |
||||
"你将不得不补回来", |
||||
"您需要了解更多信息", |
||||
"你需要考虑其他办法", |
||||
"你需要主动出击", |
||||
"你会后悔的", |
||||
"你的行动将会改善", |
||||
]; |
Loading…
Reference in new issue