Skip to content

Commit

Permalink
feat(webui): assets proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Apr 4, 2021
1 parent c9f665e commit 16f2441
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 34 deletions.
14 changes: 6 additions & 8 deletions packages/plugin-chat/client/chat.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
<template>
<k-chat-panel class="page-chat" :messages="messages" pinned>
<template #default="{ channelName, username, timestamp, content }">
<p>
<div class="header">
<span class="channel">{{ channelName || '私聊' }}</span>
<span class="username">{{ username }}</span>
<span class="timestamp">{{ formatDateTime(timestamp) }}</span>
</div>
<k-message :content="content"/>
</p>
<div class="header">
<span class="channel">{{ channelName || '私聊' }}</span>
<span class="username">{{ username }}</span>
<span class="timestamp">{{ formatDateTime(timestamp) }}</span>
</div>
<k-message :content="content"/>
</template>
</k-chat-panel>
</template>
Expand Down
3 changes: 2 additions & 1 deletion packages/plugin-chat/src/debug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const cqTypes = {
}

interface Message {
avatar?: string
content?: string
abstract?: string
username?: string
Expand Down Expand Up @@ -151,7 +152,7 @@ export default function apply(ctx: Context, config: DebugConfig = {}) {

function handleMessage(session: Session) {
const params: Message = pick(session, ['content', 'timestamp', 'platform', 'channelId', 'channelName', 'groupId', 'groupName', 'userId', 'selfId'])
Object.assign(params, pick(session.author, ['username', 'nickname']))
Object.assign(params, pick(session.author, ['username', 'nickname', 'avatar']))
if (session.type === 'message') {
userMap[session.uid] = [Promise.resolve(session.author.username), Date.now()]
}
Expand Down
4 changes: 3 additions & 1 deletion packages/plugin-chat/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ export const name = 'chat'

export function apply(ctx: Context, options: Config = {}) {
ctx.plugin(debug, options)

ctx.with(['koishi-plugin-webui'], (ctx) => {
const filename = ctx.webui.config.devMode ? '../client/index.ts' : '../dist/index.js'
const { devMode } = ctx.webui.config
const filename = devMode ? '../client/index.ts' : '../dist/index.js'
ctx.webui.addEntry(resolve(__dirname, filename))
})
}
34 changes: 23 additions & 11 deletions packages/plugin-webui/client/components/chat-panel.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<template>
<k-card class="k-chat-panel">
<div class="k-chat-panel-body" ref="body">
<template v-for="(message, index) in messages" :key="index">
<div class="k-chat-body" ref="body">
<div class="k-chat-message" v-for="(message, index) in messages" :key="index">
<slot v-bind="message"/>
</template>
</div>
</div>
<k-input v-model="text" @enter="onEnter" @paste="onPaste"></k-input>
</k-card>
Expand Down Expand Up @@ -56,25 +56,37 @@ async function onPaste(event: ClipboardEvent) {

<style lang="scss">
$padding: 1.5rem;
.k-chat-panel {
height: 100%;
position: relative;
.k-chat-panel-body {
.k-chat-body {
position: absolute;
top: 2rem;
left: 2rem;
right: 2rem;
bottom: 6rem;
top: $padding;
left: $padding;
right: $padding;
bottom: 2rem + $padding * 2;
overflow-x: visible;
overflow-y: auto;
}
.k-chat-message {
&:hover {
background-color: rgba(4, 4, 5, 0.2);
}
& + .k-chat-message {
margin-top: 0.5rem;
}
}
.k-input {
position: absolute;
bottom: 2rem;
left: 2rem;
right: 2rem;
bottom: $padding;
left: $padding;
right: $padding;
}
}
Expand Down
9 changes: 8 additions & 1 deletion packages/plugin-webui/client/components/message.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div class="k-message">
<template v-for="({ type, data }, index) in segment.parse(content)" :key="index">
<span v-if="type === 'text'">{{ data.content }}</span>
<img v-else-if="type === 'image'" :src="data.url || data.file"/>
<img v-else-if="type === 'image'" :src="normalizeUrl(data)"/>
</template>
</div>
</template>
Expand All @@ -16,12 +16,19 @@ defineProps<{
content: string
}>()
function normalizeUrl(data: any) {
if (!data.url) return console.log(data), ''
if (data.url.startsWith('base64://')) return data.url
return KOISHI_CONFIG.endpoint + '/assets/' + encodeURIComponent(data.url)
}
</script>

<style lang="scss" scoped>
.k-message {
white-space: break-spaces;
line-height: 1.5;
img {
max-height: 400px;
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin-webui/client/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ receive('expire', () => {
})

router.beforeEach((route, from) => {
if (from === START_LOCATION) {
if (from === START_LOCATION && !route.matched.length) {
loadingExtensions.then(() => router.replace(route))
}
if (route.meta.authority && !user.value) {
Expand Down
12 changes: 2 additions & 10 deletions packages/plugin-webui/client/views/sandbox.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
<template>
<k-chat-panel class="sandbox" :messages="messages" @enter="sendSandbox" :pinned="pinned">
<template #default="{ from, content }">
<p :class="from">
<k-message :content="content"/>
</p>
<k-message :class="from" :content="content"/>
</template>
</k-chat-panel>
</template>
Expand Down Expand Up @@ -55,18 +53,12 @@ receive('sandbox:clear', (data) => {
color: rgba(244, 244, 245, .8);
}
p:first-child {
margin-top: 0;
}
p:last-child {
margin-bottom: 0;
}
p.user::before {
content: '>';
position: absolute;
left: -.1rem;
}
p.bot::before {
content: '<';
position: absolute;
Expand Down
17 changes: 16 additions & 1 deletion packages/plugin-webui/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { promises as fs, Stats, createReadStream } from 'fs'
import { WebAdapter } from './adapter'
import { DataSource, Profile, Meta, Registry } from './data'
import { Statistics } from './stats'
import axios from 'axios'
import type * as Vite from 'vite'
import type PluginVue from '@vitejs/plugin-vue'

Expand Down Expand Up @@ -42,6 +43,11 @@ export class WebServer {
private vite: Vite.ViteDevServer
private readonly [Context.current]: Context

static whitelist = [
'http://gchat.qpic.cn/',
'http://c2cpicdw.qpic.cn',
]

constructor(private ctx: Context, public config: Config) {
this.root = resolve(__dirname, '..', config.devMode ? 'client' : 'dist')
this.sources = {
Expand Down Expand Up @@ -69,7 +75,7 @@ export class WebServer {
}

private async start() {
const { uiPath } = this.config
const { uiPath, apiPath } = this.config
await Promise.all([this.createVite(), this.createAdapter()])

this.ctx.router.get(uiPath + '(/.+)*', async (ctx) => {
Expand Down Expand Up @@ -98,6 +104,15 @@ export class WebServer {
ctx.type = 'html'
ctx.body = await this.transformHtml(template)
})

this.ctx.router.get(apiPath + '/assets/:url', async (ctx) => {
if (!WebServer.whitelist.some(prefix => ctx.params.url.startsWith(prefix))) {
console.log(ctx.params.url)
return ctx.status = 403
}
const { data } = await axios.get(ctx.params.url, { responseType: 'stream' })
return ctx.body = data
})
}

private async transformHtml(template: string) {
Expand Down

0 comments on commit 16f2441

Please sign in to comment.