├── .gitignore
├── .metadata
├── .vscode
└── launch.json
├── CHANGELOG.md
├── LICENSE
├── README.md
├── analysis_options.yaml
├── android
├── .gitignore
├── app
│ ├── build.gradle
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin
│ │ │ └── com
│ │ │ │ └── nightmare
│ │ │ │ └── termare
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── drawable-v21
│ │ │ └── launch_background.xml
│ │ │ ├── drawable
│ │ │ └── launch_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── values-night
│ │ │ └── styles.xml
│ │ │ ├── values
│ │ │ └── styles.xml
│ │ │ └── xml
│ │ │ └── network_security_config.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── assets
├── fonts
│ ├── DroidSansMono.ttf
│ ├── MenloforPowerline.ttf
│ ├── MesloLGMforPowerline.ttf
│ ├── SourceCodePro.ttf
│ ├── SourceCodeProMediumforPowerline.otf
│ └── UbuntuMono.ttf
├── icons
│ └── code.png
├── lib
│ └── libterm.dylib
├── ogg
│ └── InCallNotification.ogg
└── text
│ └── neofetch.txt
├── dynamic_library
├── libterm.dylib
└── libterm.so
├── ios
├── .gitignore
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ └── Release.xcconfig
├── Podfile
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
└── Runner
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── Icon-App-1024x1024@1x.png
│ │ ├── Icon-App-20x20@1x.png
│ │ ├── Icon-App-20x20@2x.png
│ │ ├── Icon-App-20x20@3x.png
│ │ ├── Icon-App-29x29@1x.png
│ │ ├── Icon-App-29x29@2x.png
│ │ ├── Icon-App-29x29@3x.png
│ │ ├── Icon-App-40x40@1x.png
│ │ ├── Icon-App-40x40@2x.png
│ │ ├── Icon-App-40x40@3x.png
│ │ ├── Icon-App-60x60@2x.png
│ │ ├── Icon-App-60x60@3x.png
│ │ ├── Icon-App-76x76@1x.png
│ │ ├── Icon-App-76x76@2x.png
│ │ └── Icon-App-83.5x83.5@2x.png
│ └── LaunchImage.imageset
│ │ ├── Contents.json
│ │ ├── LaunchImage.png
│ │ ├── LaunchImage@2x.png
│ │ ├── LaunchImage@3x.png
│ │ └── README.md
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ └── Runner-Bridging-Header.h
├── lib
├── app
│ ├── modules
│ │ ├── dashboard
│ │ │ └── views
│ │ │ │ └── dashboard.dart
│ │ ├── setting
│ │ │ ├── bindings
│ │ │ │ └── setting_binding.dart
│ │ │ ├── controllers
│ │ │ │ └── setting_controller.dart
│ │ │ ├── models
│ │ │ │ └── models.json
│ │ │ ├── models_model.dart
│ │ │ ├── utils
│ │ │ │ └── term_utils.dart
│ │ │ └── views
│ │ │ │ ├── powerlevel10k_addr.dart
│ │ │ │ ├── setting_page.dart
│ │ │ │ └── zsh_select_addr.dart
│ │ └── terminal
│ │ │ ├── bindings
│ │ │ └── terminal_binding.dart
│ │ │ ├── controllers
│ │ │ └── terminal_controller.dart
│ │ │ └── views
│ │ │ ├── download_bootstrap_page.dart
│ │ │ ├── quark_window_check.dart
│ │ │ ├── terminal_pages.dart
│ │ │ ├── terminal_title.dart
│ │ │ ├── web_view.dart
│ │ │ └── xterm_wrapper.dart
│ ├── routes
│ │ ├── app_pages.dart
│ │ └── app_routes.dart
│ └── widgets
│ │ ├── custom_icon_button.dart
│ │ ├── mac_safearea.dart
│ │ ├── pop_button.dart
│ │ ├── term_bottom_bar.dart
│ │ ├── termare_view_with_bar.dart
│ │ └── terminal_drawer.dart
├── config
│ ├── assets.dart
│ └── config.dart
├── main.dart
├── termare_app.dart
└── themes
│ ├── app_colors.dart
│ ├── color_schema_extension.dart
│ ├── default_theme_data.dart
│ └── theme.dart
├── macos
├── .gitignore
├── Flutter
│ ├── Flutter-Debug.xcconfig
│ ├── Flutter-Release.xcconfig
│ └── GeneratedPluginRegistrant.swift
├── Podfile
├── Podfile.lock
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── Runner
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── app_icon_1024.png
│ │ ├── app_icon_128.png
│ │ ├── app_icon_16.png
│ │ ├── app_icon_256.png
│ │ ├── app_icon_32.png
│ │ ├── app_icon_512.png
│ │ └── app_icon_64.png
│ ├── Base.lproj
│ └── MainMenu.xib
│ ├── Configs
│ ├── AppInfo.xcconfig
│ ├── Debug.xcconfig
│ ├── Release.xcconfig
│ └── Warnings.xcconfig
│ ├── DebugProfile.entitlements
│ ├── Info.plist
│ ├── MainFlutterWindow.swift
│ └── Release.entitlements
├── pubspec.lock
├── pubspec.yaml
├── screencap
├── cmatrix-r.jpg
├── cmatrix.jpg
├── dart-version.jpg
├── htop.jpg
├── mac-neofetch.png
├── nano.jpg
├── oh_my_zsh.jpg
├── select-page.jpg
├── setting-page-01.jpg
├── setting-page-02.jpg
├── sl.jpg
└── vim.jpg
├── scripts
├── build_macos.sh
├── build_windows.bat
├── clean.sh
├── generate_mac_app.sh
├── patch_executable.sh
├── properties.sh
├── run_release.sh
└── upload
│ └── upload.sh
├── test
└── widget_test.dart
└── web
├── favicon.png
├── icons
├── Icon-192.png
└── Icon-512.png
├── index.html
└── manifest.json
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # The .vscode folder contains launch configuration and tasks you configure in
19 | # VS Code which you may wish to be included in version control, so this line
20 | # is commented out by default.
21 | #.vscode/
22 |
23 | # Flutter/Dart/Pub related
24 | **/doc/api/
25 | **/ios/Flutter/.last_build_id
26 | .dart_tool/
27 | .flutter-plugins
28 | .flutter-plugins-dependencies
29 | .packages
30 | .pub-cache/
31 | .pub/
32 | /build/
33 |
34 | # Web related
35 | lib/generated_plugin_registrant.dart
36 |
37 | # Symbolication related
38 | app.*.symbols
39 |
40 | # Obfuscation related
41 | app.*.map.json
42 |
43 | # Android Studio will place build artifacts here
44 | /android/app/debug
45 | /android/app/profile
46 | /android/app/release
47 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: 8bee0834e4be79879f15222cce8fa9642cfefb2b
8 | channel: master
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // 使用 IntelliSense 了解相关属性。
3 | // 悬停以查看现有属性的描述。
4 | // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": "Linux",
9 | "type": "dart",
10 | "request": "launch",
11 | "program": "lib/main.dart",
12 | "deviceId": "linux"
13 | },
14 | {
15 | "name": "Mac Desktop",
16 | "request": "launch",
17 | "type": "dart",
18 | "deviceId": "macos"
19 | },
20 | {
21 | "name": "Windows Desktop",
22 | "request": "launch",
23 | "type": "dart",
24 | "deviceId": "windows"
25 | },
26 | {
27 | "name": "小米10",
28 | "request": "launch",
29 | "type": "dart",
30 | "deviceId": "Mi 10"
31 | },
32 | {
33 | "name": "小米10s",
34 | "request": "launch",
35 | "type": "dart",
36 | "deviceId": "M2102J2SC"
37 | },
38 | {
39 | "name": "红米K30",
40 | "request": "launch",
41 | "type": "dart",
42 | "deviceId": "Redmi K30"
43 | },
44 | {
45 | "name": "平板",
46 | "request": "launch",
47 | "type": "dart",
48 | "deviceId": "M2105K81AC"
49 | },
50 | ]
51 | }
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## [1.0.0]
4 |
5 | * first upload
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Nightmare-MY
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Termare application(开源版)
2 |
3 | Termare 是一个支持多平台的本地终端模拟器,与 Termux 不同的是,支持更多的平台。
4 |
5 | 在安卓端同样有自己独立的源。
6 |
7 | > 注意目前以运行在安卓平台为主,PC端目前表现很差,还在努力开发中,不要尝试将此终端模拟器正式投入到 PC 中使用。
8 |
9 | ## 安装
10 |
11 | [termare官网](http://nightmare.fun/termarehome/):
12 |
13 | ## 开发者
14 |
15 | ### 编译
16 |
17 | 这是一个 Flutter 项目,如果你是 Flutter 开发者,仓库根目录即为工程目录,直接运行即可。Flutter 为 master 分支。
18 | 非 Flutter 开发者请移步到 [Flutter 文档](https://flutter.dev/docs),阅读 Flutter 相关的文档。
19 |
20 | ## 关联仓库
21 |
22 | ## Terminal resources
23 |
24 | - [XTerm control sequences](http://invisible-island.net/xterm/ctlseqs/ctlseqs.html)
25 | - [vt100.net](http://vt100.net/)
26 | - [Terminal codes (ANSI and terminfo equivalents)](http://wiki.bash-hackers.org/scripting/terminalcodes)
27 |
28 | ## Terminal emulators
29 |
30 | - VTE (libvte): Terminal emulator widget for GTK+, mainly used in gnome-terminal.
31 | [Source](https://github.com/GNOME/vte), [Open Issues](https://bugzilla.gnome.org/buglist.cgi?quicksearch=product%3A%22vte%22+),
32 | and [All (including closed) issues](https://bugzilla.gnome.org/buglist.cgi?bug_status=RESOLVED&bug_status=VERIFIED&chfield=resolution&chfieldfrom=-2000d&chfieldvalue=FIXED&product=vte&resolution=FIXED).
33 |
34 | - iTerm 2: OS X terminal application. [Source](https://github.com/gnachman/iTerm2),
35 | [Issues](https://gitlab.com/gnachman/iterm2/issues) and [Documentation](http://www.iterm2.com/documentation.html)
36 | (which includes [iTerm2 proprietary escape codes](http://www.iterm2.com/documentation-escape-codes.html)).
37 |
38 | - Konsole: KDE terminal application. [Source](https://projects.kde.org/projects/kde/applications/konsole/repository),
39 | in particular [tests](https://projects.kde.org/projects/kde/applications/konsole/repository/revisions/master/show/tests),
40 | [Bugs](https://bugs.kde.org/buglist.cgi?bug_severity=critical&bug_severity=grave&bug_severity=major&bug_severity=crash&bug_severity=normal&bug_severity=minor&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&product=konsole)
41 | and [Wishes](https://bugs.kde.org/buglist.cgi?bug_severity=wishlist&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&product=konsole).
42 |
43 | - hterm: JavaScript terminal implementation from Chromium. [Source](https://github.com/chromium/hterm),
44 | including [tests](https://github.com/chromium/hterm/blob/master/js/hterm_vt_tests.js),
45 | and [Google group](https://groups.google.com/a/chromium.org/forum/#!forum/chromium-hterm).
46 |
47 | - xterm: The grandfather of terminal emulators.
48 | [Source](http://invisible-island.net/datafiles/release/xterm.tar.gz).
49 |
50 | - Connectbot: Android SSH client. [Source](https://github.com/connectbot/connectbot)
51 |
52 | - Android Terminal Emulator: Android terminal app which Termux terminal handling
53 | is based on. Inactive. [Source](https://github.com/jackpal/Android-Terminal-Emulator).
54 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | # Specify analysis options.
2 | #
3 | # Until there are meta linter rules, each desired lint must be explicitly enabled.
4 | # See: https://github.com/dart-lang/linter/issues/288
5 | #
6 | # For a list of lints, see: http://dart-lang.github.io/linter/lints/
7 | # See the configuration guide for more
8 | # https://github.com/dart-lang/sdk/tree/master/pkg/analyzer#configuring-the-analyzer
9 | #
10 | # There are other similar analysis options files in the flutter repos,
11 | # which should be kept in sync with this file:
12 | #
13 | # - analysis_options.yaml (this file)
14 | # - packages/flutter/lib/analysis_options_user.yaml
15 | # - https://github.com/flutter/plugins/blob/master/analysis_options.yaml
16 | # - https://github.com/flutter/engine/blob/master/analysis_options.yaml
17 | #
18 | # This file contains the analysis options used by Flutter tools, such as IntelliJ,
19 | # Android Studio, and the `flutter analyze` command.
20 |
21 | analyzer:
22 | strong-mode:
23 | implicit-casts: false
24 | implicit-dynamic: true
25 | errors:
26 | # treat missing required parameters as a warning (not a hint)
27 | missing_required_param: warning
28 | # treat missing returns as a warning (not a hint)
29 | missing_return: warning
30 | # allow having TODOs in the code
31 | todo: ignore
32 | # allow self-reference to deprecated members (we do this because otherwise we have
33 | # to annotate every member in every test, assert, etc, when we deprecate something)
34 | deprecated_member_use_from_same_package: ignore
35 | # Ignore analyzer hints for updating pubspecs when using Future or
36 | # Stream and not importing dart:async
37 | # Please see https://github.com/flutter/flutter/pull/24528 for details.
38 | sdk_version_async_exported_from_core: ignore
39 | # Turned off until null-safe rollout is complete.
40 | unnecessary_null_comparison: ignore
41 | exclude:
42 | - "bin/cache/**"
43 |
44 | linter:
45 | rules:
46 | # these rules are documented on and in the same order as
47 | # the Dart Lint rules page to make maintenance easier
48 | # https://github.com/dart-lang/linter/blob/master/example/all.yaml
49 | - always_declare_return_types
50 | - always_put_control_body_on_new_line
51 | # - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219
52 | - always_require_non_null_named_parameters
53 | # - always_specify_types
54 | # - always_use_package_imports # we do this commonly
55 | - annotate_overrides
56 | # - avoid_annotating_with_dynamic # conflicts with always_specify_types
57 | - avoid_bool_literals_in_conditional_expressions
58 | # - avoid_catches_without_on_clauses # we do this commonly
59 | # - avoid_catching_errors # we do this commonly
60 | - avoid_classes_with_only_static_members
61 | # - avoid_double_and_int_checks # only useful when targeting JS runtime
62 | # - avoid_dynamic_calls # not yet tested
63 | - avoid_empty_else
64 | - avoid_equals_and_hash_code_on_mutable_classes
65 | # - avoid_escaping_inner_quotes # not yet tested
66 | - avoid_field_initializers_in_const_classes
67 | - avoid_function_literals_in_foreach_calls
68 | # - avoid_implementing_value_types # not yet tested
69 | - avoid_init_to_null
70 | # - avoid_js_rounded_ints # only useful when targeting JS runtime
71 | - avoid_null_checks_in_equality_operators
72 | # - avoid_positional_boolean_parameters # not yet tested
73 | # - avoid_print # not yet tested
74 | # - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356)
75 | # - avoid_redundant_argument_values # not yet tested
76 | - avoid_relative_lib_imports
77 | - avoid_renaming_method_parameters
78 | - avoid_return_types_on_setters
79 | # - avoid_returning_null # there are plenty of valid reasons to return null
80 | # - avoid_returning_null_for_future # not yet tested
81 | - avoid_returning_null_for_void
82 | # - avoid_returning_this # there are plenty of valid reasons to return this
83 | # - avoid_setters_without_getters # not yet tested
84 | - avoid_shadowing_type_parameters
85 | - avoid_single_cascade_in_expression_statements
86 | - avoid_slow_async_io
87 | - avoid_type_to_string
88 | - avoid_types_as_parameter_names
89 | # - avoid_types_on_closure_parameters # conflicts with always_specify_types
90 | # - avoid_unnecessary_containers # not yet tested
91 | - avoid_unused_constructor_parameters
92 | - avoid_void_async
93 | # - avoid_web_libraries_in_flutter # not yet tested
94 | - await_only_futures
95 | - camel_case_extensions
96 | - camel_case_types
97 | - cancel_subscriptions
98 | # - cascade_invocations # not yet tested
99 | - cast_nullable_to_non_nullable
100 | # - close_sinks # not reliable enough
101 | # - comment_references # blocked on https://github.com/dart-lang/linter/issues/1142
102 | # - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204
103 | - control_flow_in_finally
104 | # - curly_braces_in_flow_control_structures # not required by flutter style
105 | # - deprecated_consistency # not yet tested
106 | # - diagnostic_describe_all_properties # not yet tested
107 | - directives_ordering
108 | # - do_not_use_environment # we do this commonly
109 | - empty_catches
110 | - empty_constructor_bodies
111 | - empty_statements
112 | - exhaustive_cases
113 | - file_names
114 | - flutter_style_todos
115 | - hash_and_equals
116 | - implementation_imports
117 | # - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811
118 | - iterable_contains_unrelated_type
119 | # - join_return_with_assignment # not required by flutter style
120 | - leading_newlines_in_multiline_strings
121 | - library_names
122 | - library_prefixes
123 | # - lines_longer_than_80_chars # not required by flutter style
124 | - list_remove_unrelated_type
125 | # - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181
126 | - missing_whitespace_between_adjacent_strings
127 | - no_adjacent_strings_in_list
128 | # - no_default_cases # too many false positives
129 | - no_duplicate_case_values
130 | - no_logic_in_create_state
131 | # - no_runtimeType_toString # ok in tests; we enable this only in packages/
132 | - non_constant_identifier_names
133 | - null_check_on_nullable_type_parameter
134 | - null_closures
135 | # - omit_local_variable_types # opposite of always_specify_types
136 | # - one_member_abstracts # too many false positives
137 | # - only_throw_errors # https://github.com/flutter/flutter/issues/5792
138 | - overridden_fields
139 | - package_api_docs
140 | - package_names
141 | - package_prefixed_library_names
142 | # - parameter_assignments # we do this commonly
143 | - prefer_adjacent_string_concatenation
144 | - prefer_asserts_in_initializer_lists
145 | # - prefer_asserts_with_message # not required by flutter style
146 | - prefer_collection_literals
147 | - prefer_conditional_assignment
148 | - prefer_const_constructors
149 | - prefer_const_constructors_in_immutables
150 | - prefer_const_declarations
151 | - prefer_const_literals_to_create_immutables
152 | # - prefer_constructors_over_static_methods # far too many false positives
153 | - prefer_contains
154 | # - prefer_double_quotes # opposite of prefer_single_quotes
155 | - prefer_equal_for_default_values
156 | # - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods
157 | - prefer_final_fields
158 | - prefer_final_in_for_each
159 | - prefer_final_locals
160 | - prefer_for_elements_to_map_fromIterable
161 | - prefer_foreach
162 | # - prefer_function_declarations_over_variables # not yet tested
163 | - prefer_generic_function_type_aliases
164 | - prefer_if_elements_to_conditional_expressions
165 | - prefer_if_null_operators
166 | - prefer_initializing_formals
167 | - prefer_inlined_adds
168 | # - prefer_int_literals # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#use-double-literals-for-double-constants
169 | # - prefer_interpolation_to_compose_strings # doesn't work with raw strings, see https://github.com/dart-lang/linter/issues/2490
170 | - prefer_is_empty
171 | - prefer_is_not_empty
172 | - prefer_is_not_operator
173 | - prefer_iterable_whereType
174 | # - prefer_mixin # https://github.com/dart-lang/language/issues/32
175 | - prefer_null_aware_operators
176 | # - prefer_relative_imports # not yet tested
177 | - prefer_single_quotes
178 | - prefer_spread_collections
179 | - prefer_typing_uninitialized_variables
180 | - prefer_void_to_null
181 | - provide_deprecation_message
182 | # - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml
183 | - recursive_getters
184 | - sized_box_for_whitespace
185 | - slash_for_doc_comments
186 | # - sort_child_properties_last # not yet tested
187 | - sort_constructors_first
188 | # - sort_pub_dependencies # prevents separating pinned transitive dependencies
189 | - sort_unnamed_constructors_first
190 | - test_types_in_equals
191 | - throw_in_finally
192 | - tighten_type_of_initializing_formals
193 | # - type_annotate_public_apis # subset of always_specify_types
194 | - type_init_formals
195 | # - unawaited_futures # too many false positives
196 | # - unnecessary_await_in_return # not yet tested
197 | - unnecessary_brace_in_string_interps
198 | - unnecessary_const
199 | # - unnecessary_final # conflicts with prefer_final_locals
200 | - unnecessary_getters_setters
201 | # - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498
202 | - unnecessary_new
203 | - unnecessary_null_aware_assignments
204 | # - unnecessary_null_checks # not yet tested
205 | - unnecessary_null_in_if_null_operators
206 | - unnecessary_nullable_for_final_variable_declarations
207 | - unnecessary_overrides
208 | - unnecessary_parenthesis
209 | # - unnecessary_raw_strings # not yet tested
210 | - unnecessary_statements
211 | - unnecessary_string_escapes
212 | - unnecessary_string_interpolations
213 | - unnecessary_this
214 | - unrelated_type_equality_checks
215 | # - unsafe_html # not yet tested
216 | - use_full_hex_values_for_flutter_colors
217 | # - use_function_type_syntax_for_parameters # not yet tested
218 | # - use_if_null_to_convert_nulls_to_bools # not yet tested
219 | - use_is_even_rather_than_modulo
220 | - use_key_in_widget_constructors
221 | - use_late_for_private_fields_and_variables
222 | # - use_named_constants # not yet yested
223 | - use_raw_strings
224 | - use_rethrow_when_possible
225 | # - use_setters_to_change_properties # not yet tested
226 | # - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182
227 | # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review
228 | - valid_regexps
229 | - void_checks
230 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 | **/*.keystore
13 | **/*.jks
14 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply plugin: 'kotlin-android'
26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 | // 本地编译注释以下代码
28 | // start
29 | def keystorePropertiesFile = rootProject.file("key.properties")
30 | def keystoreProperties = new Properties()
31 | keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
32 | // end
33 | android {
34 | compileSdkVersion 31
35 |
36 | compileOptions {
37 | sourceCompatibility JavaVersion.VERSION_1_8
38 | targetCompatibility JavaVersion.VERSION_1_8
39 | }
40 |
41 | kotlinOptions {
42 | jvmTarget = '1.8'
43 | }
44 |
45 | sourceSets {
46 | main.java.srcDirs += 'src/main/kotlin'
47 | }
48 |
49 | defaultConfig {
50 | applicationId "com.nightmare.termare"
51 | minSdkVersion 19
52 | targetSdkVersion 28
53 | versionCode flutterVersionCode.toInteger()
54 | versionName flutterVersionName
55 | }
56 | signingConfigs {
57 | // 本地编译注释以下代码
58 | // start
59 | release {
60 | keyAlias keystoreProperties['keyAlias']
61 | keyPassword keystoreProperties['keyPassword']
62 | storeFile file(keystoreProperties['storeFile'])
63 | storePassword keystoreProperties['storePassword']
64 | }
65 | // end
66 | }
67 | buildTypes {
68 | release {
69 | signingConfig signingConfigs.release
70 | }
71 | debug {
72 | signingConfig signingConfigs.release
73 | }
74 | }
75 | }
76 |
77 | flutter {
78 | source '../..'
79 | }
80 |
81 | dependencies {
82 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
83 | }
84 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/com/nightmare/termare/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.nightmare.termare
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/main/res/xml/network_security_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.6.10'
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:4.2.0'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | mavenCentral()
18 | }
19 | }
20 |
21 | rootProject.buildDir = '../build'
22 | subprojects {
23 | project.buildDir = "${rootProject.buildDir}/${project.name}"
24 | project.evaluationDependsOn(':app')
25 | }
26 |
27 | task clean(type: Delete) {
28 | delete rootProject.buildDir
29 | }
30 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip
7 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
4 | def properties = new Properties()
5 |
6 | assert localPropertiesFile.exists()
7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
8 |
9 | def flutterSdkPath = properties.getProperty("flutter.sdk")
10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
12 |
--------------------------------------------------------------------------------
/assets/fonts/DroidSansMono.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/assets/fonts/DroidSansMono.ttf
--------------------------------------------------------------------------------
/assets/fonts/MenloforPowerline.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/assets/fonts/MenloforPowerline.ttf
--------------------------------------------------------------------------------
/assets/fonts/MesloLGMforPowerline.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/assets/fonts/MesloLGMforPowerline.ttf
--------------------------------------------------------------------------------
/assets/fonts/SourceCodePro.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/assets/fonts/SourceCodePro.ttf
--------------------------------------------------------------------------------
/assets/fonts/SourceCodeProMediumforPowerline.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/assets/fonts/SourceCodeProMediumforPowerline.otf
--------------------------------------------------------------------------------
/assets/fonts/UbuntuMono.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/assets/fonts/UbuntuMono.ttf
--------------------------------------------------------------------------------
/assets/icons/code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/assets/icons/code.png
--------------------------------------------------------------------------------
/assets/lib/libterm.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/assets/lib/libterm.dylib
--------------------------------------------------------------------------------
/assets/ogg/InCallNotification.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/assets/ogg/InCallNotification.ogg
--------------------------------------------------------------------------------
/assets/text/neofetch.txt:
--------------------------------------------------------------------------------
1 | [?25l[?7l[0m[32m[1m -o o-
2 | +hydNNNNdyh+
3 | +mMMMMMMMMMMMMm+
4 | `dMM[37m[0m[1mm:[0m[32m[1mNMMMMMMN[37m[0m[1m:m[0m[32m[1mMMd`
5 | hMMMMMMMMMMMMMMMMMMh
6 | .. yyyyyyyyyyyyyyyyyyyy ..
7 | .mMMm`MMMMMMMMMMMMMMMMMMMM`mMMm.
8 | :MMMM-MMMMMMMMMMMMMMMMMMMM-MMMM:
9 | :MMMM-MMMMMMMMMMMMMMMMMMMM-MMMM:
10 | :MMMM-MMMMMMMMMMMMMMMMMMMM-MMMM:
11 | :MMMM-MMMMMMMMMMMMMMMMMMMM-MMMM:
12 | -MMMM-MMMMMMMMMMMMMMMMMMMM-MMMM-
13 | +yy+ MMMMMMMMMMMMMMMMMMMM +yy+
14 | mMMMMMMMMMMMMMMMMMMm
15 | `/++MMMMh++hMMMM++/`
16 | MMMMo oMMMM
17 | MMMMo oMMMM
18 | oNMm- -mMNs[0m
19 | [18A[9999999D[35C[0m[1m[32m[1mu0_a610[0m@[32m[1mlocalhost[0m
20 | [35C[0m-----------------[0m
21 | [35C[0m[32m[1mOS[0m[0m:[0m Android 11 aarch64[0m
22 | [35C[0m[32m[1mHost[0m[0m:[0m Xiaomi Mi 10[0m
23 | [35C[0m[32m[1mKernel[0m[0m:[0m 4.19.113-perf-g381838f372995[0m
24 | [35C[0m[32m[1mUptime[0m[0m:[0m 3 days, 16 hours, 56 mins[0m
25 | [35C[0m[32m[1mPackages[0m[0m:[0m 117 (dpkg), 1 (pkg)[0m
26 | [35C[0m[32m[1mShell[0m[0m:[0m zsh 5.8[0m
27 | [35C[0m[32m[1mResolution[0m[0m:[0m 1080x2340x60x113680cmd[0m
28 | [35C[0m[32m[1mCPU[0m[0m:[0m Qualcomm SM8250 (8) @ 1.804GHz[0m
29 | [35C[0m[32m[1mMemory[0m[0m:[0m 5310MiB / 7612MiB[0m
30 |
31 | [35C[30m[40m [31m[41m [32m[42m [33m[43m [34m[44m [35m[45m [36m[46m [37m[47m [m
32 | [35C[38;5;8m[48;5;8m [38;5;9m[48;5;9m [38;5;10m[48;5;10m [38;5;11m[48;5;11m [38;5;12m[48;5;12m [38;5;13m[48;5;13m [38;5;14m[48;5;14m [38;5;15m[48;5;15m [m
--------------------------------------------------------------------------------
/dynamic_library/libterm.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/dynamic_library/libterm.dylib
--------------------------------------------------------------------------------
/dynamic_library/libterm.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/dynamic_library/libterm.so
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | *.mode1v3
2 | *.mode2v3
3 | *.moved-aside
4 | *.pbxuser
5 | *.perspectivev3
6 | **/*sync/
7 | .sconsign.dblite
8 | .tags*
9 | **/.vagrant/
10 | **/DerivedData/
11 | Icon?
12 | **/Pods/
13 | **/.symlinks/
14 | profile
15 | xcuserdata
16 | **/.generated/
17 | Flutter/App.framework
18 | Flutter/Flutter.framework
19 | Flutter/Flutter.podspec
20 | Flutter/Generated.xcconfig
21 | Flutter/ephemeral/
22 | Flutter/app.flx
23 | Flutter/app.zip
24 | Flutter/flutter_assets/
25 | Flutter/flutter_export_environment.sh
26 | ServiceDefinitions.json
27 | Runner/GeneratedPluginRegistrant.*
28 |
29 | # Exceptions to above rules.
30 | !default.mode1v3
31 | !default.mode2v3
32 | !default.pbxuser
33 | !default.perspectivev3
34 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | # platform :ios, '9.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def flutter_root
14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
15 | unless File.exist?(generated_xcode_build_settings_path)
16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
17 | end
18 |
19 | File.foreach(generated_xcode_build_settings_path) do |line|
20 | matches = line.match(/FLUTTER_ROOT\=(.*)/)
21 | return matches[1].strip if matches
22 | end
23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
24 | end
25 |
26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
27 |
28 | flutter_ios_podfile_setup
29 |
30 | target 'Runner' do
31 | use_frameworks!
32 | use_modular_headers!
33 |
34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
35 | end
36 |
37 | post_install do |installer|
38 | installer.pods_project.targets.each do |target|
39 | flutter_additional_ios_build_settings(target)
40 | end
41 | end
42 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | termare_app
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(FLUTTER_BUILD_NAME)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/lib/app/modules/dashboard/views/dashboard.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'package:get/get.dart';
4 | import 'package:global_repository/src/utils/screen_util.dart';
5 | import 'package:termare_app/app/modules/terminal/controllers/terminal_controller.dart';
6 | import 'package:termare_app/app/modules/terminal/views/quark_window_check.dart';
7 | import 'package:termare_app/app/modules/terminal/views/terminal_pages.dart';
8 | import 'package:termare_app/app/widgets/custom_icon_button.dart';
9 | import 'package:termare_app/themes/app_colors.dart';
10 |
11 | class DashBoard extends StatefulWidget {
12 | const DashBoard({Key key, this.onSelect}) : super(key: key);
13 | final void Function() onSelect;
14 |
15 | @override
16 | _DashBoardState createState() => _DashBoardState();
17 | }
18 |
19 | class _DashBoardState extends State {
20 | bool exchangeWindow = false;
21 | TerminalController controller = Get.find();
22 |
23 | @override
24 | Widget build(BuildContext context) {
25 | if (exchangeWindow) {
26 | return Material(
27 | child: Stack(
28 | alignment: Alignment.center,
29 | children: [
30 | QuarkWindowCheck(
31 | children: controller.getPtyTermsForCheck(),
32 | onSelect: (value) {
33 | controller.switchTo(value);
34 | widget.onSelect();
35 | },
36 | ),
37 | SafeArea(
38 | child: Align(
39 | alignment: Alignment.topRight,
40 | child: Padding(
41 | padding: const EdgeInsets.all(8.0),
42 | child: NiIconButton(
43 | onTap: () {
44 | exchangeWindow = false;
45 | setState(() {});
46 | },
47 | child: Icon(Icons.cached),
48 | ),
49 | ),
50 | ),
51 | ),
52 | ],
53 | ),
54 | );
55 | }
56 |
57 | return AnnotatedRegion(
58 | child: Scaffold(
59 | backgroundColor: AppColors.grey.shade100,
60 | body: SafeArea(
61 | child: Padding(
62 | padding: const EdgeInsets.all(8.0),
63 | child: Column(
64 | crossAxisAlignment: CrossAxisAlignment.start,
65 | children: [
66 | Row(
67 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
68 | children: [
69 | Text(
70 | '本地终端',
71 | style: TextStyle(
72 | color: AppColors.fontColor,
73 | fontSize: 22.w,
74 | fontWeight: FontWeight.bold,
75 | ),
76 | ),
77 | NiIconButton(
78 | onTap: () {
79 | exchangeWindow = true;
80 | setState(() {});
81 | },
82 | child: Icon(Icons.cached),
83 | ),
84 | ],
85 | ),
86 | Container(
87 | width: MediaQuery.of(context).size.width,
88 | margin: EdgeInsets.symmetric(vertical: 10, horizontal: 0),
89 | padding: EdgeInsets.all(8),
90 | decoration: BoxDecoration(
91 | color: AppColors.grey.shade200,
92 | borderRadius: BorderRadius.circular(12.w),
93 | ),
94 | child: GetBuilder(
95 | builder: (controller) {
96 | final List children = [];
97 | for (int i = 0; i < controller.terms.length; i++) {
98 | children.add(TerminalItem(
99 | title: 'localhost',
100 | onTap: () {
101 | controller.switchTo(i);
102 | widget.onSelect();
103 | },
104 | ));
105 | }
106 | return Wrap(
107 | // crossAxisAlignment: CrossAxisAlignment.start,
108 | spacing: 12,
109 | runSpacing: 10.w,
110 | children: [
111 | ...children,
112 | Material(
113 | color: AppColors.grey.shade300,
114 | borderRadius: BorderRadius.circular(12.w),
115 | child: Container(
116 | height: 60.w,
117 | width: 80.w,
118 | decoration: BoxDecoration(
119 | borderRadius: BorderRadius.circular(12.w),
120 | ),
121 | child: InkWell(
122 | onTap: () {
123 | controller.createPtyTerm();
124 | },
125 | onTapDown: (_) {
126 | Feedback.forLongPress(context);
127 | },
128 | borderRadius: BorderRadius.circular(12.w),
129 | child: Icon(Icons.add),
130 | ),
131 | ),
132 | ),
133 | ],
134 | );
135 | },
136 | ),
137 | ),
138 | Text(
139 | '远程终端',
140 | style: TextStyle(
141 | color: AppColors.fontColor,
142 | fontSize: 22.w,
143 | fontWeight: FontWeight.bold,
144 | ),
145 | ),
146 | Container(
147 | width: MediaQuery.of(context).size.width,
148 | margin: EdgeInsets.symmetric(vertical: 10, horizontal: 0),
149 | padding: EdgeInsets.all(8),
150 | decoration: BoxDecoration(
151 | color: AppColors.borderColor,
152 | borderRadius: BorderRadius.circular(12.w),
153 | ),
154 | child: Wrap(
155 | // crossAxisAlignment: CrossAxisAlignment.start,
156 | spacing: 12,
157 | children: [
158 | Material(
159 | color: AppColors.grey.shade300,
160 | borderRadius: BorderRadius.circular(12.w),
161 | child: Container(
162 | height: 60.w,
163 | width: 80.w,
164 | decoration: BoxDecoration(
165 | borderRadius: BorderRadius.circular(12.w),
166 | ),
167 | child: InkWell(
168 | onTap: () {
169 | controller.createPtyTerm();
170 | },
171 | onTapDown: (_) {
172 | Feedback.forLongPress(context);
173 | },
174 | borderRadius: BorderRadius.circular(12.w),
175 | child: Icon(Icons.add),
176 | ),
177 | ),
178 | ),
179 | ],
180 | ),
181 | ),
182 | ],
183 | ),
184 | ),
185 | ),
186 | ),
187 | value: SystemUiOverlayStyle.dark,
188 | );
189 | }
190 | }
191 |
192 | class TerminalItem extends StatelessWidget {
193 | const TerminalItem({
194 | Key key,
195 | this.title,
196 | this.onTap,
197 | }) : super(key: key);
198 | final String title;
199 | final void Function() onTap;
200 | @override
201 | Widget build(BuildContext context) {
202 | return Material(
203 | color: Color(0xffe0e0e0),
204 | borderRadius: BorderRadius.circular(12),
205 | child: InkWell(
206 | onTap: onTap,
207 | borderRadius: BorderRadius.circular(12),
208 | child: Container(
209 | height: 60,
210 | width: 80,
211 | child: Column(
212 | mainAxisAlignment: MainAxisAlignment.center,
213 | children: [
214 | const Icon(Icons.android),
215 | Text(
216 | title ?? '',
217 | style: TextStyle(
218 | fontSize: 12,
219 | ),
220 | ),
221 | ],
222 | ),
223 | ),
224 | ),
225 | );
226 | }
227 | }
228 |
--------------------------------------------------------------------------------
/lib/app/modules/setting/bindings/setting_binding.dart:
--------------------------------------------------------------------------------
1 | import 'package:get/get.dart';
2 |
3 | import '../controllers/setting_controller.dart';
4 |
5 | class SettingBinding extends Bindings {
6 | @override
7 | void dependencies() {
8 | Get.lazyPut(
9 | () => SettingController(),
10 | );
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/lib/app/modules/setting/controllers/setting_controller.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 | import 'dart:io';
3 | import 'package:flutter/material.dart';
4 | import 'package:get/get.dart';
5 | import 'package:global_repository/global_repository.dart';
6 | import 'package:termare_app/app/modules/setting/models_model.dart';
7 | import 'package:termare_app/app/modules/terminal/controllers/terminal_controller.dart';
8 | import 'package:termare_app/app/modules/terminal/views/terminal_pages.dart';
9 | import 'package:termare_view/termare_view.dart';
10 |
11 | class SettingController extends GetxController {
12 | SettingInfo settingInfo;
13 | String filePath = RuntimeEnvir.homePath + '/.termare_setting';
14 | @override
15 | void onInit() {
16 | readLocalStorage();
17 | super.onInit();
18 | }
19 |
20 | void changeRepository() {
21 | // Get.dialog(Text('data'));
22 | final TextEditingController controller = TextEditingController(
23 | text: settingInfo.repository,
24 | );
25 | showCustomDialog(
26 | context: Get.context,
27 | child: FullHeightListView(
28 | child: Column(
29 | crossAxisAlignment: CrossAxisAlignment.center,
30 | children: [
31 | Text('更改软件源'),
32 | ClipRRect(
33 | borderRadius: BorderRadius.circular(8),
34 | child: TextField(
35 | style: const TextStyle(
36 | fontWeight: FontWeight.bold,
37 | ),
38 | controller: controller,
39 | decoration: InputDecoration(
40 | border: InputBorder.none,
41 | fillColor: const Color(0xfff0f0f0),
42 | filled: true,
43 | contentPadding: EdgeInsets.symmetric(
44 | vertical: 4,
45 | horizontal: 8,
46 | ),
47 | ),
48 | ),
49 | ),
50 | Row(
51 | mainAxisAlignment: MainAxisAlignment.end,
52 | children: [
53 | TextButton(
54 | onPressed: () {
55 | Get.back();
56 | },
57 | child: Text('取消'),
58 | ),
59 | TextButton(
60 | onPressed: () {
61 | settingInfo.repository = controller.text;
62 | showToast('目前改了没用,如果你有自己编译的可以使用的源,请联系我');
63 | saveToLocal();
64 | Get.back();
65 | },
66 | child: Text('确定'),
67 | ),
68 | ],
69 | ),
70 | ],
71 | ),
72 | ),
73 | );
74 | }
75 |
76 | void changeBufferLine() {
77 | TextEditingController controller = TextEditingController(
78 | text: settingInfo.bufferLine.toString(),
79 | );
80 | showCustomDialog(
81 | context: Get.context,
82 | child: FullHeightListView(
83 | child: Column(
84 | crossAxisAlignment: CrossAxisAlignment.center,
85 | children: [
86 | Text('更改缓冲行'),
87 | ClipRRect(
88 | borderRadius: BorderRadius.circular(8),
89 | child: TextField(
90 | style: const TextStyle(
91 | fontWeight: FontWeight.bold,
92 | ),
93 | controller: controller,
94 | decoration: InputDecoration(
95 | border: InputBorder.none,
96 | fillColor: const Color(0xfff0f0f0),
97 | filled: true,
98 | contentPadding: EdgeInsets.symmetric(
99 | vertical: 4,
100 | horizontal: 8,
101 | ),
102 | ),
103 | ),
104 | ),
105 | Row(
106 | mainAxisAlignment: MainAxisAlignment.end,
107 | children: [
108 | TextButton(
109 | onPressed: () {
110 | Get.back();
111 | },
112 | child: Text('取消'),
113 | ),
114 | TextButton(
115 | onPressed: () {
116 | settingInfo.bufferLine = int.tryParse(controller.text);
117 | showToast('目前改了没用');
118 | saveToLocal();
119 | Get.back();
120 | },
121 | child: Text('确定'),
122 | ),
123 | ],
124 | ),
125 | ],
126 | ),
127 | ),
128 | );
129 | }
130 |
131 | void changeCmdLine() {
132 | TextEditingController controller = TextEditingController(
133 | text: settingInfo.cmdLine.toString(),
134 | );
135 | showCustomDialog(
136 | context: Get.context,
137 | child: FullHeightListView(
138 | child: Column(
139 | crossAxisAlignment: CrossAxisAlignment.center,
140 | children: [
141 | Text('更改命令行'),
142 | ClipRRect(
143 | borderRadius: BorderRadius.circular(8),
144 | child: TextField(
145 | style: const TextStyle(
146 | fontWeight: FontWeight.bold,
147 | ),
148 | controller: controller,
149 | decoration: InputDecoration(
150 | border: InputBorder.none,
151 | fillColor: const Color(0xfff0f0f0),
152 | filled: true,
153 | contentPadding: EdgeInsets.symmetric(
154 | vertical: 4,
155 | horizontal: 8,
156 | ),
157 | ),
158 | ),
159 | ),
160 | Row(
161 | mainAxisAlignment: MainAxisAlignment.end,
162 | children: [
163 | TextButton(
164 | onPressed: () {
165 | Get.back();
166 | },
167 | child: Text('取消'),
168 | ),
169 | TextButton(
170 | onPressed: () {
171 | settingInfo.cmdLine = controller.text;
172 | saveToLocal();
173 | showToast('更改成功');
174 | Get.back();
175 | },
176 | child: Text('确定'),
177 | ),
178 | ],
179 | ),
180 | ],
181 | ),
182 | ),
183 | );
184 | }
185 |
186 | void changeInitCmd() {
187 | TextEditingController controller = TextEditingController(
188 | text: settingInfo.initCmd.toString(),
189 | );
190 | showCustomDialog(
191 | context: Get.context,
192 | child: FullHeightListView(
193 | child: Column(
194 | crossAxisAlignment: CrossAxisAlignment.center,
195 | children: [
196 | Text('更改初始命令'),
197 | SizedBox(
198 | height: 8,
199 | ),
200 | ClipRRect(
201 | borderRadius: BorderRadius.circular(8),
202 | child: TextField(
203 | style: const TextStyle(
204 | fontWeight: FontWeight.bold,
205 | ),
206 | controller: controller,
207 | decoration: InputDecoration(
208 | isDense: true,
209 | border: InputBorder.none,
210 | fillColor: const Color(0xfff0f0f0),
211 | filled: true,
212 | contentPadding: EdgeInsets.symmetric(
213 | vertical: 8,
214 | horizontal: 8,
215 | ),
216 | ),
217 | ),
218 | ),
219 | Row(
220 | mainAxisAlignment: MainAxisAlignment.end,
221 | children: [
222 | TextButton(
223 | onPressed: () {
224 | Get.back();
225 | },
226 | child: Text('取消'),
227 | ),
228 | TextButton(
229 | onPressed: () {
230 | settingInfo.initCmd = controller.text;
231 | saveToLocal();
232 | showToast('更改成功');
233 | Get.back();
234 | },
235 | child: Text('确定'),
236 | ),
237 | ],
238 | ),
239 | ],
240 | ),
241 | ),
242 | );
243 | }
244 |
245 | Future changeFontFamily(TermareController controller) async {
246 | await showCustomDialog(
247 | context: Get.context,
248 | child: FullHeightListView(
249 | child: Column(
250 | crossAxisAlignment: CrossAxisAlignment.center,
251 | children: [
252 | Text('更改字体样式'),
253 | SizedBox(
254 | height: 8,
255 | ),
256 | Wrap(
257 | spacing: 8.0,
258 | children: [
259 | TextButton(
260 | onPressed: () {
261 | Get.back();
262 | settingInfo.fontFamily = 'DroidSansMono';
263 | },
264 | child: Text('DroidSansMono'),
265 | ),
266 | TextButton(
267 | onPressed: () {
268 | settingInfo.fontFamily = 'MenloforPowerline';
269 | Get.back();
270 | },
271 | child: Text('MenloforPowerline'),
272 | ),
273 | TextButton(
274 | onPressed: () {
275 | settingInfo.fontFamily = 'SourceCodePro';
276 | Get.back();
277 | },
278 | child: Text('SourceCodePro'),
279 | ),
280 | TextButton(
281 | onPressed: () {
282 | settingInfo.fontFamily = 'SourceCodeProMediumforPowerline';
283 | Get.back();
284 | },
285 | child: Text('SourceCodeProMediumforPowerline'),
286 | ),
287 | TextButton(
288 | onPressed: () {
289 | settingInfo.fontFamily = 'MesloLGMforPowerline';
290 | saveToLocal();
291 | Get.back();
292 | },
293 | child: Text('MesloLGMforPowerline'),
294 | ),
295 | ],
296 | ),
297 | ],
298 | ),
299 | ),
300 | );
301 | final TerminalController terminalController =
302 | Get.find();
303 | for (final PtyTermEntity entity in terminalController.terms) {
304 | entity.controller.setFontfamily(settingInfo.fontFamily);
305 | }
306 | controller.setFontfamily(settingInfo.fontFamily);
307 | update();
308 | saveToLocal();
309 | showToast('更改成功');
310 | }
311 |
312 | void onTextStyleChange(String value) {
313 | settingInfo.termStyle = value;
314 | saveToLocal();
315 | update();
316 |
317 | final TerminalController terminalController = Get.find();
318 | for (final PtyTermEntity entity in terminalController.terms) {
319 | entity.controller.changeStyle(
320 | TermareStyle.parse(settingInfo.termStyle).copyWith(
321 | fontSize: settingInfo.fontSize.toDouble(),
322 | ),
323 | );
324 | }
325 |
326 | showToast('更改成功');
327 | }
328 |
329 | void readLocalStorage() {
330 | if (!Directory(RuntimeEnvir.homePath).existsSync()) {
331 | Directory(RuntimeEnvir.homePath).create(recursive: true);
332 | }
333 | print('filePath -> $filePath');
334 | File file = File(filePath);
335 | if (file.existsSync()) {
336 | Map json =
337 | jsonDecode(file.readAsStringSync()) as Map;
338 | settingInfo = SettingInfo.fromJson(json);
339 | } else {
340 | settingInfo = SettingInfo.fromJson(
341 | {
342 | "bufferLine": 1000,
343 | "enableUtf8": true,
344 | "bellWhenEscapeA": false,
345 | "vibrationWhenEscapeA": true,
346 | "repository": "http://nightmare.fun/termare/",
347 | "cmdLine": "login",
348 | "initCmd": "",
349 | "termType": "xterm-256color",
350 | "fontSize": 11,
351 | "fontFamily": "MenloforPowerline",
352 | "termStyle": "vsCode"
353 | },
354 | );
355 | }
356 | }
357 |
358 | void changeInfo(SettingInfo settingInfo) {
359 | this.settingInfo = settingInfo;
360 | update();
361 | }
362 |
363 | void saveToLocal() {
364 | final File file = File(filePath);
365 | file.writeAsString(settingInfo.toString());
366 | }
367 |
368 | @override
369 | void onReady() {
370 | super.onReady();
371 | }
372 |
373 | @override
374 | void onClose() {}
375 | }
376 |
--------------------------------------------------------------------------------
/lib/app/modules/setting/models/models.json:
--------------------------------------------------------------------------------
1 | {
2 | "bufferLine": 1000,
3 | "enableUtf8": true,
4 | "bellWhenEscapeA": false,
5 | "vibrationWhenEscapeA": true,
6 | "repository": "http://nightmare.fun/termare/",
7 | "cmdLine": "login",
8 | "initCmd": "",
9 | "termType": "xterm-256color",
10 | "fontSize": 11,
11 | "fontFamily": "MenloforPowerline",
12 | "termStyle": "vsCode"
13 | }
--------------------------------------------------------------------------------
/lib/app/modules/setting/models_model.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert' show json;
2 |
3 | T asT(dynamic value) {
4 | if (value is T) {
5 | return value;
6 | }
7 |
8 | return null;
9 | }
10 |
11 | class SettingInfo {
12 | SettingInfo({
13 | this.bufferLine,
14 | this.enableUtf8,
15 | this.bellWhenEscapeA,
16 | this.vibrationWhenEscapeA,
17 | this.repository,
18 | this.cmdLine,
19 | this.initCmd,
20 | this.termType,
21 | this.fontSize,
22 | this.fontFamily,
23 | this.termStyle,
24 | });
25 |
26 | factory SettingInfo.fromJson(Map jsonRes) => jsonRes == null
27 | ? null
28 | : SettingInfo(
29 | bufferLine: asT(jsonRes['bufferLine']),
30 | enableUtf8: asT(jsonRes['enableUtf8']),
31 | bellWhenEscapeA: asT(jsonRes['bellWhenEscapeA']),
32 | vibrationWhenEscapeA: asT(jsonRes['vibrationWhenEscapeA']),
33 | repository: asT(jsonRes['repository']),
34 | cmdLine: asT(jsonRes['cmdLine']),
35 | initCmd: asT(jsonRes['initCmd']),
36 | termType: asT(jsonRes['termType']),
37 | fontSize: asT(jsonRes['fontSize']),
38 | fontFamily: asT(jsonRes['fontFamily']),
39 | termStyle: asT(jsonRes['termStyle']),
40 | );
41 |
42 | int bufferLine;
43 | bool enableUtf8;
44 | bool bellWhenEscapeA;
45 | bool vibrationWhenEscapeA;
46 | String repository;
47 | String cmdLine;
48 | String initCmd;
49 | String termType;
50 | int fontSize;
51 | String fontFamily;
52 | String termStyle;
53 |
54 | Map toJson() => {
55 | 'bufferLine': bufferLine,
56 | 'enableUtf8': enableUtf8,
57 | 'bellWhenEscapeA': bellWhenEscapeA,
58 | 'vibrationWhenEscapeA': vibrationWhenEscapeA,
59 | 'repository': repository,
60 | 'cmdLine': cmdLine,
61 | 'initCmd': initCmd,
62 | 'termType': termType,
63 | 'fontSize': fontSize,
64 | 'fontFamily': fontFamily,
65 | 'termStyle': termStyle,
66 | };
67 | @override
68 | String toString() {
69 | return json.encode(this);
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/lib/app/modules/setting/utils/term_utils.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | import 'package:dart_pty/dart_pty.dart';
4 | import 'package:flutter/material.dart';
5 | import 'package:flutter/services.dart';
6 | import 'package:global_repository/global_repository.dart';
7 | import 'package:path/path.dart' as p;
8 | import 'package:termare_pty/termare_pty.dart';
9 | import 'package:termare_view/termare_view.dart';
10 |
11 | String termLockFilePath = '${RuntimeEnvir.usrPath}/tmp/termare_pop_lock';
12 |
13 | extension DefineFunc on PseudoTerminal {
14 | Future defineTermFunc({
15 | @required String func,
16 | String tmpFilePath,
17 | }) async {
18 | tmpFilePath ??=
19 | RuntimeEnvir.dataPath + '${Platform.pathSeparator}defineTermFunc';
20 | Log.d('定义函数中...--->$tmpFilePath');
21 |
22 | final File tmpFile = File(tmpFilePath);
23 | await tmpFile.writeAsString(func);
24 | Log.d('创建临时脚本成功...->${tmpFile.path}');
25 | 'export AUTO=TRUE\n'.split('').forEach(
26 | (String element) {
27 | write(element);
28 | },
29 | );
30 | Log.d('script -> source $tmpFilePath');
31 | Log.d('rm -rf $tmpFilePath');
32 | 'source $tmpFilePath\n'.split('').forEach(
33 | (String element) {
34 | write(element);
35 | },
36 | );
37 |
38 | 'rm -rf $tmpFilePath\n'.split('').forEach(
39 | (String element) {
40 | write(element);
41 | },
42 | );
43 | while (true) {
44 | final bool exist = await tmpFile.exists();
45 | // 把不想被看到的代码读掉
46 | await read();
47 | // Log.d('read()------------------->$tmp');
48 | if (!exist) {
49 | break;
50 | }
51 | await Future.delayed(const Duration(milliseconds: 100));
52 | }
53 | Log.d('创建临时脚本结束');
54 | }
55 | }
56 |
57 | class TermUtils {
58 | static Future openTerm2({
59 | @required BuildContext context,
60 | @required TermareController controller,
61 | @required String exec,
62 | @required PseudoTerminal pseudoTerminal,
63 | }) async {
64 | pseudoTerminal.write('$exec\n');
65 | await Navigator.of(context).push(
66 | MaterialPageRoute(
67 | builder: (_) {
68 | return WillPopScope(
69 | child: AnnotatedRegion(
70 | value: SystemUiOverlayStyle.light,
71 | child: Material(
72 | color: controller.theme.backgroundColor,
73 | child: SafeArea(
74 | child: TermarePty(
75 | controller: controller,
76 | pseudoTerminal: pseudoTerminal,
77 | ),
78 | ),
79 | ),
80 | ),
81 | onWillPop: () async {
82 | final bool isLock = File(termLockFilePath).existsSync();
83 | if (isLock) {
84 | showToast('请等待返回键释放');
85 | }
86 | Log.d(isLock);
87 | return !isLock;
88 | },
89 | );
90 | },
91 | ),
92 | );
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/lib/app/modules/setting/views/powerlevel10k_addr.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class PowerLevelAddr extends StatefulWidget {
4 | @override
5 | _PowerLevelAddrState createState() => _PowerLevelAddrState();
6 | }
7 |
8 | class _PowerLevelAddrState extends State {
9 | @override
10 | Widget build(BuildContext context) {
11 | return Column(
12 | children: [
13 | Text('选择地址'),
14 | Row(
15 | children: [
16 | TextButton(
17 | onPressed: () {
18 | Navigator.pop(
19 | context,
20 | 'https://github.com/romkatv/powerlevel10k',
21 | );
22 | },
23 | child: Text('Github'),
24 | ),
25 | TextButton(
26 | onPressed: () {
27 | Navigator.pop(
28 | context,
29 | 'https://gitee.com/romkatv/powerlevel10k.git',
30 | );
31 | },
32 | child: Text('Gitee'),
33 | ),
34 | ],
35 | ),
36 | ],
37 | );
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/lib/app/modules/setting/views/zsh_select_addr.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class SelectAddr extends StatefulWidget {
4 | @override
5 | _SelectAddrState createState() => _SelectAddrState();
6 | }
7 |
8 | class _SelectAddrState extends State {
9 | @override
10 | Widget build(BuildContext context) {
11 | return Column(
12 | children: [
13 | Text('选择地址'),
14 | Row(
15 | children: [
16 | TextButton(
17 | onPressed: () {
18 | Navigator.pop(
19 | context,
20 | 'https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh',
21 | );
22 | },
23 | child: Text('Github'),
24 | ),
25 | TextButton(
26 | onPressed: () {
27 | Navigator.pop(
28 | context,
29 | 'https://gitee.com/mirrors/oh-my-zsh/raw/master/tools/install.sh',
30 | );
31 | },
32 | child: Text('Gitee'),
33 | ),
34 | ],
35 | ),
36 | ],
37 | );
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/lib/app/modules/terminal/bindings/terminal_binding.dart:
--------------------------------------------------------------------------------
1 | import 'package:get/get.dart';
2 | import 'package:termare_app/app/modules/setting/controllers/setting_controller.dart';
3 |
4 | import '../controllers/terminal_controller.dart';
5 |
6 | class TerminalBinding extends Bindings {
7 | @override
8 | void dependencies() {
9 | Get.put(SettingController());
10 | Get.lazyPut(
11 | () => TerminalController(),
12 | );
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/lib/app/modules/terminal/controllers/terminal_controller.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 | import 'dart:ui';
3 | import 'package:flutter/material.dart';
4 | import 'package:get/get.dart';
5 | import 'package:global_repository/global_repository.dart';
6 | import 'package:pseudo_terminal_utils/pseudo_terminal_utils.dart';
7 | import 'package:pty/pty.dart';
8 | // import 'package:just_audio/just_audio.dart';
9 | import 'package:termare_app/app/modules/setting/controllers/setting_controller.dart';
10 | import 'package:termare_app/app/modules/setting/models_model.dart';
11 | import 'package:termare_app/app/modules/terminal/views/download_bootstrap_page.dart';
12 | import 'package:termare_app/app/modules/terminal/views/terminal_pages.dart';
13 | import 'package:termare_app/app/modules/terminal/views/xterm_wrapper.dart';
14 | import 'package:termare_app/app/widgets/termare_view_with_bar.dart';
15 | import 'package:termare_app/config/config.dart';
16 | import 'package:xterm/xterm.dart';
17 |
18 | String lockFile = RuntimeEnvir.dataPath + '/cache/init_lock';
19 |
20 | String initShell = '''
21 | function initApp(){
22 | cd ${RuntimeEnvir.usrPath}/
23 | echo 准备符号链接...
24 | for line in `cat SYMLINKS.txt`
25 | do
26 | OLD_IFS="\$IFS"
27 | IFS="←"
28 | arr=(\$line)
29 | IFS="\$OLD_IFS"
30 | ln -s \${arr[0]} \${arr[3]}
31 | done
32 | rm -rf SYMLINKS.txt
33 | TMPDIR=/data/data/com.nightmare.termare/files/usr/tmp
34 | filename=bootstrap
35 | rm -rf "\$TMPDIR/\$filename*"
36 | rm -rf "\$TMPDIR/*"
37 | chmod -R 0777 ${RuntimeEnvir.binPath}/*
38 | chmod -R 0777 ${RuntimeEnvir.usrPath}/lib/* 2>/dev/null
39 | chmod -R 0777 ${RuntimeEnvir.usrPath}/libexec/* 2>/dev/null
40 | echo "\x1b[0;31m- 执行 apt update\x1b[0m"
41 | apt update
42 | echo -e "\x1b[0;32m一切处理结束\x1b[0m"
43 | rm -rf $lockFile
44 | bash
45 | }
46 | ''';
47 |
48 | class TerminalController extends GetxController {
49 | TerminalController() {
50 | envir = Map.from(Platform.environment);
51 | envir['HOME'] = RuntimeEnvir.homePath;
52 | envir['TERMUX_PREFIX'] = RuntimeEnvir.usrPath;
53 |
54 | envir['TERM'] = 'xterm-256color';
55 | envir['PATH'] = RuntimeEnvir.path;
56 | if (File('${RuntimeEnvir.usrPath}/lib/libtermux-exec.so').existsSync()) {
57 | envir['LD_PRELOAD'] = '${RuntimeEnvir.usrPath}/lib/libtermux-exec.so';
58 | }
59 | }
60 | List terms = [];
61 | int currentTerminal = 0;
62 | // final player = AudioPlayer();
63 | Map envir;
64 | SettingController settingController = Get.find();
65 | bool hasBash() {
66 | final File bashFile = File(RuntimeEnvir.binPath + '/bash');
67 | final bool exist = bashFile.existsSync();
68 | return exist;
69 | }
70 |
71 | Future createPtyTerm() async {
72 | // final duration = await player.setAsset(
73 | // Assets.ogg,
74 | // );
75 | final SettingInfo settingInfo = settingController.settingInfo;
76 | final TermareController controller = TermareController(
77 | fontFamily: Config.flutterPackage + settingInfo.fontFamily,
78 | terminalTitle: 'localhost',
79 | theme: TermareStyle.parse(settingInfo.termStyle).copyWith(
80 | fontSize: settingInfo.fontSize.toDouble(),
81 | ),
82 | );
83 | if (Platform.isAndroid) {
84 | if (!hasBash()) {
85 | // 初始化后 bash 应该存在
86 | initTerminal(controller);
87 | return;
88 | }
89 | }
90 | final Size size = window.physicalSize;
91 | final double screenWidth = size.width / window.devicePixelRatio;
92 | final double screenHeight = size.height / window.devicePixelRatio;
93 | controller.setWindowSize(Size(screenWidth, screenHeight));
94 | Log.i('${RuntimeEnvir.binPath + '/' + 'bash'}');
95 | envir = Map.from(Platform.environment);
96 | envir.addAll({
97 | 'TERM': 'xterm-256color',
98 | 'PATH': '${RuntimeEnvir.binPath}:' + Platform.environment['PATH'],
99 | 'HOME': RuntimeEnvir.homePath,
100 | });
101 | envir['TERMUX_PREFIX'] = RuntimeEnvir.usrPath;
102 | if (File('${RuntimeEnvir.usrPath}/lib/libtermux-exec.so').existsSync()) {
103 | envir['LD_PRELOAD'] = '${RuntimeEnvir.usrPath}/lib/libtermux-exec.so';
104 | }
105 | final PseudoTerminal pseudoTerminal = PseudoTerminal.start(
106 | GetPlatform.isMacOS ? '/bin/zsh' : (RuntimeEnvir.binPath + '/' + 'bash'),
107 | ['-l'],
108 | blocking: false,
109 | workingDirectory: RuntimeEnvir.homePath,
110 | environment: envir,
111 | )..init();
112 | Future.delayed(const Duration(milliseconds: 100), () {
113 | if (settingInfo.initCmd.isNotEmpty) {
114 | pseudoTerminal.write(settingInfo.initCmd + '\n');
115 | }
116 | });
117 | if (settingInfo.vibrationWhenEscapeA) {
118 | controller.onBell = () async {
119 | Feedback.forLongPress(Get.context);
120 | // player.play();
121 | };
122 | }
123 | terms.add(
124 | PtyTermEntity(
125 | controller,
126 | pseudoTerminal,
127 | Terminal(),
128 | ),
129 | );
130 | update();
131 | }
132 |
133 | List getPtyTermsForCheck() {
134 | final List widgets = [];
135 | final List terms = this.terms;
136 | for (int i = 0; i < terms.length; i++) {
137 | final PtyTermEntity entity = terms[i];
138 | widgets.add(Hero(
139 | tag: '$i',
140 | child: XTermWrapper(
141 | pseudoTerminal: entity.pseudoTerminal,
142 | terminal: entity.terminal,
143 | ),
144 | ));
145 | }
146 | return widgets;
147 | }
148 |
149 | Future initTerminal(TermareController controller) async {
150 | // 这个 await 为了不弹太快
151 | await Future.delayed(const Duration(milliseconds: 300));
152 | await Get.dialog(DownloadBootPage());
153 | final PseudoTerminal pseudoTerminal = PseudoTerminal.start(
154 | '/system/bin/sh',
155 | [],
156 | blocking: false,
157 | environment: envir,
158 | )..init();
159 | // pseudoTerminal.startPolling();
160 | // await pseudoTerminal.defineTermFunc(
161 | // initShell,
162 | // tmpFilePath: RuntimeEnvir.filesPath + '/define',
163 | // );
164 | pseudoTerminal.write(initShell);
165 | Log.i('初始化成功');
166 | pseudoTerminal.write('initApp\n');
167 | terms.add(
168 | PtyTermEntity(
169 | controller,
170 | pseudoTerminal,
171 | Terminal(),
172 | ),
173 | );
174 | update();
175 | }
176 |
177 | void switchTo(int value) {
178 | currentTerminal = value;
179 | update();
180 | }
181 |
182 | Widget getCurTerm() {
183 | if (terms.isEmpty) {
184 | return const SizedBox();
185 | }
186 | final PtyTermEntity entity = terms[currentTerminal];
187 | return Hero(
188 | tag: '$currentTerminal',
189 | child: TermareViewWithBottomBar(
190 | pseudoTerminal: entity.pseudoTerminal,
191 | terminal: entity.terminal,
192 | termview: XTermWrapper(
193 | pseudoTerminal: entity.pseudoTerminal,
194 | terminal: entity.terminal,
195 | ),
196 | ),
197 | );
198 | }
199 |
200 | List getPtyTerms() {
201 | final List widgets = [];
202 | final List terms = this.terms;
203 | for (int i = 0; i < terms.length; i++) {
204 | final PtyTermEntity entity = terms[i];
205 | widgets.add(
206 | Hero(
207 | tag: '$i',
208 | child: TermareViewWithBottomBar(
209 | pseudoTerminal: entity.pseudoTerminal,
210 | termview: XTermWrapper(
211 | pseudoTerminal: entity.pseudoTerminal,
212 | terminal: entity.terminal,
213 | ),
214 | ),
215 | ),
216 | );
217 | }
218 | return widgets;
219 | }
220 |
221 | @override
222 | void onInit() {
223 | super.onInit();
224 | }
225 |
226 | @override
227 | void onReady() {
228 | super.onReady();
229 | }
230 |
231 | @override
232 | void onClose() {}
233 | }
234 |
--------------------------------------------------------------------------------
/lib/app/modules/terminal/views/download_bootstrap_page.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | import 'package:archive/archive.dart';
4 | import 'package:dio/dio.dart';
5 | import 'package:flutter/material.dart';
6 | import 'package:global_repository/global_repository.dart';
7 | import 'package:path/path.dart' as p;
8 |
9 | class DownloadBootPage extends StatefulWidget {
10 | @override
11 | _DownloadBootPageState createState() => _DownloadBootPageState();
12 | }
13 |
14 | class _DownloadBootPageState extends State {
15 | @override
16 | Widget build(BuildContext context) {
17 | return Material(
18 | child: Center(child: _DownloadFile()),
19 | );
20 | }
21 | }
22 |
23 | class _DownloadFile extends StatefulWidget {
24 | const _DownloadFile({Key key, this.callback}) : super(key: key);
25 | final void Function() callback;
26 | @override
27 | _DownloadFileState createState() => _DownloadFileState();
28 | }
29 |
30 | class _DownloadFileState extends State<_DownloadFile> {
31 | final Dio dio = Dio();
32 | Response response;
33 | final String filesPath = RuntimeEnvir.usrPath;
34 | List androidAdbFiles = [
35 | 'https://nightmare-my.oss-cn-beijing.aliyuncs.com/Termare/bootstrap-aarch64.zip',
36 | ];
37 | String cur;
38 | double fileDownratio = 0.0;
39 | String title = '';
40 | Future downloadFile(String urlPath) async {
41 | print(urlPath);
42 | response = await dio.head(urlPath);
43 | final int fullByte = int.tryParse(
44 | response.headers.value('content-length').toString(),
45 | ); //得到服务器文件返回的字节大小
46 | // final String _human = getFileSize(_fullByte); //拿到可读的文件大小返回给用户
47 | print('fullByte======$fullByte ${p.basename(urlPath)}');
48 | final String savePath = filesPath + '/' + p.basename(urlPath);
49 | // print(savePath);
50 | await dio.download(
51 | urlPath,
52 | savePath,
53 | onReceiveProgress: (count, total) {
54 | final double process = count / total;
55 | fileDownratio = process;
56 | setState(() {});
57 | // );
58 | },
59 | );
60 | final ProcessResult result = Process.runSync(
61 | 'chmod',
62 | [
63 | '0777',
64 | savePath,
65 | ],
66 | environment: RuntimeEnvir.envir(),
67 | );
68 | Log.e(result.stderr);
69 | Log.d(result.stdout);
70 | await installModule(savePath);
71 | }
72 |
73 | Future installModule(String modulePath) async {
74 | title = '解压中...';
75 | setState(() {});
76 | // Read the Zip file from disk.
77 | final bytes = File(modulePath).readAsBytesSync();
78 | // Decode the Zip file
79 | final archive = ZipDecoder().decodeBytes(bytes);
80 | // Extract the contents of the Zip archive to disk.
81 | final int total = archive.length;
82 | int count = 0;
83 | // print('total -> $total count -> $count');
84 | for (final file in archive) {
85 | final filename = file.name;
86 | final String path = '${RuntimeEnvir.usrPath}/$filename';
87 | cur = path;
88 | print(path);
89 | if (file.isFile) {
90 | final data = file.content as List;
91 | await File(path).create(recursive: true);
92 | await File(path).writeAsBytes(data);
93 | } else {
94 | Directory(path).create(
95 | recursive: true,
96 | );
97 | }
98 | count++;
99 | fileDownratio = count / total;
100 | print('total -> $total count -> $count');
101 | setState(() {});
102 | }
103 | File(modulePath).delete();
104 | title = '配置中...';
105 | fileDownratio = null;
106 | setState(() {});
107 | }
108 |
109 | @override
110 | void initState() {
111 | super.initState();
112 | execDownload();
113 | }
114 |
115 | Future execDownload() async {
116 | List needDownloadFile;
117 | if (Platform.isAndroid) {
118 | needDownloadFile = androidAdbFiles;
119 | }
120 | for (final String urlPath in needDownloadFile) {
121 | title = '下载 ${p.basename(urlPath)} 中...';
122 | setState(() {});
123 | await downloadFile(urlPath);
124 | }
125 | Navigator.pop(context);
126 | }
127 |
128 | @override
129 | Widget build(BuildContext context) {
130 | return WillPopScope(
131 | child: Padding(
132 | padding: const EdgeInsets.all(8.0),
133 | child: Column(
134 | mainAxisSize: MainAxisSize.min,
135 | children: [
136 | Text(
137 | title,
138 | style: const TextStyle(
139 | fontSize: 18,
140 | fontWeight: FontWeight.bold,
141 | ),
142 | ),
143 | const Align(
144 | alignment: Alignment.centerLeft,
145 | child: Text(
146 | '进度',
147 | style: TextStyle(
148 | fontWeight: FontWeight.bold,
149 | ),
150 | ),
151 | ),
152 | const SizedBox(
153 | height: 12,
154 | ),
155 | ClipRRect(
156 | borderRadius: const BorderRadius.all(Radius.circular(25.0)),
157 | child: LinearProgressIndicator(
158 | value: fileDownratio,
159 | ),
160 | ),
161 | SizedBox(height: 4),
162 | if (cur != null)
163 | SizedBox(
164 | child: Text(
165 | '当前处理文件 $cur',
166 | style: const TextStyle(
167 | fontWeight: FontWeight.w500,
168 | fontSize: 12,
169 | ),
170 | ),
171 | ),
172 | ],
173 | ),
174 | ),
175 | onWillPop: () async {
176 | showToast('等待下载完成后');
177 | return false;
178 | },
179 | );
180 | }
181 | }
182 |
--------------------------------------------------------------------------------
/lib/app/modules/terminal/views/quark_window_check.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter/services.dart';
4 |
5 | class QuarkWindowCheck extends StatefulWidget {
6 | const QuarkWindowCheck({
7 | Key key,
8 | @required this.children,
9 | this.page,
10 | this.onSelect,
11 | }) : super(key: key);
12 | final List children;
13 | final int page;
14 | final void Function(int value) onSelect;
15 | @override
16 | _QuarkWindowCheckState createState() => _QuarkWindowCheckState();
17 | }
18 |
19 | class _QuarkWindowCheckState extends State
20 | with TickerProviderStateMixin {
21 | AnimationController animationController;
22 | // 一个换粗你的 offset
23 | double tempOffset = 0.0;
24 | // 窗口的其起始位置
25 | int _position = 0;
26 | // 窗口范围
27 | final int _capacity = 5;
28 |
29 | List _children;
30 | double rotatedAngle = 0;
31 | List offsetList = [
32 | 160, //
33 | 360, // 160+200
34 | 600, //360+240
35 | 880, //600+280
36 | 1200, //880+320
37 | ];
38 | void scroll(double dy) {
39 | if (rotatedAngle < 0) {
40 | rotatedAngle += dy / 180;
41 | rotatedAngle = min(0, rotatedAngle);
42 | rotatedAngle = max(-2 * pi, rotatedAngle);
43 | return;
44 | }
45 | // Log.d(dy);
46 | if (offsetList[1] > 160) {
47 | offsetList[0] += dy * 160 / 160;
48 | offsetList[0] = max(offsetList[0], 0);
49 | if (offsetList[0] > 160) {
50 | offsetList[0] = 160;
51 | return;
52 | }
53 | }
54 | offsetList[1] += dy * 200 / 160;
55 | offsetList[1] = max(offsetList[1], 0);
56 | offsetList[2] += dy * 240 / 160;
57 | offsetList[2] = max(offsetList[2], 0);
58 | offsetList[3] += dy * 280 / 160;
59 | offsetList[3] = max(offsetList[3], 0);
60 | offsetList[4] += dy * 320 / 160;
61 | offsetList[4] = max(offsetList[4], 0);
62 | if (offsetList[1] == 0) {
63 | if (_position + 1 >= _children.length) {
64 | rotatedAngle += dy / 180;
65 | // print('rotatedAngle->$rotatedAngle');
66 | return;
67 | }
68 | _position += 1;
69 | offsetList.removeAt(0);
70 | offsetList.add(offsetList.last + 280);
71 | }
72 | if (offsetList[0] != 0 && _position != 0) {
73 | _position -= 1;
74 | offsetList.removeLast();
75 | offsetList.insert(0, 0);
76 | }
77 | }
78 |
79 | List generateWidget() {
80 | final List tmp = [];
81 | final int start = _position;
82 | for (int i = start; i < min(_children.length, _position + _capacity); i++) {
83 | final double offset = offsetList[i - _position];
84 | tmp.add(
85 | Padding(
86 | padding: EdgeInsets.only(top: offset),
87 | child: Center(
88 | child: Transform(
89 | alignment: Alignment.center,
90 | transform: Matrix4.identity()
91 | ..setEntry(3, 2, 0.002)
92 | ..rotateX(rotatedAngle),
93 | child: NiCardButton(
94 | spreadRadius: 8,
95 | blurRadius: 8,
96 | shadowColor: Colors.black,
97 | borderRadius: 16,
98 | onTap: () {
99 | widget.onSelect(i);
100 | },
101 | child: Material(
102 | color: Colors.white,
103 | child: SingleChildScrollView(
104 | physics: const NeverScrollableScrollPhysics(),
105 | child: SizedBox(
106 | width: MediaQuery.of(context).size.width - 40,
107 | height: MediaQuery.of(context).size.height * 4 / 5,
108 | child: Column(
109 | mainAxisAlignment: MainAxisAlignment.center,
110 | crossAxisAlignment: CrossAxisAlignment.center,
111 | children: [
112 | SizedBox(
113 | height: 32.0,
114 | child: Padding(
115 | padding: EdgeInsets.symmetric(
116 | horizontal: 12,
117 | ),
118 | child: Row(
119 | mainAxisAlignment:
120 | MainAxisAlignment.spaceBetween,
121 | children: [
122 | Text('终端[$i]'),
123 | SizedBox(
124 | width: 30,
125 | height: 30,
126 | child: InkWell(
127 | borderRadius: BorderRadius.circular(16),
128 | child: const Icon(Icons.clear),
129 | onTap: () {},
130 | ),
131 | ),
132 | ],
133 | ),
134 | ),
135 | ),
136 | Expanded(
137 | child: AbsorbPointer(
138 | absorbing: true,
139 | child: _children[i],
140 | ),
141 | ),
142 | ],
143 | ),
144 | ),
145 | ),
146 | ),
147 | ),
148 | ),
149 | ),
150 | ),
151 | );
152 | }
153 | return tmp;
154 | }
155 |
156 | @override
157 | void initState() {
158 | super.initState();
159 | _children = widget.children;
160 | if (widget.page != null && widget.page > 2) {
161 | _position = max(widget.page - 2, 0);
162 | offsetList.removeLast();
163 | offsetList.insert(0, 0);
164 | }
165 | }
166 |
167 | @override
168 | void dispose() {
169 | super.dispose();
170 | }
171 |
172 | @override
173 | Widget build(BuildContext context) {
174 | return AnnotatedRegion(
175 | value: SystemUiOverlayStyle.dark,
176 | child: Scaffold(
177 | backgroundColor: Colors.white,
178 | body: GestureDetector(
179 | behavior: HitTestBehavior.translucent,
180 | onPanDown: (DragDownDetails details) {
181 | animationController?.stop();
182 | tempOffset = 0;
183 | },
184 | onVerticalDragStart: (DragStartDetails details) {
185 | tempOffset = 0;
186 | },
187 | onVerticalDragUpdate: (DragUpdateDetails details) {
188 | scroll(details.delta.dy);
189 |
190 | // Log.d('curOffset====>$curOffset');
191 | setState(() {});
192 | },
193 | onVerticalDragEnd: (DragEndDetails details) {
194 | final Tolerance tolerance = Tolerance(
195 | velocity: 1.0 /
196 | (0.050 *
197 | WidgetsBinding.instance.window
198 | .devicePixelRatio), // logical pixels per second
199 | distance: 1.0 /
200 | WidgetsBinding
201 | .instance.window.devicePixelRatio, // logical pixels
202 | );
203 | final double start = tempOffset;
204 | final ClampingScrollSimulation clampingScrollSimulation =
205 | ClampingScrollSimulation(
206 | position: start,
207 | velocity: -details.velocity.pixelsPerSecond.dy * 2 / 3,
208 | tolerance: tolerance,
209 | );
210 | animationController = AnimationController(
211 | vsync: this,
212 | value: 0,
213 | lowerBound: double.negativeInfinity,
214 | upperBound: double.infinity,
215 | );
216 | animationController.reset();
217 | animationController.addListener(() {
218 | final double offset = tempOffset - animationController.value;
219 | scroll(offset);
220 | tempOffset = animationController.value;
221 | setState(() {});
222 | });
223 | animationController.animateWith(clampingScrollSimulation);
224 | },
225 | child: Stack(
226 | alignment: Alignment.topCenter,
227 | children: [
228 | ...generateWidget(),
229 | // SafeArea(
230 | // child: Text(
231 | // '${offsetList} offset${curOffset} _position->$_position',
232 | // ),
233 | // ),
234 | ],
235 | ),
236 | ),
237 | ),
238 | );
239 | }
240 | }
241 |
242 | class NiCardButton extends StatefulWidget {
243 | const NiCardButton({
244 | Key key,
245 | this.child,
246 | this.onTap,
247 | this.blurRadius = 4.0,
248 | this.shadowColor = Colors.black,
249 | this.borderRadius = 8.0,
250 | this.color,
251 | this.spreadRadius = 0,
252 | this.margin = const EdgeInsets.all(8.0),
253 | }) : super(key: key);
254 | final Widget child;
255 | final Function onTap;
256 | final double blurRadius;
257 | final double borderRadius;
258 | final double spreadRadius;
259 | final Color shadowColor;
260 | final Color color;
261 | final EdgeInsetsGeometry margin;
262 | @override
263 | _NiCardButtonState createState() => _NiCardButtonState();
264 | }
265 |
266 | class _NiCardButtonState extends State
267 | with SingleTickerProviderStateMixin {
268 | AnimationController animationController;
269 | bool isOnTap = false;
270 | @override
271 | void initState() {
272 | super.initState();
273 | animationController = AnimationController(
274 | vsync: this,
275 | duration: const Duration(milliseconds: 100),
276 | );
277 | animationController.addListener(() {
278 | setState(() {});
279 | });
280 | }
281 |
282 | @override
283 | void dispose() {
284 | animationController.dispose();
285 | super.dispose();
286 | }
287 |
288 | @override
289 | Widget build(BuildContext context) {
290 | return GestureDetector(
291 | behavior: HitTestBehavior.translucent,
292 | // onLongPress: () {
293 | // // print('sada');
294 | // },
295 | onTap: () {
296 | if (widget.onTap == null) {
297 | return;
298 | }
299 | isOnTap = false;
300 | setState(() {});
301 | Feedback.forLongPress(context);
302 | animationController.reverse();
303 | if (widget.onTap != null) {
304 | widget.onTap();
305 | }
306 | },
307 | onTapDown: (_) {
308 | if (widget.onTap == null) {
309 | return;
310 | }
311 | animationController.forward();
312 | Feedback.forLongPress(context);
313 | isOnTap = true;
314 | setState(() {});
315 | },
316 | onTapCancel: () {
317 | if (widget.onTap == null) {
318 | return;
319 | }
320 | animationController.reverse();
321 | Feedback.forLongPress(context);
322 | isOnTap = false;
323 | setState(() {});
324 | },
325 | child: Transform(
326 | alignment: Alignment.center,
327 | transform: Matrix4.identity()
328 | ..scale(
329 | 1.0 - animationController.value * 0.05,
330 | ),
331 | child: Container(
332 | margin: widget.margin,
333 | decoration: BoxDecoration(
334 | color: widget.color ?? Theme.of(context).cardColor,
335 | borderRadius: BorderRadius.circular(widget.borderRadius),
336 | boxShadow: [
337 | BoxShadow(
338 | color: widget.shadowColor.withOpacity(
339 | 0.04 - animationController.value * 0.04,
340 | ),
341 | offset: const Offset(0.0, 0.0), //阴影xy轴偏移量
342 | blurRadius: widget.blurRadius, //阴影模糊程度
343 | spreadRadius: widget.spreadRadius, //阴影扩散程度
344 | ),
345 | ],
346 | ),
347 | child: ClipRRect(
348 | borderRadius: BorderRadius.circular(widget.borderRadius),
349 | child: widget.child,
350 | ),
351 | ),
352 | ),
353 | );
354 | }
355 | }
356 |
--------------------------------------------------------------------------------
/lib/app/modules/terminal/views/terminal_pages.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/physics.dart';
3 | import 'package:flutter/services.dart';
4 | import 'package:flutter_acrylic/flutter_acrylic.dart';
5 | import 'package:get/get.dart';
6 | import 'package:global_repository/global_repository.dart';
7 | import 'package:pty/pty.dart';
8 | import 'package:termare_app/app/modules/dashboard/views/dashboard.dart';
9 | import 'package:termare_app/app/modules/terminal/controllers/terminal_controller.dart';
10 | import 'package:termare_app/config/config.dart';
11 | import 'package:termare_view/termare_view.dart';
12 | import 'package:xterm/xterm.dart' hide TerminalController;
13 |
14 | import '../../setting/views/setting_page.dart';
15 |
16 | class PtyTermEntity {
17 | PtyTermEntity(
18 | this.controller,
19 | this.pseudoTerminal,
20 | this.terminal,
21 | );
22 | final TermareController controller;
23 | final PseudoTerminal pseudoTerminal;
24 | final Terminal terminal;
25 | @override
26 | bool operator ==(dynamic other) {
27 | // 判断是否是非
28 | if (other is! TermareController) {
29 | return false;
30 | }
31 | if (other is TermareController) {
32 | return other.hashCode == hashCode;
33 | }
34 | return false;
35 | }
36 |
37 | @override
38 | int get hashCode => pseudoTerminal.hashCode;
39 | }
40 |
41 | class TerminalPages extends StatefulWidget {
42 | TerminalPages({
43 | Key key,
44 | this.packageName,
45 | }) : super(key: key) {
46 | if (packageName != null) {
47 | // 改包可能是被其他项目集成的
48 | Config.packageName = packageName;
49 | Config.flutterPackage = 'packages/termare_app/';
50 | }
51 | if (Get.arguments != null) {
52 | Config.packageName = Get.arguments.toString();
53 | Config.flutterPackage = 'packages/termare_app/';
54 | }
55 | }
56 |
57 | final String packageName;
58 |
59 | @override
60 | _TerminalPagesState createState() => _TerminalPagesState();
61 | }
62 |
63 | class _TerminalPagesState extends State
64 | with TickerProviderStateMixin {
65 | TerminalController controller = Get.find();
66 | PageController pageController = PageController();
67 | AnimationController animationController;
68 | @override
69 | void initState() {
70 | super.initState();
71 | if (controller.terms.isEmpty) {
72 | controller.createPtyTerm().then((value) {
73 | setState(() {});
74 | });
75 | }
76 | Window.makeTitlebarTransparent();
77 | Window.enableFullSizeContentView();
78 | Window.setEffect(
79 | effect: WindowEffect.acrylic,
80 | dark: false,
81 | );
82 | }
83 |
84 | double offset = 0;
85 | double maxSize = 10000;
86 | double _getPixels(double page) {
87 | return page * Get.size.width;
88 | }
89 |
90 | double _getPage(double pixels) {
91 | return pixels / Get.size.width;
92 | }
93 |
94 | double _getTargetPixels(
95 | double pixels,
96 | Tolerance tolerance,
97 | double velocity,
98 | ) {
99 | double page = _getPage(pixels);
100 | Log.e('page -> $page');
101 | if (pixels < 0) {
102 | // return 0;
103 | }
104 | if (pixels >= maxSize) {
105 | return maxSize;
106 | }
107 | if (true) {
108 | if (velocity < -tolerance.velocity) {
109 | page -= 0.5;
110 | } else if (velocity > tolerance.velocity) {
111 | page += 0.5;
112 | }
113 | return _getPixels(page.roundToDouble());
114 | }
115 | return _getPixels(page.roundToDouble());
116 | }
117 |
118 | final Tolerance _kDefaultTolerance = Tolerance(
119 | // TODO(ianh): Handle the case of the device pixel ratio changing.
120 | // TODO(ianh): Get this from the local MediaQuery not dart:ui's window object.
121 | velocity: 1.0 /
122 | (0.050 *
123 | WidgetsBinding
124 | .instance.window.devicePixelRatio), // logical pixels per second
125 | distance:
126 | 1.0 / WidgetsBinding.instance.window.devicePixelRatio, // logical pixels
127 | );
128 |
129 | @override
130 | Widget build(BuildContext context) {
131 | return Material(
132 | color: Colors.transparent,
133 | child: SafeArea(
134 | child: Column(
135 | children: [
136 | Row(
137 | children: [
138 | SizedBox(
139 | width: 8.w,
140 | ),
141 | Container(
142 | decoration: BoxDecoration(
143 | color: Theme.of(context).primaryColor,
144 | borderRadius: BorderRadius.circular(8.w),
145 | ),
146 | padding: EdgeInsets.symmetric(
147 | horizontal: 6.w,
148 | vertical: 4.w,
149 | ),
150 | child: const Text(
151 | 'bash x',
152 | style: TextStyle(
153 | color: Colors.white,
154 | height: 1.0,
155 | ),
156 | ),
157 | ),
158 | ],
159 | ),
160 | Expanded(
161 | child: controller.getCurTerm(),
162 | ),
163 | ],
164 | ),
165 | ),
166 | );
167 | final Map map = {
168 | 1: Builder(builder: (context) {
169 | double _offset;
170 | if (offset >= 0) {
171 | if (offset < Get.size.width / 2) {
172 | _offset = offset;
173 | } else {
174 | _offset = Get.size.width - offset;
175 | }
176 | } else if (offset < 0) {
177 | if (offset.abs() < Get.size.width / 2) {
178 | _offset = offset;
179 | } else {
180 | // Log.d('offset $offset');
181 | _offset = -Get.size.width - offset;
182 | }
183 | }
184 | return GetBuilder(builder: (context) {
185 | return Transform(
186 | transform: Matrix4.identity()..translate(_offset),
187 | // ..scale(((Get.width - _offset.abs()) / Get.width) / 2 + 1 / 2),
188 | alignment: Alignment.center,
189 | child: AnnotatedRegion(
190 | value: SystemUiOverlayStyle.light,
191 | child: Opacity(
192 | opacity: 1.0 - 1.0 * _offset.abs() / Get.size.width,
193 | child: controller.getCurTerm(),
194 | ),
195 | ),
196 | );
197 | });
198 | }),
199 | };
200 | if (offset < 0) {
201 | map[0] = Builder(builder: (context) {
202 | double _offset;
203 | if (offset.abs() < Get.size.width / 2) {
204 | _offset = -offset;
205 | } else {
206 | _offset = offset + Get.size.width;
207 | }
208 | return Opacity(
209 | opacity: 1.0,
210 | child: Transform(
211 | transform: Matrix4.identity()..translate(_offset),
212 | // ..scale(0.8),
213 | alignment: Alignment.center,
214 | child: SettingPage(),
215 | ),
216 | );
217 | });
218 | if (offset.abs() > Get.size.width / 2) {
219 | final Widget tmp = map[1];
220 | map[1] = map[0];
221 | map[0] = tmp;
222 | }
223 | } else {
224 | map[0] = Builder(builder: (context) {
225 | double _offset;
226 | if (offset < Get.size.width / 2) {
227 | _offset = -offset;
228 | } else {
229 | _offset = offset - Get.size.width;
230 | }
231 | return Transform(
232 | transform: Matrix4.identity()..translate(_offset),
233 | // ..scale(((Get.width - _offset.abs()) / Get.width) / 2 + 1 / 2),
234 | alignment: Alignment.center,
235 | child: Opacity(
236 | // opacity: 1.0 - 1.0 * (_offset.abs() / Get.size.width),
237 | opacity: 1.0,
238 | child: DashBoard(
239 | onSelect: () {
240 | animationController = AnimationController(
241 | vsync: this,
242 | value: Get.width,
243 | lowerBound: 0,
244 | upperBound: Get.width,
245 | duration: Duration(milliseconds: 300),
246 | );
247 | animationController.reset();
248 | animationController.addListener(() {
249 | offset = animationController.value;
250 | // Log.d(offset);
251 | setState(() {});
252 | });
253 | animationController.value = Get.width;
254 | animationController.reverse();
255 | },
256 | ),
257 | ),
258 | );
259 | });
260 | // Log.d('offset $offset');
261 | // Log.d('Get.size.width / 2 ${Get.size.width / 2}');
262 | if (offset > Get.size.width / 2) {
263 | Widget tmp = map[1];
264 | map[1] = map[0];
265 | map[0] = tmp;
266 | }
267 | }
268 | return AnnotatedRegion(
269 | value: SystemUiOverlayStyle.light,
270 | child: GetBuilder(
271 | init: TerminalController(),
272 | builder: (_) {
273 | return GestureDetector(
274 | behavior: HitTestBehavior.translucent,
275 | onHorizontalDragStart: (details) {
276 | animationController?.stop();
277 | },
278 | onHorizontalDragUpdate: (details) {
279 | offset += details.delta.dx;
280 | // Log.e(offset);
281 | setState(() {});
282 | },
283 | onHorizontalDragEnd: (details) {
284 | double velocity = details.velocity.pixelsPerSecond.dx;
285 | double start = offset;
286 | double target = _getTargetPixels(
287 | start,
288 | _kDefaultTolerance,
289 | velocity,
290 | );
291 | final spring = SpringDescription.withDampingRatio(
292 | mass: 0.5,
293 | stiffness: 100.0,
294 | ratio: 1.1,
295 | );
296 | final ScrollSpringSimulation scrollSpringSimulation =
297 | ScrollSpringSimulation(
298 | spring,
299 | start,
300 | target,
301 | velocity,
302 | tolerance: _kDefaultTolerance,
303 | );
304 | animationController = AnimationController(
305 | vsync: this,
306 | value: 0,
307 | lowerBound: double.negativeInfinity,
308 | upperBound: double.infinity,
309 | );
310 | animationController.reset();
311 | animationController.addListener(() {
312 | offset = animationController.value;
313 | // Log.d(offset);
314 | setState(() {});
315 | });
316 | animationController.animateWith(scrollSpringSimulation);
317 | },
318 | child: Stack(
319 | alignment: Alignment.center,
320 | children: [
321 | map[0],
322 | map[1],
323 | ],
324 | ),
325 | );
326 | },
327 | ),
328 | );
329 | }
330 | }
331 |
--------------------------------------------------------------------------------
/lib/app/modules/terminal/views/terminal_title.dart:
--------------------------------------------------------------------------------
1 | // import 'package:flutter/material.dart';
2 | // import 'package:termare_view/termare_view.dart';
3 |
4 | // class TerminalTitle extends StatefulWidget {
5 | // const TerminalTitle({Key key, this.controller}) : super(key: key);
6 | // final TermareController controller;
7 |
8 | // @override
9 | // _TerminalTitleState createState() => _TerminalTitleState();
10 | // }
11 |
12 | // class _TerminalTitleState extends State {
13 | // @override
14 | // void initState() {
15 | // super.initState();
16 | // widget.controller?.addListener(update);
17 | // }
18 |
19 | // void update() {
20 | // if (mounted) {
21 | // setState(() {});
22 | // }
23 | // }
24 |
25 | // @override
26 | // void dispose() {
27 | // widget.controller?.removeListener(update);
28 | // super.dispose();
29 | // }
30 |
31 | // @override
32 | // Widget build(BuildContext context) {
33 | // return SingleChildScrollView(
34 | // scrollDirection: Axis.horizontal,
35 | // child: Center(
36 | // child: Text(
37 | // widget.controller?.terminalTitle ?? '',
38 | // style: const TextStyle(
39 | // height: 1.0,
40 | // fontWeight: FontWeight.bold,
41 | // ),
42 | // ),
43 | // ),
44 | // );
45 | // }
46 | // }
47 |
--------------------------------------------------------------------------------
/lib/app/modules/terminal/views/web_view.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:webview_flutter/webview_flutter.dart';
5 |
6 | class WebViewExample extends StatefulWidget {
7 | @override
8 | WebViewExampleState createState() => WebViewExampleState();
9 | }
10 |
11 | class WebViewExampleState extends State {
12 | @override
13 | void initState() {
14 | super.initState();
15 | // Enable hybrid composition.
16 | if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
17 | }
18 |
19 | @override
20 | Widget build(BuildContext context) {
21 | return const WebView(
22 | initialUrl: 'http://127.0.0.1:8080',
23 | );
24 | }
25 | }
--------------------------------------------------------------------------------
/lib/app/modules/terminal/views/xterm_wrapper.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:get/utils.dart';
5 | import 'package:pty/pty.dart';
6 | import 'package:xterm/xterm.dart';
7 |
8 | class XTermWrapper extends StatefulWidget {
9 | const XTermWrapper({
10 | Key key,
11 | this.terminal,
12 | this.pseudoTerminal,
13 | }) : super(key: key);
14 | final Terminal terminal;
15 | final PseudoTerminal pseudoTerminal;
16 |
17 | @override
18 | State createState() => _XTermWrapperState();
19 | }
20 |
21 | class _XTermWrapperState extends State {
22 | StreamSubscription streamSubscription;
23 |
24 | @override
25 | void initState() {
26 | super.initState();
27 | // print('$this init');
28 | // print('\x1b[31m监听的id 为${pseudoTerminal.pseudoTerminalId}');
29 | // 延时有用,是termare_app引起的。
30 | // PageView.builder会在短时间init与dispose这个widget
31 | // if (!mounted) {
32 | // return;
33 | // }
34 | widget.terminal.onOutput = (data) {
35 | widget.pseudoTerminal.write(data);
36 | };
37 |
38 | widget.terminal.onResize = (width, height, pixelWidth, pixelHeight) {
39 | widget.pseudoTerminal.resize(width, height);
40 | };
41 | streamSubscription ??= widget.pseudoTerminal.out.listen(
42 | (String data) {
43 | widget.terminal.write(data);
44 | },
45 | );
46 | }
47 |
48 | @override
49 | Widget build(BuildContext context) {
50 | return TerminalView(
51 | widget.terminal,
52 | backgroundOpacity: 0,
53 | keyboardType: TextInputType.text,
54 | theme: GetPlatform.isAndroid ? android : theme,
55 | );
56 | }
57 | }
58 |
59 | TerminalTheme android = const TerminalTheme(
60 | cursor: Color(0XAAAEAFAD),
61 | selection: Color(0XFFFFFF40),
62 | foreground: Colors.white,
63 | background: Color(0XFF000000),
64 | black: Color(0XFF000000),
65 | red: Color(0XFFCD3131),
66 | green: Color(0XFF0DBC79),
67 | yellow: Color(0XFFE5E510),
68 | blue: Color(0XFF2472C8),
69 | magenta: Color(0XFFBC3FBC),
70 | cyan: Color(0XFF11A8CD),
71 | white: Color(0XFFE5E5E5),
72 | brightBlack: Color(0XFF666666),
73 | brightRed: Color(0XFFF14C4C),
74 | brightGreen: Color(0XFF23D18B),
75 | brightYellow: Color(0XFFF5F543),
76 | brightBlue: Color(0XFF3B8EEA),
77 | brightMagenta: Color(0XFFD670D6),
78 | brightCyan: Color(0XFF29B8DB),
79 | brightWhite: Color(0XFFFFFFFF),
80 | searchHitBackground: Color(0XFFFFFF2B),
81 | searchHitBackgroundCurrent: Color(0XFF31FF26),
82 | searchHitForeground: Color(0XFF000000),
83 | );
84 |
85 | TerminalTheme theme = const TerminalTheme(
86 | cursor: Color(0XAAAEAFAD),
87 | selection: Color(0XFFFFFF40),
88 | foreground: Color(0XFF000000),
89 | background: Color(0XFF000000),
90 | black: Color(0XFF000000),
91 | red: Color(0XFFCD3131),
92 | green: Color(0XFF0DBC79),
93 | yellow: Color(0XFFE5E510),
94 | blue: Color(0XFF2472C8),
95 | magenta: Color(0XFFBC3FBC),
96 | cyan: Color(0XFF11A8CD),
97 | white: Color(0XFFE5E5E5),
98 | brightBlack: Color(0XFF666666),
99 | brightRed: Color(0XFFF14C4C),
100 | brightGreen: Color(0XFF23D18B),
101 | brightYellow: Color(0XFFF5F543),
102 | brightBlue: Color(0XFF3B8EEA),
103 | brightMagenta: Color(0XFFD670D6),
104 | brightCyan: Color(0XFF29B8DB),
105 | brightWhite: Color(0XFFFFFFFF),
106 | searchHitBackground: Color(0XFFFFFF2B),
107 | searchHitBackgroundCurrent: Color(0XFF31FF26),
108 | searchHitForeground: Color(0XFF000000),
109 | );
110 |
--------------------------------------------------------------------------------
/lib/app/routes/app_pages.dart:
--------------------------------------------------------------------------------
1 | import 'package:get/get.dart';
2 |
3 | import 'package:termare_app/app/modules/setting/bindings/setting_binding.dart';
4 | import 'package:termare_app/app/modules/setting/views/setting_page.dart';
5 | import 'package:termare_app/app/modules/terminal/bindings/terminal_binding.dart';
6 | import 'package:termare_app/app/modules/terminal/views/terminal_pages.dart';
7 |
8 | part 'app_routes.dart';
9 |
10 | class AppPages {
11 | AppPages._();
12 |
13 | static const INITIAL = Routes.HOME;
14 |
15 | static final routes = [
16 | GetPage(
17 | name: Routes.HOME,
18 | page: () => TerminalPages(),
19 | binding: TerminalBinding(),
20 | ),
21 | GetPage(
22 | name: Routes.SETTING,
23 | page: () => SettingPage(),
24 | binding: SettingBinding(),
25 | ),
26 | ];
27 | }
28 |
--------------------------------------------------------------------------------
/lib/app/routes/app_routes.dart:
--------------------------------------------------------------------------------
1 | part of 'app_pages.dart';
2 | // DO NOT EDIT. This is code generated via package:get_cli/get_cli.dart
3 |
4 | abstract class Routes {
5 | static const String prefix = '/termareApp';
6 | static const HOME = '$prefix/home';
7 | static const SETTING = '$prefix/setting';
8 | }
9 |
--------------------------------------------------------------------------------
/lib/app/widgets/custom_icon_button.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:global_repository/global_repository.dart';
3 |
4 | class NiIconButton extends StatelessWidget {
5 | const NiIconButton({Key key, this.child, this.onTap}) : super(key: key);
6 | final Widget child;
7 | final GestureTapCallback onTap;
8 | @override
9 | Widget build(BuildContext context) {
10 | return Container(
11 | width: 36,
12 | height: 36,
13 | child: InkWell(
14 | canRequestFocus: false,
15 | borderRadius: BorderRadius.circular(24),
16 | onTap: onTap,
17 | child: child,
18 | ),
19 | );
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/lib/app/widgets/mac_safearea.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_acrylic/flutter_acrylic.dart';
3 | import 'package:get/utils.dart';
4 |
5 | double titlebarHeight = 0;
6 |
7 | class MacSafeArea extends StatefulWidget {
8 | const MacSafeArea({
9 | Key key,
10 | this.child,
11 | }) : super(key: key);
12 | final Widget child;
13 |
14 | @override
15 | State createState() => _MacSafeAreaState();
16 | }
17 |
18 | class _MacSafeAreaState extends State {
19 | Future calculateTitlebarHeight() async {
20 | if (!GetPlatform.isMacOS) {
21 | return;
22 | }
23 | titlebarHeight = await Window.getTitlebarHeight();
24 | setState(() {});
25 | }
26 |
27 | @override
28 | void initState() {
29 | super.initState();
30 | calculateTitlebarHeight();
31 | }
32 |
33 | @override
34 | Widget build(BuildContext context) {
35 | return Padding(
36 | padding: EdgeInsets.only(top: titlebarHeight),
37 | child: widget.child,
38 | );
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/lib/app/widgets/pop_button.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class PopButton extends StatelessWidget {
4 | /// 路由栈使用的时候会有些问题
5 | const PopButton({Key key, this.navigatorContext}) : super(key: key);
6 | final BuildContext navigatorContext;
7 |
8 | @override
9 | Widget build(BuildContext context) {
10 | return Align(
11 | alignment: Alignment.center,
12 | child: Container(
13 | decoration: BoxDecoration(borderRadius: BorderRadius.circular(25)),
14 | height: 36,
15 | width: 36,
16 | child: InkWell(
17 | borderRadius: BorderRadius.circular(25),
18 | child: const Icon(
19 | Icons.arrow_back,
20 | color: Colors.black,
21 | ),
22 | onTap: () {
23 | Navigator.pop(context ?? navigatorContext);
24 | },
25 | ),
26 | ),
27 | );
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/lib/app/widgets/term_bottom_bar.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:global_repository/src/utils/screen_util.dart';
5 | import 'package:pty/pty.dart';
6 | import 'package:xterm/xterm.dart';
7 |
8 | class TerminalFoot extends StatefulWidget {
9 | const TerminalFoot({Key key, this.pseudoTerminal, this.terminal})
10 | : super(key: key);
11 | final PseudoTerminal pseudoTerminal;
12 | final Terminal terminal;
13 |
14 | @override
15 | _TerminalFootState createState() => _TerminalFootState();
16 | }
17 |
18 | class _TerminalFootState extends State
19 | with SingleTickerProviderStateMixin {
20 | Color defaultDragColor = Colors.white.withOpacity(0.4);
21 | Animation height;
22 | AnimationController controller;
23 | Color dragColor;
24 | @override
25 | void initState() {
26 | super.initState();
27 | dragColor = defaultDragColor;
28 | controller = AnimationController(
29 | vsync: this,
30 | duration: Duration(milliseconds: 100),
31 | );
32 | height = Tween(begin: 18.0, end: 82).animate(CurvedAnimation(
33 | curve: Curves.easeIn,
34 | parent: controller,
35 | ));
36 | height.addListener(() {
37 | setState(() {});
38 | });
39 | }
40 |
41 | @override
42 | void dispose() {
43 | super.dispose();
44 | }
45 |
46 | @override
47 | Widget build(BuildContext context) {
48 | return SizedBox(
49 | width: 414.w,
50 | height: height.value,
51 | child: SingleChildScrollView(
52 | physics: const NeverScrollableScrollPhysics(),
53 | child: Column(
54 | children: [
55 | GestureDetector(
56 | behavior: HitTestBehavior.translucent,
57 | onPanDown: (_) {
58 | dragColor = Colors.white.withOpacity(0.8);
59 | setState(() {});
60 | },
61 | onPanCancel: () {
62 | dragColor = defaultDragColor;
63 | setState(() {});
64 | },
65 | onPanEnd: (_) {
66 | dragColor = defaultDragColor;
67 | setState(() {});
68 | },
69 | onTap: () {
70 | if (controller.isCompleted) {
71 | controller.reverse();
72 | } else {
73 | controller.forward();
74 | }
75 | },
76 | child: SizedBox(
77 | height: 16,
78 | child: Center(
79 | child: Container(
80 | width: 100,
81 | height: 4,
82 | decoration: BoxDecoration(
83 | color: dragColor,
84 | borderRadius: BorderRadius.circular(3),
85 | ),
86 | ),
87 | ),
88 | ),
89 | ),
90 | SizedBox(
91 | height: 2,
92 | ),
93 | Row(
94 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
95 | children: [
96 | Expanded(
97 | child: BottomItem(
98 | pseudoTerminal: widget.pseudoTerminal,
99 | title: 'ESC',
100 | onTap: () {
101 | // widget.pseudoTerminal.input?.call(
102 | // utf8.decode([0x1b]),
103 | // );
104 | },
105 | ),
106 | ),
107 | Expanded(
108 | child: BottomItem(
109 | pseudoTerminal: widget.pseudoTerminal,
110 | title: 'TAB',
111 | onTap: () {
112 | // widget.pseudoTerminal.input?.call(
113 | // utf8.decode([9]),
114 | // );
115 | },
116 | ),
117 | ),
118 | Expanded(
119 | child: BottomItem(
120 | pseudoTerminal: widget.pseudoTerminal,
121 | title: 'CTRL',
122 | enable: false,
123 | onTap: () {
124 | // widget.pseudoTerminal.enbaleOrDisableCtrl();
125 | // setState(() {});
126 | },
127 | ),
128 | ),
129 | Expanded(
130 | child: BottomItem(
131 | pseudoTerminal: widget.pseudoTerminal,
132 | title: 'ALT',
133 | ),
134 | ),
135 | Expanded(
136 | child: BottomItem(
137 | pseudoTerminal: widget.pseudoTerminal,
138 | title: '-',
139 | onTap: () {
140 | // widget.pseudoTerminal.input?.call(
141 | // utf8.decode([110 - 96]),
142 | // );
143 | },
144 | ),
145 | ),
146 | Expanded(
147 | child: BottomItem(
148 | pseudoTerminal: widget.pseudoTerminal,
149 | title: '↑',
150 | onTap: () {
151 | // widget.pseudoTerminal.input?.call(
152 | // utf8.decode([112 - 96]),
153 | // );
154 | },
155 | ),
156 | ),
157 | Expanded(
158 | child: BottomItem(
159 | pseudoTerminal: widget.pseudoTerminal,
160 | title: '↲',
161 | onTap: () {
162 | widget.terminal.keyInput(TerminalKey.enter);
163 | // widget.pseudoTerminal.input?.call(
164 | // utf8.decode([110 - 96]),
165 | // );
166 | },
167 | ),
168 | ),
169 | ],
170 | ),
171 | Row(
172 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
173 | children: [
174 | Expanded(
175 | child: BottomItem(
176 | pseudoTerminal: widget.pseudoTerminal,
177 | title: 'INS',
178 | onTap: () {
179 | // widget.pseudoTerminal.input?.call(
180 | // utf8.decode([0x1b]),
181 | // );
182 | },
183 | ),
184 | ),
185 | Expanded(
186 | child: BottomItem(
187 | pseudoTerminal: widget.pseudoTerminal,
188 | title: 'END',
189 | onTap: () {
190 | // widget.pseudoTerminal.input?.call(
191 | // utf8.decode([9]),
192 | // );
193 | },
194 | ),
195 | ),
196 | Expanded(
197 | child: BottomItem(
198 | pseudoTerminal: widget.pseudoTerminal,
199 | title: 'SHIFT',
200 | onTap: () {
201 | // widget.pseudoTerminal.enbaleOrDisableCtrl();
202 | // setState(() {});
203 | },
204 | ),
205 | ),
206 | Expanded(
207 | child: BottomItem(
208 | pseudoTerminal: widget.pseudoTerminal,
209 | title: ':',
210 | ),
211 | ),
212 | Expanded(
213 | child: BottomItem(
214 | pseudoTerminal: widget.pseudoTerminal,
215 | title: '←',
216 | onTap: () {
217 | // widget.pseudoTerminal.input?.call(
218 | // utf8.decode([112 - 96]),
219 | // );
220 | },
221 | ),
222 | ),
223 | Expanded(
224 | child: BottomItem(
225 | pseudoTerminal: widget.pseudoTerminal,
226 | title: '↓',
227 | onTap: () {
228 | // widget.pseudoTerminal.input?.call(
229 | // utf8.decode([110 - 96]),
230 | // );
231 | },
232 | ),
233 | ),
234 | Expanded(
235 | child: BottomItem(
236 | pseudoTerminal: widget.pseudoTerminal,
237 | title: '→',
238 | onTap: () {
239 | // widget.pseudoTerminal.input?.call(
240 | // utf8.decode([110 - 96]),
241 | // );
242 | },
243 | ),
244 | ),
245 | ],
246 | ),
247 | ],
248 | ),
249 | ),
250 | );
251 | }
252 | }
253 |
254 | class BottomItem extends StatefulWidget {
255 | const BottomItem({
256 | Key key,
257 | this.pseudoTerminal,
258 | this.title,
259 | this.onTap,
260 | this.enable = false,
261 | }) : super(key: key);
262 | final PseudoTerminal pseudoTerminal;
263 | final String title;
264 | final void Function() onTap;
265 | final bool enable;
266 |
267 | @override
268 | _BottomItemState createState() => _BottomItemState();
269 | }
270 |
271 | class _BottomItemState extends State {
272 | Color backgroundColor = Colors.transparent;
273 |
274 | @override
275 | void initState() {
276 | super.initState();
277 | }
278 |
279 | @override
280 | void dispose() {
281 | super.dispose();
282 | }
283 |
284 | @override
285 | Widget build(BuildContext context) {
286 | return GestureDetector(
287 | behavior: HitTestBehavior.opaque,
288 | // onTap: widget.onTap,
289 | onPanDown: (_) {
290 | widget.onTap?.call();
291 | backgroundColor = Colors.white.withOpacity(0.2);
292 | setState(() {});
293 | Feedback.forLongPress(context);
294 | },
295 | onPanEnd: (_) {
296 | backgroundColor = Colors.transparent;
297 | setState(() {});
298 | Feedback.forLongPress(context);
299 | },
300 | onPanCancel: () {
301 | backgroundColor = Colors.transparent;
302 | setState(() {});
303 | Feedback.forLongPress(context);
304 | },
305 | child: Container(
306 | decoration: BoxDecoration(
307 | color:
308 | widget.enable ? Colors.white.withOpacity(0.4) : backgroundColor,
309 | ),
310 | height: 30,
311 | child: Center(
312 | child: Text(
313 | widget.title,
314 | style: TextStyle(
315 | color: Colors.white,
316 | fontWeight: FontWeight.w500,
317 | ),
318 | ),
319 | ),
320 | ),
321 | );
322 | }
323 | }
324 |
--------------------------------------------------------------------------------
/lib/app/widgets/termare_view_with_bar.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter/services.dart';
4 | import 'package:global_repository/global_repository.dart';
5 | import 'package:pty/pty.dart';
6 | import 'package:xterm/xterm.dart';
7 | import 'term_bottom_bar.dart';
8 |
9 | class TermareViewWithBottomBar extends StatefulWidget {
10 | const TermareViewWithBottomBar({
11 | Key key,
12 | this.termview,
13 | this.pseudoTerminal,
14 | this.terminal,
15 | }) : super(key: key);
16 | final Widget termview;
17 | final PseudoTerminal pseudoTerminal;
18 | final Terminal terminal;
19 | @override
20 | _TermareViewWithBottomBarState createState() =>
21 | _TermareViewWithBottomBarState();
22 | }
23 |
24 | class _TermareViewWithBottomBarState extends State {
25 | @override
26 | void dispose() {
27 | super.dispose();
28 | }
29 |
30 | SystemUiOverlayStyle systemUiOverlayStyle = SystemUiOverlayStyle.light;
31 | @override
32 | Widget build(BuildContext context) {
33 | return AnnotatedRegion(
34 | value: systemUiOverlayStyle,
35 | child: Scaffold(
36 | resizeToAvoidBottomInset: true,
37 | backgroundColor: Colors.transparent,
38 | body: SafeArea(
39 | child: Stack(
40 | children: [
41 | Column(
42 | children: [
43 | Expanded(
44 | child: widget.termview,
45 | ),
46 | TerminalFoot(
47 | pseudoTerminal: widget.pseudoTerminal,
48 | terminal: widget.terminal,
49 | ),
50 | ],
51 | ),
52 | // if (PlatformUtil.isDesktop())
53 | // Align(
54 | // alignment: Alignment.topRight,
55 | // child: SizedBox(
56 | // height: 32.0,
57 | // child: IconButton(
58 | // onPressed: () {
59 | // Navigator.pop(context);
60 | // },
61 | // icon: const Icon(
62 | // Icons.clear,
63 | // color: Colors.white,
64 | // ),
65 | // ),
66 | // ),
67 | // ),
68 | ],
69 | ),
70 | ),
71 | ),
72 | );
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/lib/app/widgets/terminal_drawer.dart:
--------------------------------------------------------------------------------
1 | // import 'package:flutter/cupertino.dart';
2 | // import 'package:flutter/material.dart';
3 | // import 'package:termare_app/modules/code/code_list.dart';
4 | // import 'package:termare_app/modules/setting/setting_page.dart';
5 | // import 'package:termare_view/termare_view.dart';
6 |
7 | // class TerminalDrawer extends StatefulWidget {
8 | // const TerminalDrawer({Key key, this.controller}) : super(key: key);
9 | // final TermareController controller;
10 |
11 | // @override
12 | // _TerminalDrawerState createState() => _TerminalDrawerState();
13 | // }
14 |
15 | // class _TerminalDrawerState extends State {
16 | // final children = {
17 | // 0: const Text(
18 | // '视图',
19 | // style: TextStyle(color: Colors.white),
20 | // ),
21 | // 1: const Text(
22 | // '代码片段',
23 | // style: TextStyle(color: Colors.white),
24 | // ),
25 | // };
26 |
27 | // int currentSegment = 0;
28 |
29 | // void onValueChanged(int newValue) {
30 | // setState(() {
31 | // currentSegment = newValue;
32 | // });
33 | // }
34 |
35 | // @override
36 | // Widget build(BuildContext context) {
37 | // return SizedBox(
38 | // width: MediaQuery.of(context).size.width,
39 | // height: MediaQuery.of(context).size.height,
40 | // child: Padding(
41 | // padding: const EdgeInsets.fromLTRB(32, 64, 32, 32),
42 | // child: Material(
43 | // textStyle: const TextStyle(
44 | // color: Colors.white,
45 | // ),
46 | // borderRadius: BorderRadius.circular(8),
47 | // color: Colors.black.withOpacity(0.2),
48 | // child: SafeArea(
49 | // child: Column(
50 | // children: [
51 | // SizedBox(
52 | // width: 500,
53 | // child: Padding(
54 | // padding: const EdgeInsets.all(16),
55 | // child: CupertinoSlidingSegmentedControl(
56 | // backgroundColor: Colors.white.withOpacity(0.2),
57 | // children: children,
58 | // onValueChanged: onValueChanged,
59 | // groupValue: currentSegment,
60 | // thumbColor: Colors.white.withOpacity(0.2),
61 | // ),
62 | // ),
63 | // ),
64 | // Expanded(
65 | // child: [
66 | // Column(
67 | // children: [
68 | // const Text('字体大小'),
69 | // Row(
70 | // mainAxisAlignment: MainAxisAlignment.spaceBetween,
71 | // children: [
72 | // IconButton(
73 | // icon: const Icon(
74 | // Icons.remove,
75 | // color: Colors.white,
76 | // ),
77 | // onPressed: () {
78 | // widget.controller.setFontSize(
79 | // widget.controller.theme.fontSize - 1,
80 | // );
81 | // setState(() {});
82 | // },
83 | // ),
84 | // Text(widget.controller.theme.fontSize.toString()),
85 | // IconButton(
86 | // icon: const Icon(
87 | // Icons.add,
88 | // color: Colors.white,
89 | // ),
90 | // onPressed: () {
91 | // widget.controller.setFontSize(
92 | // widget.controller.theme.fontSize + 1,
93 | // );
94 | // setState(() {});
95 | // },
96 | // ),
97 | // ],
98 | // ),
99 | // Row(
100 | // mainAxisAlignment: MainAxisAlignment.spaceAround,
101 | // children: [
102 | // const Text('显示网格'),
103 | // Checkbox(
104 | // checkColor: Colors.black,
105 | // // c: MaterialStateProperty.resolveWith((_) {
106 | // // return Colors.white;
107 | // // }),
108 | // value: widget.controller.showBackgroundLine,
109 | // onChanged: (value) {
110 | // widget.controller.showBackgroundLine = value;
111 | // widget.controller.dirty = true;
112 | // setState(() {});
113 | // widget.controller.notifyListeners();
114 | // },
115 | // ),
116 | // ],
117 | // ),
118 | // Column(
119 | // children: [
120 | // Container(
121 | // color: TermareStyles.termux.backgroundColor,
122 | // child: Row(
123 | // mainAxisAlignment:
124 | // MainAxisAlignment.spaceBetween,
125 | // children: [
126 | // Text(
127 | // 'termux',
128 | // style: TextStyle(
129 | // color: TermareStyles.termux.defaultColor,
130 | // ),
131 | // ),
132 | // TermColorList(
133 | // style: TermareStyles.termux,
134 | // ),
135 | // Radio(
136 | // value: TermareStyles.termux,
137 | // groupValue: termareStyle,
138 | // onChanged: (v) {
139 | // termareStyle = v;
140 | // // systemUiOverlayStyle =
141 | // // SystemUiOverlayStyle.light;
142 | // setState(() {});
143 | // widget.controller.theme =
144 | // termareStyle.copyWith(
145 | // fontSize:
146 | // widget.controller.theme.fontSize,
147 | // );
148 | // widget.controller.dirty = true;
149 | // widget.controller.notifyListeners();
150 | // },
151 | // ),
152 | // ],
153 | // ),
154 | // ),
155 | // Container(
156 | // color: TermareStyles.manjaro.backgroundColor,
157 | // child: Row(
158 | // mainAxisAlignment:
159 | // MainAxisAlignment.spaceBetween,
160 | // children: [
161 | // Text(
162 | // 'manjaro',
163 | // style: TextStyle(
164 | // color: TermareStyles.manjaro.defaultColor,
165 | // ),
166 | // ),
167 | // TermColorList(
168 | // style: TermareStyles.manjaro,
169 | // ),
170 | // Radio(
171 | // value: TermareStyles.manjaro,
172 | // groupValue: termareStyle,
173 | // onChanged: (v) {
174 | // termareStyle = v;
175 | // // systemUiOverlayStyle =
176 | // // SystemUiOverlayStyle.light;
177 | // setState(() {});
178 | // widget.controller.theme =
179 | // termareStyle.copyWith(
180 | // fontSize:
181 | // widget.controller.theme.fontSize,
182 | // );
183 | // widget.controller.dirty = true;
184 | // widget.controller.notifyListeners();
185 | // },
186 | // ),
187 | // ],
188 | // ),
189 | // ),
190 | // Container(
191 | // color: TermareStyles.macos.backgroundColor,
192 | // child: Row(
193 | // mainAxisAlignment:
194 | // MainAxisAlignment.spaceBetween,
195 | // children: [
196 | // Text(
197 | // 'macos',
198 | // style: TextStyle(
199 | // color: TermareStyles.macos.defaultColor,
200 | // ),
201 | // ),
202 | // TermColorList(
203 | // style: TermareStyles.macos,
204 | // ),
205 | // Radio(
206 | // value: TermareStyles.macos,
207 | // groupValue: termareStyle,
208 | // onChanged: (v) {
209 | // termareStyle = v;
210 | // // systemUiOverlayStyle =
211 | // // SystemUiOverlayStyle.dark;
212 | // setState(() {});
213 | // widget.controller.theme =
214 | // termareStyle.copyWith(
215 | // fontSize:
216 | // widget.controller.theme.fontSize,
217 | // );
218 | // widget.controller.dirty = true;
219 | // widget.controller.notifyListeners();
220 | // },
221 | // ),
222 | // ],
223 | // ),
224 | // ),
225 | // ],
226 | // ),
227 | // ],
228 | // ),
229 | // LayoutBuilder(
230 | // builder: (c, cc) {
231 | // print(cc.maxHeight);
232 | // return Scaffold(
233 | // backgroundColor: Colors.transparent,
234 | // body: Theme(
235 | // data: ThemeData(
236 | // textTheme: const TextTheme(
237 | // subtitle1: TextStyle(
238 | // fontSize: 16.0,
239 | // fontWeight: FontWeight.bold,
240 | // color: Colors.white,
241 | // ),
242 | // bodyText2: TextStyle(
243 | // fontSize: 14.0,
244 | // color: Colors.white,
245 | // ),
246 | // ),
247 | // ),
248 | // child: CodeListPage(
249 | // controller: widget.controller,
250 | // ),
251 | // ),
252 | // );
253 | // },
254 | // ),
255 | // ][currentSegment],
256 | // )
257 | // ],
258 | // ),
259 | // ),
260 | // ),
261 | // ),
262 | // );
263 | // }
264 | // }
265 |
--------------------------------------------------------------------------------
/lib/config/assets.dart:
--------------------------------------------------------------------------------
1 | import 'config.dart';
2 |
3 | class Assets {
4 | Assets._();
5 | static String neofetchContent =
6 | Config.flutterPackage + 'assets/text/neofetch.txt';
7 | static String ogg =
8 | Config.flutterPackage + 'assets/ogg/InCallNotification.ogg';
9 | }
10 |
--------------------------------------------------------------------------------
/lib/config/config.dart:
--------------------------------------------------------------------------------
1 | import 'package:global_repository/global_repository.dart';
2 |
3 | class Config {
4 | Config._();
5 | static String bashPath = '${RuntimeEnvir.binPath}/bash';
6 | static String packageName = 'com.nightmare.termare';
7 | // flutter package名,因为这个会影响assets的路径
8 | static String flutterPackage = '';
9 | }
10 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'dart:developer';
2 | import 'dart:io';
3 |
4 | import 'package:flutter/material.dart';
5 | import 'package:flutter/services.dart';
6 | import 'package:flutter_acrylic/flutter_acrylic.dart';
7 |
8 | import 'package:get/get.dart';
9 | import 'package:global_repository/global_repository.dart';
10 |
11 | import 'app/routes/app_pages.dart';
12 |
13 | Future main() async {
14 | RuntimeEnvir.initEnvirWithPackageName('com.nightmare.termare');
15 | WidgetsFlutterBinding.ensureInitialized();
16 | if (GetPlatform.isDesktop) {
17 | await Window.initialize();
18 | }
19 | runApp(
20 | ToastApp(
21 | child: GetMaterialApp(
22 | // showPerformanceOverlay: true,
23 | title: 'Termare开源版',
24 | initialRoute: AppPages.INITIAL,
25 | getPages: AppPages.routes,
26 | defaultTransition: Transition.fade,
27 | ),
28 | ),
29 | );
30 | SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
31 | statusBarColor: Colors.transparent,
32 | systemNavigationBarColor: Colors.transparent,
33 | systemNavigationBarDividerColor: Colors.transparent,
34 | ));
35 | }
36 |
--------------------------------------------------------------------------------
/lib/termare_app.dart:
--------------------------------------------------------------------------------
1 | export 'app/routes/app_pages.dart';
2 |
--------------------------------------------------------------------------------
/lib/themes/app_colors.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | const MaterialColor _grey = MaterialColor(
6 | _greyPrimaryValue,
7 | {
8 | // 对应UI的灰度4
9 | 100: Color(0xFFf1f1f1),
10 | // 对应UI的灰度3
11 | 200: Color(0xFFe1e1e1),
12 | // 对应UI的灰度2
13 | 500: Color(_greyPrimaryValue),
14 | // 对应UI的灰度1
15 | 900: Color(0x00000000),
16 | },
17 | );
18 | const int _greyPrimaryValue = 0xFF9999999;
19 |
20 | class AppColors {
21 | AppColors._();
22 | static const MaterialColor grey = Colors.grey;
23 | static const Color accentColor = Color(0xffd3c1fe);
24 | static const Color fontColor = Color(0xff201b1a);
25 | static const Color borderColor = Color(0xffeeeeee);
26 | static const Color surface = Color(0xffede8f8);
27 | static const Color background = Color(0xfff8f8f8);
28 | }
29 |
--------------------------------------------------------------------------------
/lib/themes/color_schema_extension.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | extension ColorSchemaExtension on ColorScheme {
4 | static const Color _sidebar = Color(0xFFF0F0F0);
5 | static const Color _dark_sidebar = Color(0xFF202020);
6 |
7 | static const Color _divider_line = Color(0xFFF2F2F2);
8 | static const Color _divider_dark_line = Color(0xFF3B3B3B);
9 |
10 | static const Color _input_background = Color(0xFFF8F8F8);
11 | static const Color _dark_input_background = Color(0xFF1F1F1F);
12 |
13 | static const Color _mask = Color(0x00000000);
14 | static const Color _dark_mask = Color(0x4D000000);
15 |
16 | static const Color _text_1 = Color(0xFF262626);
17 | static const Color _dark_text_1 = Color(0xFFA8A8A8);
18 |
19 | static const Color _text_2 = Color(0xff4b5c76);
20 | // static const Color _text_2 = Color(0xFF595959);
21 | static const Color _dark_text_2 = Color(0xFFA8A8A8);
22 |
23 | static const Color _text_3 = Color(0xFF8C8C8C);
24 | static const Color _dark_text_3 = Color(0xFF8C8C8C);
25 |
26 | static const Color _text_4 = Color(0xFFBFBFBF);
27 | static const Color _dark_text_4 = Color(0xFF696969);
28 |
29 | static const Color _text_5 = Color(0xFFEFEFEF);
30 | static const Color _dark_text_5 = Color(0xFF4C4C4C);
31 |
32 | static const Color _text_6 = Color(0xFFFFFFFF);
33 | static const Color _dark_text_6 = Color(0xFFFFFFFF);
34 |
35 | static const Color _toast_text = Color(0xFFFFFFFF);
36 | static const Color _dark_toast_text = Color(0xFF1D1D1D);
37 |
38 | static const Color _toast_icon = Color(0xFFFFFFFF);
39 | static const Color _dark_toast_icon = Color(0xFF696969);
40 |
41 | static const Color _toast_background = Color(0xCC000000);
42 | static const Color _dark_toast_background = Color(0xCCFFFFFF);
43 |
44 | static const Color _dialog_cancel_background = Color(0xFFE6E6E6);
45 | static const Color _dark_dialog_cancel_background = Color(0xFF1F1F1F);
46 |
47 | static const Color _border_color = Color(0xFFE7E7E7);
48 | static const Color _dark_border_color = Color(0xFFE7E7E7);
49 |
50 | static const Color _material_shadow_color = Color(0x0F000000);
51 | static const Color _dark_material_shadow_color = Color(0x0F000000);
52 |
53 | static const Color _track_color = Color(0x40636363);
54 | static const Color _dark_track_color = Color(0x40636363);
55 |
56 | static const Color _sublist_background = Color(0xFFF5F5F8);
57 | static const Color _dark_sublist_background = Color(0xFF363636);
58 |
59 | static const Color _normal_button_background = Color(0xFFE4F6EC);
60 | static const Color _dark_normal_button_background = Color(0xFFE4F6EC);
61 |
62 | static const Color _imbar_icon_color = Color(0xFFB7B7B7);
63 | static const Color _dark_imbar_icon_color = Color(0xFFB7B7B7);
64 |
65 | static const Color _thrice_color = Color(0xFFFFAF64);
66 | static const Color _dark_thrice_color = Color(0xFFFFAF64);
67 |
68 | static const Color _on_thrice_color = Color(0xFFFFFFFF);
69 | static const Color _dark_on_thrice_color = Color(0xFFFFFFFF);
70 |
71 | Color get sidebar {
72 | if (brightness == Brightness.light) {
73 | return _sidebar;
74 | }
75 |
76 | return _dark_sidebar;
77 | }
78 |
79 | Color get dividerLine {
80 | if (brightness == Brightness.light) {
81 | return _divider_line;
82 | }
83 |
84 | return _divider_dark_line;
85 | }
86 |
87 | Color get inputBackground {
88 | if (brightness == Brightness.light) {
89 | return _input_background;
90 | }
91 |
92 | return _dark_input_background;
93 | }
94 |
95 | Color get mask {
96 | if (brightness == Brightness.light) {
97 | return _mask;
98 | }
99 |
100 | return _dark_mask;
101 | }
102 |
103 | Color get textTitle {
104 | if (brightness == Brightness.light) {
105 | return _text_1;
106 | }
107 |
108 | return _dark_text_1;
109 | }
110 |
111 | Color get textContent {
112 | if (brightness == Brightness.light) {
113 | return _text_2;
114 | }
115 |
116 | return _dark_text_2;
117 | }
118 |
119 | Color get textIconCaption {
120 | if (brightness == Brightness.light) {
121 | return _text_3;
122 | }
123 |
124 | return _dark_text_3;
125 | }
126 |
127 | Color get textCaption {
128 | if (brightness == Brightness.light) {
129 | return _text_4;
130 | }
131 |
132 | return _dark_text_4;
133 | }
134 |
135 | Color get textHit {
136 | if (brightness == Brightness.light) {
137 | return _text_5;
138 | }
139 |
140 | return _dark_text_5;
141 | }
142 |
143 | Color get textButton {
144 | if (brightness == Brightness.light) {
145 | return _text_6;
146 | }
147 |
148 | return _dark_text_6;
149 | }
150 |
151 | Color get toastText {
152 | if (brightness == Brightness.light) {
153 | return _toast_text;
154 | }
155 |
156 | return _dark_toast_text;
157 | }
158 |
159 | Color get toastIcon {
160 | if (brightness == Brightness.light) {
161 | return _toast_icon;
162 | }
163 |
164 | return _dark_toast_icon;
165 | }
166 |
167 | Color get toastBackground {
168 | if (brightness == Brightness.light) {
169 | return _toast_background;
170 | }
171 |
172 | return _dark_toast_background;
173 | }
174 |
175 | Color get dialogCancelBackground {
176 | if (brightness == Brightness.light) {
177 | return _dialog_cancel_background;
178 | }
179 |
180 | return _dark_dialog_cancel_background;
181 | }
182 |
183 | Color get barrierColor {
184 | return _dark_mask;
185 | }
186 |
187 | Color get borderColor {
188 | if (brightness == Brightness.light) {
189 | return _border_color;
190 | }
191 |
192 | return _dark_border_color;
193 | }
194 |
195 | Color get materialShadowColor {
196 | if (brightness == Brightness.light) {
197 | return _material_shadow_color;
198 | }
199 |
200 | return _dark_material_shadow_color;
201 | }
202 |
203 | Color get trackColor {
204 | if (brightness == Brightness.light) {
205 | return _track_color;
206 | }
207 |
208 | return _dark_track_color;
209 | }
210 |
211 | Color get sublistBackground {
212 | if (brightness == Brightness.light) {
213 | return _sublist_background;
214 | }
215 |
216 | return _dark_sublist_background;
217 | }
218 |
219 | Color get normalButtonBackground {
220 | if (brightness == Brightness.light) {
221 | return _normal_button_background;
222 | }
223 |
224 | return _dark_normal_button_background;
225 | }
226 |
227 | Color get imbarIconColor {
228 | if (brightness == Brightness.light) {
229 | return _imbar_icon_color;
230 | }
231 |
232 | return _dark_imbar_icon_color;
233 | }
234 |
235 | Color get thriceColor =>
236 | brightness == Brightness.light ? _thrice_color : _dark_thrice_color;
237 |
238 | Color get onThriceColor =>
239 | brightness == Brightness.light ? _on_thrice_color : _dark_on_thrice_color;
240 | }
241 |
--------------------------------------------------------------------------------
/lib/themes/theme.dart:
--------------------------------------------------------------------------------
1 | export 'color_schema_extension.dart';
2 | export 'default_theme_data.dart';
3 |
--------------------------------------------------------------------------------
/macos/.gitignore:
--------------------------------------------------------------------------------
1 | # Flutter-related
2 | **/Flutter/ephemeral/
3 | **/Pods/
4 |
5 | # Xcode-related
6 | **/xcuserdata/
7 |
--------------------------------------------------------------------------------
/macos/Flutter/Flutter-Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "ephemeral/Flutter-Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/macos/Flutter/Flutter-Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "ephemeral/Flutter-Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/macos/Flutter/GeneratedPluginRegistrant.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | import FlutterMacOS
6 | import Foundation
7 |
8 | import flutter_acrylic
9 |
10 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
11 | FlutterAcrylicPlugin.register(with: registry.registrar(forPlugin: "FlutterAcrylicPlugin"))
12 | }
13 |
--------------------------------------------------------------------------------
/macos/Podfile:
--------------------------------------------------------------------------------
1 | platform :osx, '10.11'
2 |
3 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
4 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
5 |
6 | project 'Runner', {
7 | 'Debug' => :debug,
8 | 'Profile' => :release,
9 | 'Release' => :release,
10 | }
11 |
12 | def flutter_root
13 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__)
14 | unless File.exist?(generated_xcode_build_settings_path)
15 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first"
16 | end
17 |
18 | File.foreach(generated_xcode_build_settings_path) do |line|
19 | matches = line.match(/FLUTTER_ROOT\=(.*)/)
20 | return matches[1].strip if matches
21 | end
22 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\""
23 | end
24 |
25 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
26 |
27 | flutter_macos_podfile_setup
28 |
29 | target 'Runner' do
30 | use_frameworks!
31 | use_modular_headers!
32 |
33 | flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__))
34 | end
35 |
36 | post_install do |installer|
37 | installer.pods_project.targets.each do |target|
38 | flutter_additional_macos_build_settings(target)
39 | end
40 | end
41 |
--------------------------------------------------------------------------------
/macos/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - flutter_acrylic (0.1.0):
3 | - FlutterMacOS
4 | - FlutterMacOS (1.0.0)
5 |
6 | DEPENDENCIES:
7 | - flutter_acrylic (from `Flutter/ephemeral/.symlinks/plugins/flutter_acrylic/macos`)
8 | - FlutterMacOS (from `Flutter/ephemeral`)
9 |
10 | EXTERNAL SOURCES:
11 | flutter_acrylic:
12 | :path: Flutter/ephemeral/.symlinks/plugins/flutter_acrylic/macos
13 | FlutterMacOS:
14 | :path: Flutter/ephemeral
15 |
16 | SPEC CHECKSUMS:
17 | flutter_acrylic: c3df24ae52ab6597197837ce59ef2a8542640c17
18 | FlutterMacOS: ae6af50a8ea7d6103d888583d46bd8328a7e9811
19 |
20 | PODFILE CHECKSUM: 6eac6b3292e5142cfc23bdeb71848a40ec51c14c
21 |
22 | COCOAPODS: 1.11.3
23 |
--------------------------------------------------------------------------------
/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
41 |
42 |
52 |
54 |
60 |
61 |
62 |
63 |
64 |
65 |
71 |
73 |
79 |
80 |
81 |
82 |
84 |
85 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/macos/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/macos/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import FlutterMacOS
3 |
4 | @NSApplicationMain
5 | class AppDelegate: FlutterAppDelegate {
6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
7 | return true
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "16x16",
5 | "idiom" : "mac",
6 | "filename" : "app_icon_16.png",
7 | "scale" : "1x"
8 | },
9 | {
10 | "size" : "16x16",
11 | "idiom" : "mac",
12 | "filename" : "app_icon_32.png",
13 | "scale" : "2x"
14 | },
15 | {
16 | "size" : "32x32",
17 | "idiom" : "mac",
18 | "filename" : "app_icon_32.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "32x32",
23 | "idiom" : "mac",
24 | "filename" : "app_icon_64.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "128x128",
29 | "idiom" : "mac",
30 | "filename" : "app_icon_128.png",
31 | "scale" : "1x"
32 | },
33 | {
34 | "size" : "128x128",
35 | "idiom" : "mac",
36 | "filename" : "app_icon_256.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "256x256",
41 | "idiom" : "mac",
42 | "filename" : "app_icon_256.png",
43 | "scale" : "1x"
44 | },
45 | {
46 | "size" : "256x256",
47 | "idiom" : "mac",
48 | "filename" : "app_icon_512.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "512x512",
53 | "idiom" : "mac",
54 | "filename" : "app_icon_512.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "512x512",
59 | "idiom" : "mac",
60 | "filename" : "app_icon_1024.png",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png
--------------------------------------------------------------------------------
/macos/Runner/Configs/AppInfo.xcconfig:
--------------------------------------------------------------------------------
1 | // Application-level settings for the Runner target.
2 | //
3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the
4 | // future. If not, the values below would default to using the project name when this becomes a
5 | // 'flutter create' template.
6 |
7 | // The application's name. By default this is also the title of the Flutter window.
8 | PRODUCT_NAME = termare_app
9 |
10 | // The application's bundle identifier
11 | PRODUCT_BUNDLE_IDENTIFIER = com.nightmare.termareApp
12 |
13 | // The copyright displayed in application information
14 | PRODUCT_COPYRIGHT = Copyright © 2021 com.nightmare. All rights reserved.
15 |
--------------------------------------------------------------------------------
/macos/Runner/Configs/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "../../Flutter/Flutter-Debug.xcconfig"
2 | #include "Warnings.xcconfig"
3 |
--------------------------------------------------------------------------------
/macos/Runner/Configs/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "../../Flutter/Flutter-Release.xcconfig"
2 | #include "Warnings.xcconfig"
3 |
--------------------------------------------------------------------------------
/macos/Runner/Configs/Warnings.xcconfig:
--------------------------------------------------------------------------------
1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings
2 | GCC_WARN_UNDECLARED_SELECTOR = YES
3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES
4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE
5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES
6 | CLANG_WARN_PRAGMA_PACK = YES
7 | CLANG_WARN_STRICT_PROTOTYPES = YES
8 | CLANG_WARN_COMMA = YES
9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES
10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES
11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES
12 | GCC_WARN_SHADOW = YES
13 | CLANG_WARN_UNREACHABLE_CODE = YES
14 |
--------------------------------------------------------------------------------
/macos/Runner/DebugProfile.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.cs.allow-jit
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/macos/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSMinimumSystemVersion
24 | $(MACOSX_DEPLOYMENT_TARGET)
25 | NSHumanReadableCopyright
26 | $(PRODUCT_COPYRIGHT)
27 | NSMainNibFile
28 | MainMenu
29 | NSPrincipalClass
30 | NSApplication
31 |
32 |
33 |
--------------------------------------------------------------------------------
/macos/Runner/MainFlutterWindow.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import FlutterMacOS
3 | import flutter_acrylic
4 |
5 | class MainFlutterWindow: NSWindow {
6 | override func awakeFromNib() {
7 | let windowFrame = self.frame
8 | let blurryContainerViewController = BlurryContainerViewController()
9 | self.contentViewController = blurryContainerViewController
10 | self.setFrame(windowFrame, display: true)
11 |
12 | /* Initialize the flutter_acrylic plugin */
13 | MainFlutterWindowManipulator.start(mainFlutterWindow: self)
14 |
15 | RegisterGeneratedPlugins(registry: blurryContainerViewController.flutterViewController)
16 | super.awakeFromNib()
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/macos/Runner/Release.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | archive:
5 | dependency: "direct main"
6 | description:
7 | name: archive
8 | url: "https://pub.flutter-io.cn"
9 | source: hosted
10 | version: "3.3.2"
11 | async:
12 | dependency: transitive
13 | description:
14 | name: async
15 | url: "https://pub.flutter-io.cn"
16 | source: hosted
17 | version: "2.9.0"
18 | boolean_selector:
19 | dependency: transitive
20 | description:
21 | name: boolean_selector
22 | url: "https://pub.flutter-io.cn"
23 | source: hosted
24 | version: "2.1.0"
25 | characters:
26 | dependency: transitive
27 | description:
28 | name: characters
29 | url: "https://pub.flutter-io.cn"
30 | source: hosted
31 | version: "1.2.1"
32 | clock:
33 | dependency: transitive
34 | description:
35 | name: clock
36 | url: "https://pub.flutter-io.cn"
37 | source: hosted
38 | version: "1.1.1"
39 | collection:
40 | dependency: transitive
41 | description:
42 | name: collection
43 | url: "https://pub.flutter-io.cn"
44 | source: hosted
45 | version: "1.16.0"
46 | convert:
47 | dependency: transitive
48 | description:
49 | name: convert
50 | url: "https://pub.flutter-io.cn"
51 | source: hosted
52 | version: "3.1.1"
53 | crypto:
54 | dependency: transitive
55 | description:
56 | name: crypto
57 | url: "https://pub.flutter-io.cn"
58 | source: hosted
59 | version: "3.0.2"
60 | cupertino_icons:
61 | dependency: "direct main"
62 | description:
63 | name: cupertino_icons
64 | url: "https://pub.flutter-io.cn"
65 | source: hosted
66 | version: "1.0.5"
67 | dart_pty:
68 | dependency: transitive
69 | description:
70 | path: "."
71 | ref: HEAD
72 | resolved-ref: a437347d882e8e9110564cef9495f8dafc6c8b89
73 | url: "https://github.com/Termare/dart_pty"
74 | source: git
75 | version: "0.0.3"
76 | dio:
77 | dependency: "direct main"
78 | description:
79 | name: dio
80 | url: "https://pub.flutter-io.cn"
81 | source: hosted
82 | version: "4.0.6"
83 | equatable:
84 | dependency: transitive
85 | description:
86 | name: equatable
87 | url: "https://pub.flutter-io.cn"
88 | source: hosted
89 | version: "2.0.5"
90 | event_bus:
91 | dependency: transitive
92 | description:
93 | name: event_bus
94 | url: "https://pub.flutter-io.cn"
95 | source: hosted
96 | version: "1.1.1"
97 | fake_async:
98 | dependency: transitive
99 | description:
100 | name: fake_async
101 | url: "https://pub.flutter-io.cn"
102 | source: hosted
103 | version: "1.3.1"
104 | ffi:
105 | dependency: transitive
106 | description:
107 | name: ffi
108 | url: "https://pub.flutter-io.cn"
109 | source: hosted
110 | version: "1.2.1"
111 | flutter:
112 | dependency: "direct main"
113 | description: flutter
114 | source: sdk
115 | version: "0.0.0"
116 | flutter_acrylic:
117 | dependency: "direct main"
118 | description:
119 | name: flutter_acrylic
120 | url: "https://pub.flutter-io.cn"
121 | source: hosted
122 | version: "1.0.0+2"
123 | flutter_test:
124 | dependency: "direct dev"
125 | description: flutter
126 | source: sdk
127 | version: "0.0.0"
128 | get:
129 | dependency: "direct main"
130 | description:
131 | name: get
132 | url: "https://pub.flutter-io.cn"
133 | source: hosted
134 | version: "4.6.5"
135 | global_repository:
136 | dependency: "direct main"
137 | description:
138 | path: "."
139 | ref: HEAD
140 | resolved-ref: "5a1f3d90c0d1abff1065b593154de2f15dafaa64"
141 | url: "https://github.com/nightmare-space/global_repository"
142 | source: git
143 | version: "0.0.1"
144 | http_parser:
145 | dependency: transitive
146 | description:
147 | name: http_parser
148 | url: "https://pub.flutter-io.cn"
149 | source: hosted
150 | version: "4.0.2"
151 | matcher:
152 | dependency: transitive
153 | description:
154 | name: matcher
155 | url: "https://pub.flutter-io.cn"
156 | source: hosted
157 | version: "0.12.12"
158 | material_color_utilities:
159 | dependency: transitive
160 | description:
161 | name: material_color_utilities
162 | url: "https://pub.flutter-io.cn"
163 | source: hosted
164 | version: "0.1.5"
165 | meta:
166 | dependency: transitive
167 | description:
168 | name: meta
169 | url: "https://pub.flutter-io.cn"
170 | source: hosted
171 | version: "1.8.0"
172 | path:
173 | dependency: transitive
174 | description:
175 | name: path
176 | url: "https://pub.flutter-io.cn"
177 | source: hosted
178 | version: "1.8.2"
179 | permission_handler:
180 | dependency: transitive
181 | description:
182 | name: permission_handler
183 | url: "https://pub.flutter-io.cn"
184 | source: hosted
185 | version: "6.0.0"
186 | permission_handler_platform_interface:
187 | dependency: transitive
188 | description:
189 | name: permission_handler_platform_interface
190 | url: "https://pub.flutter-io.cn"
191 | source: hosted
192 | version: "3.9.0"
193 | platform_info:
194 | dependency: transitive
195 | description:
196 | name: platform_info
197 | url: "https://pub.flutter-io.cn"
198 | source: hosted
199 | version: "3.2.0"
200 | plugin_platform_interface:
201 | dependency: transitive
202 | description:
203 | name: plugin_platform_interface
204 | url: "https://pub.flutter-io.cn"
205 | source: hosted
206 | version: "2.1.3"
207 | pseudo_terminal_utils:
208 | dependency: "direct main"
209 | description:
210 | path: "."
211 | ref: HEAD
212 | resolved-ref: "90d635ced306dc4237171da20ce497fd12134902"
213 | url: "https://github.com/Termare/pseudo_terminal_utils"
214 | source: git
215 | version: "0.0.1"
216 | pty:
217 | dependency: "direct main"
218 | description:
219 | path: "."
220 | ref: HEAD
221 | resolved-ref: "5c3798fef3f304316a8c8b8b66d611c944213dac"
222 | url: "https://github.com/TerminalStudio/pty"
223 | source: git
224 | version: "0.2.2-pre"
225 | quiver:
226 | dependency: transitive
227 | description:
228 | name: quiver
229 | url: "https://pub.flutter-io.cn"
230 | source: hosted
231 | version: "3.1.0"
232 | signale:
233 | dependency: transitive
234 | description:
235 | name: signale
236 | url: "https://pub.flutter-io.cn"
237 | source: hosted
238 | version: "0.0.8"
239 | sky_engine:
240 | dependency: transitive
241 | description: flutter
242 | source: sdk
243 | version: "0.0.99"
244 | source_span:
245 | dependency: transitive
246 | description:
247 | name: source_span
248 | url: "https://pub.flutter-io.cn"
249 | source: hosted
250 | version: "1.9.0"
251 | stack_trace:
252 | dependency: transitive
253 | description:
254 | name: stack_trace
255 | url: "https://pub.flutter-io.cn"
256 | source: hosted
257 | version: "1.10.0"
258 | stream_channel:
259 | dependency: transitive
260 | description:
261 | name: stream_channel
262 | url: "https://pub.flutter-io.cn"
263 | source: hosted
264 | version: "2.1.0"
265 | string_scanner:
266 | dependency: transitive
267 | description:
268 | name: string_scanner
269 | url: "https://pub.flutter-io.cn"
270 | source: hosted
271 | version: "1.1.1"
272 | synchronized:
273 | dependency: transitive
274 | description:
275 | name: synchronized
276 | url: "https://pub.flutter-io.cn"
277 | source: hosted
278 | version: "3.0.0+3"
279 | term_glyph:
280 | dependency: transitive
281 | description:
282 | name: term_glyph
283 | url: "https://pub.flutter-io.cn"
284 | source: hosted
285 | version: "1.2.1"
286 | test_api:
287 | dependency: transitive
288 | description:
289 | name: test_api
290 | url: "https://pub.flutter-io.cn"
291 | source: hosted
292 | version: "0.4.12"
293 | typed_data:
294 | dependency: transitive
295 | description:
296 | name: typed_data
297 | url: "https://pub.flutter-io.cn"
298 | source: hosted
299 | version: "1.3.1"
300 | vector_math:
301 | dependency: transitive
302 | description:
303 | name: vector_math
304 | url: "https://pub.flutter-io.cn"
305 | source: hosted
306 | version: "2.1.2"
307 | vibration:
308 | dependency: "direct main"
309 | description:
310 | name: vibration
311 | url: "https://pub.flutter-io.cn"
312 | source: hosted
313 | version: "1.7.6"
314 | webview_flutter:
315 | dependency: "direct main"
316 | description:
317 | name: webview_flutter
318 | url: "https://pub.flutter-io.cn"
319 | source: hosted
320 | version: "2.8.0"
321 | webview_flutter_android:
322 | dependency: transitive
323 | description:
324 | name: webview_flutter_android
325 | url: "https://pub.flutter-io.cn"
326 | source: hosted
327 | version: "2.10.4"
328 | webview_flutter_platform_interface:
329 | dependency: transitive
330 | description:
331 | name: webview_flutter_platform_interface
332 | url: "https://pub.flutter-io.cn"
333 | source: hosted
334 | version: "1.9.5"
335 | webview_flutter_wkwebview:
336 | dependency: transitive
337 | description:
338 | name: webview_flutter_wkwebview
339 | url: "https://pub.flutter-io.cn"
340 | source: hosted
341 | version: "2.9.5"
342 | win32:
343 | dependency: transitive
344 | description:
345 | name: win32
346 | url: "https://pub.flutter-io.cn"
347 | source: hosted
348 | version: "2.6.1"
349 | xterm:
350 | dependency: "direct main"
351 | description:
352 | path: "."
353 | ref: HEAD
354 | resolved-ref: cb0de8b55858cee8261ca3676074851eb4beb7c2
355 | url: "https://github.com/TerminalStudio/xterm.dart"
356 | source: git
357 | version: "3.2.7"
358 | sdks:
359 | dart: ">=2.18.0 <3.0.0"
360 | flutter: ">=3.0.0"
361 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: termare_app
2 | description: A new Flutter project.
3 |
4 | publish_to: 'none'
5 |
6 | version: 1.0.0+1
7 |
8 | environment:
9 | sdk: ">=2.9.0 <3.0.0"
10 |
11 | dependencies:
12 | xterm:
13 | git: https://github.com/TerminalStudio/xterm.dart
14 |
15 | flutter_acrylic: ^1.0.0
16 | pty:
17 | git: https://github.com/TerminalStudio/pty
18 | vibration: ^1.7.3
19 | archive: ^3.1.2
20 | get: ^4.1.4
21 | flutter:
22 | sdk: flutter
23 | # just_audio: ^0.9.5
24 | global_repository:
25 | git: https://github.com/nightmare-space/global_repository
26 | cupertino_icons: ^1.0.2
27 | dio: ^4.0.0
28 | webview_flutter: ^2.0.12
29 | pseudo_terminal_utils:
30 | git: https://github.com/Termare/pseudo_terminal_utils
31 | dev_dependencies:
32 | flutter_test:
33 | sdk: flutter
34 |
35 |
36 | flutter:
37 | uses-material-design: true
38 | fonts:
39 | - family: SourceCodePro
40 | fonts:
41 | - asset: assets/fonts/SourceCodePro.ttf
42 | - family: SourceCodeProMediumforPowerline
43 | fonts:
44 | - asset: assets/fonts/SourceCodeProMediumforPowerline.otf
45 | - family: MesloLGMforPowerline
46 | fonts:
47 | - asset: assets/fonts/MesloLGMforPowerline.ttf
48 | - family: MenloforPowerline
49 | fonts:
50 | - asset: assets/fonts/MenloforPowerline.ttf
51 | - family: DroidSansMono
52 | fonts:
53 | - asset: assets/fonts/DroidSansMono.ttf
54 |
55 | assets:
56 | - assets/ogg/
57 | - assets/icons/
58 | - assets/lib/
59 | - assets/text/
60 |
61 |
62 | dependency_overrides:
63 | # xterm:
64 | # path: /Users/nightmare/Desktop/TerminalStudio/xterm.dart
--------------------------------------------------------------------------------
/screencap/cmatrix-r.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/screencap/cmatrix-r.jpg
--------------------------------------------------------------------------------
/screencap/cmatrix.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/screencap/cmatrix.jpg
--------------------------------------------------------------------------------
/screencap/dart-version.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/screencap/dart-version.jpg
--------------------------------------------------------------------------------
/screencap/htop.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/screencap/htop.jpg
--------------------------------------------------------------------------------
/screencap/mac-neofetch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/screencap/mac-neofetch.png
--------------------------------------------------------------------------------
/screencap/nano.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/screencap/nano.jpg
--------------------------------------------------------------------------------
/screencap/oh_my_zsh.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/screencap/oh_my_zsh.jpg
--------------------------------------------------------------------------------
/screencap/select-page.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/screencap/select-page.jpg
--------------------------------------------------------------------------------
/screencap/setting-page-01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/screencap/setting-page-01.jpg
--------------------------------------------------------------------------------
/screencap/setting-page-02.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/screencap/setting-page-02.jpg
--------------------------------------------------------------------------------
/screencap/sl.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/screencap/sl.jpg
--------------------------------------------------------------------------------
/screencap/vim.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/screencap/vim.jpg
--------------------------------------------------------------------------------
/scripts/build_macos.sh:
--------------------------------------------------------------------------------
1 | flutter build macos
--------------------------------------------------------------------------------
/scripts/build_windows.bat:
--------------------------------------------------------------------------------
1 | flutter build windows
--------------------------------------------------------------------------------
/scripts/clean.sh:
--------------------------------------------------------------------------------
1 | flutter clean
--------------------------------------------------------------------------------
/scripts/generate_mac_app.sh:
--------------------------------------------------------------------------------
1 | flutter build macos
2 | rm -rf ./build/macos/Build/Products/Release/移动到这
3 | ln -s -f /Applications ./build/macos/Build/Products/Release/移动到这
4 | tar -zcvf ./Termare.tar -C ./build/macos/Build/Products/ Release/Termare.app/ Release/移动到这
5 | rm -rf ./build/macos/Build/Products/Release/移动到这
--------------------------------------------------------------------------------
/scripts/patch_executable.sh:
--------------------------------------------------------------------------------
1 | cp ./executable/macos/adb ./build/macos/Build/Products/Release/adb_tool.app/Contents/MacOS/data/usr/bin/
2 | mkdir -p ./build/macos/Build/Products/Release/adb_tool.app/Contents/MacOS/data/usr/bin
3 | cp ./executable/macos/adb ./build/macos/Build/Products/Debug/adb_tool.app/Contents/MacOS/data/usr/bin/
--------------------------------------------------------------------------------
/scripts/properties.sh:
--------------------------------------------------------------------------------
1 | VERSION='1.0.0'
2 | TARGET_PATH=root@$server:/home/nightmare/YanTool/resources/Termare
3 | APP_NAME='Termare'
--------------------------------------------------------------------------------
/scripts/run_release.sh:
--------------------------------------------------------------------------------
1 | flutter run --release
--------------------------------------------------------------------------------
/scripts/upload/upload.sh:
--------------------------------------------------------------------------------
1 | LOCAL_DIR=$(cd `dirname $0`; pwd)
2 | PROJECT_DIR=$LOCAL_DIR/../..
3 | source $LOCAL_DIR/../properties.sh
4 | echo $PROJECT_DIR
5 | if [ -f $PROJECT_DIR/$app_name'_macOS.tar' ]; then
6 | rsync -v $PROJECT_DIR/$app_name'_macOS.tar' $TARGET_PATH'/'$app_name'_'$version'_macOS'.tar
7 | fi
8 | rsync -v $PROJECT_DIR/build/app/outputs/flutter-apk/app-release.apk $TARGET_PATH/$APP_NAME'_'$VERSION'_'Android_arm64.apk
9 |
--------------------------------------------------------------------------------
/test/widget_test.dart:
--------------------------------------------------------------------------------
1 | // This is a basic Flutter widget test.
2 | //
3 | // To perform an interaction with a widget in your test, use the WidgetTester
4 | // utility that Flutter provides. For example, you can send tap and scroll
5 | // gestures. You can also use WidgetTester to find child widgets in the widget
6 | // tree, read text, and verify that the values of widget properties are correct.
7 |
8 | import 'package:flutter/material.dart';
9 | import 'package:flutter_test/flutter_test.dart';
10 |
11 | import 'package:termare_app/main.dart';
12 |
13 | void main() {
14 | // testWidgets('Counter increments smoke test', (WidgetTester tester) async {
15 | // // Build our app and trigger a frame.
16 | // await tester.pumpWidget(const MyApp());
17 |
18 | // // Verify that our counter starts at 0.
19 | // expect(find.text('0'), findsOneWidget);
20 | // expect(find.text('1'), findsNothing);
21 |
22 | // // Tap the '+' icon and trigger a frame.
23 | // await tester.tap(find.byIcon(Icons.add));
24 | // await tester.pump();
25 |
26 | // // Verify that our counter has incremented.
27 | // expect(find.text('0'), findsNothing);
28 | // expect(find.text('1'), findsOneWidget);
29 | // });
30 | }
31 |
--------------------------------------------------------------------------------
/web/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/web/favicon.png
--------------------------------------------------------------------------------
/web/icons/Icon-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/web/icons/Icon-192.png
--------------------------------------------------------------------------------
/web/icons/Icon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Termare/termare_app/37543659928881391ead872e8ab59805d91e8ddc/web/icons/Icon-512.png
--------------------------------------------------------------------------------
/web/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | termare_app
30 |
31 |
32 |
33 |
36 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/web/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "termare_app",
3 | "short_name": "termare_app",
4 | "start_url": ".",
5 | "display": "standalone",
6 | "background_color": "#0175C2",
7 | "theme_color": "#0175C2",
8 | "description": "A new Flutter project.",
9 | "orientation": "portrait-primary",
10 | "prefer_related_applications": false,
11 | "icons": [
12 | {
13 | "src": "icons/Icon-192.png",
14 | "sizes": "192x192",
15 | "type": "image/png"
16 | },
17 | {
18 | "src": "icons/Icon-512.png",
19 | "sizes": "512x512",
20 | "type": "image/png"
21 | }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------