From 72b078c3845c0c2a651a6ba757c1858e5dc405ca Mon Sep 17 00:00:00 2001 From: Rarya <3148438955@qq.com> Date: Thu, 20 Aug 2026 03:01:55 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20=E7=BB=88=E7=AB=AF?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=8F=8C=E6=8C=87=E7=BC=A9=E6=94=BE=E5=AD=97?= =?UTF-8?q?=E4=BD=93=E5=A4=A7=E5=B0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release-apk.yml | 52 +++++++++++++++----- lib/ui/controllers/terminal_controller.dart | 10 ++++ lib/ui/pages/terminal/terminal_keyboard.dart | 4 +- lib/ui/pages/terminal/terminal_tab_view.dart | 50 ++++++++++++++++++- 4 files changed, 99 insertions(+), 17 deletions(-) diff --git a/.github/workflows/release-apk.yml b/.github/workflows/release-apk.yml index 7dfc3bb..0577cf0 100644 --- a/.github/workflows/release-apk.yml +++ b/.github/workflows/release-apk.yml @@ -16,7 +16,7 @@ permissions: jobs: publish: if: github.event_name == 'pull_request' && github.event.pull_request.merged == true - timeout-minutes: 10 + timeout-minutes: 60 runs-on: ubuntu-latest steps: @@ -36,23 +36,49 @@ jobs: - name: Find latest successful fork build for this PR env: GH_TOKEN: ${{ github.token }} - PR_NUMBER: ${{ github.event.pull_request.number }} + EXPECTED_SHA: ${{ github.event.pull_request.head.sha }} run: | - mapfile -t PR_COMMITS < <(gh pr view "$PR_NUMBER" --json commits --jq '.commits[].oid') - test "${#PR_COMMITS[@]}" -gt 0 || { echo 'No PR commits found'; exit 1; } + test -n "$EXPECTED_SHA" || { echo 'No PR head commit found'; exit 1; } + echo "Waiting for the latest fork build of PR head $EXPECTED_SHA" RUN_ID="" - while read -r ID SHA; do - for COMMIT in "${PR_COMMITS[@]}"; do - if [ "$SHA" = "$COMMIT" ]; then - RUN_ID="$ID" - break 2 + BUILD_SUCCEEDED=false + for ATTEMPT in {1..12}; do + RUN_INFO=$(gh run list \ + --workflow build-apk.yml \ + --branch fork \ + --commit "$EXPECTED_SHA" \ + --limit 100 \ + --json databaseId,headSha,status,conclusion,createdAt \ + --jq 'sort_by(.createdAt) | last // empty') + + if [ -n "$RUN_INFO" ]; then + RUN_ID=$(printf '%s' "$RUN_INFO" | jq -r '.databaseId') + STATUS=$(printf '%s' "$RUN_INFO" | jq -r '.status') + CONCLUSION=$(printf '%s' "$RUN_INFO" | jq -r '.conclusion // empty') + echo "Build $RUN_ID status=$STATUS conclusion=${CONCLUSION:-pending}" + + if [ "$STATUS" = "completed" ]; then + if [ "$CONCLUSION" = "success" ]; then + BUILD_SUCCEEDED=true + break + fi + echo "Latest fork build did not succeed: $CONCLUSION" + exit 1 fi - done - done < <(gh run list --workflow build-apk.yml --branch fork --status success --limit 100 --json databaseId,headSha --jq '.[] | [.databaseId, .headSha] | @tsv') + else + echo "No fork build found yet for $EXPECTED_SHA" + fi + + echo 'Build is not finished; polling again in 5 minutes' + sleep 300 + done - test -n "$RUN_ID" || { echo 'No successful fork build found for this PR'; exit 1; } - echo "Using successful fork build $RUN_ID" + test "$BUILD_SUCCEEDED" = true || { + echo 'Timed out waiting for the latest fork build' + exit 1 + } + echo "Using fork build $RUN_ID for PR tip $EXPECTED_SHA" gh run download "$RUN_ID" --dir downloaded-artifact APK=$(find downloaded-artifact -type f -name '*.apk' | head -n 1) test -n "$APK" || { echo 'APK not found in build artifact'; exit 1; } diff --git a/lib/ui/controllers/terminal_controller.dart b/lib/ui/controllers/terminal_controller.dart index 5cd37cb..9174bd9 100644 --- a/lib/ui/controllers/terminal_controller.dart +++ b/lib/ui/controllers/terminal_controller.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; + import 'package:flutter/services.dart'; import 'package:flutter_pty/flutter_pty.dart'; import 'package:get/get.dart'; @@ -19,6 +20,9 @@ import 'terminal_tab_manager.dart'; class HomeController extends GetxController { static const _nativeWebViewChannel = MethodChannel('astrbot_native_webview'); + static const double defaultTerminalFontSize = 12.0; + static const double minTerminalFontSize = 8.0; + static const double maxTerminalFontSize = 16.0; // 终端标签页管理器 late final TerminalTabManager terminalTabManager; // bool vsCodeStaring = false; @@ -31,6 +35,8 @@ class HomeController extends GetxController { final RxString napCatWebUiToken = ''.obs; // 存储 NapCat WebUI Token final RxBool napCatWebUiEnabledRx = false.obs; // GetX 响应式变量用于导航栏更新 final RxBool showTerminalWhiteTextRx = false.obs; // GetX 响应式变量用于设置页更新 + // 仅保存在当前运行期间,应用重启后恢复 xterm 默认字号 + final RxDouble terminalFontSize = defaultTerminalFontSize.obs; final RxList> customWebViews = >[].obs; // 自定义 WebView 列表 final RxInt navigateToTab = (-1).obs; // 通知 WebViewPage 切换标签页 @@ -63,6 +69,10 @@ class HomeController extends GetxController { double step = 14.0; final RxString currentProgress = ''.obs; + void setTerminalFontSize(double size) { + terminalFontSize.value = size.clamp(minTerminalFontSize, maxTerminalFontSize).toDouble(); + } + // 进度 +1 // Progress +1 void bumpProgress() { diff --git a/lib/ui/pages/terminal/terminal_keyboard.dart b/lib/ui/pages/terminal/terminal_keyboard.dart index 699e9b2..62a881f 100644 --- a/lib/ui/pages/terminal/terminal_keyboard.dart +++ b/lib/ui/pages/terminal/terminal_keyboard.dart @@ -66,9 +66,7 @@ class _TerminalKeyboardState extends State { final bottom = MediaQuery.of(context).viewInsets.bottom; final cs = Theme.of(context).colorScheme; - return AnimatedContainer( - duration: const Duration(milliseconds: 200), - curve: Curves.easeOut, + return Container( margin: EdgeInsets.only(bottom: bottom), decoration: BoxDecoration( color: cs.surface, diff --git a/lib/ui/pages/terminal/terminal_tab_view.dart b/lib/ui/pages/terminal/terminal_tab_view.dart index b09a84f..9731f92 100644 --- a/lib/ui/pages/terminal/terminal_tab_view.dart +++ b/lib/ui/pages/terminal/terminal_tab_view.dart @@ -20,6 +20,13 @@ class TerminalTabView extends StatefulWidget { class _TerminalTabViewState extends State { final HomeController homeController = Get.find(); bool _isCopyDialogOpen = false; + final Map _terminalPointers = {}; + double? _pinchStartDistance; + double? _pinchStartFontSize; + bool _isPinching = false; + + static const double _fontSizeStep = 0.2; + static const double _distancePerFontSizeStep = 24.0; @override Widget build(BuildContext context) { @@ -183,7 +190,47 @@ class _TerminalTabViewState extends State { children: [ Expanded( child: Listener( - onPointerUp: (_) => _tryCopySelection(tab), + onPointerDown: (event) { + _terminalPointers[event.pointer] = event.localPosition; + if (_terminalPointers.length == 2) { + final points = _terminalPointers.values.toList(); + _pinchStartDistance = (points[0] - points[1]).distance; + _pinchStartFontSize = homeController.terminalFontSize.value; + _isPinching = true; + } + }, + onPointerMove: (event) { + if (!_terminalPointers.containsKey(event.pointer)) return; + _terminalPointers[event.pointer] = event.localPosition; + if (_terminalPointers.length != 2 || + _pinchStartDistance == null || + _pinchStartFontSize == null) { + return; + } + + final points = _terminalPointers.values.toList(); + final distance = (points[0] - points[1]).distance; + final distanceDelta = distance - _pinchStartDistance!; + final sizeDelta = (distanceDelta / _distancePerFontSizeStep).round() * _fontSizeStep; + homeController.setTerminalFontSize( + _pinchStartFontSize! + sizeDelta, + ); + }, + onPointerUp: (event) { + _terminalPointers.remove(event.pointer); + final wasPinching = _isPinching; + if (_terminalPointers.isEmpty) { + _pinchStartDistance = null; + _pinchStartFontSize = null; + _isPinching = false; + } + if (!wasPinching) _tryCopySelection(tab); + }, + onPointerCancel: (event) { + _terminalPointers.remove(event.pointer); + _pinchStartDistance = null; + _pinchStartFontSize = null; + }, child: ClipRect( child: TerminalView( tab.terminal, @@ -191,6 +238,7 @@ class _TerminalTabViewState extends State { readOnly: tab.type == TerminalTabType.fixed, backgroundOpacity: 1, theme: ManjaroTerminalTheme(), + textStyle: TerminalStyle(fontSize: homeController.terminalFontSize.value), ), ), ), From 29186c8416795cd2e3c2027e90553f1b5f53709d Mon Sep 17 00:00:00 2001 From: Rarya <3148438955@qq.com> Date: Thu, 20 Aug 2026 06:43:40 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20=E9=87=8D=E5=90=AF?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=84=9A=E6=9C=AC=E6=8A=A5=E9=94=99'name=20'?= =?UTF-8?q?count'=20is=20not=20defined'=20=E5=A2=9E=E5=8A=A0=20python?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E7=9A=84=E6=97=A5=E5=BF=97=E7=BA=A7=E5=88=AB?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=EF=BC=8C=E9=81=BF=E5=85=8D=E7=BB=88=E7=AB=AF?= =?UTF-8?q?=E5=A4=A7=E9=87=8FDEBUG=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release-apk.yml | 10 ++++--- assets/proot.py | 43 ++++++++++++++++++++++++++++--- pubspec.yaml | 2 +- 3 files changed, 46 insertions(+), 9 deletions(-) diff --git a/.github/workflows/release-apk.yml b/.github/workflows/release-apk.yml index 0577cf0..033e9a0 100644 --- a/.github/workflows/release-apk.yml +++ b/.github/workflows/release-apk.yml @@ -100,18 +100,20 @@ jobs: separators = r"\s,,、;;::|//\\" label = re.compile(rf"(?:^|[{separators}])(?P