Compare commits

..

246 Commits

Author SHA1 Message Date
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
Eugene Pankov
9badd88c80 force GNU screen dependency on Linux (fixes #1) 2017-06-30 10:44:43 +02:00
Eugene Pankov
7a24c9aa3a don't auto enable devtools 2017-06-29 14:26:39 +02:00
Eugene Pankov
8a7e7c4eb5 fixes 2017-06-28 16:55:09 +02:00
Eugene Pankov
d0c10278fb build fixes 2017-06-27 23:35:19 +02:00
Eugene Pankov
2ae004db53 alpha 2017-06-27 23:19:18 +02:00
Eugene Pankov
7b34b668c1 readme 2017-06-27 23:13:05 +02:00
Eugene Pankov
7c09fc4a38 docs 2017-06-27 23:12:23 +02:00
Eugene Pankov
89ff9d0ea2 . 2017-06-26 22:01:08 +02:00
Eugene Pankov
b4e503b26c . 2017-06-26 21:54:36 +02:00
Eugene Pankov
edc911605b . 2017-06-24 20:15:09 +02:00
Eugene Pankov
30115d0996 . 2017-06-24 20:05:49 +02:00
Eugene Pankov
5204d944c6 . 2017-06-24 19:34:25 +02:00
Eugene Pankov
39335bc23a . 2017-06-24 19:24:49 +02:00
Eugene Pankov
cad417694d . 2017-06-24 19:13:44 +02:00
Eugene Pankov
fe75b77420 . 2017-06-24 19:01:56 +02:00
Eugene Pankov
5372ccf59c . 2017-06-24 18:52:19 +02:00
Eugene Pankov
4dad9b1661 . 2017-06-24 18:43:31 +02:00
Eugene Pankov
19e4620676 . 2017-06-24 18:28:13 +02:00
180 changed files with 15097 additions and 1219 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

@@ -1,7 +1,5 @@
matrix:
include:
- os: linux
env: BUILD_FOR=windows
- os: linux
env: BUILD_FOR=linux
- os: osx
@@ -16,27 +14,25 @@ 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
dist: trusty
sudo: false
addons:
apt:
packages:
- rpm
deploy:
provider: releases
api_key: $GITHUB_TOKEN
file_glob: true
file: 'dist/terminus*'
skip_cleanup: true
on:
tags: true
- wine
- mono-runtime
- 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,2 +1,52 @@
[![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)
<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)
----
![](https://github.com/Eugeny/terminus/raw/master/docs/linux.png)
**Terminus** is a web technology based terminal heavily inspired by Hyper. It is, however, designed for people who need to get things done.
* Runs on Windows, macOS and Linux
* Theming and color schemes
* Configurable hotkey schemes
* **GNU Screen** style hotkeys available by default
* Full Unicode support including double-width characters
* 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, 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
---
# Contributing
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 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

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,13 +1,15 @@
if (process.platform == 'win32' && require('electron-squirrel-startup')) process.exit(0)
const electron = require('electron')
require('electron-debug')({enabled: true, showDevTools: (process.argv.indexOf('--debug') != -1) ? 'undocked' : false})
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) {
@@ -20,7 +22,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'})
@@ -29,28 +30,28 @@ 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('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()
})
@@ -84,48 +85,118 @@ 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: 'close'},
{role: 'minimize'},
{role: 'zoom'},
{type: 'separator'},
{role: 'front'}
]
},
{
role: 'help',
submenu: [
{
label: 'Website',
click () { electron.shell.openExternal('https://eugeny.github.io/terminus') }
}
]
}]
@@ -146,8 +217,7 @@ start = () => {
let options = {
width: 800,
height: 400,
//icon: `${app.getAppPath()}/assets/img/icon.png`,
height: 600,
title: 'Terminus',
minWidth: 400,
minHeight: 300,

View File

@@ -12,23 +12,27 @@
"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",
"electron-is-dev": "0.1.2",
"electron-squirrel-startup": "^1.0.0",
"fs-promise": "^2.0.2",
"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,4 +1,4 @@
import 'zone.js/dist/zone.js'
import 'zone.js'
import 'core-js/es7/reflect'
import 'core-js/core/delay'
import 'rxjs'
@@ -6,11 +6,15 @@ import 'rxjs'
// 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 +22,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

@@ -1,4 +1,4 @@
import * as fs from 'fs-promise'
import * as fs from 'mz/fs'
import * as path from 'path'
const nodeModule = require('module')
const nodeRequire = (global as any).require
@@ -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 = await fs.readJson(infoPath)
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;
}

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',
'fs-promise': 'commonjs fs-promise',
'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

@@ -9,8 +9,6 @@ environment:
cache:
- '%USERPROFILE%\.electron'
skip_tags: true
version: "{build}"
install:
@@ -25,4 +23,4 @@ build_script:
- node scripts/build-windows.js
artifacts:
- path: 'dist\*.exe'
- path: 'dist\win\*.exe'

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>

View File

@@ -1,22 +1,53 @@
<!DOCTYPE html><html><head><link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"><link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"><link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400" rel="stylesheet"><style>body {
<!DOCTYPE html><html><head><link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400" rel="stylesheet"><link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"><link href="https://cdn.jsdelivr.net/g/bootstrap@4.0.0-alpha.6(css/bootstrap.min.css)" rel="stylesheet"><script src="https://cdn.jsdelivr.net/g/jquery@3.2.1,tether@1.4.0,bootstrap@4.0.0-alpha.6,modernizr@3.3.1,detectizr@2.2.0"></script><title>Terminus</title><style>body {
font-family: 'Source Sans Pro', sans-serif;
background: #111;
color: #ccc;
min-height: 100vh;
background-image: radial-gradient(#111, #000);
}
h1 {
font-size: 64px;
}
h1, h3, h5 {
h1, h2, h3, h5 {
font-weight: 300;
color: white;
}
.btn i + span {
.btn i + span,
.nav-link i + span {
margin-left: 10px;
}
.btn-outline-primary {
color: #b6e7ff !important;
}</style></head><body><div class="container mt-5 mb-3"><div class="text-center"><h1>Terminus</h1><h5>A terminal for a more modern age</h5><div class="btn-group mt-3 mb-3"><a class="btn btn-outline-primary"><i class="fa fa-windows"></i><span>Windows</span></a><a class="btn btn-outline-primary"><i class="fa fa-apple"></i><span>macOS</span></a><a class="btn btn-outline-primary"><i class="fa fa-archive"></i><span>DEB</span></a><a class="btn btn-outline-primary"><i class="fa fa-archive"></i><span>RPM</span></a><a class="btn btn-outline-primary"><i class="fa fa-archive"></i><span>TGZ</span></a></div></div><div class="row mt-5"><div class="col-6"><h3>Proper Windows experience</h3><p> <b>Clink </b>provides tab completion, readline-style editing and persistent command history on Windows.</p><p>Also supported:<ul> <li>Classic CMD</li><li>PowerShell </li><li>Bash on Windows </li></ul></p></div><div class="col-6"><h3>User experience</h3><ul><li>Spawn and hide with a global hotkey</li><li>Fully customizable hotkey schema</li><li>Restores tabs </li><li>Drag in a file to paste the path</li><li>Click paths and URLs to open in browser/file manager</li><li>Keeps the current directory in new tabs</li></ul></div></div><div class="row mt-5"><div class="col-6"><h3>Customizable</h3><p>Multiple app themes and a myriad of community color schemes for the terminal. Color scheme editor included.</p></div><div class="col-6"><h3>Infinitely extensible</h3><p>Install plugins from the NPM repository, or create your own with Typescript and Angular framework.</p></div></div></div></body></html>
}
.nav-link {
font-size: 22px;
}
video, img {
max-width: 100%;
box-shadow: 0 0 50px black;
}
</style><script defer>setTimeout(function () {
/*
if (Detectizr.os.name == 'windows') {
$('[href="#windows"]').tab('show')
}
if (Detectizr.os.name == 'mac os') {
$('[href="#macos"]').tab('show')
}
if (Detectizr.os.name == 'linux') {
$('[href="#linux"]').tab('show')
}
*/
})</script></head><body><div class="container mt-5 mb-5"><div class="text-center"><h1>Terminus</h1><h5>A terminal for a more modern age</h5><h2 class="text-muted">alpha</h2></div><div class="d-flex flex-row mt-5 mb-5"><ul class="nav nav-pills flex-column mr-5" style="min-width: 200px;"><li class="nav-item"><a class="nav-link active" data-toggle="tab" href="#windows" role="tab"><i class="fa fa-windows"></i><span>Windows</span></a></li><li class="nav-item"><a class="nav-link" data-toggle="tab" href="#macos" role="tab"><i class="fa fa-apple"></i><span>macOS</span></a></li><li class="nav-item"><a class="nav-link" data-toggle="tab" href="#linux" role="tab"><i class="fa fa-linux"></i><span>Linux</span></a></li></ul><div class="tab-content"><div class="tab-pane active" id="windows" role="tabpanel"><div class="row"><div class="col-6"><video src="videos/windows.mp4" autoplay loop></video></div><div class="col-6"><h3>A proper Windows experience</h3><p> <b>Clink </b>provides tab completion, readline-style editing and persistent command history on Windows.</p><p>Also supported:<ul> <li>Classic CMD</li><li>PowerShell </li><li>Bash on Windows </li></ul></p></div></div></div><div class="tab-pane" id="macos" role="tabpanel"><div class="row"><div class="col-6"><!--video(src='videos/windows.mp4', autoplay, loop)--></div><div class="col-6"><h3>Well...</h3><p>Not much to say here, it just works.</p></div></div></div><div class="tab-pane" id="linux" role="tabpanel"><div class="row"><div class="col-6"><img src="linux.png"></div><div class="col-6"><p><ul> <li>Spawn with a global hotkey</li><li>Tabs persist after restart</li><li>Auto-dock to any side of any screen</li><li>Full Unicode and double-width character support</li></ul></p></div></div></div></div></div><div class="text-center"><div class="mt-3 mb-3"><h2></h2><div><div class="btn-group mt-3 mb-1"><a class="btn btn-lg btn-outline-success" href="https://github.com/Eugeny/terminus/releases/latest" target="_blank"><i class="fa fa-download"></i><span>Downloads</span></a><a class="btn btn-lg btn-outline-secondary" href="https://github.com/Eugeny/terminus" target="_blank"><i class="fa fa-github"></i><span>GitHub</span></a></div></div><small class="text-muted">EXE, DMG, DEB, RPM, TGZ</small></div></div><div class="row mt-5"><div class="col-6"><h3>User experience</h3><ul><li>Spawn and hide with a global hotkey</li><li>Fully customizable hotkey schema</li><li>Restores tabs </li><li>Drag in a file to paste the path</li><li>Click paths and URLs to open in browser/file manager</li><li>Keeps the current directory in new tabs</li></ul></div><div class="col-6"><div class="mb-5"><h3>Customizable</h3><p>Multiple app themes and a myriad of community color schemes for the terminal. Color scheme editor included.</p></div><div> <h3>Infinitely extensible</h3><p>Install plugins from the NPM repository, or create your own with Typescript and Angular framework.</p></div></div></div></div><script>(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-3278102-18', 'auto');
ga('send', 'pageview');</script></body></html>

View File

@@ -1,71 +1,136 @@
doctype html
html
head
link(href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css", rel="stylesheet")
link(href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css", rel="stylesheet")
link(href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400", rel="stylesheet")
link(href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css", rel="stylesheet")
link(href="https://cdn.jsdelivr.net/g/bootstrap@4.0.0-alpha.6(css/bootstrap.min.css)", rel="stylesheet")
script(src="https://cdn.jsdelivr.net/g/jquery@3.2.1,tether@1.4.0,bootstrap@4.0.0-alpha.6,modernizr@3.3.1,detectizr@2.2.0")
title Terminus
style.
body {
font-family: 'Source Sans Pro', sans-serif;
background: #111;
color: #ccc;
min-height: 100vh;
background-image: radial-gradient(#111, #000);
}
h1 {
font-size: 64px;
}
h1, h3, h5 {
h1, h2, h3, h5 {
font-weight: 300;
color: white;
}
.btn i + span {
.btn i + span,
.nav-link i + span {
margin-left: 10px;
}
.btn-outline-primary {
color: #b6e7ff !important;
}
.nav-link {
font-size: 22px;
}
video, img {
max-width: 100%;
box-shadow: 0 0 50px black;
}
script(defer).
setTimeout(function () {
/*
if (Detectizr.os.name == 'windows') {
$('[href="#windows"]').tab('show')
}
if (Detectizr.os.name == 'mac os') {
$('[href="#macos"]').tab('show')
}
if (Detectizr.os.name == 'linux') {
$('[href="#linux"]').tab('show')
}
*/
})
body
.container.mt-5.mb-3
.container.mt-5.mb-5
.text-center
h1 Terminus
h5 A terminal for a more modern age
h2.text-muted alpha
.d-flex.flex-row.mt-5.mb-5
ul.nav.nav-pills.flex-column.mr-5(style='min-width: 200px')
li.nav-item
a.nav-link.active(data-toggle='tab', href='#windows', role='tab')
i.fa.fa-windows
span Windows
li.nav-item
a.nav-link(data-toggle='tab', href='#macos', role='tab')
i.fa.fa-apple
span macOS
li.nav-item
a.nav-link(data-toggle='tab', href='#linux', role='tab')
i.fa.fa-linux
span Linux
.tab-content
#windows.tab-pane.active(role='tabpanel')
.row
.col-6
video(src='videos/windows.mp4', autoplay, loop)
.col-6
h3 A proper Windows experience
p
b Clink
| provides tab completion, readline-style editing and persistent command history on Windows.
p Also supported:
ul
li Classic CMD
li PowerShell
li Bash on Windows
#macos.tab-pane(role='tabpanel')
.row
.col-6
//video(src='videos/windows.mp4', autoplay, loop)
.col-6
h3 Well...
p Not much to say here, it just works.
#linux.tab-pane(role='tabpanel')
.row
.col-6
img(src='linux.png')
.col-6
p
ul
li Spawn with a global hotkey
li Tabs persist after restart
li Auto-dock to any side of any screen
li Full Unicode and double-width character support
.btn-group.mt-3.mb-3
a.btn.btn-outline-primary
i.fa.fa-windows
span Windows
a.btn.btn-outline-primary
i.fa.fa-apple
span macOS
.text-center
.mt-3.mb-3
h2
a.btn.btn-outline-primary
i.fa.fa-archive
span DEB
div
.btn-group.mt-3.mb-1
a.btn.btn-lg.btn-outline-success(href='https://github.com/Eugeny/terminus/releases/latest', target='_blank')
i.fa.fa-download
span Downloads
a.btn.btn-lg.btn-outline-secondary(href='https://github.com/Eugeny/terminus', target='_blank')
i.fa.fa-github
span GitHub
small.text-muted EXE, DMG, DEB, RPM, TGZ
a.btn.btn-outline-primary
i.fa.fa-archive
span RPM
a.btn.btn-outline-primary
i.fa.fa-archive
span TGZ
.row.mt-5
.col-6
h3 Proper Windows experience
p
b Clink
| provides tab completion, readline-style editing and persistent command history on Windows.
p Also supported:
ul
li Classic CMD
li PowerShell
li Bash on Windows
.col-6
h3 User experience
ul
@@ -76,13 +141,20 @@ html
li Click paths and URLs to open in browser/file manager
li Keeps the current directory in new tabs
.row.mt-5
.col-6
h3 Customizable
p Multiple app themes and a myriad of community color schemes for the terminal. Color scheme editor included.
.col-6
h3 Infinitely extensible
p Install plugins from the NPM repository, or create your own with Typescript and Angular framework.
.mb-5
h3 Customizable
p Multiple app themes and a myriad of community color schemes for the terminal. Color scheme editor included.
div
h3 Infinitely extensible
p Install plugins from the NPM repository, or create your own with Typescript and Angular framework.
script.
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-3278102-18', 'auto');
ga('send', 'pageview');

BIN
docs/linux.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

BIN
docs/videos/windows.mp4 Normal file

Binary file not shown.

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.6.16",
"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-sass": "4.5.3",
"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,27 +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",
"python-gnomekeyring",
"tmux"
],
"artifactName": "terminus-${version}-${os}-${arch}.deb"
},
"rpm": {
"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,19 @@ 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('..')
})

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

@@ -1,16 +1,20 @@
const path = require('path')
const fs = require('fs')
const childProcess = require('child_process')
const appInfo = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../app/package.json')))
const pkgInfo = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../package.json')))
exports.version = childProcess.execSync('git describe --tags', {encoding:'utf-8'})
exports.version = exports.version.substring(1, exports.version.length - 1)
exports.builtinPlugins = [
'terminus-core',
'terminus-settings',
'terminus-terminal',
'terminus-community-color-schemes',
'terminus-plugin-manager',
'terminus-ssh',
]
exports.nativeModules = ['node-pty', 'font-manager']
exports.version = appInfo.version
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,12 +1,13 @@
title-bar(
*ngIf='config.store.appearance.frame == "full" && config.store.appearance.dock == "off"',
*ngIf='!hostApp.getWindow().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.getWindow().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,18 @@
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 { SafeModeModalComponent } from './safeModeModal.component'
import { AppService, IToolbarButton, ToolbarButtonProvider } from '../api'
@Component({
@@ -28,9 +30,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 +54,21 @@ 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,
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 +85,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 +97,9 @@ export class AppRootComponent {
this.app.previousTab()
}
}
if (hotkey === 'toggle-fullscreen') {
this.hostApp.toggleFullscreen()
}
})
this.docking.dock()
@@ -93,12 +107,20 @@ 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
})
}
onGlobalHotkey () {
@@ -131,16 +153,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 +166,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,11 @@
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
customTitle: string
scrollable: boolean
hasActivity = false
focused$ = new Subject<void>()
@@ -30,9 +31,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,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,29 +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
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;
@@ -24,9 +23,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 +35,7 @@ $tabs-height: 36px;
white-space: nowrap;
text-overflow: ellipsis;
min-width: 0;
align-self: center;
}
button {
@@ -49,11 +49,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,75 @@ 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.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,25 @@ 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 { UpdaterService } from './services/updater.service'
import { AppRootComponent } from './components/appRoot.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 +44,10 @@ const PROVIDERS = [
LogService,
TabRecoveryService,
ThemesService,
QuitterService,
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,7 +56,7 @@ const PROVIDERS = [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
NgbModule,
NgbModule.forRoot(),
PerfectScrollbarModule.forRoot({
suppressScrollX: true,
}),
@@ -65,7 +68,13 @@ const PROVIDERS = [
TabHeaderComponent,
TitleBarComponent,
WindowControlsComponent,
RenameTabModalComponent,
SafeModeModalComponent,
],
entryComponents: [
RenameTabModalComponent,
SafeModeModalComponent,
]
})
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 { ConfigService } from '../services/config.service'
export declare type TabComponentType = new (...args: any[]) => BaseTabComponent
@@ -12,11 +13,13 @@ export class AppService {
activeTab: BaseTabComponent
lastTabIndex = 0
logger: Logger
tabsChanged$ = new Subject()
tabsChanged$ = new Subject<void>()
ready$ = new AsyncSubject<void>()
constructor (
private componentFactoryResolver: ComponentFactoryResolver,
@Optional() private defaultTabProvider: DefaultTabProvider,
private config: ConfigService,
private injector: Injector,
log: LogService,
) {
@@ -69,26 +72,45 @@ 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()
}
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()
@@ -40,12 +43,12 @@ export class DockingService {
newBounds.height = 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 +74,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

@@ -9,22 +9,26 @@ export class ElectronService {
clipboard: any
globalShortcut: any
screen: any
remote: any
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
}
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(globals.require.resolve(`${plugin}/node_modules/${module}`))
}
}

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,10 +18,10 @@ 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 }>()
private logger: Logger
@@ -37,18 +38,18 @@ 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-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,12 +73,13 @@ 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 () {

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()
}
}

View File

@@ -1,8 +1,9 @@
import { Injectable, Inject } from '@angular/core'
import { TabRecoveryProvider } from '../api/tabRecovery'
import { TabRecoveryProvider, RecoveredTab } from '../api/tabRecovery'
import { BaseTabComponent } from '../components/baseTab.component'
import { Logger, LogService } from '../services/log.service'
import { AppService } from '../services/app.service'
import { ConfigService } from '../services/config.service'
@Injectable()
export class TabRecoveryService {
@@ -10,7 +11,8 @@ export class TabRecoveryService {
constructor (
@Inject(TabRecoveryProvider) private tabRecoveryProviders: TabRecoveryProvider[],
app: AppService,
private app: AppService,
private config: ConfigService,
log: LogService
) {
this.logger = log.create('tabRecovery')
@@ -29,15 +31,22 @@ export class TabRecoveryService {
async recoverTabs (): Promise<void> {
if (window.localStorage.tabsRecovery) {
let tabs: RecoveredTab[] = []
for (let token of JSON.parse(window.localStorage.tabsRecovery)) {
for (let provider of this.tabRecoveryProviders) {
for (let provider of this.config.enabledServices(this.tabRecoveryProviders)) {
try {
await provider.recover(token)
let tab = await provider.recover(token)
if (tab) {
tabs.push(tab)
}
} catch (error) {
this.logger.warn('Tab recovery crashed:', token, provider, error)
}
}
}
tabs.forEach(tab => {
this.app.openNewTab(tab.type, tab.options)
})
}
}

View File

@@ -13,12 +13,11 @@ export class ThemesService {
this.applyCurrentTheme()
config.changed$.subscribe(() => {
this.applyCurrentTheme()
document.querySelector('style#custom-css').innerHTML = config.store.appearance.css
})
}
findTheme (name: string): Theme {
return this.themes.find(x => x.name === name)
return this.config.enabledServices(this.themes).find(x => x.name === name)
}
findCurrentTheme (): Theme {
@@ -32,6 +31,7 @@ export class ThemesService {
document.querySelector('head').appendChild(this.styleElement)
}
this.styleElement.textContent = theme.css
document.querySelector('style#custom-css').innerHTML = this.config.store.appearance.css
}
applyCurrentTheme (): void {

View File

@@ -0,0 +1,36 @@
import axios from 'axios'
import { Injectable } from '@angular/core'
import { Logger, LogService } from './log.service'
import { ElectronService } from './electron.service'
const UPDATES_URL = 'https://api.github.com/repos/eugeny/terminus/releases/latest'
export interface Update {
version: string
url: string
}
@Injectable()
export class UpdaterService {
private logger: Logger
constructor (
log: LogService,
private electron: ElectronService,
) {
this.logger = log.create('updater')
}
async check (): Promise<Update> {
this.logger.debug('Checking for updates')
let response = await axios.get(UPDATES_URL)
let data = response.data
let version = data.tag_name.substring(1)
if (this.electron.app.getVersion() !== version) {
this.logger.info('Update available:', version)
return { version, url: data.html_url }
}
this.logger.info('No updates')
return null
}
}

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