Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,22 @@

## 当前维护内容

以下内容为更改包名前 相较于 AstrBot-Android-App 1.5.3 的最终更新内容。
- 自定义启动项 (准备更新)

- 终端页新功能
- 细节优化

- 具体信息请查看发行版更新内容

## 后续计划

- 适配深色模式
- 自定义接入平台
- 暂无更多


### fix版最终更新内容
以下内容为更改包名前 fix版 相较于 AstrBot-Android-App 1.5.3 原版的最终更新内容。

### 新增功能

Expand Down Expand Up @@ -34,11 +49,6 @@
- 安装完成后后续进入无需等待 AstrBot 启动。
- 在启动时请求存储权限,避免因无存储权限无法从备份中恢复。

### 后续计划

- 适配深色模式
- 自定义接入平台
- 暂无更多

你是否想过,用自己的 QQ 号,变成一个可以自动回复消息、调用大模型进行智能对话的“AI 账号”?

Expand Down
58 changes: 36 additions & 22 deletions lib/ui/controllers/terminal_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class HomeController extends GetxController {
SettingNode privacySetting = 'privacy'.setting;
SettingNode napCatWebUiEnabled = 'napcat_webui_enabled'.setting;
SettingNode showTerminalWhiteText = 'show_terminal_white_text'.setting;
SettingNode customStartupCommand = 'custom_startup_command'.setting;
Pty? pseudoTerminal;
Pty? napcatTerminal;

Expand Down Expand Up @@ -73,6 +74,10 @@ class HomeController extends GetxController {
terminalFontSize.value = size.clamp(minTerminalFontSize, maxTerminalFontSize).toDouble();
}

String getCustomStartupCommand() {
return customStartupCommand.get() as String? ?? '';
}

// 进度 +1
// Progress +1
void bumpProgress() {
Expand Down Expand Up @@ -244,6 +249,34 @@ class HomeController extends GetxController {

// 检查条件是否满足,如果满足则触发跳转
void _checkAndNavigateToWebview() {

if (!_isNapCatLogin && !_isNapCatQuickLogin) {
Get.snackbar(
'NapCat 未登录',
'请前往 NapCat 终端页或 WebUI 自行扫码登录',
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Colors.red.withValues(alpha: 0.8),
colorText: Colors.white,
duration: const Duration(seconds: 5),
);
} else if (!_isNapCatLogin && _isNapCatQuickLogin) {
Get.snackbar(
'NapCat 未配置快速登录',
'请前往设置页配置快速登录QQ账号设置',
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Colors.yellow.withValues(alpha: 0.8),
colorText: Colors.white,
duration: const Duration(seconds: 5),
);
_isNapCatLogin = true; // 视为已登录,防止重复触发
}

// 新建终端页并运行自定义启动命令
final command = getCustomStartupCommand();
if (command.trim().isNotEmpty) {
terminalTabManager.addSystemTerminalTab(command);
}

// 只有当条件满足且应用在前台时才跳转
if (isLocalhostDetected.value &&
_isAppInForeground &&
Expand All @@ -252,26 +285,6 @@ class HomeController extends GetxController {
// 使用路由跳转
Get.toNamed(AppRoutes.webview);
webviewHasOpen = true; // 只有真正打开webview时才设置为true
if (!_isNapCatLogin && !_isNapCatQuickLogin) {
Get.snackbar(
'NapCat 未登录',
'请前往 NapCat 终端页或 WebUI 自行扫码登录',
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Colors.red.withValues(alpha: 0.8),
colorText: Colors.white,
duration: const Duration(seconds: 5),
);
} else if (!_isNapCatLogin && _isNapCatQuickLogin) {
Get.snackbar(
'NapCat 未配置快速登录',
'请前往设置页配置快速登录QQ账号设置',
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Colors.yellow.withValues(alpha: 0.8),
colorText: Colors.white,
duration: const Duration(seconds: 5),
);
_isNapCatLogin = true; // 视为已登录,防止重复触发
}
});
}
}
Expand Down Expand Up @@ -301,7 +314,8 @@ class HomeController extends GetxController {
isLocalhostDetected.value = true;
bumpProgress();

// 检查是否两个条件都满足
// 检查是否条件满足
// 现在的实际功能为检查napcat登录状态和新建终端运行自定义启动命令
_checkAndNavigateToWebview();

Future.delayed(const Duration(milliseconds: 2000), () {
Expand Down Expand Up @@ -449,7 +463,7 @@ class HomeController extends GetxController {
// 清除终端先前显示的所有文本
terminal.buffer.clear();
terminal.buffer.setCursor(0, 0);
Log.i('检测到 AstrBot 配置中,清除终端内容并开始过滤非彩色终端输出', tag: 'AstrBot');
Log.i('检测到 AstrBot 配置中,清除终端内容', tag: 'AstrBot');
}

update();
Expand Down
20 changes: 18 additions & 2 deletions lib/ui/controllers/terminal_tab_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class TerminalTabManager extends GetxController {
}

/// 添加新的系统终端标签页
Future<void> addSystemTerminalTab() async {
Future<void> addSystemTerminalTab([String? customCommand]) async {
try {
final newIndex =
tabs.where((t) => t.type == TerminalTabType.system).length + 1;
Expand All @@ -97,6 +97,9 @@ class TerminalTabManager extends GetxController {
// 标志:是否已经创建了标签页
var tabCreated = false;

// 标志:是否已发送自定义启动命令
var commandSent = false;

// 连接终端的 onResize 和 onOutput 事件(需要在监听输出前就连接好)
newTerminal.onResize = (width, height, pixelWidth, pixelHeight) {
newPty.resize(height, width);
Expand Down Expand Up @@ -142,6 +145,19 @@ class TerminalTabManager extends GetxController {

// 标签页创建后,正常输出所有内容
if (tabCreated) {

// 如果未发送自定义启动命令并且有设置自定义启动命令
// 就向终端发送格式化后的自定义启动命令
if (!commandSent && customCommand != null) {
final normalizedCommand = customCommand
?.split(RegExp(r'\r?\n'))
?.where((line) => line.trim().isNotEmpty)
?.map((line) => ' $line\n')
?.join() ?? '';
newPty.writeString('$normalizedCommand\n');
commandSent = true;
}

// 自动清理旧行,避免行数满后不更新
while (newTerminal.buffer.lines.length >= newTerminal.maxLines) {
newTerminal.buffer.lines.remove(0, 1);
Expand All @@ -153,7 +169,7 @@ class TerminalTabManager extends GetxController {

// 登录到ubuntu容器
final command =
'source ${RuntimeEnvir.homePath}/common.sh\nlogin_ubuntu "exec bash -il" \n';
'source ${RuntimeEnvir.homePath}/common.sh\nlogin_ubuntu "exec bash -il"\n';
newPty.writeString(command);
} catch (e) {
Log.e('添加系统终端标签页失败: $e', tag: 'TerminalTabManager');
Expand Down
69 changes: 69 additions & 0 deletions lib/ui/pages/settings/settings_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -973,6 +973,7 @@ class _SettingsPageState extends State<SettingsPage> {
hintText: '留空使用默认逻辑',
border: OutlineInputBorder(),
),
minLines: 1,
maxLines: 3,
keyboardType: TextInputType.multiline,
),
Expand Down Expand Up @@ -1029,6 +1030,68 @@ class _SettingsPageState extends State<SettingsPage> {
commandController.dispose();
}

Future<void> _showCustomStartupCommandDialog() async {
final currentCommand =
homeController.customStartupCommand.get() as String? ?? '';
final commandController = TextEditingController(text: currentCommand);
final result = await Get.dialog<bool>(
AlertDialog(
title: const Text('自定义启动命令'),
content: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'自动打开新终端并执行任意启动命令',
style: TextStyle(fontSize: 12, color: Colors.grey),
),
const SizedBox(height: 8),
const Text(
'示例:\ncd /root/AstrBot\npython main.py &',
style: TextStyle(fontSize: 11, color: Colors.grey),
),
const SizedBox(height: 16),
TextField(
controller: commandController,
decoration: const InputDecoration(
labelText: '自定义启动命令',
hintText: '留空则不执行',
border: OutlineInputBorder(),
),
minLines: 1,
maxLines: 6,
keyboardType: TextInputType.multiline,
),
],
),
),
actions: [
TextButton(
onPressed: () => Get.back(result: false),
child: const Text('取消'),
),
TextButton(
onPressed: () => Get.back(result: true),
child: const Text('保存'),
),
],
),
);

if (result == true) {
final command = commandController.text.trim();
homeController.customStartupCommand.set(command);
Get.snackbar(
'保存成功',
command.isEmpty ? '已清除自定义启动命令' : '自定义启动命令已保存',
snackPosition: SnackPosition.BOTTOM,
duration: const Duration(seconds: 2),
);
}
commandController.dispose();
}

// 打开文件管理器并导航到 AstrBot Ubuntu 文件系统位置
Future<void> _openFileManager() async {
try {
Expand Down Expand Up @@ -1689,6 +1752,12 @@ class _SettingsPageState extends State<SettingsPage> {
subtitle: const Text('自定义 AstrBot 的获取方式'),
onTap: () => _showCustomGitCloneDialog(),
),
ListTile(
leading: const Icon(Icons.terminal),
title: const Text('自定义启动命令'),
subtitle: const Text('自动打开新终端并执行任意启动命令'),
onTap: () => _showCustomStartupCommandDialog(),
),
ListTile(
leading: const Icon(Icons.text_fields),
title: const Text('显示终端白色文本日志'),
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: astrbot_android
description: AstrBot Android App
publish_to: "none" # Remove this line if you wish to publish to pub.dev
version: 1.0.4+5
version: 1.0.5+6
environment:
sdk: ">=3.3.0 <4.0.0"

Expand Down
Loading