Compare commits

...

251 Commits

Author SHA1 Message Date
Eugene Pankov
d3a192da58 offer using Alt key as Meta key (fixes #316) 2018-04-24 16:41:34 +02:00
Eugene Pankov
4b30dfef58 settings layout fixes 2018-04-24 16:07:42 +02:00
Eugene Pankov
8432e3ef66 remove selection after copying using smart Ctrl-C 2018-04-24 16:01:05 +02:00
Eugene Pankov
cdfd84a7f8 auto-show window when cmd-tabbing into Terminus 2018-04-24 15:56:54 +02:00
Eugene Pankov
128fe24003 fixed NPM detection in cases when node is not on PATH 2018-04-03 13:31:56 +02:00
Eugene Pankov
30f221d05e convert CRLF to LF on paste (fixes #293) 2018-04-01 20:05:30 +02:00
Eugene Pankov
5087224017 refreshed settings UI (fixes #314) 2018-04-01 19:51:04 +02:00
Eugene Pankov
9a8bad4851 touchbar improvements 2018-04-01 19:50:43 +02:00
Eugene Pankov
c3c983daf6 updated to the new NPM API 2018-03-31 13:23:32 +02:00
Eugene Pankov
dce8647f55 smart ctrl-c behaviour (fixes #307) 2018-03-30 23:42:50 +02:00
Eugene Pankov
f947fe3f0f paste as a configurable hotkey (fixes #260) 2018-03-30 23:33:46 +02:00
Eugene Pankov
b5f96a59f8 copy notification 2018-03-30 23:24:34 +02:00
Eugene Pankov
c90a5678cf don't repatch node-pty on window reload 2018-03-29 14:23:33 +02:00
Eugene Pankov
663da34e6d performance improv for flowing output 2018-03-29 00:25:57 +02:00
Eugene Pankov
049f08b8f9 namespacing fix 2018-03-24 23:45:40 +01:00
Eugene Pankov
3c3b14bf09 Smarted spawn hotkey behaviour on macOS to give the focus to the previous app on hide 2018-03-24 23:40:45 +01:00
Eugene Pankov
5e07dd5442 macOS touchbar support 2018-03-24 23:19:47 +01:00
Eugene Pankov
8f2d2cbe30 don't attempt to resize beyond min size when docking (fixes #308) 2018-03-23 17:53:20 +01:00
Eugene Pankov
bebde4799d updated tab design 2018-03-23 17:45:11 +01:00
Eugene Pankov
9cedeb3efb build fixes 2018-03-23 17:15:11 +01:00
Eugene Pankov
63158ac6cd package.json fix 2018-03-18 19:07:31 +01:00
Eugene Pankov
4f44087989 possibly npm $PATH (fixes #305, fixes #4) 2018-03-18 18:59:58 +01:00
Eugene Pankov
ab3c49b9b2 upgraded electron (fixes #306) 2018-03-18 17:36:19 +01:00
Eugene Pankov
28d01a1b56 added gnome-python2-gnomekeyring RPM dependency (fixes #302) 2018-03-13 11:37:59 +01:00
Eugene Pankov
a979f0108e added a tray icon (fixes #226) 2018-03-11 20:29:53 +01:00
Eugene Pankov
3c74b8ec38 possible fix to docking (fixes #9, fixes #18) 2018-03-11 20:07:02 +01:00
Eugene Pankov
9d7bf2ae44 skip failing tmux init commands (fixes #300) 2018-03-11 20:01:48 +01:00
Eugene Pankov
3b43b3914b added powershell core as a separate shell (#123) 2018-03-11 19:53:13 +01:00
Eugene Pankov
e9f22dd8b5 yarn bump 2018-03-11 19:53:10 +01:00
Eugene Pankov
e68cafdb70 fullscreen mode (fixes #283) 2018-02-12 17:04:49 +01:00
Eugene Pankov
fde16b8699 fixed #291 2018-02-12 16:54:04 +01:00
Eugene Pankov
245c65d750 bumped electron 2018-02-12 16:52:40 +01:00
Eugene Pankov
c7d9f944d5 Merge pull request #285 from VaultVulp/master
Fixed typo in SSH client's configuration window.
2018-02-03 10:11:17 +01:00
Pavel Alimpiev
4ca806e142 Fixed typo in SSH client's configuration window. 2018-02-03 01:15:55 +03:00
Eugene Pankov
0255985bc6 icon update 2018-01-24 19:39:51 +01:00
Eugene Pankov
104f1ee7aa yarn.lock 2018-01-24 16:40:35 +01:00
Eugene Pankov
132d0553ae fixed alt-arrow keys on Mac as well as Home and End combinations (fixes #255) 2018-01-24 16:40:30 +01:00
Eugene Pankov
b007ff6ff6 scrollbar fix 2018-01-24 16:01:32 +01:00
Eugene Pankov
2bea4b9d6c bump 2018-01-19 15:57:33 +01:00
Eugene Pankov
4a76c12f15 ignore Hyper theme errors 2018-01-19 15:53:14 +01:00
Eugene Pankov
181f3e3d33 Merge branch 'master' of github.com:Eugeny/terminus 2018-01-19 15:37:51 +01:00
Eugene Pankov
ee2fadbf60 added message popups 2018-01-19 15:31:28 +01:00
Eugene Pankov
4259d3b53d enforce GPU composition 2018-01-19 15:30:52 +01:00
Eugene Pankov
65aaa131ef removed Screen hotkeys from the standard macOS config 2018-01-04 21:38:17 +01:00
Eugene Pankov
46d9aabbdd configure() doesn't have to be async 2018-01-04 21:38:02 +01:00
Eugene Pankov
692045ce77 fixed button alignment on macOS 2018-01-04 21:20:42 +01:00
Eugene Pankov
9c257b0002 allow specifying the SSH port (fixes #269) 2018-01-04 21:13:46 +01:00
Eugene Pankov
15c23eb7dd deps 2018-01-04 21:04:44 +01:00
Eugene Pankov
5fc67d3648 launch devtools in detached mode 2018-01-04 21:04:31 +01:00
Eugene Pankov
571884f39c Merge branch 'master' of github.com:Eugeny/terminus 2017-12-27 23:12:50 +01:00
Eugene Pankov
ccbcd30813 support encrypted private ssh keys (fixes #262) 2017-12-27 23:11:28 +01:00
Eugene Pankov
30666c2838 Merge pull request #241 from tnguyen14/base16-xresources
use base16-xresources
2017-12-15 19:07:55 +01:00
Tri Nguyen
953558a866 process #define variables 2017-12-14 23:51:21 -05:00
Eugene Pankov
ace81aced2 Merge pull request #261 from kwonoj/feat-tab-cycle
feat(tab): enable cycle tab selection
2017-12-14 19:48:48 +01:00
OJ Kwon
dc781deeb0 feat(tab): enable cycle tab selection 2017-12-14 08:40:00 -08:00
Eugene Pankov
e24d3d56eb Revert "Delete icon.ico"
This reverts commit aaac14dbd5.
2017-12-14 17:32:41 +01:00
Eugene Pankov
6f35e60468 added missing hotkeys 2017-12-14 15:03:51 +01:00
Eugene Pankov
110b57bc64 added Ctrl-Tab hotkeys for tab switching 2017-12-14 14:56:59 +01:00
Eugene Pankov
fd47a32bdb use yarn for Travis builds 2017-12-14 14:55:31 +01:00
Eugene Pankov
dfd1ffbffc ssh agent support (closes #251) 2017-12-07 20:47:25 +01:00
Eugene Pankov
f841cfeb5e Merge branch 'master' of github.com:Eugeny/terminus 2017-12-07 20:21:58 +01:00
Eugene Pankov
9d2398bc12 fixed tmux argument list handling (closes #231) 2017-12-07 20:21:02 +01:00
Eugene Pankov
da9cee0792 Delete Info.plist 2017-12-05 12:26:39 +01:00
Eugene Pankov
aaac14dbd5 Delete icon.ico 2017-12-05 12:25:40 +01:00
Eugene Pankov
23396b5c53 Delete build.wxs 2017-12-05 12:25:30 +01:00
Eugene Pankov
021390952a Delete elements.wxs 2017-12-05 12:25:16 +01:00
Eugene Pankov
ad59baa4f5 Delete wix-theme.xml 2017-12-05 12:25:06 +01:00
Eugene Pankov
0420b2dbb9 Merge pull request #254 from tnguyen14/update-hacking-npm-install
update instruction to use npx
2017-12-01 15:42:02 +01:00
Tri Nguyen
fab9429707 update instruction to use npx 2017-12-01 09:31:00 -05:00
Eugene Pankov
5b62d5f92a Merge pull request #252 from tnguyen14/local-npx
Include all build tools in project's dependencies
2017-12-01 09:00:30 +01:00
Eugene Pankov
298637a150 Merge branch 'master' of github.com:Eugeny/terminus 2017-11-28 22:02:43 +01:00
Eugene Pankov
49c738451e fixed the private key selection dialog 2017-11-28 22:02:28 +01:00
Eugene Pankov
892b18df4d fixed #250 2017-11-28 20:30:06 +01:00
Tri Nguyen
de6e545f8f Include all build tools in project's dependencies 2017-11-28 00:19:38 -05:00
Tri Nguyen
e3d1d5e61e use base16-xresources 2017-11-27 23:37:07 -05:00
Eugene Pankov
d9e337aa46 build fix 2017-11-27 22:37:32 +01:00
Eugene Pankov
2881481fc2 higher log verbosity 2017-11-27 22:37:15 +01:00
Eugene Pankov
fa4c59e3c0 support Xresources colors beyond 16 2017-11-27 21:29:35 +01:00
Eugene Pankov
f783e1ab06 ssh plugin fixes 2017-11-27 17:29:45 +01:00
Eugene Pankov
5cdb7527c8 added SSH connection manager (fixes #220) 2017-11-27 16:30:59 +01:00
Eugene Pankov
13a76db9af Merge branch 'master' of github.com:Eugeny/terminus 2017-11-26 22:14:57 +01:00
Eugene Pankov
0de12b6b38 allow disabling plugins 2017-11-26 22:14:46 +01:00
Eugene Pankov
92993db122 fixed #234 2017-11-21 22:16:59 +01:00
Eugene Pankov
02082c385c include wincredmgr for Windows 2017-11-21 22:15:23 +01:00
Eugene Pankov
0c15f5033d build fix 2017-11-18 23:07:02 +01:00
Eugene Pankov
a280658bbb added xkeyring dep 2017-11-18 22:41:13 +01:00
Eugene Pankov
3673542197 bumped plugins 2017-11-18 22:40:57 +01:00
Eugene Pankov
11f188f1e8 layout fix 2017-11-16 22:54:37 +01:00
Eugene Pankov
9a9db28054 Merge branch 'master' of github.com:Eugeny/terminus 2017-11-16 22:49:23 +01:00
Eugene Pankov
47d57d08ee rearranged terminal settings tab 2017-11-16 22:46:33 +01:00
Eugene Pankov
39e2c386f0 copy-on-select and right click behaviour settings (fixes #201) 2017-11-16 22:37:41 +01:00
Eugene Pankov
c73d39026b API updates 2017-11-04 19:06:58 +01:00
Eugene Pankov
89dff969b1 bumped plugins 2017-10-31 15:27:28 +01:00
Eugene Pankov
e1eb1beb87 log into a file 2017-10-23 22:58:19 +02:00
Eugene Pankov
8d12d6a547 allow specifying a custom startup directory (fixes #223) 2017-10-23 21:54:40 +02:00
Eugene Pankov
33f67503bd pass alt-numbers to the shell (fixes #217) 2017-10-22 22:10:48 +02:00
Eugene Pankov
21e1656780 only show drag space on Win & Linux with thin titlebar (ref #219) 2017-10-22 21:23:53 +02:00
Eugene Pankov
ceacf5c760 added tab context menu (ref #219) 2017-10-22 21:01:31 +02:00
Eugene Pankov
e0c0cd17bd Handle multiple arguments in custom shell 2017-10-21 22:11:27 +02:00
Eugene Pankov
e81e5034b9 explicitly specify --login for POSIX shells 2017-10-20 21:44:34 +02:00
Eugene Pankov
11e0c36ebc properly position context menu (fixes #215) 2017-10-13 20:33:10 +02:00
Eugene Pankov
e52fd0a3dd theming fix 2017-10-08 14:56:51 +02:00
Eugene Pankov
48ccc538e5 fixed button group appearance in settings 2017-10-08 14:48:59 +02:00
Eugene Pankov
53ac39232c a compact theme 2017-10-08 14:47:14 +02:00
Eugene Pankov
f68e06c9ed . 2017-10-07 18:09:22 +02:00
Eugene Pankov
6c884e090c blinking cursor (fixes #191) 2017-10-07 18:07:57 +02:00
Eugene Pankov
38cda117e2 option to auto-start a terminal tab (fixes #107) 2017-10-07 17:47:04 +02:00
Eugene Pankov
fb64ca08d3 custom shells (fixes #50) 2017-10-07 17:27:58 +02:00
Eugene Pankov
0fe7edc5b5 auto reposition window on resolution changes (fixes #150) 2017-10-07 16:47:37 +02:00
Eugene Pankov
1614405c62 link plugin pages in the plugin list 2017-09-28 20:47:19 +02:00
Eugene Pankov
87730ba7b3 fixed #204 2017-09-28 20:34:37 +02:00
Eugene Pankov
eb2eef64fc fixed #133 2017-09-28 20:27:16 +02:00
Eugene Pankov
766ab48e1a ci fix 2017-09-10 09:22:28 +02:00
Eugene Pankov
e255ca7737 context menu (fixes #42) 2017-09-09 21:42:48 +02:00
Eugene Pankov
558c72bb42 update checker (fixes #166, #99) 2017-09-09 14:09:27 +02:00
Eugene Pankov
ede59ed4d4 ignore stray tmux responses (fixes #178) 2017-09-09 13:25:12 +02:00
Eugene Pankov
3ced784568 drop x86 2017-09-09 12:55:20 +02:00
Eugene Pankov
6b12196761 properly close hotkey input windows (fixes #198) 2017-09-09 12:53:30 +02:00
Eugene Pankov
9f58e9f183 ci 2017-09-09 12:36:06 +02:00
Eugene Pankov
607efaa075 appveyor 2017-09-09 11:43:21 +02:00
Eugene Pankov
706f2042af travis 2017-09-09 11:33:06 +02:00
Eugene Pankov
fa2650cd1f appveyor fix 2017-09-06 17:07:14 +02:00
Eugene Pankov
33514cb073 bumped ng-bootstrap 2017-08-30 11:47:49 +02:00
Eugene Pankov
4d2be9ec89 handle Hyper plugin crashes (fixes #71) 2017-08-30 11:23:51 +02:00
Eugene Pankov
1b2236eb90 fixed #187, fixed #188 2017-08-30 11:12:04 +02:00
Eugene Pankov
f84fd07857 invert scroll-zoom (fixes #184) 2017-08-26 20:02:15 +02:00
Eugene Pankov
24c59b88ca Merge branch 'master' of https://github.com/Eugeny/terminus 2017-08-20 19:31:17 +02:00
Eugene Pankov
e45090cc89 handle compose key on Windows (fixes #17) 2017-08-20 19:31:15 +02:00
Eugene Pankov
f53b96eba8 detect git-bash when installed for current user only (closes #161) 2017-08-18 18:28:38 +03:00
Eugene Pankov
80699ee13f handle plugin loading errors 2017-08-13 15:13:04 +03:00
Eugene Pankov
7e7d537868 allow null values in config (fixes #165) 2017-08-11 19:47:52 +03:00
Eugene Pankov
1afb1e718b change default tmux hotkey (fixes #171) 2017-08-11 19:26:24 +03:00
Eugene Pankov
f71f518058 store Screen configuration in Terminus user directory (fixes #177) 2017-08-11 19:21:32 +03:00
Eugene Pankov
7a005132cc Merge branch 'master' of github.com:Eugeny/terminus 2017-08-11 19:17:54 +03:00
Eugene Pankov
34ef809aee handle null results from winreg (fixes #174) 2017-08-11 19:16:58 +03:00
Eugene Pankov
6352f22c48 Merge pull request #167 from koraktor/patch-1
Start an interactive logon shell for Git Bash
2017-08-07 13:52:54 +02:00
Sebastian Staudt
d0f378764f Start an interactive logon shell for Git Bash
Provide additional arguments to `bash.exe` to get an interactive login shell.
This ensures e.g. `.profile` and `.bash_profile` are sourced. As there’s no way
to have an existing session under Windows, `--login` is mandatory. Each bash
session must be started from scratch.

Fixes #105
2017-08-07 10:07:07 +02:00
Eugene Pankov
7885badbfd make line padding adjustable (fixes #141) 2017-08-05 16:57:00 +02:00
Eugene Pankov
5999d169bc mac & windows icons 2017-08-05 16:27:25 +02:00
Eugene Pankov
40b0f8cb69 added tmux dependency 2017-08-05 10:15:07 +02:00
Eugene Pankov
f428be5ae7 ignore unavaiable persistence providers in SessionsService (fixes #159) 2017-08-05 09:25:25 +02:00
Eugene Pankov
39183b1205 Merge branch 'master' of github.com:Eugeny/terminus 2017-08-04 14:42:06 +02:00
Eugene Pankov
36f82545ae fixed #155 2017-08-04 14:41:36 +02:00
Eugene Pankov
1ef8343ea9 default to tmux if available on Linux 2017-08-04 14:40:49 +02:00
fossabot
c9e24819ae Add license scan report and status 2017-08-04 13:39:41 +02:00
Eugene Pankov
e2f0ceef19 README 2017-08-04 13:26:08 +02:00
Eugene Pankov
acd6995bcc README 2017-08-04 13:25:14 +02:00
Eugene Pankov
ca5e6079bc README 2017-08-04 13:22:38 +02:00
Eugene Pankov
48ad16946b README 2017-08-04 13:20:44 +02:00
Eugene Pankov
0a8af12a93 branding 2017-08-04 13:17:50 +02:00
Eugene Pankov
7e602a3612 bump 2017-08-02 15:22:32 +02:00
Eugene Pankov
c880db21a1 README update 2017-08-02 15:19:47 +02:00
Eugene Pankov
26e212ff2f bump 2017-08-02 14:31:07 +02:00
Eugene Pankov
cdc7daf029 exported TerminalService 2017-08-02 14:30:52 +02:00
Eugene Pankov
41b6e1d54e expose TerminalService 2017-08-02 13:47:50 +02:00
Eugene Pankov
1c62f3074c selectable persistence providers 2017-07-31 13:52:32 +02:00
Eugene Pankov
514fdbfb6a build fix 2017-07-30 21:24:27 +02:00
Eugene Pankov
466d862caa tmux fixes 2017-07-30 21:03:35 +02:00
Eugene Pankov
1f825b16c1 make shell providers pluggable 2017-07-30 20:58:31 +02:00
Eugene Pankov
17ad43bf65 cursor shape hints 2017-07-30 20:47:37 +02:00
Eugene Pankov
c957ebabda tmux: PID detection 2017-07-29 10:11:30 +02:00
Eugene Pankov
0755ff291d docs 2017-07-28 09:18:37 +02:00
Eugene Pankov
c0c2b693f3 autoselect tmux 2017-07-27 12:54:51 +02:00
Eugene Pankov
23dabca2ab . 2017-07-26 19:59:05 +02:00
Eugene Pankov
98a5a95bec wip 2017-07-26 19:29:47 +02:00
Eugene Pankov
5045c4c82a wip 2017-07-26 16:14:18 +02:00
Eugene Pankov
feb4c5bcb6 tmux wip 2017-07-26 16:04:55 +02:00
Eugene Pankov
de29e34363 possible fix for docking sizing (#9) 2017-07-25 21:49:20 +02:00
Eugene Pankov
0fe2de591a cursor shape setting (fixes #55) 2017-07-25 19:36:28 +02:00
Eugene Pankov
9bee253dd0 reapply screen config on reattach 2017-07-24 16:04:17 +02:00
Eugene Pankov
a26b38f5ae . 2017-07-24 15:34:30 +02:00
Eugene Pankov
9312db1fc6 fixed #126 2017-07-24 14:48:16 +02:00
Eugene Pankov
932ed9b8f2 proper visual bell (fixes #131) 2017-07-23 20:55:41 +02:00
Eugene Pankov
49b90f15bc inherit session environment (fixes #119, fixes #125, fixes #124, fixes #129) 2017-07-20 23:32:17 +02:00
Eugene Pankov
5f5772501b apply styles on start and to the terminal iframe (fixes #134) 2017-07-20 23:09:04 +02:00
Eugene Pankov
ed0bfb39f3 fixes 2017-07-15 19:17:44 +02:00
Eugene Pankov
60ce10d1e3 tab renaming (fixes #19) 2017-07-15 19:11:49 +02:00
Eugene Pankov
e64126af37 bumped Angular 2017-07-15 19:07:41 +02:00
Eugene Pankov
19565fba2c re-enable Ctrl-S on Linux (fixes #111) 2017-07-15 18:33:53 +02:00
Eugene Pankov
f39443b0ff fix 2017-07-15 18:20:51 +02:00
Eugene Pankov
5dde5479d8 bump 2017-07-15 18:16:45 +02:00
Eugene Pankov
3d29b99ddf use yarn for plugin deps 2017-07-15 18:16:27 +02:00
Eugene Pankov
4ba7cf106f provide a fallback monospace font for characters missing in user's font (fixes #112) 2017-07-15 18:15:49 +02:00
Eugene Pankov
23c7acde51 fixed CLI paths on Windows (fixes #90) 2017-07-12 20:52:06 +02:00
Eugene Pankov
c41efbd62b quit properly (fixes #109) 2017-07-12 20:24:35 +02:00
Eugene Pankov
1643ca2bd5 Merge branch 'master' of https://github.com/Eugeny/terminus 2017-07-10 18:26:47 +02:00
Eugene Pankov
b640abd85d set proper $TERM on Windows (fixes #91, fixes #28) 2017-07-10 18:26:46 +02:00
Tri Nguyen
dcf9817075 update Base16 Default Dark theme to 256 colors 2017-07-10 18:12:44 +02:00
Eugene Pankov
6f8f83d178 detect 32-bit Cygwin setups (fixes #106) 2017-07-10 18:11:47 +02:00
Eugene Pankov
475c4f91be handle directory paths supplied on cli (fixes #90) 2017-07-10 17:57:58 +02:00
Eugene Pankov
29a6fb60de make middle mouse button close tabs (fixes #92) 2017-07-10 17:35:01 +02:00
Eugene Pankov
42007f4fef upgraded node-pty (fixes #84) 2017-07-10 17:30:42 +02:00
Eugene Pankov
92c0df7629 Merge branch 'master' of github.com:Eugeny/terminus 2017-07-10 15:30:51 +02:00
Eugene Pankov
e70cb25180 non-debug start script 2017-07-10 15:25:50 +02:00
Eugene Pankov
980834df6f macOS UTF8 fixes fixed #31, fixed #40 2017-07-08 11:30:25 +02:00
Eugene Pankov
50968508df fixed cwd detection on el capitan (fixes #63) 2017-07-06 10:37:52 +02:00
Eugene Pankov
8ee93297be properly display Space in hotkeys (fixes #76) 2017-07-06 10:28:33 +02:00
Eugene Pankov
dc9b2553ae Merge branch 'master' of github.com:Eugeny/terminus 2017-07-06 10:28:31 +02:00
Eugene Pankov
a6f7f7aa05 re-re-fixed custom npm path detection 2017-07-05 21:13:41 +02:00
Eugene Pankov
c087a969d6 cmd-k to clear the terminal (fixes #39) 2017-07-05 19:31:58 +02:00
Eugene Pankov
f4eb03fee0 proper macOS menu (fixes #39) 2017-07-05 19:05:45 +02:00
Eugene Pankov
deb4b963cd copy hotkey for macOS (fixes #61) 2017-07-05 18:46:16 +02:00
Eugene Pankov
9834b27b8d bump 2017-07-05 16:24:03 +02:00
Eugene Pankov
fc060acd88 open new tabs from cli (fixes #67) 2017-07-05 16:22:44 +02:00
Eugene Pankov
709ffadc7c don't resize dead PTYs 2017-07-05 15:33:50 +02:00
Eugene Pankov
536d9537ff show plugin author names 2017-07-05 15:31:23 +02:00
Eugene Pankov
94217f0b01 ignore screen shutdown errors 2017-07-05 15:21:01 +02:00
Eugene Pankov
80762e92d6 don't crash when closing a background tab after recovery 2017-07-05 14:58:40 +02:00
Eugene Pankov
e6ef21fa9d replaced fs-promise with mz/fs 2017-07-05 14:48:02 +02:00
Eugene Pankov
da89560d6b fixed #2 - search for NPM in profile search paths 2017-07-05 14:46:04 +02:00
Eugene Pankov
c0c2373ed6 hopefully fixed #2 2017-07-05 12:49:01 +02:00
Eugene Pankov
f2a8eb92a1 add a custom npm path option (fixes #10) 2017-07-05 11:36:00 +02:00
Eugene Pankov
48e8ffd729 ligatures switch (fixes #51) 2017-07-05 11:26:28 +02:00
Eugene Pankov
7327a7008c . 2017-07-05 11:09:17 +02:00
Eugene Pankov
856c7e7e9e fixed #62 2017-07-05 11:07:46 +02:00
Eugene Pankov
353a4da083 added zoom hotkeys & mouse handler (fixes #24) 2017-07-05 11:01:03 +02:00
Eugene Pankov
3068c27fd6 Merge branch 'master' of github.com:Eugeny/terminus 2017-07-04 22:18:40 +02:00
Eugene Pankov
7de0bd95b9 fixed env.HOME on Windows (fixes #6, fixes #60) 2017-07-04 18:25:58 +02:00
Eugene Pankov
904828c3e3 hterm update 2017-07-04 18:17:23 +02:00
Eugene Pankov
63757f7726 bumped community color schemes 2017-07-04 16:15:53 +02:00
Tri Nguyen
05f16f1719 add Base16 color scheme
This was generated using https://github.com/mbadolato/iTerm2-Color-Schemes/blob/master/tools/xrdb2Xresources.py
from a xrdb file, which was generated by using https://github.com/mbadolato/iTerm2-Color-Schemes/blob/master/tools/iterm2xrdb
on https://github.com/chriskempson/base16-iterm2/blob/master/base16-default.dark.256.itermcolors
2017-07-04 16:15:17 +02:00
Tri Nguyen
78e115b698 npm is not Node Package Manager
npm does not (just?) stand for Node Package Manager
2017-07-04 11:51:21 +02:00
Idan Asraf
55b53ed5b7 Tab-close button outline removed 2017-07-04 11:50:42 +02:00
Eugene Pankov
1fa7b40913 Update HACKING.md 2017-07-04 11:48:03 +02:00
Eugene Pankov
5b7ded9097 make size non-observable 2017-07-03 19:00:58 +02:00
Eugene Pankov
06b60b86f2 emoji support (fixes #35) 2017-07-03 18:21:12 +02:00
Eugene Pankov
052c941275 yarn 2017-07-03 17:55:46 +02:00
Eugene Pankov
72899b0cf2 Merge branch 'master' of github.com:Eugeny/terminus 2017-07-03 17:50:36 +02:00
Eugene Pankov
342316f5a5 downgraded Electron (fixes #41) 2017-07-03 17:50:00 +02:00
Samuel Hilson
c215faaeb8 adding line to readme for copy and paste hotkey 2017-07-03 16:57:44 +02:00
Eugene Pankov
c4c342bd0a bumped color schemes 2017-07-03 15:25:13 +02:00
atelierbram
4472a033a1 added Base2Tone colorschemes 2017-07-03 15:23:26 +02:00
Eugene Pankov
093876a445 Delete .gitlab-ci.yml 2017-07-03 14:51:08 +02:00
Eugene Pankov
359e0926cb include version info in issues 2017-07-01 15:08:42 +02:00
Eugene Pankov
0e9282e079 docs 2017-07-01 14:13:07 +02:00
Eugene Pankov
5511f4d7cb docs fix 2017-07-01 14:03:14 +02:00
Eugene Pankov
3ae76e66ed Merge branch 'master' of github.com:Eugeny/terminus 2017-07-01 12:48:48 +02:00
Eugene Pankov
42059e3bc6 Create CODE_OF_CONDUCT.md 2017-07-01 10:54:04 +02:00
Eugene Pankov
c093b204d7 override plugin module resolution 2017-07-01 01:22:01 +02:00
Eugene Pankov
8a8f89b386 wip 2017-07-01 00:55:21 +02:00
Eugene Pankov
b109fb8766 plugin versions 2017-07-01 00:54:55 +02:00
Eugene Pankov
f58cf469ed Linux default shell fix 2017-06-30 21:20:03 +02:00
Eugene Pankov
57227ae6ce Merge branch 'master' of github.com:Eugeny/terminus 2017-06-30 21:08:19 +02:00
Eugene Pankov
b670fa843a don't force electron-debug 2017-06-30 21:08:12 +02:00
Eugene Pankov
c41e551c58 README update 2017-06-30 20:59:23 +02:00
Eugene Pankov
60b02b17e4 Start shell as login shell (fixes #2) 2017-06-30 20:52:22 +02:00
Eugene Pankov
bf8bb7ee80 use user's default shell (#2) 2017-06-30 20:44:17 +02:00
Eugene Pankov
1e1d48a5f8 rollback 2017-06-30 20:01:41 +02:00
Eugene Pankov
77b55a003c Git-bash support (fixes #12) 2017-06-30 19:54:17 +02:00
Eugene Pankov
165ab1cfbf version mgmt 2017-06-30 19:40:18 +02:00
Eugene Pankov
d4840bafaf Some docking fixes (fixed #13) 2017-06-30 19:39:01 +02:00
186 changed files with 15352 additions and 1289 deletions

View File

@@ -1,108 +0,0 @@
cache:
untracked: true
key: "$CI_BUILD_REF_NAME"
paths:
- app/node_modules
- node_modules
- typings
stages:
- Build
- Test
- Package
- Upload
Build:
stage: Build
script:
- npm prune
- npm install
- cd app; npm prune && npm install; cd ..
- ./node_modules/.bin/typings install
tags:
- Linux
artifacts:
paths:
- node_modules
- typings
- app
Test:
stage: Test
dependencies:
- Build
script:
- apt-get install -y xvfb libxtst6 libxss1 libgconf2-4 libnss3 libasound2
- xvfb-run -a make coverage
tags:
- Linux
Windows package:
stage: Package
dependencies:
- Build
script:
- call npm install
- call npm install webpack # regenerate the .cmd launcher
- cd app
- call npm install
- cd ..
- call ./node_modules/.bin/webpack.cmd --progress
- call make package-windows
- call copy dist\Elements-Electron.exe Elements-Windows-%CI_BUILD_REF_NAME%.exe
artifacts:
name: Elements-Windows-%CI_BUILD_REF_NAME%
paths:
- Elements-Windows-%CI_BUILD_REF_NAME%.exe
tags:
- Windows
macOS package:
stage: Package
dependencies:
- Build
script:
- npm install
- rm -rf node_modules/electron-macos-sign || true
- cp -r node_modules/electron-osx-sign node_modules/electron-macos-sign
- cd app; npm install; cd ..
- ./node_modules/.bin/webpack --progress
- security unlock-keychain -p rjvg login.keychain
- make package-mac
- cp dist/Elements-Electron.pkg ./Elements-macOS-$CI_BUILD_REF_NAME.pkg
artifacts:
name: Elements-macOS-$CI_BUILD_REF_NAME
paths:
- Elements-macOS-$CI_BUILD_REF_NAME.pkg
tags:
- macOS
Linux package:
stage: Package
dependencies:
- Build
script:
- npm install
- cd app; npm install; cd ..
- ./node_modules/.bin/webpack --progress
- make build-linux
- cp dist/ELEMENTS*.AppImage ./Elements-Linux-$CI_BUILD_REF_NAME.AppImage
artifacts:
name: Elements-Linux-$CI_BUILD_REF_NAME
paths:
- Elements-Linux-$CI_BUILD_REF_NAME.AppImage
tags:
- Linux
Upload packages:
stage: Upload
dependencies:
- Windows package
- macOS package
- Linux package
script:
- scp Elements-Windows-$CI_BUILD_REF_NAME.exe root@cloud.elements.tv:/mnt/elements/www/clients/
- scp Elements-macOS-$CI_BUILD_REF_NAME.pkg root@cloud.elements.tv:/mnt/elements/www/clients/
- scp Elements-Linux-$CI_BUILD_REF_NAME.AppImage root@cloud.elements.tv:/mnt/elements/www/clients/
tags:
- Local

View File

@@ -14,12 +14,12 @@ cache:
- app/node_modules
before_install:
- npm i
- yarn install
- scripts/install-deps.js
script:
- scripts/build-native.js
- npm run build
- yarn run build
- scripts/prepackage-plugins.js
- scripts/build-$BUILD_FOR.js
@@ -32,12 +32,7 @@ addons:
- rpm
- wine
- mono-runtime
deploy:
provider: releases
api_key: $GITHUB_TOKEN
file_glob: true
file: "dist/terminus*"
skip_cleanup: true
on:
tags: true
- yarn
sources:
- sourceline: 'deb https://dl.yarnpkg.com/debian/ stable main'
key_url: 'https://dl.yarnpkg.com/debian/pubkey.gpg'

46
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,46 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at e@ajenti.org. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

View File

@@ -10,12 +10,13 @@ First, install the dependencies:
```
# macOS/Linux:
npm i
npm install
./scripts/install-deps.js
./scripts/build-native.js
# Windows:
npm i
npm -g install windows-build-tools
npm install
node scripts\install-deps.js
node scripts\build-native.js
```
@@ -67,7 +68,11 @@ terminus-pluginname
# Plugins
The app will load all plugins from the source checkout in the dev mode, and from the user's plugins directory at all times (click `Open Plugins Directory` under `Settings` > `Plugins`).
The app will load all plugins from the source checkout in the dev mode, from the user's plugins directory at all times (click `Open Plugins Directory` under `Settings` > `Plugins`) and from the directory specified by the `TERMINUS_PLUGINS` environment var.
Only modules whose `package.json` file contains a `terminus-plugin` keyword will be loaded.
If you're currently in your plugin's directory, start Terminus as `TERMINUS_PLUGINS=$(pwd) terminus --debug`
A plugin should only provide a default export, which should be a `NgModule` class (or a `NgModuleWithDependencies` where applicable). This module will be injected as a dependency to the app's root module.

View File

@@ -1,7 +1,16 @@
# Terminus α
*A terminal for a more modern age*
<div align="center">
<img src="https://raw.githubusercontent.com/Eugeny/terminus/master/build/icons/128x128.png">
<h1>Terminus α</h1>
<p>
<i>A terminal for a more modern age</i>
</p>
<br/>
<br/>
<br/>
</div>
[![Build Status](https://travis-ci.org/Eugeny/terminus.svg?branch=master)](https://travis-ci.org/Eugeny/terminus) [![Build status](https://ci.appveyor.com/api/projects/status/wnnq4hm5mbd9rgoy?svg=true)](https://ci.appveyor.com/project/Eugeny/terminus) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/Eugeny/terminus/master/LICENSE) [![Downloads](https://img.shields.io/badge/downloads-latest_release-brightgreen.svg)](https://github.com/Eugeny/terminus/releases/latest)
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2FEugeny%2Fterminus.svg?type=shield)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2FEugeny%2Fterminus?ref=badge_shield)
----
@@ -17,7 +26,18 @@
* Doesn't choke on fast-flowing outputs
* Tab persistence on macOS and Linux
* Proper shell-like experience on Windows including tab completion (thanks, Clink!)
* CMD, PowerShell and Bash on Windows support
* CMD, PowerShell, Cygwin, Git-Bash and Bash on Windows support
* Default Linux style hotkeys for copy (`Ctrl`+`Shift`+`C`) and paste (`Ctrl`+`Shift`+`V`)
---
# Plugins
Plugins can be installed directly from the Settings view inside Terminus.
* [clickable-links](https://github.com/Eugeny/terminus-clickable-links) - makes paths and URLs in the terminal clickable
* [theme-hype](https://github.com/Eugeny/terminus-theme-hype) - a Hyper inspired theme
* [shell-selector](https://github.com/Eugeny/terminus-shell-selector) - a quick shell selector pane
---
@@ -25,4 +45,8 @@
Pull requests and plugins are welcome! Publish your plugin on NPM with a `terminus-plugin` keyword to make them appear in the Plugin Manager.
See [HACKING.md](https://github.com/Eugeny/terminus/blob/master/HACKING.md) for a very plugin development tutorial!
See [HACKING.md](https://github.com/Eugeny/terminus/blob/master/HACKING.md) for a very brief plugin development tutorial!
## License
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2FEugeny%2Fterminus.svg?type=large)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2FEugeny%2Fterminus?ref=badge_large)

91
app/assets/logo.svg Normal file
View File

@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="150mm"
height="150mm"
viewBox="0 0 150 150"
version="1.1"
id="svg8"
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
sodipodi:docname="logo.svg"
inkscape:export-filename="/home/eugene/Work/term/build/icons/512x512.png"
inkscape:export-xdpi="86.699997"
inkscape:export-ydpi="86.699997">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.49497475"
inkscape:cx="85.897128"
inkscape:cy="375.72042"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:snap-bbox="true"
inkscape:window-width="1366"
inkscape:window-height="692"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:snap-intersection-paths="true"
inkscape:object-paths="true" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-10.356544,-82.309525)">
<path
inkscape:connector-curvature="0"
id="path138"
style="opacity:0.9;fill:#bfd9f1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.12037313px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
d="M 33.048081,103.66303 101.30357,143.02426 80.80219,154.86063 33.048089,125.73315 Z"
sodipodi:nodetypes="ccccc" />
<path
inkscape:connector-curvature="0"
id="path116"
style="opacity:0.9;fill:#6666af;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.12037313px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
d="m 141.59934,143.95811 0.051,23.16109 -87.420905,49.42651 -0.0034,-22.16232 z"
sodipodi:nodetypes="ccccc" />
<path
inkscape:connector-curvature="0"
id="path118"
style="opacity:0.9;fill:#bfd9f1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.12037313px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
d="m 33.233182,182.28294 20.992812,12.1202 0.0034,22.16208 -20.996251,-12.19239 z"
sodipodi:nodetypes="ccccc" />
<path
style="opacity:0.9;fill:#9dbef0;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.12649226px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
d="m 52.236336,92.196079 -19.484508,11.249681 68.551742,39.5785 -68.366041,39.4708 21.107487,12.18633 68.366044,-39.4708 19.48451,-11.24968 z"
id="path134"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 955 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 894 B

BIN
app/assets/tray.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

50
app/bufferizedPTY.js Normal file
View File

@@ -0,0 +1,50 @@
module.exports = function patchPTYModule (path) {
const mod = require(path)
const oldSpawn = mod.spawn
if (mod.patched) {
return mod
}
mod.patched = true
mod.spawn = (file, args, opt) => {
let terminal = oldSpawn(file, args, opt)
let timeout = null
let buffer = ''
let lastFlush = 0
let nextTimeout = 0
const maxWindow = 250
const minWindow = 50
function flush () {
if (buffer) {
terminal.emit('data-buffered', buffer)
}
lastFlush = Date.now()
buffer = ''
}
function reschedule () {
if (timeout) {
clearTimeout(timeout)
}
nextTimeout = Date.now() + minWindow
timeout = setTimeout(() => {
timeout = null
flush()
}, minWindow)
}
terminal.on('data', data => {
buffer += data
if (Date.now() - lastFlush > maxWindow) {
flush()
} else {
if (Date.now() > nextTimeout - (minWindow / 10)) {
reschedule()
}
}
})
return terminal
}
return mod
}

View File

@@ -13,22 +13,9 @@ html
app-root
.preload-logo
div
.terminus-logo.animated
.part(style='transform: rotateZ(0deg)')
div
.part(style='transform: rotateZ(51deg)')
div
.part(style='transform: rotateZ(102deg)')
div
.part(style='transform: rotateZ(154deg)')
div
.part(style='transform: rotateZ(205deg)')
div
.part(style='transform: rotateZ(257deg)')
div
.part(style='transform: rotateZ(308deg)')
div
.terminus-logo
h1.terminus-title Terminus
sup α
.progress
.bar(style='width: 0%')

View File

@@ -1,15 +1,13 @@
if (process.platform == 'win32' && require('electron-squirrel-startup')) process.exit(0)
const electron = require('electron')
if (process.argv.indexOf('--debug') !== -1) {
require('electron-debug')({enabled: true, showDevTools: 'undocked'})
}
let app = electron.app
let secondInstance = app.makeSingleInstance((argv) => {
app.window.webContents.send('host:second-instance')
let secondInstance = app.makeSingleInstance((argv, cwd) => {
app.window.webContents.send('host:second-instance', argv, cwd)
})
if (secondInstance) {
@@ -22,7 +20,6 @@ const yaml = require('js-yaml')
const path = require('path')
const fs = require('fs')
const Config = require('electron-config')
require('electron-debug')({enabled: true, showDevTools: process.argv.indexOf('--debug') != -1})
let windowConfig = new Config({name: 'window'})
@@ -31,40 +28,35 @@ if (!process.env.TERMINUS_PLUGINS) {
}
setupWindowManagement = () => {
let windowCloseable
app.window.on('show', () => {
app.window.webContents.send('host:window-shown')
if (app.tray) {
app.tray.destroy()
app.tray = null
}
})
app.window.on('hide', (e) => {
if (!app.tray) {
setupTray()
}
})
app.window.on('enter-full-screen', () => app.window.webContents.send('host:window-enter-full-screen'))
app.window.on('leave-full-screen', () => app.window.webContents.send('host:window-leave-full-screen'))
app.window.on('close', (e) => {
windowConfig.set('windowBoundaries', app.window.getBounds())
if (!windowCloseable) {
app.window.minimize()
e.preventDefault()
}
})
app.window.on('closed', () => {
app.window = null
})
electron.ipcMain.on('window-closeable', (event, flag) => {
windowCloseable = flag
})
electron.ipcMain.on('window-focus', () => {
app.window.focus()
})
electron.ipcMain.on('window-toggle-focus', () => {
if (app.window.isFocused()) {
app.window.minimize()
} else {
app.window.focus()
}
})
electron.ipcMain.on('window-maximize', () => {
app.window.maximize()
})
@@ -86,48 +78,117 @@ setupWindowManagement = () => {
})
electron.ipcMain.on('window-set-bounds', (event, bounds) => {
let actualBounds = app.window.getBounds()
actualBounds.x = bounds.x
actualBounds.y = bounds.y
app.window.setBounds(actualBounds)
setTimeout(() => {
actualBounds = app.window.getBounds()
bounds.width += bounds.x - actualBounds.x
bounds.height += bounds.y - actualBounds.y
bounds.x = actualBounds.x
bounds.y = actualBounds.y
app.window.setBounds(bounds)
}, 100)
app.window.setBounds(bounds)
})
electron.ipcMain.on('window-set-always-on-top', (event, flag) => {
app.window.setAlwaysOnTop(flag)
})
}
app.on('before-quit', () => windowCloseable = true)
setupTray = () => {
if (process.platform == 'darwin') {
app.tray = new electron.Tray(`${app.getAppPath()}/assets/tray-darwinTemplate.png`)
app.tray.setPressedImage(`${app.getAppPath()}/assets/tray-darwinHighlightTemplate.png`)
} else {
app.tray = new electron.Tray(`${app.getAppPath()}/assets/tray.png`)
}
app.tray.on('click', () => {
app.window.show()
app.window.focus()
})
const contextMenu = electron.Menu.buildFromTemplate([{
label: 'Show',
click () {
app.window.show()
app.window.focus()
}
}])
if (process.platform != 'darwin') {
app.tray.setContextMenu(contextMenu)
}
app.tray.setToolTip(`Terminus ${app.getVersion()}`)
}
setupMenu = () => {
var template = [{
let template = [{
label: "Application",
submenu: [
{ type: "separator" },
{ label: "Quit", accelerator: "CmdOrCtrl+Q", click: () => {
app.window.webContents.send('host:quit-request')
}}
{ role: 'about', label: 'About Terminus' },
{ type: 'separator' },
{
label: 'Preferences',
accelerator: 'Cmd+,',
click () {
app.window.webContents.send('host:preferences-menu')
}
},
{ type: 'separator' },
{ role: 'services', submenu: [] },
{ type: 'separator' },
{ role: 'hide' },
{ role: 'hideothers' },
{ role: 'unhide' },
{ type: 'separator' },
{
label: 'Quit',
accelerator: 'Cmd+Q',
click () {
app.quit()
}
}
]
},
{
},
{
label: "Edit",
submenu: [
{ label: "Undo", accelerator: "CmdOrCtrl+Z", selector: "undo:" },
{ label: "Redo", accelerator: "Shift+CmdOrCtrl+Z", selector: "redo:" },
{ type: "separator" },
{ label: "Cut", accelerator: "CmdOrCtrl+X", selector: "cut:" },
{ label: "Copy", accelerator: "CmdOrCtrl+C", selector: "copy:" },
{ label: "Paste", accelerator: "CmdOrCtrl+V", selector: "paste:" },
{ label: "Select All", accelerator: "CmdOrCtrl+A", selector: "selectAll:" }
{role: 'undo'},
{role: 'redo'},
{type: 'separator'},
{role: 'cut'},
{role: 'copy'},
{role: 'paste'},
{role: 'pasteandmatchstyle'},
{role: 'delete'},
{role: 'selectall'}
]
},
{
label: 'View',
submenu: [
{role: 'reload'},
{role: 'forcereload'},
{role: 'toggledevtools'},
{type: 'separator'},
{role: 'resetzoom'},
{role: 'zoomin'},
{role: 'zoomout'},
{type: 'separator'},
{role: 'togglefullscreen'}
]
},
{
role: 'window',
submenu: [
{role: 'minimize'},
{role: 'zoom'},
{type: 'separator'},
{role: 'front'}
]
},
{
role: 'help',
submenu: [
{
label: 'Website',
click () { electron.shell.openExternal('https://eugeny.github.io/terminus') }
}
]
}]
@@ -149,7 +210,6 @@ start = () => {
let options = {
width: 800,
height: 600,
//icon: `${app.getAppPath()}/assets/img/icon.png`,
title: 'Terminus',
minWidth: 400,
minHeight: 300,

View File

@@ -12,14 +12,14 @@
"watch": "webpack --progress --color --watch"
},
"dependencies": {
"@angular/animations": "4.0.1",
"@angular/common": "4.0.1",
"@angular/compiler": "4.0.1",
"@angular/core": "4.0.1",
"@angular/forms": "4.0.1",
"@angular/platform-browser": "4.0.1",
"@angular/platform-browser-dynamic": "4.0.1",
"@ng-bootstrap/ng-bootstrap": "1.0.0-alpha.22",
"@angular/animations": "4.3.0",
"@angular/common": "4.3.0",
"@angular/compiler": "4.3.0",
"@angular/core": "4.3.0",
"@angular/forms": "4.3.0",
"@angular/platform-browser": "4.3.0",
"@angular/platform-browser-dynamic": "4.3.0",
"@ng-bootstrap/ng-bootstrap": "^1.0.0-beta.2",
"devtron": "1.4.0",
"electron-config": "0.2.1",
"electron-debug": "^1.0.1",
@@ -27,9 +27,10 @@
"electron-squirrel-startup": "^1.0.0",
"js-yaml": "3.8.2",
"mz": "^2.6.0",
"ngx-toastr": "^8.0.0",
"path": "0.12.7",
"rxjs": "5.3.0",
"zone.js": "0.8.4"
"zone.js": "0.8.12"
},
"devDependencies": {
"@types/mz": "0.0.31"

View File

@@ -1,12 +1,18 @@
import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
import { ToastrModule } from 'ngx-toastr'
export async function getRootModule (plugins: any[]): Promise<any> {
export function getRootModule (plugins: any[]) {
let imports = [
BrowserModule,
...(plugins.map(x => x.default.forRoot ? x.default.forRoot() : x.default)),
...plugins,
NgbModule.forRoot(),
ToastrModule.forRoot({
positionClass: 'toast-bottom-center',
preventDuplicates: true,
extendedTimeOut: 5000,
}),
]
let bootstrap = [
...(plugins.filter(x => x.bootstrap).map(x => x.bootstrap)),

View File

@@ -1,5 +1,6 @@
import 'source-sans-pro'
import 'font-awesome/css/font-awesome.css'
import 'ngx-toastr/toastr.css'
import './preload.scss'
import * as Raven from 'raven-js'
@@ -31,3 +32,7 @@ process.on('uncaughtException', (err) => {
Raven.captureException(err)
console.error(err)
})
const childProcess = require('child_process')
childProcess.spawn = require('electron').remote.require('child_process').spawn
childProcess.exec = require('electron').remote.require('child_process').exec

View File

@@ -1,16 +1,21 @@
import 'zone.js/dist/zone.js'
import 'zone.js'
import 'core-js/es7/reflect'
import 'core-js/core/delay'
import 'rxjs'
import './toastr.scss'
// Always land on the start view
location.hash = ''
import { enableProdMode } from '@angular/core'
import { enableProdMode, NgModuleRef } from '@angular/core'
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'
import { getRootModule } from './app.module'
import { findPlugins, loadPlugins } from './plugins'
import { findPlugins, loadPlugins, IPluginInfo } from './plugins'
if (process.platform === 'win32') {
process.env.HOME = process.env.HOMEDRIVE + process.env.HOMEPATH
}
if (require('electron-is-dev')) {
console.warn('Running in debug mode')
@@ -18,10 +23,30 @@ if (require('electron-is-dev')) {
enableProdMode()
}
findPlugins().then(async plugins => {
async function bootstrap (plugins: IPluginInfo[], safeMode = false): Promise<NgModuleRef<any>> {
if (safeMode) {
plugins = plugins.filter(x => x.isBuiltin)
}
let pluginsModules = await loadPlugins(plugins, (current, total) => {
(document.querySelector('.progress .bar') as HTMLElement).style.width = 100 * current / total + '%'
})
let module = await getRootModule(pluginsModules)
platformBrowserDynamic().bootstrapModule(module)
let module = getRootModule(pluginsModules)
window['rootModule'] = module
return await platformBrowserDynamic().bootstrapModule(module)
}
findPlugins().then(async plugins => {
console.log('Starting with plugins:', plugins)
try {
await bootstrap(plugins)
} catch (error) {
console.error('Angular bootstrapping error:', error)
console.warn('Trying safe mode')
window['safeModeReason'] = error
try {
await bootstrap(plugins, true)
} catch (error) {
console.error('Bootstrap failed:', error)
}
}
})

View File

@@ -20,11 +20,7 @@ if (process.env.DEV) {
nodeModule.globalPaths.unshift(path.dirname(require('electron').remote.app.getAppPath()))
}
const builtinPluginsPath = path.join(
path.dirname(require('electron').remote.app.getPath('exe')),
(process.platform === 'darwin') ? '../Resources' : 'resources',
'builtin-plugins',
)
const builtinPluginsPath = process.env.DEV ? path.dirname(require('electron').remote.app.getAppPath()) : path.join((process as any).resourcesPath, 'builtin-plugins')
const userPluginsPath = path.join(
require('electron').remote.app.getPath('appData'),
@@ -35,9 +31,9 @@ const userPluginsPath = path.join(
Object.assign(window, { builtinPluginsPath, userPluginsPath })
nodeModule.globalPaths.unshift(builtinPluginsPath)
nodeModule.globalPaths.unshift(path.join(userPluginsPath, 'node_modules'))
// nodeModule.globalPaths.unshift(path.join((process as any).resourcesPath, 'app.asar', 'node_modules'))
if (process.env.TERMINUS_PLUGINS) {
process.env.TERMINUS_PLUGINS.split(':').map(x => nodeModule.globalPaths.unshift(normalizePath(x)))
process.env.TERMINUS_PLUGINS.split(':').map(x => nodeModule.globalPaths.push(normalizePath(x)))
}
export declare type ProgressCallback = (current, total) => void
@@ -48,14 +44,46 @@ export interface IPluginInfo {
packageName: string
isBuiltin: boolean
version: string
author: string
homepage?: string
path?: string
info?: any
}
const builtinModules = [
'@angular/animations',
'@angular/common',
'@angular/compiler',
'@angular/core',
'@angular/forms',
'@angular/platform-browser',
'@angular/platform-browser-dynamic',
'@ng-bootstrap/ng-bootstrap',
'ngx-toastr',
'rxjs',
'terminus-core',
'terminus-settings',
'terminus-terminal',
'zone.js/dist/zone.js',
]
const cachedBuiltinModules = {}
builtinModules.forEach(m => {
cachedBuiltinModules[m] = nodeRequire(m)
})
const originalRequire = nodeRequire('module').prototype.require
nodeRequire('module').prototype.require = function (query) {
if (cachedBuiltinModules[query]) {
return cachedBuiltinModules[query]
}
return originalRequire.apply(this, arguments)
}
export async function findPlugins (): Promise<IPluginInfo[]> {
let paths = nodeModule.globalPaths
let foundPlugins: IPluginInfo[] = []
let candidateLocations: { pluginDir: string, packageName: string }[] = []
for (let pluginDir of paths) {
pluginDir = normalizePath(pluginDir)
@@ -63,32 +91,50 @@ export async function findPlugins (): Promise<IPluginInfo[]> {
continue
}
let pluginNames = await fs.readdir(pluginDir)
for (let pluginName of pluginNames.filter(x => /^terminus-/.exec(x))) {
let pluginPath = path.join(pluginDir, pluginName)
let infoPath = path.join(pluginPath, 'package.json')
if (!await fs.exists(infoPath)) {
if (await fs.exists(path.join(pluginDir, 'package.json'))) {
candidateLocations.push({
pluginDir: path.dirname(pluginDir),
packageName: path.basename(pluginDir)
})
}
for (let packageName of pluginNames) {
candidateLocations.push({ pluginDir, packageName })
}
}
for (let { pluginDir, packageName } of candidateLocations) {
let pluginPath = path.join(pluginDir, packageName)
let infoPath = path.join(pluginPath, 'package.json')
if (!await fs.exists(infoPath)) {
continue
}
let name = packageName.substring('terminus-'.length)
if (foundPlugins.some(x => x.name === name)) {
console.info(`Plugin ${packageName} already exists, overriding`)
foundPlugins = foundPlugins.filter(x => x.name !== name)
}
try {
let info = JSON.parse(await fs.readFile(infoPath, {encoding: 'utf-8'}))
if (!info.keywords || !(info.keywords.includes('terminus-plugin') || info.keywords.includes('terminus-builtin-plugin'))) {
continue
}
if (foundPlugins.some(x => x.name === pluginName)) {
console.info(`Plugin ${pluginName} already exists`)
}
try {
let info = JSON.parse(await fs.readFile(infoPath, {encoding: 'utf-8'}))
console.log(pluginDir, builtinPluginsPath)
foundPlugins.push({
name: pluginName.substring('terminus-'.length),
packageName: pluginName,
isBuiltin: pluginDir === builtinPluginsPath,
version: info.version,
description: info.description,
path: pluginPath,
info,
})
} catch (error) {
console.error('Cannot load package info for', pluginName)
}
let author = info.author
author = author.name || author
foundPlugins.push({
name: name,
packageName: packageName,
isBuiltin: pluginDir === builtinPluginsPath,
version: info.version,
description: info.description,
author,
path: pluginPath,
info,
})
} catch (error) {
console.error('Cannot load package info for', packageName)
}
}
@@ -104,7 +150,10 @@ export async function loadPlugins (foundPlugins: IPluginInfo[], progress: Progre
console.info(`Loading ${foundPlugin.name}: ${nodeRequire.resolve(foundPlugin.path)}`)
progress(index, foundPlugins.length)
try {
let pluginModule = nodeRequire(foundPlugin.path)
let packageModule = nodeRequire(foundPlugin.path)
let pluginModule = packageModule.default.forRoot ? packageModule.default.forRoot() : packageModule.default
pluginModule['pluginName'] = foundPlugin.name
pluginModule['bootstrap'] = packageModule.bootstrap
plugins.push(pluginModule)
} catch (error) {
console.error(`Could not load ${foundPlugin.name}:`, error)

View File

@@ -1,6 +1,3 @@
$color: rgba(66, 142, 173, 0.75);
.preload-logo {
-webkit-app-region: drag;
position: fixed;
@@ -24,7 +21,7 @@ $color: rgba(66, 142, 173, 0.75);
.bar {
transition: 1s ease-out width;
background: $color;
background: #a1c5e4;
height: 3px;
}
}
@@ -42,63 +39,26 @@ $color: rgba(66, 142, 173, 0.75);
.terminus-logo {
width: 160px;
height: 160px;
background: url('../assets/logo.svg');
background-repeat: none;
background-size: contain;
margin: auto;
position: relative;
transform: rotateZ(-14.5deg);
.part {
position: absolute;
width: 160px;
height: 160px;
div {
position: absolute;
top: 33px;
left: 24px;
width: 44px;
height: 44px;
background: $color;
transform: rotateX(52deg) rotateY(-42deg);
animation: terminusLogoPartOnce ease-out 1s;
}
}
&.animated .part div {
animation: terminusLogoPart infinite ease-out 2s;
}
}
.terminus-title {
color: $color;
color: #a1c5e4;
font-family: 'Source Sans Pro';
text-align: center;
font-weight: normal;
font-size: 42px;
margin: 0;
}
@keyframes terminusLogoPart {
0% {
transform: rotateX(90deg) rotateY(-90deg);
}
25% {
transform: rotateX(52deg) rotateY(-42deg);
}
75% {
transform: rotateX(52deg) rotateY(-42deg);
}
100% {
transform: rotateX(-90deg) rotateY(-90deg);
sup {
color: #842fe0;
}
}
@keyframes terminusLogoPartOnce {
0% {
transform: rotateX(90deg) rotateY(-90deg);
}
100% {
transform: rotateX(52deg) rotateY(-42deg);
}
.modal-dialog {
-webkit-app-region: no-drag;
}

16
app/src/toastr.scss Normal file
View File

@@ -0,0 +1,16 @@
#toast-container {
display: flex;
flex-direction: column;
align-items: center;
.toast {
box-shadow: 0 1px 0 rgba(0,0,0,.25);
padding: 10px;
background-image: none;
width: auto;
&.toast-info {
background-color: #555;
}
}
}

View File

@@ -55,13 +55,15 @@ module.exports = {
'@angular/forms': 'commonjs @angular/forms',
'@angular/common': 'commonjs @angular/common',
'@ng-bootstrap/ng-bootstrap': 'commonjs @ng-bootstrap/ng-bootstrap',
'child_process': 'commonjs child_process',
'electron': 'commonjs electron',
'electron-is-dev': 'commonjs electron-is-dev',
'ngx-toastr': 'commonjs ngx-toastr',
'module': 'commonjs module',
'mz': 'commonjs mz',
'path': 'commonjs path',
'rxjs': 'commonjs rxjs',
'zone.js': 'commonjs zone.js',
'zone.js': 'commonjs zone.js/dist/zone.js',
},
plugins: [
new webpack.optimize.ModuleConcatenationPlugin(),

277
app/yarn.lock Normal file
View File

@@ -0,0 +1,277 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@angular/animations@4.3.0":
version "4.3.0"
resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-4.3.0.tgz#56f34b84649379202ac359929b82eb0b915e9c72"
dependencies:
tslib "^1.7.1"
"@angular/common@4.3.0":
version "4.3.0"
resolved "https://registry.yarnpkg.com/@angular/common/-/common-4.3.0.tgz#13a54a6929dd52f9729b16ae446fad58fe163053"
dependencies:
tslib "^1.7.1"
"@angular/compiler@4.3.0":
version "4.3.0"
resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-4.3.0.tgz#55503bf27a1f062f71b9495393f3311903a8fc43"
dependencies:
tslib "^1.7.1"
"@angular/core@4.3.0":
version "4.3.0"
resolved "https://registry.yarnpkg.com/@angular/core/-/core-4.3.0.tgz#bd2249c3de1224a7c6536c4aba728d6565329334"
dependencies:
tslib "^1.7.1"
"@angular/forms@4.3.0":
version "4.3.0"
resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-4.3.0.tgz#7d0c7a854737e9a30a5fd9665f8d4f56a1b91bd8"
dependencies:
tslib "^1.7.1"
"@angular/platform-browser-dynamic@4.3.0":
version "4.3.0"
resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-4.3.0.tgz#551fb18851b27ee8f3e4b0ee25aad10bd7b312e3"
dependencies:
tslib "^1.7.1"
"@angular/platform-browser@4.3.0":
version "4.3.0"
resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-4.3.0.tgz#02389489185185c3becf06359346100e5479c7e1"
dependencies:
tslib "^1.7.1"
"@ng-bootstrap/ng-bootstrap@^1.0.0-beta.2":
version "1.0.0-beta.2"
resolved "https://registry.yarnpkg.com/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-1.0.0-beta.2.tgz#3d4b567b0334a9ee631b73c72156cd3a9d3cd29f"
"@types/mz@0.0.31":
version "0.0.31"
resolved "https://registry.yarnpkg.com/@types/mz/-/mz-0.0.31.tgz#a4d80c082fefe71e40a7c0f07d1e6555bbbc7b52"
dependencies:
"@types/node" "*"
"@types/node@*":
version "8.0.13"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.13.tgz#530f0f9254209b0335bf5cc6387822594ef47093"
accessibility-developer-tools@^2.11.0:
version "2.12.0"
resolved "https://registry.yarnpkg.com/accessibility-developer-tools/-/accessibility-developer-tools-2.12.0.tgz#3da0cce9d6ec6373964b84f35db7cfc3df7ab514"
any-promise@^1.0.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
argparse@^1.0.7:
version "1.0.9"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86"
dependencies:
sprintf-js "~1.0.2"
conf@^0.11.1:
version "0.11.2"
resolved "https://registry.yarnpkg.com/conf/-/conf-0.11.2.tgz#879f479267600483e502583462ca4063fc9779b2"
dependencies:
dot-prop "^3.0.0"
env-paths "^0.3.0"
mkdirp "^0.5.1"
pkg-up "^1.0.0"
debug@^2.2.0, debug@^2.6.8:
version "2.6.8"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc"
dependencies:
ms "2.0.0"
devtron@1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/devtron/-/devtron-1.4.0.tgz#b5e748bd6e95bbe70bfcc68aae6fe696119441e1"
dependencies:
accessibility-developer-tools "^2.11.0"
highlight.js "^9.3.0"
humanize-plus "^1.8.1"
dot-prop@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177"
dependencies:
is-obj "^1.0.0"
electron-config@0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/electron-config/-/electron-config-0.2.1.tgz#7e12c26412d06bf3ed3896d0479df162986b95ba"
dependencies:
conf "^0.11.1"
electron-debug@^1.0.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/electron-debug/-/electron-debug-1.2.0.tgz#22e51a73e1bf095d0bb51a6c3d97a203364c4222"
dependencies:
electron-is-dev "^0.1.0"
electron-localshortcut "^2.0.0"
electron-is-accelerator@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/electron-is-accelerator/-/electron-is-accelerator-0.1.2.tgz#509e510c26a56b55e17f863a4b04e111846ab27b"
electron-is-dev@0.1.2, electron-is-dev@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/electron-is-dev/-/electron-is-dev-0.1.2.tgz#8a1043e32b3a1da1c3f553dce28ce764246167e3"
electron-localshortcut@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/electron-localshortcut/-/electron-localshortcut-2.0.2.tgz#6a1adcd6514c957328ec7912f5ccb5e1c10706db"
dependencies:
debug "^2.6.8"
electron-is-accelerator "^0.1.0"
electron-squirrel-startup@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/electron-squirrel-startup/-/electron-squirrel-startup-1.0.0.tgz#19b4e55933fa0ef8f556784b9c660f772546a0b8"
dependencies:
debug "^2.2.0"
env-paths@^0.3.0:
version "0.3.1"
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-0.3.1.tgz#c30ccfcbc30c890943dc08a85582517ef00da463"
esprima@^3.1.1:
version "3.1.3"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
find-up@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
dependencies:
path-exists "^2.0.0"
pinkie-promise "^2.0.0"
highlight.js@^9.3.0:
version "9.12.0"
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.12.0.tgz#e6d9dbe57cbefe60751f02af336195870c90c01e"
humanize-plus@^1.8.1:
version "1.8.2"
resolved "https://registry.yarnpkg.com/humanize-plus/-/humanize-plus-1.8.2.tgz#a65b34459ad6367adbb3707a82a3c9f916167030"
inherits@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
is-obj@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
js-yaml@3.8.2:
version "3.8.2"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.2.tgz#02d3e2c0f6beab20248d412c352203827d786721"
dependencies:
argparse "^1.0.7"
esprima "^3.1.1"
minimist@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
mkdirp@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
dependencies:
minimist "0.0.8"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
mz@^2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/mz/-/mz-2.6.0.tgz#c8b8521d958df0a4f2768025db69c719ee4ef1ce"
dependencies:
any-promise "^1.0.0"
object-assign "^4.0.1"
thenify-all "^1.0.0"
ngx-toastr@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/ngx-toastr/-/ngx-toastr-8.0.0.tgz#f3bc53146b2f7da3eabf3daa1b1bbdf65cb49697"
object-assign@^4.0.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
path-exists@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b"
dependencies:
pinkie-promise "^2.0.0"
path@0.12.7:
version "0.12.7"
resolved "https://registry.yarnpkg.com/path/-/path-0.12.7.tgz#d4dc2a506c4ce2197eb481ebfcd5b36c0140b10f"
dependencies:
process "^0.11.1"
util "^0.10.3"
pinkie-promise@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
dependencies:
pinkie "^2.0.0"
pinkie@^2.0.0:
version "2.0.4"
resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
pkg-up@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-1.0.0.tgz#3e08fb461525c4421624a33b9f7e6d0af5b05a26"
dependencies:
find-up "^1.0.0"
process@^0.11.1:
version "0.11.10"
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
rxjs@5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.3.0.tgz#d88ccbdd46af290cbdb97d5d8055e52453fabe2d"
dependencies:
symbol-observable "^1.0.1"
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
symbol-observable@^1.0.1:
version "1.0.4"
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d"
thenify-all@^1.0.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"
dependencies:
thenify ">= 3.1.0 < 4"
"thenify@>= 3.1.0 < 4":
version "3.3.0"
resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839"
dependencies:
any-promise "^1.0.0"
tslib@^1.7.1:
version "1.7.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.7.1.tgz#bc8004164691923a79fe8378bbeb3da2017538ec"
util@^0.10.3:
version "0.10.3"
resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9"
dependencies:
inherits "2.0.1"
zone.js@0.8.12:
version "0.8.12"
resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.8.12.tgz#86ff5053c98aec291a0bf4bbac501d694a05cfbb"

View File

@@ -24,14 +24,3 @@ build_script:
artifacts:
- path: 'dist\win\*.exe'
deploy:
provider: GitHub
auth_token:
secure: wvxHVlprvhfdOHgmVEDIwjCHYlmuDykteIEHpAfpi807+1lJD3ld2/OS6+0fgU4e
artifact: /.*\.exe/
draft: false
prerelease: false
force_update: true
on:
branch: master
appveyor_repo_tag: true

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 644 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

124
build/icons/icon.svg Normal file
View File

@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="150mm"
height="150mm"
viewBox="0 0 150 150"
version="1.1"
id="svg8"
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
sodipodi:docname="icon.svg"
inkscape:export-filename="/home/eugene/Work/term/build/icons/512x512.png"
inkscape:export-xdpi="86.699997"
inkscape:export-ydpi="86.699997">
<defs
id="defs2">
<linearGradient
inkscape:collect="always"
id="linearGradient4649">
<stop
style="stop-color:#000316;stop-opacity:1"
offset="0"
id="stop4645" />
<stop
style="stop-color:#190065;stop-opacity:1"
offset="1"
id="stop4647" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4649"
id="linearGradient4651"
x1="89.26284"
y1="85.146751"
x2="89.26284"
y2="229.47229"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.82182032,0,0,0.82182032,15.208802,28.029361)" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.49497475"
inkscape:cx="85.897128"
inkscape:cy="375.72042"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:snap-bbox="true"
inkscape:window-width="1366"
inkscape:window-height="692"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:snap-intersection-paths="true"
inkscape:object-paths="true" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-10.356544,-82.309525)">
<rect
id="rect168"
width="123.27305"
height="123.27305"
x="23.72002"
y="95.673004"
style="fill:url(#linearGradient4651);fill-opacity:1;stroke-width:0.21743995"
rx="8.2182035"
ry="8.2182035" />
<path
inkscape:connector-curvature="0"
id="path138"
style="opacity:0.9;fill:#bfd9f1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.82182032px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
d="m 47.511243,117.17807 50.067023,28.8724 -15.038249,8.68226 -35.028768,-21.3657 z"
sodipodi:nodetypes="ccccc" />
<path
inkscape:connector-curvature="0"
id="path116"
style="opacity:0.9;fill:#6666af;fill-rule:evenodd;stroke:none;stroke-width:0.82182032px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;fill-opacity:1"
d="m 127.13617,146.73547 0.0374,16.98921 -64.125308,36.25552 -0.0025,-16.25659 z"
sodipodi:nodetypes="ccccc" />
<path
inkscape:connector-curvature="0"
id="path118"
style="opacity:0.9;fill:#bfd9f1;fill-rule:evenodd;stroke:none;stroke-width:0.82182032px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;fill-opacity:1"
d="m 47.647019,174.84764 15.398727,8.89046 0.0025,16.25641 -15.401249,-8.94341 z"
sodipodi:nodetypes="ccccc" />
<path
style="opacity:0.9;fill:#9dbef0;fill-rule:evenodd;stroke:none;stroke-width:0.82630885px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;fill-opacity:1"
d="m 61.586284,108.76679 -14.292349,8.25191 50.284331,29.03177 -50.148115,28.95277 15.482843,8.93896 50.148116,-28.95277 14.29235,-8.25191 z"
id="path134"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@@ -1,50 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en_US</string>
<key>CFBundleExecutable</key>
<string>ELEMENTS</string>
<key>CFBundleIdentifier</key>
<string>com.syslink.elements</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>${VERSION}</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>Elements Client</string>
<key>CFBundleURLSchemes</key>
<array>
<string>elements-client</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>619</string>
<key>LSMinimumSystemVersion</key>
<string>10.8.0</string>
<key>LSUIElement</key>
<false/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2016 Syslink GmbH. All rights reserved.</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>AtomApplication</string>
</dict>
</plist>

Binary file not shown.

View File

@@ -1,34 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Wix RequiredVersion="3.6.2830.0" xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension">
<Bundle Name="ELEMENTS" Version="$(var.Version)" Manufacturer="ELEMENTS.tv" UpgradeCode="508475fc-0e76-4cd1-8e98-6953023ba518"
HelpUrl="http://elements.tv"
Copyright="Copyright © 2016 ELEMENTS" IconSourceFile="build/icon.ico"
AboutUrl="http://elements.tv">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.HyperlinkLicense">
<bal:WixStandardBootstrapperApplication
LicenseUrl=""
LogoFile="build\logo.png"
ThemeFile="build\windows\wix-theme.xml"
/>
</BootstrapperApplicationRef>
<Chain>
<MsiPackage
Id="ClientMSI"
Compressed="yes"
ForcePerMachine="yes"
SourceFile="dist\elements-app.msi"
Vital="yes">
</MsiPackage>
<MsiPackage
Id="DriverMSI"
Compressed="yes"
ForcePerMachine="yes"
SourceFile="build/windows/ElementsDriver_x64.msi"
Vital="yes">
</MsiPackage>
</Chain>
</Bundle>
</Wix>

View File

@@ -1,84 +0,0 @@
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" UpgradeCode="37484543-5276-2386-5427-275941245342"
Name="ELEMENTS" Version="$(var.ProductVersion)" Manufacturer="ELEMENTS.tv" Language="1033">
<Package InstallerVersion="200"
Compressed="yes"
Comments="Windows Installer Package"
Platform="x64"
InstallScope="perMachine"
InstallPrivileges="elevated" />
<MajorUpgrade AllowDowngrades="yes" Schedule="afterInstallValidate" />
<Media Id="1" Cabinet="product.cab" EmbedCab="yes"/>
<Feature Id="DefaultFeature" Level="1">
<ComponentRef Id="RegistryEntries" />
<ComponentRef Id="AppDir"/>
<ComponentRef Id="AvidSharedStorageAccess"/>
<ComponentRef Id="ApplicationShortcutDesktop"/>
<ComponentGroupRef Id="Files" />
</Feature>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="DesktopFolder" Name="Desktop">
<Component Id="ApplicationShortcutDesktop" Guid="*">
<Shortcut Id="ApplicationDesktopShortcut"
Name="ELEMENTS"
Description="ELEMENTS client app"
Target="[INSTALLDIR]\\Elements.exe"
WorkingDirectory="INSTALLDIR"/>
<RemoveFolder Id="DesktopFolder" On="uninstall"/>
<RegistryValue
Root="HKCU"
Key="Software\ELEMENTS"
Name="installed"
Type="integer"
Value="1"
KeyPath="yes"/>
</Component>
</Directory>
<Directory Id="ProgramFiles64Folder">
<Directory Id="ElementsDir" Name="ELEMENTS">
<Directory Id="INSTALLDIR" Name="ELEMENTS Client">
<Component Id="AppDir" Guid="284957a6-a462-4e34-babd-c17800f11054" Win64="yes">
<CreateFolder />
<!--RemoveFile Id="RemoveFilesFromAppDirectory" Name="*.*" On="uninstall" /-->
<!--RemoveFolder Id="AppDir" On="uninstall"/-->
</Component>
</Directory>
</Directory>
</Directory>
<Component Id="RegistryEntries" Guid="572998d8-719e-4124-8fe6-6d4f8b855d7b">
<RegistryKey Root="HKLM"
Key="system\currentcontrolset\services\AvidFs"
Action="create">
<RegistryValue Type="string" Name="Description" Value="AIFMRX" />
<RegistryValue Type="string" Name="DisplayName" Value="AIFMRX" />
<RegistryValue Type="integer" Name="ErrorControl" Value="1" />
<RegistryValue Type="string" Name="Group" Value="Network" />
<RegistryValue Type="string" Name="ImagePath" Value="System32\DRIVERS\aifmrx.sys" />
<RegistryValue Type="integer" Name="Start" Value="1" />
<RegistryValue Type="integer" Name="Type" Value="2" />
</RegistryKey>
<RegistryKey Root="HKLM"
Key="system\currentcontrolset\services\AifMRx\NetworkProvider"
Action="create">
<RegistryValue Type="string" Name="DeviceName" Value="\Device\AvidFs" />
<RegistryValue Type="string" Name="Name" Value="Interface Network" />
<RegistryValue Type="string" Name="ProviderPath" Value="System32\aifmrxnp.dll" />
</RegistryKey>
<RegistryKey Root="HKLM"
Key="system\CurrentControlSet\services\LanmanWorkstation\Parameters"
Action="create">
<RegistryValue Type="integer" Name="DisableLargeMtu" Value="0" KeyPath="yes" />
<RegistryValue Type="integer" Name="DisableBandwidthThrottling" Value="1" />
<RegistryValue Type="integer" Name="EnableWsd" Value="0" />
</RegistryKey>
</Component>
<Directory Id="System64Folder" Name="SystemFolder">
<Component Id="AvidSharedStorageAccess" Guid="972c67f2-ee17-4b20-8939-b92cfa13fcf6" NeverOverwrite="yes" Win64="yes" Permanent="yes">
<File Id="AvidSharedStorageAccess.dll" Source="build\windows\AvidSharedStorageAccess.dll" KeyPath="yes"/>
</Component>
</Directory>
</Directory>
</Product>
</Wix>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 361 KiB

After

Width:  |  Height:  |  Size: 361 KiB

View File

@@ -1,80 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
<Theme xmlns="http://wixtoolset.org/schemas/thmutil/2010">
<Window Width="300" Height="360" HexStyle="100a0000" FontId="0">#(loc.Caption)</Window>
<Font Id="0" Height="-12" Weight="500" Foreground="000000" Background="FFFFFF">Segoe UI</Font>
<Font Id="1" Height="-24" Weight="500" Foreground="000000">Segoe UI</Font>
<Font Id="2" Height="-22" Weight="500" Foreground="666666">Segoe UI</Font>
<Font Id="3" Height="-12" Weight="500" Foreground="000000" Background="FFFFFF">Segoe UI</Font>
<Font Id="4" Height="-12" Weight="500" Foreground="ff0000" Background="FFFFFF" Underline="yes">Segoe UI</Font>
<Image X="30" Y="30" Width="256" Height="60" ImageFile="logo.png" Visible="yes"/>
<Page Name="Help">
<Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.HelpHeader)</Text>
<Text X="11" Y="112" Width="-11" Height="-35" FontId="3" DisablePrefix="yes">#(loc.HelpText)</Text>
<Button Name="HelpCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.HelpCloseButton)</Button>
</Page>
<Page Name="Install">
<!--Hypertext Name="EulaHyperlink" X="11" Y="121" Width="-11" Height="51" TabStop="yes" FontId="3" HideWhenDisabled="yes">#(loc.InstallLicenseLinkText)</Hypertext>
<Checkbox Name="EulaAcceptCheckbox" X="-11" Y="-41" Width="260" Height="17" TabStop="yes" FontId="3" HideWhenDisabled="yes">#(loc.InstallAcceptCheckbox)</Checkbox-->
<Button Name="InstallButton" X="90" Y="-120" Width="120" Height="50" TabStop="yes" FontId="0">#(loc.InstallInstallButton)</Button>
<Button Name="WelcomeCancelButton" X="110" Y="-80" Width="80" Height="23" TabStop="yes" FontId="0">#(loc.InstallCloseButton)</Button>
</Page>
<Page Name="Options">
<Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.OptionsHeader)</Text>
<Text X="11" Y="121" Width="-11" Height="17" FontId="3" DisablePrefix="yes">#(loc.OptionsLocationLabel)</Text>
<Editbox Name="FolderEditbox" X="11" Y="143" Width="-91" Height="21" TabStop="yes" FontId="3" FileSystemAutoComplete="yes" />
<Button Name="BrowseButton" X="-11" Y="142" Width="75" Height="23" TabStop="yes" FontId="3">#(loc.OptionsBrowseButton)</Button>
<Button Name="OptionsOkButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.OptionsOkButton)</Button>
<Button Name="OptionsCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.OptionsCancelButton)</Button>
</Page>
<Page Name="FilesInUse">
<Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.FilesInUseHeader)</Text>
<Text X="11" Y="121" Width="-11" Height="34" FontId="3" DisablePrefix="yes">#(loc.FilesInUseLabel)</Text>
<Text Name="FilesInUseText" X="11" Y="150" Width="-11" Height="-86" FontId="3" DisablePrefix="yes" HexStyle="0x0000C000"></Text>
<Button Name="FilesInUseCloseRadioButton" X="11" Y="-60" Width="-11" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes" HexStyle="0x000009">#(loc.FilesInUseCloseRadioButton)</Button>
<Button Name="FilesInUseDontCloseRadioButton" X="11" Y="-40" Width="-11" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes" HexStyle="0x000009">#(loc.FilesInUseDontCloseRadioButton)</Button>
<Button Name="FilesInUseOkButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.FilesInUseOkButton)</Button>
<Button Name="FilesInUseCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.FilesInUseCancelButton)</Button>
</Page>
<Page Name="Progress">
<Text X="30" Y="120" Width="-30" Height="30" FontId="2" DisablePrefix="yes">#(loc.ProgressHeader)</Text>
<Text X="30" Y="150" Width="70" Height="17" FontId="3" DisablePrefix="yes">#(loc.ProgressLabel)</Text>
<Text Name="OverallProgressPackageText" X="30" Y="200" Width="-30" Height="17" FontId="3" DisablePrefix="yes">#(loc.OverallProgressPackageText)</Text>
<Progressbar Name="OverallCalculatedProgressbar" X="30" Y="220" Width="-30" Height="20" />
<Button Name="ProgressCancelButton" X="110" Y="-40" Width="80" Height="23" TabStop="yes" FontId="0">#(loc.ProgressCancelButton)</Button>
</Page>
<Page Name="Modify">
<Text X="30" Y="110" Width="-30" Height="30" FontId="2" DisablePrefix="yes">#(loc.ModifyHeader)</Text>
<Button Name="UninstallButton" X="90" Y="-100" Width="120" Height="50" TabStop="yes" FontId="0">#(loc.ModifyUninstallButton)</Button>
<Button Name="RepairButton" X="110" Y="-60" Width="80" Height="23" TabStop="yes" FontId="0">#(loc.ModifyRepairButton)</Button>
<Button Name="ModifyCancelButton" X="110" Y="-30" Width="80" Height="23" TabStop="yes" FontId="0">#(loc.ModifyCloseButton)</Button>
</Page>
<Page Name="Success">
<Text Name="SuccessHeader" X="30" Y="110" Width="-30" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">Success</Text>
<Text Name="SuccessInstallHeader" X="30" Y="110" Width="-30" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">Installed successfully</Text>
<Text Name="SuccessRepairHeader" X="30" Y="110" Width="-30" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">Repaired successfully</Text>
<Text Name="SuccessUninstallHeader" X="30" Y="110" Width="-30" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">Uninstalled successfully</Text>
<Button Name="LaunchButton" X="90" Y="-100" Width="120" Height="50" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.SuccessLaunchButton)</Button>
<Button Name="SuccessCancelButton" X="110" Y="-60" Width="80" Height="23" TabStop="yes" FontId="0">#(loc.SuccessCloseButton)</Button>
</Page>
<Page Name="Failure">
<Text Name="FailureHeader" X="30" Y="110" Width="-30" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureHeader)</Text>
<Text Name="FailureInstallHeader" X="30" Y="110" Width="-30" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">Setup failed</Text>
<Text Name="FailureUninstallHeader" X="30" Y="110" Width="-30" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">Uninstall failed</Text>
<Text Name="FailureRepairHeader" X="30" Y="110" Width="-30" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">Repair failed</Text>
<Hypertext Name="FailureLogFileLink" X="30" Y="145" Width="-30" Height="50" FontId="3" TabStop="yes" HideWhenDisabled="yes">#(loc.FailureHyperlinkLogText)</Hypertext>
<Hypertext Name="FailureMessageText" X="30" Y="195" Width="-30" Height="50" FontId="3" TabStop="yes" HideWhenDisabled="yes" />
<Text Name="FailureRestartText" X="-30" Y="255" Width="400" Height="34" FontId="3" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureRestartText)</Text>
<Button Name="FailureRestartButton" X="90" Y="-100" Width="120" Height="50" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.FailureRestartButton)</Button>
<Button Name="FailureCloseButton" X="110" Y="-60" Width="80" Height="23" TabStop="yes" FontId="0">#(loc.FailureCloseButton)</Button>
</Page>
</Theme>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 138 KiB

View File

@@ -9,20 +9,22 @@
"core-js": "2.4.1",
"cross-env": "4.0.0",
"css-loader": "0.28.0",
"electron": "1.7.2",
"electron": "1.8.4",
"electron-builder": "17.1.1",
"electron-builder-squirrel-windows": "17.0.1",
"electron-rebuild": "1.5.11",
"file-loader": "0.9.0",
"font-awesome": "4.7.0",
"graceful-fs": "^4.1.11",
"html-loader": "0.4.4",
"json-loader": "0.5.4",
"less": "2.7.1",
"less-loader": "2.2.3",
"node-abi": "2.0.3",
"node-gyp": "3.4.0",
"node-gyp": "^3.6.2",
"node-sass": "^4.5.3",
"npmlog": "4.1.0",
"npx": "^9.7.1",
"pug": "2.0.0-beta11",
"pug-html-loader": "1.0.9",
"pug-loader": "2.3.0",
@@ -41,7 +43,8 @@
"url-loader": "0.5.7",
"val-loader": "0.5.0",
"webpack": "^3.0.0",
"yaml-loader": "0.4.0"
"yaml-loader": "0.4.0",
"yarn": "^1.3.2"
},
"build": {
"appId": "org.terminus",
@@ -52,33 +55,62 @@
"clink"
],
"win": {
"icon": "./build/windows/icon.ico"
"icon": "./build/windows/icon.ico",
"publish": [
"github"
]
},
"squirrelWindows": {
"iconUrl": "https://github.com/Eugeny/terminus/raw/master/build/windows/icon.ico"
"iconUrl": "https://github.com/Eugeny/terminus/raw/master/build/windows/icon.ico",
"artifactName": "terminus-${version}-${os}-${arch}.exe"
},
"mac": {
"category": "public.app-category.video",
"icon": "./build/mac/icon.icns",
"identity": null
"identity": null,
"publish": [
"github"
]
},
"dmg": {
"artifactName": "terminus-${version}-${os}-${arch}.dmg"
},
"linux": {
"category": "Utilities",
"icon": "./build/icons"
"icon": "./build/icons",
"publish": [
"github"
]
},
"deb": {
"depends": ["screen", "gconf2", "gconf-service", "libnotify4", "libappindicator1", "libxtst6", "libnss3"]
"depends": [
"screen",
"gconf2",
"gconf-service",
"libnotify4",
"libappindicator1",
"libxtst6",
"libnss3",
"python-gnomekeyring",
"tmux"
],
"artifactName": "terminus-${version}-${os}-${arch}.deb"
},
"rpm": {
"depends": ["screen"]
"depends": [
"screen",
"gnome-python2-gnomekeyring"
],
"artifactName": "terminus-${version}-${os}-${arch}.rpm"
}
},
"scripts": {
"build": "webpack --color --config app/webpack.config.js && webpack --color --config terminus-core/webpack.config.js && webpack --color --config terminus-settings/webpack.config.js && webpack --color --config terminus-terminal/webpack.config.js && webpack --color --config terminus-settings/webpack.config.js && webpack --color --config terminus-plugin-manager/webpack.config.js && webpack --color --config terminus-community-color-schemes/webpack.config.js",
"build": "webpack --color --config app/webpack.config.js && webpack --color --config terminus-core/webpack.config.js && webpack --color --config terminus-settings/webpack.config.js && webpack --color --config terminus-terminal/webpack.config.js && webpack --color --config terminus-settings/webpack.config.js && webpack --color --config terminus-plugin-manager/webpack.config.js && webpack --color --config terminus-community-color-schemes/webpack.config.js && webpack --color --config terminus-ssh/webpack.config.js",
"watch": "webpack --progress --color --watch",
"start": "cross-env DEV=1 electron --js-flags='--ignition' app --debug",
"prod": "cross-env DEV=1 electron --js-flags='--ignition' app",
"lint": "tslint -c tslint.json -t stylish terminus-*/src/**/*.ts terminus-*/src/*.ts app/src/*.ts",
"postinstall": "install-app-deps"
},
"false": {}
"repository": "eugeny/terminus"
}

View File

@@ -8,4 +8,6 @@ builder({
extraMetadata: {
version: vars.version,
},
publish: 'onTag',
draft: false
})

View File

@@ -8,4 +8,6 @@ builder({
extraMetadata: {
version: vars.version,
},
publish: 'onTag',
draft: false
})

View File

@@ -3,7 +3,5 @@ const rebuild = require('electron-rebuild').default
const path = require('path')
const vars = require('./vars')
let buildPath = path.resolve(__dirname, '../terminus-terminal')
rebuild(buildPath, vars.electronVersion, process.arch, [], true).then(() => {
console.log('Done')
})
rebuild(path.resolve(__dirname, '../terminus-ssh'), vars.electronVersion, process.arch, [], true)
rebuild(path.resolve(__dirname, '../terminus-terminal'), vars.electronVersion, process.arch, [], true)

View File

@@ -8,4 +8,6 @@ builder({
extraMetadata: {
version: vars.version,
},
publish: 'onTag',
draft: false
})

View File

@@ -4,22 +4,30 @@ const path = require('path')
const vars = require('./vars')
const log = require('npmlog')
const localBinPath = path.resolve(__dirname, '../node_modules/.bin');
const npx = `${localBinPath}/npx`;
log.info('deps', 'app')
sh.exec('npm prune')
sh.exec('npm install')
sh.exec('npm update --dev')
sh.exec(`${npx} yarn install`)
sh.cd('app')
sh.exec('npm prune')
sh.exec('npm install')
sh.exec('npm update --dev')
sh.exec(`${npx} yarn install`)
sh.cd('..')
vars.builtinPlugins.forEach(plugin => {
log.info('deps', plugin)
sh.cd(plugin)
sh.exec('npm prune')
sh.exec('npm install')
sh.exec('npm update --dev')
sh.exec(`${npx} yarn install`)
sh.cd('..')
})
if (['darwin', 'linux'].includes(process.platform)) {
sh.cd('node_modules')
for (let x of vars.builtinPlugins) {
sh.ln('-fs', '../' + x, x)
}
for (let x of vars.bundledModules) {
sh.ln('-fs', '../app/node_modules/' + x, x)
}
sh.cd('..')
}

View File

@@ -22,3 +22,4 @@ vars.builtinPlugins.forEach(plugin => {
}
sh.cd('..')
})
fs.unlinkSync(path.join(target, 'package.json'), '{}')

11
scripts/set-plugin-versions.js Executable file
View File

@@ -0,0 +1,11 @@
#!/usr/bin/env node
const sh = require('shelljs')
const vars = require('./vars')
const log = require('npmlog')
vars.builtinPlugins.forEach(plugin => {
log.info('bump', plugin)
sh.cd(plugin)
sh.exec('npm --no-git-tag-version version ' + vars.version)
sh.cd('..')
})

View File

@@ -14,7 +14,11 @@ exports.builtinPlugins = [
'terminus-terminal',
'terminus-community-color-schemes',
'terminus-plugin-manager',
'terminus-ssh',
]
exports.nativeModules = ['node-pty', 'font-manager']
exports.version = appInfo.version
exports.bundledModules = [
'@angular',
'@ng-bootstrap',
]
exports.nativeModules = ['node-pty-tmp', 'font-manager', 'xkeychain']
exports.electronVersion = pkgInfo.devDependencies.electron

View File

@@ -1,7 +1,10 @@
{
"name": "terminus-community-color-schemes",
"version": "0.0.1",
"version": "1.0.0-alpha.36",
"description": "Community color schemes for Terminus",
"keywords": [
"terminus-builtin-plugin"
],
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"scripts": {

View File

@@ -0,0 +1,54 @@
! Base16 Default Dark
! Scheme: Chris Kempson (http://chriskempson.com)
#define base00 #181818
#define base01 #282828
#define base02 #383838
#define base03 #585858
#define base04 #b8b8b8
#define base05 #d8d8d8
#define base06 #e8e8e8
#define base07 #f8f8f8
#define base08 #ab4642
#define base09 #dc9656
#define base0A #f7ca88
#define base0B #a1b56c
#define base0C #86c1b9
#define base0D #7cafc2
#define base0E #ba8baf
#define base0F #a16946
*.foreground: base05
#ifdef background_opacity
*.background: [background_opacity]base00
#else
*.background: base00
#endif
*.cursorColor: base05
*.color0: base00
*.color1: base08
*.color2: base0B
*.color3: base0A
*.color4: base0D
*.color5: base0E
*.color6: base0C
*.color7: base05
*.color8: base03
*.color9: base08
*.color10: base0B
*.color11: base0A
*.color12: base0D
*.color13: base0E
*.color14: base0C
*.color15: base07
! Note: colors beyond 15 might not be loaded (e.g., xterm, urxvt),
! use 'shell' template to set these if necessary
*.color16: base09
*.color17: base0F
*.color18: base01
*.color19: base02
*.color20: base04
*.color21: base06

View File

@@ -0,0 +1,44 @@
!
! Generated with :
! XRDB2Xrecources.py
!
*.foreground: #9f999b
*.background: #222021
*.cursorColor: #996e00
!
! Black
*.color0: #222021
*.color8: #635f60
!
! Red
*.color1: #936c7a
*.color9: #ddaf3c
!
! Green
*.color2: #cca133
*.color10: #2f2d2e
!
! Yellow
*.color3: #ffcc4d
*.color11: #565254
!
! Blue
*.color4: #9c818b
*.color12: #706b6d
!
! Magenta
*.color5: #cca133
*.color13: #f0a8c1
!
! Cyan
*.color6: #d27998
*.color14: #c39622
!
! White
*.color7: #9f999b
*.color15: #ffebf2
!
! Bold, Italic, Underline
*.colorBD: #9f999b
!*.colorIT:
!*.colorUL:

View File

@@ -0,0 +1,44 @@
!
! Generated with :
! XRDB2Xrecources.py
!
*.foreground: #ada594
*.background: #292724
*.cursorColor: #bc672f
!
! Black
*.color0: #292724
*.color8: #7e7767
!
! Red
*.color1: #816f4b
*.color9: #f29d63
!
! Green
*.color2: #ec9255
*.color10: #3d3a34
!
! Yellow
*.color3: #ffb380
*.color11: #615c51
!
! Blue
*.color4: #957e50
*.color12: #908774
!
! Magenta
*.color5: #ec9255
*.color13: #ddcba6
!
! Cyan
*.color6: #ac8e53
*.color14: #e58748
!
! White
*.color7: #ada594
*.color15: #f2ead9
!
! Bold, Italic, Underline
*.colorBD: #ada594
!*.colorIT:
!*.colorUL:

View File

@@ -0,0 +1,44 @@
!
! Generated with :
! XRDB2Xrecources.py
!
*.foreground: #9094a7
*.background: #1b1f32
*.cursorColor: #289dbd
!
! Black
*.color0: #1b1f32
*.color8: #51587b
!
! Red
*.color1: #627af4
*.color9: #75d5f0
!
! Green
*.color2: #67c9e4
*.color10: #252a41
!
! Yellow
*.color3: #99e9ff
*.color11: #444b6f
!
! Blue
*.color4: #7289fd
*.color12: #5e6587
!
! Magenta
*.color5: #67c9e4
*.color13: #c3cdfe
!
! Cyan
*.color6: #8b9efd
*.color14: #5cbcd6
!
! White
*.color7: #9094a7
*.color15: #e1e6ff
!
! Bold, Italic, Underline
*.colorBD: #9094a7
!*.colorIT:
!*.colorUL:

View File

@@ -0,0 +1,44 @@
!
! Generated with :
! XRDB2Xrecources.py
!
*.foreground: #a4a1b5
*.background: #2a2734
*.cursorColor: #b37537
!
! Black
*.color0: #2a2734
*.color8: #6c6783
!
! Red
*.color1: #8a75f5
*.color9: #ffb870
!
! Green
*.color2: #ffad5c
*.color10: #363342
!
! Yellow
*.color3: #ffcc99
*.color11: #545167
!
! Blue
*.color4: #9a86fd
*.color12: #787391
!
! Magenta
*.color5: #ffad5c
*.color13: #d9d2fe
!
! Cyan
*.color6: #afa0fe
*.color14: #ffa142
!
! White
*.color7: #a4a1b5
*.color15: #eeebff
!
! Bold, Italic, Underline
*.colorBD: #a4a1b5
!*.colorIT:
!*.colorUL:

View File

@@ -0,0 +1,44 @@
!
! Generated with :
! XRDB2Xrecources.py
!
*.foreground: #a1b5a1
*.background: #2a2d2a
*.cursorColor: #656b47
!
! Black
*.color0: #2a2d2a
*.color8: #535f53
!
! Red
*.color1: #5c705c
*.color9: #cbe25a
!
! Green
*.color2: #bfd454
*.color10: #353b35
!
! Yellow
*.color3: #e5fb79
*.color11: #485148
!
! Blue
*.color4: #687d68
*.color12: #5e6e5e
!
! Magenta
*.color5: #bfd454
*.color13: #c8e4c8
!
! Cyan
*.color6: #8fae8f
*.color14: #b1c44f
!
! White
*.color7: #a1b5a1
*.color15: #f0fff0
!
! Bold, Italic, Underline
*.colorBD: #a1b5a1
!*.colorIT:
!*.colorUL:

View File

@@ -0,0 +1,44 @@
!
! Generated with :
! XRDB2Xrecources.py
!
*.foreground: #9e999f
*.background: #222022
*.cursorColor: #995900
!
! Black
*.color0: #222022
*.color8: #635f63
!
! Red
*.color1: #8f6c93
*.color9: #d9b98c
!
! Green
*.color2: #cc8c33
*.color10: #2f2d2f
!
! Yellow
*.color3: #ffd599
*.color11: #575158
!
! Blue
*.color4: #9a819c
*.color12: #6f6b70
!
! Magenta
*.color5: #cc8c33
*.color13: #eaa8f0
!
! Cyan
*.color6: #cb79d2
*.color14: #c38022
!
! White
*.color7: #9e999f
*.color15: #fdebff
!
! Bold, Italic, Underline
*.colorBD: #9e999f
!*.colorIT:
!*.colorUL:

View File

@@ -0,0 +1,44 @@
!
! Generated with :
! XRDB2Xrecources.py
!
*.foreground: #575158
*.background: #fbfaf9
*.cursorColor: #eaa8f0
!
! Black
*.color0: #222022
*.color8: #635f63
!
! Red
*.color1: #8f6c93
*.color9: #d9b98c
!
! Green
*.color2: #cc8c33
*.color10: #2f2d2f
!
! Yellow
*.color3: #ffd599
*.color11: #575158
!
! Blue
*.color4: #9a819c
*.color12: #6f6b70
!
! Magenta
*.color5: #b87414
*.color13: #eaa8f0
!
! Cyan
*.color6: #cb79d2
*.color14: #c38022
!
! White
*.color7: #9e999f
*.color15: #fbfaf9
!
! Bold, Italic, Underline
*.colorBD: #575158
!*.colorIT:
!*.colorUL:

View File

@@ -0,0 +1,44 @@
!
! Generated with :
! XRDB2Xrecources.py
!
*.foreground: #7ba8b7
*.background: #192d34
*.cursorColor: #84740b
!
! Black
*.color0: #192d34
*.color8: #3d6876
!
! Red
*.color1: #3e91ac
*.color9: #d6c65c
!
! Green
*.color2: #cbbb4d
*.color10: #223c44
!
! Yellow
*.color3: #ffeb66
*.color11: #335966
!
! Blue
*.color4: #499fbc
*.color12: #467686
!
! Magenta
*.color5: #cbbb4d
*.color13: #a5d8e9
!
! Cyan
*.color6: #62b1cb
*.color14: #c4b031
!
! White
*.color7: #7ba8b7
*.color15: #e1f7ff
!
! Bold, Italic, Underline
*.colorBD: #7ba8b7
!*.colorIT:
!*.colorUL:

View File

@@ -0,0 +1,44 @@
!
! Generated with :
! XRDB2Xrecources.py
!
*.foreground: #7b9eb7
*.background: #192834
*.cursorColor: #4d8217
!
! Black
*.color0: #192834
*.color8: #3d5e76
!
! Red
*.color1: #277fbe
*.color9: #8cdd3c
!
! Green
*.color2: #80bf40
*.color10: #223644
!
! Yellow
*.color3: #a6f655
*.color11: #335166
!
! Blue
*.color4: #4299d7
*.color12: #466b86
!
! Magenta
*.color5: #80bf40
*.color13: #afddfe
!
! Cyan
*.color6: #47adf5
*.color14: #73b234
!
! White
*.color7: #7b9eb7
*.color15: #d1ecff
!
! Bold, Italic, Underline
*.colorBD: #7b9eb7
!*.colorIT:
!*.colorUL:

View File

@@ -0,0 +1,44 @@
!
! Generated with :
! XRDB2Xrecources.py
!
*.foreground: #4f5664
*.background: #faf8f5
*.cursorColor: #b7c9eb
!
! Black
*.color0: #232834
*.color8: #656e81
!
! Red
*.color1: #1659df
*.color9: #c6b28b
!
! Green
*.color2: #b29762
*.color10: #31363f
!
! Yellow
*.color3: #e5ddcd
*.color11: #4f5664
!
! Blue
*.color4: #3d75e6
*.color12: #707a8f
!
! Magenta
*.color5: #896724
*.color13: #b7c9eb
!
! Cyan
*.color6: #728fcb
*.color14: #9a7c42
!
! White
*.color7: #8d95a5
*.color15: #faf8f5
!
! Bold, Italic, Underline
*.colorBD: #4f5664
!*.colorIT:
!*.colorUL:

View File

@@ -0,0 +1,44 @@
!
! Generated with :
! XRDB2Xrecources.py
!
*.foreground: #9a90a7
*.background: #2a2433
*.cursorColor: #cf504a
!
! Black
*.color0: #2a2433
*.color8: #635775
!
! Red
*.color1: #aa75f5
*.color9: #fc8983
!
! Green
*.color2: #f87972
*.color10: #372f42
!
! Yellow
*.color3: #ffb6b3
*.color11: #574b68
!
! Blue
*.color4: #b886fd
*.color12: #706383
!
! Magenta
*.color5: #f87972
*.color13: #e4d2fe
!
! Cyan
*.color6: #c7a0fe
*.color14: #f36f68
!
! White
*.color7: #9a90a7
*.color15: #f3ebff
!
! Bold, Italic, Underline
*.colorBD: #9a90a7
!*.colorIT:
!*.colorUL:

View File

@@ -0,0 +1,44 @@
!
! Generated with :
! XRDB2Xrecources.py
!
*.foreground: #a1aab5
*.background: #1d262f
*.cursorColor: #067953
!
! Black
*.color0: #1d262f
*.color8: #4a5f78
!
! Red
*.color1: #34659d
*.color9: #14e19d
!
! Green
*.color2: #0fc78a
*.color10: #27323f
!
! Yellow
*.color3: #47ebb4
*.color11: #405368
!
! Blue
*.color4: #57718e
*.color12: #738191
!
! Magenta
*.color5: #0fc78a
*.color13: #afd4fe
!
! Cyan
*.color6: #6e9bcf
*.color14: #0db57d
!
! White
*.color7: #a1aab5
*.color15: #ebf4ff
!
! Bold, Italic, Underline
*.colorBD: #a1aab5
!*.colorIT:
!*.colorUL:

View File

@@ -0,0 +1,44 @@
!
! Generated with :
! XRDB2Xrecources.py
!
*.foreground: #a1a1b5
*.background: #24242e
*.cursorColor: #b25424
!
! Black
*.color0: #24242e
*.color8: #5b5b76
!
! Red
*.color1: #7676f4
*.color9: #f37b3f
!
! Green
*.color2: #ec7336
*.color10: #333342
!
! Yellow
*.color3: #fe8c52
*.color11: #515167
!
! Blue
*.color4: #767693
*.color12: #737391
!
! Magenta
*.color5: #ec7336
*.color13: #cecee3
!
! Cyan
*.color6: #8a8aad
*.color14: #e66e33
!
! White
*.color7: #a1a1b5
*.color15: #ebebff
!
! Bold, Italic, Underline
*.colorBD: #a1a1b5
!*.colorIT:
!*.colorUL:

View File

@@ -10,38 +10,38 @@ export class ColorSchemes extends TerminalColorSchemeProvider {
schemeContents.keys().forEach(schemeFile => {
let lines = (schemeContents(schemeFile) as string).split('\n')
// process #define variables
let variables: any = {}
lines
.filter(x => x.startsWith('#define'))
.map(x => x.split(' ').map(v => v.trim()))
.forEach(([ignore, variableName, variableValue]) => {
variables[variableName] = variableValue
})
let values: any = {}
lines
.filter(x => x.startsWith('*.'))
.map(x => x.substring(2))
.map(x => x.split(':').map(v => v.trim()))
.forEach(([key, value]) => {
values[key] = value
values[key] = variables[value] ? variables[value] : value
})
let colors: string[] = []
let colorIndex = 0
while (values[`color${colorIndex}`]) {
colors.push(values[`color${colorIndex}`])
colorIndex++
}
schemes.push({
name: schemeFile.split('/')[1].trim(),
foreground: values.foreground,
background: values.background,
cursor: values.cursorColor,
colors: [
values.color0,
values.color1,
values.color2,
values.color3,
values.color4,
values.color5,
values.color6,
values.color7,
values.color8,
values.color9,
values.color10,
values.color11,
values.color12,
values.color13,
values.color14,
values.color15,
],
colors,
})
})

View File

@@ -0,0 +1,11 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@types/node@7.0.12":
version "7.0.12"
resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.12.tgz#ae5f67a19c15f752148004db07cbbb372e69efc9"
"@types/webpack-env@^1.13.0":
version "1.13.1"
resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.13.1.tgz#b45c222e24301bd006e3edfc762cc6b51bda236a"

View File

@@ -1,7 +1,10 @@
{
"name": "terminus-core",
"version": "0.0.1",
"version": "1.0.0-alpha.36",
"description": "Terminus core",
"keywords": [
"terminus-builtin-plugin"
],
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"scripts": {
@@ -14,14 +17,16 @@
"author": "Eugene Pankov",
"license": "MIT",
"devDependencies": {
"@ng-bootstrap/ng-bootstrap": "1.0.0-alpha.22",
"@types/js-yaml": "^3.5.29",
"@types/node": "^7.0.12",
"@types/js-yaml": "^3.9.0",
"@types/node": "^7.0.37",
"@types/webpack-env": "^1.13.0",
"@types/winston": "^2.3.6",
"axios": "0.16.2",
"bootstrap": "4.0.0-alpha.6",
"core-js": "^2.4.1",
"electron-updater": "^2.8.9",
"ngx-perfect-scrollbar": "4.0.0",
"typescript": "^2.4.0"
"typescript": "^2.4.1"
},
"peerDependencies": {
"@angular/animations": "4.0.1",
@@ -34,8 +39,9 @@
"zone.js": "0.8.4"
},
"dependencies": {
"deepmerge": "^1.4.4",
"js-yaml": "^3.8.4"
"deepmerge": "^1.5.0",
"js-yaml": "^3.9.0",
"winston": "^2.4.0"
},
"false": {}
}

View File

@@ -1,5 +1,5 @@
export { BaseTabComponent } from '../components/baseTab.component'
export { TabRecoveryProvider } from './tabRecovery'
export { TabRecoveryProvider, RecoveredTab } from './tabRecovery'
export { ToolbarButtonProvider, IToolbarButton } from './toolbarButtonProvider'
export { ConfigProvider } from './configProvider'
export { HotkeyProvider, IHotkeyDescription } from './hotkeyProvider'

View File

@@ -1,3 +1,10 @@
export abstract class TabRecoveryProvider {
abstract async recover (recoveryToken: any): Promise<void>
import { TabComponentType } from '../services/app.service'
export interface RecoveredTab {
type: TabComponentType,
options?: any,
}
export abstract class TabRecoveryProvider {
abstract async recover (recoveryToken: any): Promise<RecoveredTab|null>
}

View File

@@ -1,6 +1,7 @@
export interface IToolbarButton {
icon: string
title: string
touchBarTitle?: string
weight?: number
click: () => void
}

View File

@@ -1,12 +1,13 @@
title-bar(
*ngIf='config.store.appearance.frame == "full" && config.store.appearance.dock == "off"',
*ngIf='!hostApp.isFullScreen && config.store.appearance.frame == "full" && config.store.appearance.dock == "off"',
[class.inset]='hostApp.platform == Platform.macOS'
)
.content(
[class.tabs-on-top]='config.store.appearance.tabsLocation == "top"'
[class.tabs-on-top]='config.store.appearance.tabsLocation == "top"'
)
.tab-bar(
*ngIf='!hostApp.isFullScreen',
[class.inset]='hostApp.platform == Platform.macOS && config.store.appearance.frame == "thin" && config.store.appearance.tabsLocation == "top"'
)
.tabs
@@ -19,9 +20,8 @@ title-bar(
[class.drag-region]='hostApp.platform == Platform.macOS',
@animateTab,
(click)='app.selectTab(tab)',
(closeClicked)='app.closeTab(tab)',
)
.btn-group
button.btn.btn-secondary.btn-tab-bar(
*ngFor='let button of leftToolbarButtons',
@@ -29,9 +29,9 @@ title-bar(
(click)='button.click()',
)
i.fa([class]='"fa fa-" + button.icon')
.drag-space
.drag-space([class.persistent]='config.store.appearance.frame == "thin" && hostApp.platform != Platform.macOS')
.btn-group
button.btn.btn-secondary.btn-tab-bar(
*ngFor='let button of rightToolbarButtons',
@@ -39,6 +39,13 @@ title-bar(
(click)='button.click()',
)
i.fa([class]='"fa fa-" + button.icon')
button.btn.btn-secondary.btn-tab-bar(
*ngIf='appUpdate',
title='Update available',
(click)='updateApp()',
)
i.fa.fa-arrow-up.text-info
span.text-info Update
window-controls(
*ngIf='config.store.appearance.frame == "thin" && (hostApp.platform == Platform.Windows || hostApp.platform == Platform.Linux)',
@@ -47,7 +54,7 @@ title-bar(
start-page(*ngIf='ready && app.tabs.length == 0')
tab-body(
*ngFor='let tab of app.tabs; trackBy: tab?.id',
*ngFor='let tab of app.tabs; trackBy: tab?.id',
[active]='tab == app.activeTab',
[tab]='tab',
[scrollable]='tab.scrollable',

View File

@@ -7,6 +7,7 @@
-webkit-user-select: none;
-webkit-user-drag: none;
-webkit-font-smoothing: antialiased;
will-change: transform;
cursor: default;
animation: 0.5s ease-out fadeIn;
}
@@ -55,15 +56,20 @@ $tab-border-radius: 4px;
}
&>.drag-space {
min-width: 100px;
flex: 1 0 25%;
min-width: 1px;
flex: 1 0 1%;
-webkit-app-region: drag;
&.persistent {
min-width: 100px;
flex: 1 0 25%;
}
}
&.inset {
padding-left: 85px;
}
window-controls {
margin-left: 10px;
}

View File

@@ -1,16 +1,19 @@
import { Component, Inject, Input, HostListener } from '@angular/core'
import { trigger, style, animate, transition, state } from '@angular/animations'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { ElectronService } from '../services/electron.service'
import { HostAppService, Platform } from '../services/hostApp.service'
import { HotkeysService } from '../services/hotkeys.service'
import { Logger, LogService } from '../services/log.service'
import { QuitterService } from '../services/quitter.service'
import { ConfigService } from '../services/config.service'
import { DockingService } from '../services/docking.service'
import { TabRecoveryService } from '../services/tabRecovery.service'
import { ThemesService } from '../services/themes.service'
import { UpdaterService, Update } from '../services/updater.service'
import { TouchbarService } from '../services/touchbar.service'
import { SafeModeModalComponent } from './safeModeModal.component'
import { AppService, IToolbarButton, ToolbarButtonProvider } from '../api'
@Component({
@@ -28,9 +31,16 @@ import { AppService, IToolbarButton, ToolbarButtonProvider } from '../api'
'flex-basis': '1px',
'width': '1px',
}),
animate('250ms ease-in-out')
animate('250ms ease-in-out', style({
'flex-basis': '200px',
'width': '200px',
}))
]),
transition(':leave', [
style({
'flex-basis': '200px',
'width': '200px',
}),
animate('250ms ease-in-out', style({
'flex-basis': '1px',
'width': '1px',
@@ -45,19 +55,22 @@ export class AppRootComponent {
@Input() leftToolbarButtons: IToolbarButton[]
@Input() rightToolbarButtons: IToolbarButton[]
private logger: Logger
private appUpdate: Update
constructor (
private docking: DockingService,
private electron: ElectronService,
private tabRecovery: TabRecoveryService,
private hotkeys: HotkeysService,
private updater: UpdaterService,
private touchbar: TouchbarService,
public hostApp: HostAppService,
public hotkeys: HotkeysService,
public config: ConfigService,
public app: AppService,
@Inject(ToolbarButtonProvider) private toolbarButtonProviders: ToolbarButtonProvider[],
log: LogService,
ngbModal: NgbModal,
_themes: ThemesService,
_quitter: QuitterService,
) {
this.logger = log.create('main')
this.logger.info('v', electron.app.getVersion())
@@ -74,7 +87,7 @@ export class AppRootComponent {
}
if (this.app.activeTab) {
if (hotkey === 'close-tab') {
this.app.closeTab(this.app.activeTab)
this.app.closeTab(this.app.activeTab, true)
}
if (hotkey === 'toggle-last-tab') {
this.app.toggleLastTab()
@@ -86,6 +99,9 @@ export class AppRootComponent {
this.app.previousTab()
}
}
if (hotkey === 'toggle-fullscreen') {
this.hostApp.toggleFullscreen()
}
})
this.docking.dock()
@@ -93,22 +109,36 @@ export class AppRootComponent {
this.docking.dock()
})
this.hostApp.secondInstance.subscribe(() => {
this.hostApp.secondInstance$.subscribe(() => {
this.onGlobalHotkey()
})
this.hotkeys.globalHotkey.subscribe(() => {
this.onGlobalHotkey()
})
if (window['safeModeReason']) {
ngbModal.open(SafeModeModalComponent)
}
this.updater.check().then(update => {
this.appUpdate = update
})
this.touchbar.update()
}
onGlobalHotkey () {
if (this.electron.app.window.isFocused()) {
// focused
this.electron.app.window.hide()
this.electron.loseFocus()
if (this.hostApp.platform !== Platform.macOS) {
this.electron.app.window.hide()
}
} else {
if (!this.electron.app.window.isVisible()) {
// unfocused, invisible
this.electron.app.window.show()
this.electron.app.window.focus()
} else {
if (this.config.store.appearance.dock === 'off') {
// not docked, visible
@@ -131,16 +161,8 @@ export class AppRootComponent {
if (this.app.tabs.length === 0) {
this.app.openDefaultTab()
}
}
private getToolbarButtons (aboveZero: boolean): IToolbarButton[] {
let buttons: IToolbarButton[] = []
this.toolbarButtonProviders.forEach((provider) => {
buttons = buttons.concat(provider.provide())
})
return buttons
.filter((button) => (button.weight > 0) === aboveZero)
.sort((a: IToolbarButton, b: IToolbarButton) => (a.weight || 0) - (b.weight || 0))
this.app.emitReady()
}
@HostListener('dragover')
@@ -152,4 +174,18 @@ export class AppRootComponent {
onDrop () {
return false
}
updateApp () {
this.electron.shell.openExternal(this.appUpdate.url)
}
private getToolbarButtons (aboveZero: boolean): IToolbarButton[] {
let buttons: IToolbarButton[] = []
this.config.enabledServices(this.toolbarButtonProviders).forEach(provider => {
buttons = buttons.concat(provider.provide())
})
return buttons
.filter((button) => (button.weight > 0) === aboveZero)
.sort((a: IToolbarButton, b: IToolbarButton) => (a.weight || 0) - (b.weight || 0))
}
}

View File

@@ -1,10 +1,12 @@
import { Subject, BehaviorSubject } from 'rxjs'
import { Subject } from 'rxjs'
import { ViewRef } from '@angular/core'
export abstract class BaseTabComponent {
private static lastTabID = 0
id: number
title$ = new BehaviorSubject<string>(null)
title: string
titleChange$ = new Subject<string>()
customTitle: string
scrollable: boolean
hasActivity = false
focused$ = new Subject<void>()
@@ -22,6 +24,13 @@ export abstract class BaseTabComponent {
})
}
setTitle (title: string) {
this.title = title
if (!this.customTitle) {
this.titleChange$.next(title)
}
}
displayActivity (): void {
this.hasActivity = true
}
@@ -30,9 +39,12 @@ export abstract class BaseTabComponent {
return null
}
async canClose (): Promise<boolean> {
return true
}
destroy (): void {
this.focused$.complete()
this.blurred$.complete()
this.title$.complete()
}
}

View File

@@ -0,0 +1,4 @@
.icon((click)='click()', tabindex='0', [class.active]='model', (keyup.space)='click()')
i.fa.fa-square-o.off
i.fa.fa-check-square.on
.text((click)='click()') {{text}}

View File

@@ -0,0 +1,51 @@
:host {
cursor: pointer;
margin: 5px 0;
&:focus {
background: rgba(255,255,255,.05);
border-radius: 5px;
}
&:active {
background: rgba(255,255,255,.1);
border-radius: 3px;
}
&[disabled] {
opacity: 0.5;
}
display: flex;
flex-direction: row;
align-items: center;
.icon {
position: relative;
flex: none;
width: 14px;
height: 14px;
i {
position: absolute;
left: 0;
top: -2px;
transition: 0.25s opacity;
display: block;
font-size: 18px;
}
i.on, &.active i.off {
opacity: 0;
}
i.off, &.active i.on {
opacity: 1;
}
}
.text {
flex: auto;
margin-left: 8px;
}
}

View File

@@ -0,0 +1,45 @@
import { NgZone, Component, Input } from '@angular/core'
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'
@Component({
selector: 'checkbox',
template: require('./checkbox.component.pug'),
styles: [require('./checkbox.component.scss')],
providers: [
{ provide: NG_VALUE_ACCESSOR, useExisting: CheckboxComponent, multi: true },
]
})
export class CheckboxComponent implements ControlValueAccessor {
@Input() model: boolean
@Input() disabled: boolean
@Input() text: string
private changed = new Array<(val: boolean) => void>()
click () {
NgZone.assertInAngularZone()
if (this.disabled) {
return
}
this.model = !this.model
for (let fx of this.changed) {
fx(this.model)
}
}
writeValue (obj: any) {
this.model = obj
}
registerOnChange (fn: any): void {
this.changed.push(fn)
}
registerOnTouched (fn: any): void {
this.changed.push(fn)
}
setDisabledState (isDisabled: boolean) {
this.disabled = isDisabled
}
}

View File

@@ -0,0 +1,6 @@
.modal-body
input.form-control(type='text', [(ngModel)]='value', (keyup.enter)='save()', autofocus)
.modal-footer
button.btn.btn-outline-primary((click)='save()') Save
button.btn.btn-outline-secondary((click)='close()') Cancel

View File

@@ -0,0 +1,22 @@
import { Component, Input } from '@angular/core'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
@Component({
selector: 'rename-tab-modal',
template: require('./renameTabModal.component.pug'),
})
export class RenameTabModalComponent {
@Input() value: string
constructor (
private modalInstance: NgbActiveModal
) { }
save () {
this.modalInstance.close(this.value)
}
close () {
this.modalInstance.dismiss()
}
}

View File

@@ -0,0 +1,7 @@
.modal-body
.alert.alert-danger Terminus could not start with your plugins, so all third party plugins have been disabled in this session. The error was:
pre {{error}}
.modal-footer
button.btn.btn-outline-primary((click)='close()') Close

View File

@@ -0,0 +1,19 @@
import { Component, Input } from '@angular/core'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
@Component({
template: require('./safeModeModal.component.pug'),
})
export class SafeModeModalComponent {
@Input() error: Error
constructor (
public modalInstance: NgbActiveModal,
) {
this.error = window['safeModeReason']
}
close () {
this.modalInstance.dismiss()
}
}

View File

@@ -1,30 +1,20 @@
div
.terminus-logo
.part(style='transform: rotateZ(0deg)')
div
.part(style='transform: rotateZ(51deg)')
div
.part(style='transform: rotateZ(102deg)')
div
.part(style='transform: rotateZ(154deg)')
div
.part(style='transform: rotateZ(205deg)')
div
.part(style='transform: rotateZ(257deg)')
div
.part(style='transform: rotateZ(308deg)')
div
h1.terminus-title Terminus
span.text-muted α
sup α
button.btn.btn-primary.btn-lg.btn-block(
*ngFor='let button of getButtons()',
(click)='button.click()',
)
i.fa([class]='"fa fa-" + button.icon')
span {{button.title}}
.list-group
a.list-group-item.list-group-item-action(
*ngFor='let button of getButtons()',
(click)='button.click()',
)
i([class]='"fa fa-fw fa-" + button.icon')
span {{button.title}}
footer
.pull-right
.form-control-static Version: {{version}}
.btn-group
button.btn.btn-secondary((click)='openGitHub()')
i.fa.fa-github

View File

@@ -24,6 +24,6 @@ footer {
background: rgba(0,0,0,.5);
}
button {
a, button {
-webkit-app-region: no-drag;
}

View File

@@ -1,5 +1,7 @@
import * as os from 'os'
import { Component, Inject } from '@angular/core'
import { ElectronService } from '../services/electron.service'
import { ConfigService } from '../services/config.service'
import { IToolbarButton, ToolbarButtonProvider } from '../api'
@Component({
@@ -8,13 +10,18 @@ import { IToolbarButton, ToolbarButtonProvider } from '../api'
styles: [require('./startPage.component.scss')],
})
export class StartPageComponent {
version: string
constructor (
private electron: ElectronService,
private config: ConfigService,
@Inject(ToolbarButtonProvider) private toolbarButtonProviders: ToolbarButtonProvider[],
) { }
) {
this.version = electron.app.getVersion()
}
getButtons (): IToolbarButton[] {
return this.toolbarButtonProviders
return this.config.enabledServices(this.toolbarButtonProviders)
.map(provider => provider.provide())
.reduce((a, b) => a.concat(b))
.sort((a: IToolbarButton, b: IToolbarButton) => (a.weight || 0) - (b.weight || 0))
@@ -25,6 +32,13 @@ export class StartPageComponent {
}
reportBug () {
this.electron.shell.openExternal('https://github.com/eugeny/terminus/issues/new')
let body = `Version: ${this.version}\n`
body += `Platform: ${os.platform()} ${os.release()}\n\n`
let label = {
darwin: 'macOS',
windows: 'Windows',
linux: 'Linux',
}[os.platform()]
this.electron.shell.openExternal(`https://github.com/eugeny/terminus/issues/new?body=${encodeURIComponent(body)}&labels=${label}`)
}
}

View File

@@ -1,3 +1,3 @@
.index {{index + 1}}
.name {{tab.title$ | async}}
button((click)='closeClicked.emit()') &times;
.name([title]='tab.customTitle || tab.title') {{tab.customTitle || tab.title}}
button((click)='app.closeTab(tab, true)') &times;

View File

@@ -1,7 +1,6 @@
$tabs-height: 36px;
:host {
line-height: $tabs-height - 2px;
cursor: pointer;
flex: 1000 1 200px;
@@ -15,8 +14,6 @@ $tabs-height: 36px;
transition: 0.125s ease-out all;
border-top: 1px solid transparent;
.index {
flex: none;
font-weight: bold;
@@ -24,9 +21,9 @@ $tabs-height: 36px;
margin-left: 10px;
width: 20px;
border-radius: 10px;
line-height: 35px;
text-align: center;
transition: 0.25s all;
align-self: center;
}
.name {
@@ -36,6 +33,7 @@ $tabs-height: 36px;
white-space: nowrap;
text-overflow: ellipsis;
min-width: 0;
align-self: center;
}
button {
@@ -49,11 +47,15 @@ $tabs-height: 36px;
height: $button-size;
border-radius: $button-size / 2;
line-height: $button-size * 0.87;
margin-top: ($tabs-height - $button-size) * 0.5;
align-self: center;
margin-right: 10px;
text-align: center;
font-size: 20px;
&:focus {
outline: 0;
}
}
&:hover button {

View File

@@ -1,5 +1,9 @@
import { Component, Input, Output, EventEmitter, HostBinding } from '@angular/core'
import { BaseTabComponent } from '../components/baseTab.component'
import { Component, Input, HostBinding, HostListener, NgZone } from '@angular/core'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { BaseTabComponent } from './baseTab.component'
import { RenameTabModalComponent } from './renameTabModal.component'
import { ElectronService } from '../services/electron.service'
import { AppService } from '../services/app.service'
@Component({
selector: 'tab-header',
@@ -11,5 +15,76 @@ export class TabHeaderComponent {
@Input() @HostBinding('class.active') active: boolean
@Input() @HostBinding('class.has-activity') hasActivity: boolean
@Input() tab: BaseTabComponent
@Output() closeClicked = new EventEmitter()
private contextMenu: any
constructor (
zone: NgZone,
electron: ElectronService,
public app: AppService,
private ngbModal: NgbModal,
) {
this.contextMenu = electron.remote.Menu.buildFromTemplate([
{
label: 'Close',
click: () => {
zone.run(() => {
app.closeTab(this.tab, true)
})
}
},
{
label: 'Close other tabs',
click: () => {
zone.run(() => {
for (let tab of app.tabs.filter(x => x !== this.tab)) {
app.closeTab(tab, true)
}
})
}
},
{
label: 'Close tabs to the right',
click: () => {
zone.run(() => {
for (let tab of app.tabs.slice(app.tabs.indexOf(this.tab) + 1)) {
app.closeTab(tab, true)
}
})
}
},
{
label: 'Close tabs to the left',
click: () => {
zone.run(() => {
for (let tab of app.tabs.slice(0, app.tabs.indexOf(this.tab))) {
app.closeTab(tab, true)
}
})
}
},
])
}
@HostListener('dblclick') onDoubleClick (): void {
let modal = this.ngbModal.open(RenameTabModalComponent)
modal.componentInstance.value = this.tab.customTitle || this.tab.title
modal.result.then(result => {
this.tab.setTitle(result)
this.tab.customTitle = result
}).catch(() => null)
}
@HostListener('auxclick', ['$event']) onAuxClick ($event: MouseEvent): void {
if ($event.which === 2) {
this.app.closeTab(this.tab, true)
}
if ($event.which === 3) {
this.contextMenu.popup({
x: $event.pageX,
y: $event.pageY,
async: true,
})
event.preventDefault()
}
}
}

View File

@@ -1,6 +1,8 @@
hotkeys:
toggle-window:
- 'Ctrl+Space'
toggle-fullscreen:
- 'F11'
close-tab:
- 'Ctrl-Shift-W'
- ['Ctrl-A', 'K']
@@ -10,9 +12,11 @@ hotkeys:
next-tab:
- 'Ctrl-Shift-ArrowRight'
- ['Ctrl-A', 'N']
- 'Ctrl-Tab'
previous-tab:
- 'Ctrl-Shift-ArrowLeft'
- ['Ctrl-A', 'P']
- 'Ctrl-Shift-Tab'
tab-1:
- 'Alt-1'
- ['Ctrl-A', '1']
@@ -43,3 +47,4 @@ hotkeys:
tab-10:
- 'Alt-0'
- ['Ctrl-A', '0']
pluginBlacklist: ['ssh']

View File

@@ -1,45 +1,33 @@
hotkeys:
toggle-window:
- 'Ctrl+Space'
toggle-fullscreen:
- 'Ctrl+⌘+F'
close-tab:
- '⌘-W'
- ['Ctrl-A', 'K']
toggle-last-tab:
- ['Ctrl-A', 'A']
- ['Ctrl-A', 'Ctrl-A']
toggle-last-tab: []
next-tab:
- '⌘-ArrowRight'
- ['Ctrl-A', 'N']
- 'Ctrl-Tab'
previous-tab:
- '⌘-ArrowLeft'
- ['Ctrl-A', 'P']
- 'Ctrl-Shift-Tab'
tab-1:
- '⌘-1'
- ['Ctrl-A', '1']
tab-2:
- '⌘-2'
- ['Ctrl-A', '2']
tab-3:
- '⌘-3'
- ['Ctrl-A', '3']
tab-4:
- '⌘-4'
- ['Ctrl-A', '4']
tab-5:
- '⌘-5'
- ['Ctrl-A', '5']
tab-6:
- '⌘-6'
- ['Ctrl-A', '6']
tab-7:
- '⌘-7'
- ['Ctrl-A', '7']
tab-8:
- '⌘-8'
- ['Ctrl-A', '8']
tab-9:
- '⌘-9'
- ['Ctrl-A', '9']
tab-10:
- '⌘-0'
- ['Ctrl-A', '0']
pluginBlacklist: ['ssh']

View File

@@ -1,6 +1,8 @@
hotkeys:
toggle-window:
- 'Ctrl+Space'
toggle-fullscreen:
- 'F11'
close-tab:
- 'Ctrl-Shift-W'
- ['Ctrl-A', 'K']
@@ -10,9 +12,11 @@ hotkeys:
next-tab:
- 'Ctrl-Shift-ArrowRight'
- ['Ctrl-A', 'N']
- 'Ctrl-Tab'
previous-tab:
- 'Ctrl-Shift-ArrowLeft'
- ['Ctrl-A', 'P']
- 'Ctrl-Shift-Tab'
tab-1:
- 'Alt-1'
- ['Ctrl-A', '1']
@@ -43,3 +47,4 @@ hotkeys:
tab-10:
- 'Alt-0'
- ['Ctrl-A', '0']
pluginBlacklist: []

View File

@@ -3,6 +3,7 @@ appearance:
dockScreen: current
dockFill: 50
tabsLocation: top
cycleTabs: true
theme: Standard
frame: thin
css: '/* * { color: blue !important; } */'

View File

@@ -11,23 +11,27 @@ import { ElectronService } from './services/electron.service'
import { HostAppService } from './services/hostApp.service'
import { LogService } from './services/log.service'
import { HotkeysService, AppHotkeyProvider } from './services/hotkeys.service'
import { QuitterService } from './services/quitter.service'
import { DockingService } from './services/docking.service'
import { TabRecoveryService } from './services/tabRecovery.service'
import { ThemesService } from './services/themes.service'
import { TouchbarService } from './services/touchbar.service'
import { UpdaterService } from './services/updater.service'
import { AppRootComponent } from './components/appRoot.component'
import { CheckboxComponent } from './components/checkbox.component'
import { TabBodyComponent } from './components/tabBody.component'
import { SafeModeModalComponent } from './components/safeModeModal.component'
import { StartPageComponent } from './components/startPage.component'
import { TabHeaderComponent } from './components/tabHeader.component'
import { TitleBarComponent } from './components/titleBar.component'
import { WindowControlsComponent } from './components/windowControls.component'
import { RenameTabModalComponent } from './components/renameTabModal.component'
import { HotkeyProvider } from './api/hotkeyProvider'
import { ConfigProvider } from './api/configProvider'
import { Theme } from './api/theme'
import { StandardTheme } from './theme'
import { StandardTheme, StandardCompactTheme } from './theme'
import { CoreConfigProvider } from './config'
import 'perfect-scrollbar/dist/css/perfect-scrollbar.css'
@@ -42,9 +46,11 @@ const PROVIDERS = [
LogService,
TabRecoveryService,
ThemesService,
QuitterService,
TouchbarService,
UpdaterService,
{ provide: HotkeyProvider, useClass: AppHotkeyProvider, multi: true },
{ provide: Theme, useClass: StandardTheme, multi: true },
{ provide: Theme, useClass: StandardCompactTheme, multi: true },
{ provide: ConfigProvider, useClass: CoreConfigProvider, multi: true },
]
@@ -53,19 +59,29 @@ const PROVIDERS = [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
NgbModule,
NgbModule.forRoot(),
PerfectScrollbarModule.forRoot({
suppressScrollX: true,
}),
],
declarations: [
AppRootComponent,
CheckboxComponent,
StartPageComponent,
TabBodyComponent,
TabHeaderComponent,
TitleBarComponent,
WindowControlsComponent,
RenameTabModalComponent,
SafeModeModalComponent,
],
entryComponents: [
RenameTabModalComponent,
SafeModeModalComponent,
],
exports: [
CheckboxComponent
]
})
export default class AppModule {
static forRoot (): ModuleWithProviders {

View File

@@ -1,8 +1,9 @@
import { Subject } from 'rxjs'
import { Subject, AsyncSubject } from 'rxjs'
import { Injectable, ComponentFactoryResolver, Injector, Optional } from '@angular/core'
import { DefaultTabProvider } from '../api/defaultTabProvider'
import { BaseTabComponent } from '../components/baseTab.component'
import { Logger, LogService } from '../services/log.service'
import { Logger, LogService } from './log.service'
import { ConfigService } from './config.service'
export declare type TabComponentType = new (...args: any[]) => BaseTabComponent
@@ -10,13 +11,18 @@ export declare type TabComponentType = new (...args: any[]) => BaseTabComponent
export class AppService {
tabs: BaseTabComponent[] = []
activeTab: BaseTabComponent
activeTabChange$ = new Subject<BaseTabComponent>()
lastTabIndex = 0
logger: Logger
tabsChanged$ = new Subject()
tabsChanged$ = new Subject<void>()
tabOpened$ = new Subject<BaseTabComponent>()
tabClosed$ = new Subject<BaseTabComponent>()
ready$ = new AsyncSubject<void>()
constructor (
private componentFactoryResolver: ComponentFactoryResolver,
@Optional() private defaultTabProvider: DefaultTabProvider,
private config: ConfigService,
private injector: Injector,
log: LogService,
) {
@@ -32,6 +38,7 @@ export class AppService {
this.tabs.push(componentRef.instance)
this.selectTab(componentRef.instance)
this.tabsChanged$.next()
this.tabOpened$.next(componentRef.instance)
return componentRef.instance
}
@@ -56,6 +63,7 @@ export class AppService {
this.activeTab.blurred$.next()
}
this.activeTab = tab
this.activeTabChange$.next(tab)
if (this.activeTab) {
this.activeTab.focused$.next()
}
@@ -69,26 +77,46 @@ export class AppService {
}
nextTab () {
let tabIndex = this.tabs.indexOf(this.activeTab)
if (tabIndex < this.tabs.length - 1) {
this.selectTab(this.tabs[tabIndex + 1])
if (this.tabs.length > 1) {
let tabIndex = this.tabs.indexOf(this.activeTab)
if (tabIndex < this.tabs.length - 1) {
this.selectTab(this.tabs[tabIndex + 1])
} else if (this.config.store.appearance.cycleTabs) {
this.selectTab(this.tabs[0])
}
}
}
previousTab () {
let tabIndex = this.tabs.indexOf(this.activeTab)
if (tabIndex > 0) {
this.selectTab(this.tabs[tabIndex - 1])
if (this.tabs.length > 1) {
let tabIndex = this.tabs.indexOf(this.activeTab)
if (tabIndex > 0) {
this.selectTab(this.tabs[tabIndex - 1])
} else if (this.config.store.appearance.cycleTabs) {
this.selectTab(this.tabs[this.tabs.length - 1])
}
}
}
closeTab (tab: BaseTabComponent) {
async closeTab (tab: BaseTabComponent, checkCanClose?: boolean): Promise<void> {
if (!this.tabs.includes(tab)) {
return
}
if (checkCanClose && !await tab.canClose()) {
return
}
this.tabs = this.tabs.filter((x) => x !== tab)
tab.destroy()
let newIndex = Math.max(0, this.tabs.indexOf(tab) - 1)
this.tabs = this.tabs.filter((x) => x !== tab)
if (tab === this.activeTab) {
this.selectTab(this.tabs[newIndex])
}
this.tabsChanged$.next()
this.tabClosed$.next(tab)
}
emitReady () {
this.ready$.next(null)
this.ready$.complete()
}
}

View File

@@ -6,6 +6,7 @@ import { Injectable, Inject } from '@angular/core'
import { ConfigProvider } from '../api/configProvider'
import { ElectronService } from './electron.service'
import { HostAppService } from './hostApp.service'
import * as Reflect from 'core-js/es7/reflect'
const configMerge = (a, b) => require('deepmerge')(a, b, { arrayMerge: (_d, s) => s })
@@ -38,7 +39,7 @@ export class ConfigProxy {
{
enumerable: true,
configurable: false,
get: () => real[key] || defaults[key],
get: () => (real[key] !== undefined) ? real[key] : defaults[key],
set: (value) => {
real[key] = value
}
@@ -57,6 +58,7 @@ export class ConfigService {
private _store: any
private path: string
private defaults: any
private servicesCache: { [id: string]: Function[] } = null
constructor (
electron: ElectronService,
@@ -67,7 +69,7 @@ export class ConfigService {
this.defaults = configProviders.map(provider => {
let defaults = {}
if (provider.platformDefaults) {
defaults = configMerge(defaults, provider.platformDefaults[hostApp.platform])
defaults = configMerge(defaults, provider.platformDefaults[hostApp.platform] || {})
}
if (provider.defaults) {
defaults = configMerge(defaults, provider.defaults)
@@ -98,4 +100,28 @@ export class ConfigService {
requestRestart (): void {
this.restartRequested = true
}
enabledServices<T> (services: T[]): T[] {
if (!this.servicesCache) {
this.servicesCache = {}
let ngModule = Reflect.getMetadata('annotations', window['rootModule'])[0]
for (let imp of ngModule.imports) {
let module = imp['module'] || imp
let annotations = Reflect.getMetadata('annotations', module)
if (annotations) {
this.servicesCache[module['pluginName']] = annotations[0].providers.map(provider => {
return provider['useClass'] || provider
})
}
}
}
return services.filter(service => {
for (let pluginName in this.servicesCache) {
if (this.servicesCache[pluginName].includes(service.constructor)) {
return !this.store.pluginBlacklist.includes(pluginName)
}
}
return true
})
}
}

View File

@@ -14,7 +14,10 @@ export class DockingService {
private electron: ElectronService,
private config: ConfigService,
private hostApp: HostAppService,
) {}
) {
electron.screen.on('display-removed', () => this.repositionWindow())
electron.screen.on('display-metrics-changed', () => this.repositionWindow())
}
dock () {
let display = this.electron.screen.getAllDisplays()
@@ -26,26 +29,27 @@ export class DockingService {
let dockSide = this.config.store.appearance.dock
let newBounds: Bounds = { x: 0, y: 0, width: 0, height: 0 }
let fill = this.config.store.appearance.dockFill
let [minWidth, minHeight] = this.hostApp.getWindow().getMinimumSize()
if (dockSide === 'off') {
this.hostApp.setAlwaysOnTop(false)
return
}
if (dockSide === 'left' || dockSide === 'right') {
newBounds.width = Math.round(fill * display.bounds.width)
newBounds.width = Math.max(minWidth, Math.round(fill * display.bounds.width))
newBounds.height = display.bounds.height
}
if (dockSide === 'top' || dockSide === 'bottom') {
newBounds.width = display.bounds.width
newBounds.height = Math.round(fill * display.bounds.height)
newBounds.height = Math.max(minHeight, Math.round(fill * display.bounds.height))
}
if (dockSide === 'right') {
newBounds.x = display.bounds.x + display.bounds.width * (1.0 - fill)
newBounds.x = display.bounds.x + display.bounds.width - newBounds.width
} else {
newBounds.x = display.bounds.x
}
if (dockSide === 'bottom') {
newBounds.y = display.bounds.y + display.bounds.height * (1.0 - fill)
newBounds.y = display.bounds.y + display.bounds.height - newBounds.height
} else {
newBounds.y = display.bounds.y
}
@@ -71,4 +75,20 @@ export class DockingService {
}
})
}
getWindow () {
return this.electron.app.window
}
repositionWindow () {
let [x, y] = this.getWindow().getPosition()
for (let screen of this.electron.screen.getAllDisplays()) {
let bounds = screen.bounds
if (x >= bounds.x && x <= bounds.x + bounds.width && y >= bounds.y && y <= bounds.y + bounds.height) {
return
}
}
let screen = this.electron.screen.getPrimaryDisplay()
this.getWindow().setPosition(screen.bounds.x, screen.bounds.y)
}
}

View File

@@ -1,4 +1,5 @@
import { Injectable } from '@angular/core'
import { TouchBar } from 'electron'
@Injectable()
export class ElectronService {
@@ -9,22 +10,38 @@ export class ElectronService {
clipboard: any
globalShortcut: any
screen: any
remote: any
TouchBar: typeof TouchBar
private electron: any
private remoteElectron: any
constructor () {
this.electron = require('electron')
this.remoteElectron = this.remoteRequire('electron')
this.app = this.electron.remote.app
this.screen = this.electron.remote.screen
this.dialog = this.electron.remote.dialog
this.remote = this.electron.remote
this.app = this.remote.app
this.screen = this.remote.screen
this.dialog = this.remote.dialog
this.shell = this.electron.shell
this.clipboard = this.electron.clipboard
this.ipcRenderer = this.electron.ipcRenderer
this.globalShortcut = this.electron.remote.globalShortcut
this.globalShortcut = this.remote.globalShortcut
this.TouchBar = this.remote.TouchBar
}
remoteRequire (name: string): any {
return this.electron.remote.require(name)
return this.remote.require(name)
}
remoteRequirePluginModule (plugin: string, module: string, globals: any): any {
return this.remoteRequire(this.remoteResolvePluginModule(plugin, module, globals))
}
remoteResolvePluginModule (plugin: string, module: string, globals: any): any {
return globals.require.resolve(`${plugin}/node_modules/${module}`)
}
loseFocus () {
if (process.platform === 'darwin') {
this.remote.Menu.sendActionToFirstResponder('hide:')
}
}
}

View File

@@ -1,3 +1,4 @@
import { Subject } from 'rxjs'
import { Injectable, NgZone, EventEmitter } from '@angular/core'
import { ElectronService } from '../services/electron.service'
import { Logger, LogService } from '../services/log.service'
@@ -17,11 +18,11 @@ export interface Bounds {
export class HostAppService {
platform: Platform
nodePlatform: string
quitRequested = new EventEmitter<any>()
preferencesMenu$ = new Subject<void>()
ready = new EventEmitter<any>()
shown = new EventEmitter<any>()
secondInstance = new EventEmitter<any>()
secondInstance$ = new Subject<{ argv: string[], cwd: string }>()
isFullScreen = false
private logger: Logger
constructor (
@@ -37,18 +38,26 @@ export class HostAppService {
linux: Platform.Linux
}[this.nodePlatform]
electron.ipcRenderer.on('host:quit-request', () => this.zone.run(() => this.quitRequested.emit()))
electron.ipcRenderer.on('host:preferences-menu', () => this.zone.run(() => this.preferencesMenu$.next()))
electron.ipcRenderer.on('uncaughtException', (err) => {
electron.ipcRenderer.on('uncaughtException', ($event, err) => {
this.logger.error('Unhandled exception:', err)
})
electron.ipcRenderer.on('host:window-enter-full-screen', () => this.zone.run(() => {
this.isFullScreen = true
}))
electron.ipcRenderer.on('host:window-leave-full-screen', () => this.zone.run(() => {
this.isFullScreen = false
}))
electron.ipcRenderer.on('host:window-shown', () => {
this.shown.emit()
this.zone.run(() => this.shown.emit())
})
electron.ipcRenderer.on('host:second-instance', () => {
this.secondInstance.emit()
electron.ipcRenderer.on('host:second-instance', ($event, argv: string[], cwd: string) => {
this.zone.run(() => this.secondInstance$.next({ argv, cwd }))
})
this.ready.subscribe(() => {
@@ -72,22 +81,19 @@ export class HostAppService {
return this.electron.app.getPath(type)
}
openDevTools () {
this.getWindow().webContents.openDevTools()
toggleFullscreen () {
let window = this.getWindow()
window.setFullScreen(!window.isFullScreen())
}
setCloseable (flag: boolean) {
this.electron.ipcRenderer.send('window-set-closeable', flag)
openDevTools () {
this.getWindow().webContents.openDevTools({ mode: 'undocked' })
}
focusWindow () {
this.electron.ipcRenderer.send('window-focus')
}
toggleWindow () {
this.electron.ipcRenderer.send('window-toggle-focus')
}
minimize () {
this.electron.ipcRenderer.send('window-minimize')
}

View File

@@ -42,7 +42,7 @@ export class HotkeysService {
}
})
})
this.hotkeyDescriptions = hotkeyProviders.map(x => x.hotkeys).reduce((a, b) => a.concat(b))
this.hotkeyDescriptions = this.config.enabledServices(hotkeyProviders).map(x => x.hotkeys).reduce((a, b) => a.concat(b))
this.config.changed$.subscribe(() => {
this.registerGlobalHotkey()
})
@@ -179,8 +179,8 @@ export class AppHotkeyProvider extends HotkeyProvider {
name: 'Toggle terminal window',
},
{
id: 'new-tab',
name: 'New tab',
id: 'toggle-fullscreen',
name: 'Toggle fullscreen mode',
},
{
id: 'close-tab',

View File

@@ -5,7 +5,7 @@ export const metaKeyName = {
}[process.platform]
export const altKeyName = {
darwin: 'Option',
darwin: '',
win32: 'Alt',
linux: 'Alt',
}[process.platform]
@@ -45,7 +45,9 @@ export function stringifyKeySequence (events: NativeKeyEvent[]): string[] {
// TODO make this optional?
continue
}
if (event.key.length === 1) {
if (event.key === ' ') {
itemKeys.push('Space')
} else if (event.key.length === 1) {
itemKeys.push(event.key.toUpperCase())
} else {
itemKeys.push(event.key)

View File

@@ -1,23 +1,67 @@
import { Injectable } from '@angular/core'
import { ElectronService } from './electron.service'
import * as winston from 'winston'
import * as fs from 'fs'
import * as path from 'path'
const initializeWinston = (electron: ElectronService) => {
const logDirectory = electron.app.getPath('userData')
if (!fs.existsSync(logDirectory)) {
fs.mkdirSync(logDirectory)
}
return new winston.Logger({
transports: [
new winston.transports.File({
level: 'debug',
filename: path.join(logDirectory, 'log.txt'),
handleExceptions: false,
json: false,
maxsize: 5242880,
maxFiles: 5,
colorize: false
}),
new winston.transports.Console({
level: 'info',
handleExceptions: false,
json: false,
colorize: true
})
],
exitOnError: false
})
}
export class Logger {
constructor (
private winstonLogger: any,
private name: string,
) {}
log (level: string, ...args: any[]) {
doLog (level: string, ...args: any[]) {
console[level](`%c[${this.name}]`, 'color: #aaa', ...args)
if (this.winstonLogger) {
this.winstonLogger[level](...args)
}
}
debug (...args: any[]) { this.log('debug', ...args) }
info (...args: any[]) { this.log('info', ...args) }
warn (...args: any[]) { this.log('warn', ...args) }
error (...args: any[]) { this.log('error', ...args) }
debug (...args: any[]) { this.doLog('debug', ...args) }
info (...args: any[]) { this.doLog('info', ...args) }
warn (...args: any[]) { this.doLog('warn', ...args) }
error (...args: any[]) { this.doLog('error', ...args) }
log (...args: any[]) { this.doLog('log', ...args) }
}
@Injectable()
export class LogService {
private log: any
constructor (electron: ElectronService) {
this.log = initializeWinston(electron)
}
create (name: string): Logger {
return new Logger(name)
return new Logger(this.log, name)
}
}

View File

@@ -1,18 +0,0 @@
import { Injectable } from '@angular/core'
import { HostAppService } from '../services/hostApp.service'
@Injectable()
export class QuitterService {
constructor (
private hostApp: HostAppService,
) {
hostApp.quitRequested.subscribe(() => {
this.quit()
})
}
quit () {
this.hostApp.setCloseable(true)
this.hostApp.quit()
}
}

Some files were not shown because too many files have changed in this diff Show More