This commit is contained in:
Pig Fang 2020-02-17 18:27:56 +08:00
parent 39e135e644
commit f721ac269c
9 changed files with 122 additions and 3 deletions

View File

@ -25,7 +25,8 @@ class UserMenuComposer
$user = auth()->user();
$avatarUrl = route('avatar.user', ['uid' => $user->uid, 'size' => 25]);
$avatar = $this->filter->apply('user_avatar', $avatarUrl, [$user]);
$cli = $this->request->is('admin', 'admin/*');
$view->with(compact('user', 'avatar'));
$view->with(compact('user', 'avatar', 'cli'));
}
}

View File

@ -21,6 +21,7 @@
"@hot-loader/react-dom": "^16.11.0",
"@tweenjs/tween.js": "^18.4.2",
"admin-lte": "^3.0.1",
"blessing-skin-shell": "^0.1.0",
"echarts": "^4.6.0",
"jquery": "^3.4.1",
"lodash.debounce": "^4.0.8",
@ -35,7 +36,9 @@
"vue-good-table": "^2.18.1",
"vue-recaptcha": "^1.2.0",
"vue-upload-component": "^2.8.20",
"vuejs-paginate": "^2.1.0"
"vuejs-paginate": "^2.1.0",
"xterm": "^4.4.0",
"xterm-addon-fit": "^0.3.0"
},
"devDependencies": {
"@babel/core": "^7.8.0",

View File

@ -24,3 +24,5 @@
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
AddType application/wasm .wasm

View File

@ -10,6 +10,14 @@ Vue.config.productionTip = false
loadModules()
function loadModules() {
if (blessing.route.startsWith('admin')) {
const entry = document.querySelector<HTMLAnchorElement>('#launch-cli')
entry?.addEventListener('click', async () => {
const { launch } = await import('./scripts/cli')
launch()
})
}
const route = routes.find(
// eslint-disable-next-line no-shadow
route => new RegExp(`^${route.path}$`, 'i').test(blessing.route),

View File

@ -0,0 +1,60 @@
import { Terminal } from 'xterm'
import { FitAddon } from 'xterm-addon-fit'
import { Shell } from 'blessing-skin-shell'
import 'xterm/css/xterm.css'
import styles from '@/styles/terminal.scss'
let launched = false
export function launch() {
if (launched) {
return
}
const card = document.createElement('div')
card.className = `card ${styles.terminal}`
const header = document.createElement('div')
header.className = 'card-header'
const headerStuff = document.createElement('div')
headerStuff.className = 'd-flex justify-content-between'
const title = document.createElement('h4')
title.className = 'card-title mt-1'
title.textContent = 'Blessing Skin Shell'
headerStuff.appendChild(title)
const btnClose = document.createElement('button')
btnClose.innerHTML = '&times;'
btnClose.className = 'btn btn-default'
headerStuff.appendChild(btnClose)
header.appendChild(headerStuff)
card.appendChild(header)
const body = document.createElement('div')
body.className = 'card-body p-2'
body.style.backgroundColor = '#000'
const container = document.createElement('div')
body.appendChild(container)
card.appendChild(body)
document.body.appendChild(card)
const terminal = new Terminal()
const fitAddon = new FitAddon()
terminal.loadAddon(fitAddon)
terminal.setOption('fontFamily', 'Monaco, Consolas, "Roboto Mono", "Noto Sans", "Droid Sans Mono"')
terminal.open(container)
fitAddon.fit()
const shell = new Shell(terminal)
const unbind = terminal.onData(e => shell.input(e))
launched = true
const handleClose = () => {
unbind.dispose()
shell.free()
fitAddon.dispose()
terminal.dispose()
btnClose.removeEventListener('click', handleClose)
card.remove()
launched = false
}
btnClose.addEventListener('click', handleClose)
}

View File

@ -15,7 +15,7 @@ $breakpoints: (
}
@mixin between($down, $up) {
@media (max-width: map-get($breakpoints, $down)) and (min-width: map-get($breakpoints, $up)) {
@media (min-width: map-get($breakpoints, $down)) and (max-width: map-get($breakpoints, $up)) {
@content;
}
}

View File

@ -0,0 +1,25 @@
@use '../styles/breakpoints';
.terminal {
z-index: 1060;
position: fixed;
bottom: 0;
@include breakpoints.greater-than('xl') {
left: 25vw;
width: 50vw;
height: 50vh;
}
@include breakpoints.between('md', 'xl') {
left: 5vw;
width: 90vw;
height: 40vh;
}
@include breakpoints.less-than('md') {
left: 1vw;
width: 98vw;
height: 35vh;
}
}

View File

@ -24,6 +24,11 @@
<a class="dropdown-item" href="{{ url('admin/reports') }}">
{{ trans('general.report-manage') }}
</a>
{% if cli %}
<a class="dropdown-item" href="#" id="launch-cli">
Web CLI
</a>
{% endif %}
<div class="dropdown-divider"></div>
{% endif %}
<a class="dropdown-item" href="#" id="logout-button">

View File

@ -2265,6 +2265,11 @@ binary-extensions@^2.0.0:
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c"
integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==
blessing-skin-shell@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/blessing-skin-shell/-/blessing-skin-shell-0.1.0.tgz#6251b154d2e5b225d65f1b6e8c7489bb2eb67303"
integrity sha512-6c7RwPqLS1mXsrLd6QU7xUjr/gfmDgAY5L+CqOMWwwjLfjuohw6SK6cnGyfWxeK8KoDj5zX3QyoYuCKapXlkUg==
bluebird@^3.1.1, bluebird@^3.5.5:
version "3.5.5"
resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz#a8d0afd73251effbbd5fe384a77d73003c17a71f"
@ -10702,6 +10707,16 @@ xtend@^4.0.1:
resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68=
xterm-addon-fit@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/xterm-addon-fit/-/xterm-addon-fit-0.3.0.tgz#341710741027de9d648a9f84415a01ddfdbbe715"
integrity sha512-kvkiqHVrnMXgyCH9Xn0BOBJ7XaWC/4BgpSWQy3SueqximgW630t/QOankgqkvk11iTOCwWdAY9DTyQBXUMN3lw==
xterm@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.4.0.tgz#5915d3c4c8800fadbcf555a0a603c672ab9df589"
integrity sha512-JGIpigWM3EBWvnS3rtBuefkiToIILSK1HYMXy4BCsUpO+O4UeeV+/U1AdAXgCB6qJrnPNb7yLgBsVCQUNMteig==
"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"