CH-J SM Mobilepamamahala ng server sa pamamagitan ng SSH
Menu
Nailathalang source

CH-J SM Mobile

I-browse ang mga direktoryo at file ng isang partikular na release ng application.

I-download ang source ZIP
CH-J / SM Mobile 175 file
sm-mobile-20261016T185235Z-8e93ecc1b59a Idinagdag: · Binuo:
terminal_page.dart Idinagdag: Hindi naitala ang petsa 7.0 KB · 201 linya
Code I-download ang file
1import 'package:flutter/foundation.dart';
2import 'package:flutter/material.dart';
3import 'package:flutter/services.dart';
4import 'package:xterm/xterm.dart';
5import '../core/app_controller.dart';
6import '../l10n/strings.dart';
7import 'adaptive.dart';
8import 'common.dart';
9import 'theme.dart';
11// xterm's default palette on the desktop terminal background.
12const _terminalTheme = TerminalTheme(
13 cursor: Color(0xccecf5ff),
14 selection: Color(0x6642a5ff),
15 foreground: Color(0xffdce8f5),
16 background: Brand.terminal,
17 black: Color(0xff000000),
18 red: Color(0xffcd3131),
19 green: Color(0xff0dbc79),
20 yellow: Color(0xffe5e510),
21 blue: Color(0xff2472c8),
22 magenta: Color(0xffbc3fbc),
23 cyan: Color(0xff11a8cd),
24 white: Color(0xffe5e5e5),
25 brightBlack: Color(0xff666666),
26 brightRed: Color(0xfff14c4c),
27 brightGreen: Color(0xff23d18b),
28 brightYellow: Color(0xfff5f543),
29 brightBlue: Color(0xff3b8eea),
30 brightMagenta: Color(0xffd670d6),
31 brightCyan: Color(0xff29b8db),
32 brightWhite: Color(0xffffffff),
33 searchHitBackground: Color(0xffffff2b),
34 searchHitBackgroundCurrent: Color(0xff31ff26),
35 searchHitForeground: Color(0xff000000),
36);
38class TerminalPage extends StatefulWidget {
39 final AppController controller;
40 const TerminalPage(this.controller, {super.key});
41 @override
42 State<TerminalPage> createState() => _TerminalPageState();
45class _TerminalPageState extends State<TerminalPage> {
46 final selection = TerminalController();
47 final focus = FocusNode();
48 bool ctrl = false, alt = false;
49 @override
50 void initState() {
51 super.initState();
52 // The keyboard button offers show or hide depending on focus.
53 focus.addListener(_focusChanged);
54 }
56 void _focusChanged() {
57 if (mounted) setState(() {});
58 }
60 @override
61 void dispose() {
62 focus.removeListener(_focusChanged);
63 selection.dispose();
64 focus.dispose();
65 super.dispose();
66 }
68 @override
69 Widget build(BuildContext context) {
70 final c = widget.controller;
71 if (!c.ssh.connected) {
72 return const PageMessage('selectServer', icon: Icons.terminal);
73 }
74 final terminal = c.ssh.terminal;
75 // Key bar plus at least a few terminal rows; shorter space scrolls.
76 return MinHeight(
77 minHeight: 120,
78 child: Column(
79 children: [
80 Expanded(
81 child: Focus(
82 onKeyEvent: (_, _) {
83 c.activity();
84 return KeyEventResult.ignored;
85 },
86 // xterm paints lines without clipping; scrolled-out lines
87 // would otherwise draw over the status row and app bar.
88 child: ClipRect(
89 child: ColoredBox(
90 color: Brand.terminal,
91 child: TerminalView(
92 terminal,
93 controller: selection,
94 focusNode: focus,
95 theme: _terminalTheme,
96 // Desktop terminal insets; narrower on compact phones.
97 padding: MediaQuery.sizeOf(context).width < 600
98 ? const EdgeInsets.fromLTRB(8, 6, 4, 4)
99 : const EdgeInsets.fromLTRB(14, 12, 8, 8),
100 // Soft keyboards (iOS, many Android IMEs) send no backspace
101 // key event on an empty input buffer; this detects deletion.
102 deleteDetection:
103 defaultTargetPlatform == TargetPlatform.iOS ||
104 defaultTargetPlatform == TargetPlatform.android,
105 textStyle: TerminalStyle(
106 fontSize: 14 * MediaQuery.textScalerOf(context).scale(1),
107 ),
108 onKeyEvent: (_, key) {
109 c.activity();
110 return KeyEventResult.ignored;
111 },
112 ),
113 ),
114 ),
115 ),
116 ),
117 // Key bar styled like the desktop terminal toolbar.
118 DecoratedBox(
119 decoration: BoxDecoration(
120 color: Theme.of(context).navigationBarTheme.backgroundColor,
121 border: Border(
122 top: BorderSide(color: Theme.of(context).dividerColor),
123 ),
124 ),
125 child: SingleChildScrollView(
126 scrollDirection: Axis.horizontal,
127 padding: const EdgeInsets.symmetric(horizontal: 4),
128 child: Row(
129 children: [
130 for (final entry in {
131 'ESC': TerminalKey.escape,
132 'TAB': TerminalKey.tab,
133 '↑': TerminalKey.arrowUp,
134 '↓': TerminalKey.arrowDown,
135 '←': TerminalKey.arrowLeft,
136 '→': TerminalKey.arrowRight,
137 }.entries)
138 TextButton(
139 onPressed: () {
140 c.activity();
141 terminal.keyInput(entry.value);
142 },
143 child: Text(entry.key),
144 ),
145 FilterChip(
146 label: const Text('CTRL'),
147 selected: c.ssh.ctrlNext,
148 onSelected: (v) => setState(() => c.ssh.ctrlNext = v),
149 ),
150 const SizedBox(width: 6),
151 FilterChip(
152 label: const Text('ALT'),
153 selected: c.ssh.altNext,
154 onSelected: (v) => setState(() => c.ssh.altNext = v),
155 ),
156 IconButton(
157 tooltip: context.tr(
158 focus.hasFocus ? 'hideKeyboard' : 'keyboard',
159 ),
160 icon: Icon(
161 focus.hasFocus ? Icons.keyboard_hide : Icons.keyboard,
162 ),
163 onPressed: () =>
164 focus.hasFocus ? focus.unfocus() : focus.requestFocus(),
165 ),
166 IconButton(
167 tooltip: context.tr('copy'),
168 icon: const Icon(Icons.copy),
169 onPressed: () {
170 if (selection.selection != null) {
171 Clipboard.setData(
172 ClipboardData(
173 text: terminal.buffer.getText(selection.selection),
174 ),
175 );
176 }
177 },
178 ),
179 IconButton(
180 tooltip: context.tr('paste'),
181 icon: const Icon(Icons.paste),
182 onPressed: () async {
183 final data = await Clipboard.getData(
184 Clipboard.kTextPlain,
185 );
186 if (c.ssh.connected &&
187 c.vault.unlocked &&
188 data?.text != null) {
189 terminal.paste(data!.text!);
190 }
191 },
192 ),
193 ],
194 ),
195 ),
196 ),
197 ],
198 ),
199 );
200 }
SHA-2561f129c620e60f667af0ce40aa55cebad926b99ad2e54e40158ece95f8601aa5e

CH-J Proprietary Software License 1.14 · Ibinibigay ang source sa ilalim ng CH-J Proprietary Software License 1.14. Hindi binabago ng pagiging available nito ang mga tuntunin ng lisensya at hindi ito nagbibigay ng karagdagang karapatan.

SHA-256 ng archive46e427a43e87af091004f36145590bda8fe90086dfb0f631afeb5029fb0b5655
Mga file