parent
7e93319873
commit
5e9cc09fcb
11 changed files with 271 additions and 5 deletions
|
@ -45,7 +45,7 @@ gulp.task('build:copy:locales', cb => {
|
|||
});
|
||||
|
||||
gulp.task('build:client:script', () => {
|
||||
return gulp.src(['./src/server/web/boot.js'])
|
||||
return gulp.src(['./src/server/web/boot.js', './src/server/web/bios.js', './src/server/web/cli.js'])
|
||||
.pipe(replace('VERSION', JSON.stringify(meta.version)))
|
||||
.pipe(replace('LANGS', JSON.stringify(Object.keys(locales))))
|
||||
.pipe(terser({
|
||||
|
@ -55,7 +55,7 @@ gulp.task('build:client:script', () => {
|
|||
});
|
||||
|
||||
gulp.task('build:client:style', () => {
|
||||
return gulp.src(['./src/server/web/style.css'])
|
||||
return gulp.src(['./src/server/web/style.css', './src/server/web/bios.css', './src/server/web/cli.css'])
|
||||
.pipe(cssnano())
|
||||
.pipe(gulp.dest('./built/server/web/'));
|
||||
});
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<Fa :icon="faExternalLinkAlt" class="icon"/>
|
||||
</span>
|
||||
</a>
|
||||
<MkA class="main _button _formPanel _formClickable" :class="{ active }" :to="to" v-else>
|
||||
<MkA class="main _button _formPanel _formClickable" :class="{ active }" :to="to" :behavior="behavior" v-else>
|
||||
<span class="icon"><slot name="icon"></slot></span>
|
||||
<span class="text"><slot></slot></span>
|
||||
<span class="right">
|
||||
|
@ -38,6 +38,10 @@ export default defineComponent({
|
|||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
behavior: {
|
||||
type: String,
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
|
@ -98,6 +98,11 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
nav() {
|
||||
if (this.behavior === 'browser') {
|
||||
location.href = this.to;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.to.startsWith('/my/messaging')) {
|
||||
if (ColdDeviceStorage.get('chatOpenBehavior') === 'window') return this.window();
|
||||
if (ColdDeviceStorage.get('chatOpenBehavior') === 'popout') return this.popout();
|
||||
|
|
|
@ -23,13 +23,16 @@
|
|||
|
||||
<FormLink to="/settings/registry"><template #icon><Fa :icon="faCogs"/></template>{{ $ts.registry }}</FormLink>
|
||||
|
||||
<FormLink to="/bios" behavior="browser"><template #icon><Fa :icon="faDoorOpen"/></template>BIOS</FormLink>
|
||||
<FormLink to="/cli" behavior="browser"><template #icon><Fa :icon="faDoorOpen"/></template>CLI</FormLink>
|
||||
|
||||
<FormButton @click="closeAccount" danger>{{ $ts.closeAccount }}</FormButton>
|
||||
</FormBase>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineAsyncComponent, defineComponent } from 'vue';
|
||||
import { faEllipsisH, faCogs } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faEllipsisH, faCogs, faDoorOpen } from '@fortawesome/free-solid-svg-icons';
|
||||
import FormSwitch from '@/components/form/switch.vue';
|
||||
import FormSelect from '@/components/form/select.vue';
|
||||
import FormLink from '@/components/form/link.vue';
|
||||
|
@ -61,7 +64,7 @@ export default defineComponent({
|
|||
icon: faEllipsisH
|
||||
},
|
||||
debug,
|
||||
faCogs
|
||||
faCogs, faDoorOpen,
|
||||
}
|
||||
},
|
||||
|
||||
|
|
40
src/server/web/bios.css
Normal file
40
src/server/web/bios.css
Normal file
|
@ -0,0 +1,40 @@
|
|||
* {
|
||||
font-family: Fira code, Fira Mono, Consolas, Menlo, Courier, monospace;
|
||||
}
|
||||
|
||||
html {
|
||||
background: #ffb4e1;
|
||||
}
|
||||
|
||||
main {
|
||||
background: #dedede;
|
||||
}
|
||||
main > .tabs {
|
||||
padding: 16px;
|
||||
border-bottom: solid 4px #c3c3c3;
|
||||
}
|
||||
|
||||
#lsEditor > .adder {
|
||||
margin: 16px;
|
||||
padding: 16px;
|
||||
border: solid 2px #c3c3c3;
|
||||
}
|
||||
#lsEditor > .adder > textarea {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-height: 5em;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
#lsEditor > .record {
|
||||
padding: 16px;
|
||||
border-bottom: solid 1px #c3c3c3;
|
||||
}
|
||||
#lsEditor > .record > header {
|
||||
font-weight: bold;
|
||||
}
|
||||
#lsEditor > .record > textarea {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-height: 5em;
|
||||
box-sizing: border-box;
|
||||
}
|
87
src/server/web/bios.js
Normal file
87
src/server/web/bios.js
Normal file
|
@ -0,0 +1,87 @@
|
|||
'use strict';
|
||||
|
||||
window.onload = async () => {
|
||||
const account = JSON.parse(localStorage.getItem('account'));
|
||||
const i = account.token;
|
||||
|
||||
const api = (endpoint, data = {}) => {
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
// Append a credential
|
||||
if (i) data.i = i;
|
||||
|
||||
// Send request
|
||||
fetch(endpoint.indexOf('://') > -1 ? endpoint : `/api/${endpoint}`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data),
|
||||
credentials: 'omit',
|
||||
cache: 'no-cache'
|
||||
}).then(async (res) => {
|
||||
const body = res.status === 204 ? null : await res.json();
|
||||
|
||||
if (res.status === 200) {
|
||||
resolve(body);
|
||||
} else if (res.status === 204) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(body.error);
|
||||
}
|
||||
}).catch(reject);
|
||||
});
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
const content = document.getElementById('content');
|
||||
|
||||
document.getElementById('ls').addEventListener('click', () => {
|
||||
content.innerHTML = '';
|
||||
|
||||
const lsEditor = document.createElement('div');
|
||||
lsEditor.id = 'lsEditor';
|
||||
|
||||
const adder = document.createElement('div');
|
||||
adder.classList.add('adder');
|
||||
const addKeyInput = document.createElement('input');
|
||||
const addValueTextarea = document.createElement('textarea');
|
||||
const addButton = document.createElement('button');
|
||||
addButton.textContent = 'add';
|
||||
addButton.addEventListener('click', () => {
|
||||
localStorage.setItem(addKeyInput.value, addValueTextarea.value);
|
||||
location.reload();
|
||||
});
|
||||
|
||||
adder.appendChild(addKeyInput);
|
||||
adder.appendChild(addValueTextarea);
|
||||
adder.appendChild(addButton);
|
||||
lsEditor.appendChild(adder);
|
||||
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
const k = localStorage.key(i);
|
||||
const record = document.createElement('div');
|
||||
record.classList.add('record');
|
||||
const header = document.createElement('header');
|
||||
header.textContent = k;
|
||||
const textarea = document.createElement('textarea');
|
||||
textarea.textContent = localStorage.getItem(k);
|
||||
const saveButton = document.createElement('button');
|
||||
saveButton.textContent = 'save';
|
||||
saveButton.addEventListener('click', () => {
|
||||
localStorage.setItem(k, textarea.value);
|
||||
location.reload();
|
||||
});
|
||||
const removeButton = document.createElement('button');
|
||||
removeButton.textContent = 'remove';
|
||||
removeButton.addEventListener('click', () => {
|
||||
localStorage.removeItem(k);
|
||||
location.reload();
|
||||
});
|
||||
record.appendChild(header);
|
||||
record.appendChild(textarea);
|
||||
record.appendChild(saveButton);
|
||||
record.appendChild(removeButton);
|
||||
lsEditor.appendChild(record);
|
||||
}
|
||||
|
||||
content.appendChild(lsEditor);
|
||||
});
|
||||
};
|
19
src/server/web/cli.css
Normal file
19
src/server/web/cli.css
Normal file
|
@ -0,0 +1,19 @@
|
|||
* {
|
||||
font-family: Fira code, Fira Mono, Consolas, Menlo, Courier, monospace;
|
||||
}
|
||||
|
||||
html {
|
||||
background: #ffb4e1;
|
||||
}
|
||||
|
||||
main {
|
||||
background: #dedede;
|
||||
}
|
||||
|
||||
#tl > div {
|
||||
padding: 16px;
|
||||
border-bottom: solid 1px #c3c3c3;
|
||||
}
|
||||
#tl > div > header {
|
||||
font-weight: bold;
|
||||
}
|
55
src/server/web/cli.js
Normal file
55
src/server/web/cli.js
Normal file
|
@ -0,0 +1,55 @@
|
|||
'use strict';
|
||||
|
||||
window.onload = async () => {
|
||||
const account = JSON.parse(localStorage.getItem('account'));
|
||||
const i = account.token;
|
||||
|
||||
const api = (endpoint, data = {}) => {
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
// Append a credential
|
||||
if (i) data.i = i;
|
||||
|
||||
// Send request
|
||||
fetch(endpoint.indexOf('://') > -1 ? endpoint : `/api/${endpoint}`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data),
|
||||
credentials: 'omit',
|
||||
cache: 'no-cache'
|
||||
}).then(async (res) => {
|
||||
const body = res.status === 204 ? null : await res.json();
|
||||
|
||||
if (res.status === 200) {
|
||||
resolve(body);
|
||||
} else if (res.status === 204) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(body.error);
|
||||
}
|
||||
}).catch(reject);
|
||||
});
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
document.getElementById('submit').addEventListener('click', () => {
|
||||
api('notes/create', {
|
||||
text: document.getElementById('text').value
|
||||
}).then(() => {
|
||||
location.reload();
|
||||
});
|
||||
});
|
||||
|
||||
api('notes/timeline').then(notes => {
|
||||
const tl = document.getElementById('tl');
|
||||
for (const note of notes) {
|
||||
const el = document.createElement('div');
|
||||
const name = document.createElement('header');
|
||||
name.textContent = `${note.user.name} @${note.user.username}`;
|
||||
const text = document.createElement('div');
|
||||
text.textContent = `${note.text}`;
|
||||
el.appendChild(name);
|
||||
el.appendChild(text);
|
||||
tl.appendChild(el);
|
||||
}
|
||||
});
|
||||
};
|
|
@ -376,6 +376,18 @@ router.get('/info', async ctx => {
|
|||
});
|
||||
});
|
||||
|
||||
router.get('/bios', async ctx => {
|
||||
await ctx.render('bios', {
|
||||
version: config.version,
|
||||
});
|
||||
});
|
||||
|
||||
router.get('/cli', async ctx => {
|
||||
await ctx.render('cli', {
|
||||
version: config.version,
|
||||
});
|
||||
});
|
||||
|
||||
const override = (source: string, target: string, depth: number = 0) =>
|
||||
[, ...target.split('/').filter(x => x), ...source.split('/').filter(x => x).splice(depth)].join('/');
|
||||
|
||||
|
|
20
src/server/web/views/bios.pug
Normal file
20
src/server/web/views/bios.pug
Normal file
|
@ -0,0 +1,20 @@
|
|||
doctype html
|
||||
|
||||
html
|
||||
|
||||
head
|
||||
meta(charset='utf-8')
|
||||
meta(name='application-name' content='Misskey')
|
||||
title Misskey BIOS
|
||||
style
|
||||
include ../bios.css
|
||||
script
|
||||
include ../bios.js
|
||||
|
||||
body
|
||||
header
|
||||
h1 Misskey BIOS #{version}
|
||||
main
|
||||
div.tabs
|
||||
button#ls edit local storage
|
||||
div#content
|
21
src/server/web/views/cli.pug
Normal file
21
src/server/web/views/cli.pug
Normal file
|
@ -0,0 +1,21 @@
|
|||
doctype html
|
||||
|
||||
html
|
||||
|
||||
head
|
||||
meta(charset='utf-8')
|
||||
meta(name='application-name' content='Misskey')
|
||||
title Misskey Cli
|
||||
style
|
||||
include ../cli.css
|
||||
script
|
||||
include ../cli.js
|
||||
|
||||
body
|
||||
header
|
||||
h1 Misskey Cli #{version}
|
||||
main
|
||||
div#form
|
||||
textarea#text
|
||||
button#submit submit
|
||||
div#tl
|
Loading…
Reference in a new issue