diff --git a/frontend/src/api/chat/ChatClientDirect/index.js b/frontend/src/api/chat/ChatClientDirect/index.js
index 30b396e..6ef00c9 100644
--- a/frontend/src/api/chat/ChatClientDirect/index.js
+++ b/frontend/src/api/chat/ChatClientDirect/index.js
@@ -336,7 +336,7 @@ export default class ChatClientDirect {
medalLevel: roomId === this.roomId ? medalLevel : 0,
id: getUuid4Hex(),
translation: '',
- emoticon: info[0][13].url || null // TODO 改成对象?
+ emoticon: info[0][13].url || null
}
this.onAddText(data)
}
diff --git a/frontend/src/api/chat/ChatClientRelay.js b/frontend/src/api/chat/ChatClientRelay.js
index e44bea1..c49a47c 100644
--- a/frontend/src/api/chat/ChatClientRelay.js
+++ b/frontend/src/api/chat/ChatClientRelay.js
@@ -130,7 +130,7 @@ export default class ChatClientRelay {
let contentType = data[13]
let contentTypeParams = data[14]
if (contentType === CONTENT_TYPE_EMOTICON) {
- emoticon = contentTypeParams[0] // TODO 改成对象?
+ emoticon = contentTypeParams[0]
}
data = {
diff --git a/frontend/src/api/chat/ChatClientTest.js b/frontend/src/api/chat/ChatClientTest.js
index 5e7b565..8fa668d 100644
--- a/frontend/src/api/chat/ChatClientTest.js
+++ b/frontend/src/api/chat/ChatClientTest.js
@@ -19,7 +19,6 @@ const CONTENTS = [
'有一说一,这件事大家懂的都懂,不懂的,说了你也不明白,不如不说', '让我看看', '我柜子动了,我不玩了'
]
-// TODO 改成对象?
const EMOTICONS = [
'/static/img/emoticons/233.png',
'/static/img/emoticons/miaoa.png',
diff --git a/frontend/src/components/ChatRenderer/TextMessage.vue b/frontend/src/components/ChatRenderer/TextMessage.vue
index 7bcd901..e8c089a 100644
--- a/frontend/src/components/ChatRenderer/TextMessage.vue
+++ b/frontend/src/components/ChatRenderer/TextMessage.vue
@@ -9,11 +9,14 @@
:isInMemberMessage="false" :authorName="authorName" :authorType="authorType" :privilegeType="privilegeType"
>
- {{ content }}
-
-
+ {{ content.text }}
+
+
+
@@ -42,11 +45,16 @@ export default {
time: Date,
authorName: String,
authorType: Number,
- content: String,
- emoticon: String,
+ richContent: Array,
privilegeType: Number,
repeated: Number
},
+ data() {
+ return {
+ CONTENT_TYPE_TEXT: constants.CONTENT_TYPE_TEXT,
+ CONTENT_TYPE_IMAGE: constants.CONTENT_TYPE_IMAGE
+ }
+ },
computed: {
timeText() {
return utils.getTimeTextHourMin(this.time)
diff --git a/frontend/src/components/ChatRenderer/constants.js b/frontend/src/components/ChatRenderer/constants.js
index afcdfd8..b9e05d3 100644
--- a/frontend/src/components/ChatRenderer/constants.js
+++ b/frontend/src/components/ChatRenderer/constants.js
@@ -34,6 +34,9 @@ export const MESSAGE_TYPE_SUPER_CHAT = 3
export const MESSAGE_TYPE_DEL = 4
export const MESSAGE_TYPE_UPDATE = 5
+export const CONTENT_TYPE_TEXT = 0
+export const CONTENT_TYPE_IMAGE = 1
+
// 美元 -> 人民币 汇率
const EXCHANGE_RATE = 7
export const PRICE_CONFIGS = [
@@ -139,6 +142,17 @@ export function getShowContent(message) {
return message.content
}
+export function getShowRichContent(message) {
+ let richContent = [...message.richContent]
+ if (message.translation) {
+ richContent.push({
+ type: CONTENT_TYPE_TEXT,
+ text: `(${message.translation})`
+ })
+ }
+ return richContent
+}
+
export function getGiftShowContent(message, showGiftName) {
if (!showGiftName) {
return ''
diff --git a/frontend/src/components/ChatRenderer/index.vue b/frontend/src/components/ChatRenderer/index.vue
index 113eb84..811004f 100644
--- a/frontend/src/components/ChatRenderer/index.vue
+++ b/frontend/src/components/ChatRenderer/index.vue
@@ -12,24 +12,37 @@
@@ -137,6 +150,7 @@ export default {
return constants.getGiftShowContent(message, this.showGiftName)
},
getShowContent: constants.getShowContent,
+ getShowRichContent: constants.getShowRichContent,
getShowAuthorName: constants.getShowAuthorName,
addMessage(message) {
diff --git a/frontend/src/lang/en.js b/frontend/src/lang/en.js
index 79065b9..0ffb1f2 100644
--- a/frontend/src/lang/en.js
+++ b/frontend/src/lang/en.js
@@ -1,10 +1,10 @@
export default {
sidebar: {
home: 'Home',
- stylegen: 'Style generator',
+ stylegen: 'Style Generator',
help: 'Help',
- projectAddress: 'Project address',
- giftRecordOfficial: 'Official Super Chat record',
+ projectAddress: 'Project Address',
+ giftRecordOfficial: 'Official Super Chat Record',
},
home: {
roomIdEmpty: "Room ID can't be empty",
@@ -38,8 +38,13 @@ export default {
pinyin: 'Pinyin',
kana: 'Kana',
+ emoticon: 'Custom Emotes',
+ emoticonKeyword: 'Emote Code',
+ emoticonUrl: 'URL',
+ operation: 'Operation',
+ addEmoticon: 'Add emote',
+
roomUrl: 'Room URL',
- copy: 'Copy',
enterRoom: 'Enter room',
enterTestRoom: 'Enter test room',
exportConfig: 'Export config',
@@ -63,7 +68,7 @@ export default {
showAvatars: 'Show avatars',
avatarSize: 'Avatar size',
- userNames: 'User names',
+ userNames: 'User Names',
showUserNames: 'Show user names',
font: 'Font',
fontSize: 'Font size',
@@ -91,7 +96,7 @@ export default {
moderatorMessageBgColor: 'Moderator background color',
memberMessageBgColor: 'Member background color',
- scAndNewMember: 'Super Chat / New member',
+ scAndNewMember: 'Super Chat / New Member',
firstLineFont: 'First line font',
firstLineFontSize: 'First line font size',
firstLineLineHeight: 'First line line height (0 for default)',
diff --git a/frontend/src/lang/ja.js b/frontend/src/lang/ja.js
index f2948df..cdd94b3 100644
--- a/frontend/src/lang/ja.js
+++ b/frontend/src/lang/ja.js
@@ -38,8 +38,13 @@ export default {
pinyin: 'ピンイン',
kana: '仮名',
+ emoticon: 'カスタムスタンプ',
+ emoticonKeyword: '置き換えるキーワード',
+ emoticonUrl: 'URL',
+ operation: '操作',
+ addEmoticon: 'スタンプを追加',
+
roomUrl: 'ルームのURL',
- copy: 'コピー',
enterRoom: 'ルームに入る',
enterTestRoom: 'テストルームに入る',
exportConfig: 'コンフィグの導出',
diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js
index d243435..c133bbe 100644
--- a/frontend/src/lang/zh.js
+++ b/frontend/src/lang/zh.js
@@ -38,8 +38,13 @@ export default {
pinyin: '拼音',
kana: '日文假名',
+ emoticon: '自定义表情',
+ emoticonKeyword: '替换关键词',
+ emoticonUrl: 'URL',
+ operation: '操作',
+ addEmoticon: '添加表情',
+
roomUrl: '房间URL',
- copy: '复制',
enterRoom: '进入房间',
enterTestRoom: '进入测试房间',
exportConfig: '导出配置',
diff --git a/frontend/src/main.js b/frontend/src/main.js
index 7d78dd0..44d8874 100644
--- a/frontend/src/main.js
+++ b/frontend/src/main.js
@@ -1,9 +1,9 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
import {
- Aside, Autocomplete, Badge, Button, Card, Col, ColorPicker, Container, Divider, Form, FormItem, Image,
+ Aside, Autocomplete, Badge, Button, ButtonGroup, Card, Col, ColorPicker, Container, Divider, Form, FormItem, Image,
Input, Main, Menu, MenuItem, Message, Option, OptionGroup, Radio, RadioGroup, Row, Select, Scrollbar,
- Slider, Submenu, Switch, TabPane, Tabs, Tooltip
+ Slider, Submenu, Switch, Table, TableColumn, TabPane, Tabs, Tooltip
} from 'element-ui'
import axios from 'axios'
@@ -28,6 +28,7 @@ Vue.use(Aside)
Vue.use(Autocomplete)
Vue.use(Badge)
Vue.use(Button)
+Vue.use(ButtonGroup)
Vue.use(Card)
Vue.use(Col)
Vue.use(ColorPicker)
@@ -50,6 +51,8 @@ Vue.use(Scrollbar)
Vue.use(Slider)
Vue.use(Submenu)
Vue.use(Switch)
+Vue.use(Table)
+Vue.use(TableColumn)
Vue.use(TabPane)
Vue.use(Tabs)
Vue.use(Tooltip)
diff --git a/frontend/src/utils/trie.js b/frontend/src/utils/trie.js
new file mode 100644
index 0000000..86a54f5
--- /dev/null
+++ b/frontend/src/utils/trie.js
@@ -0,0 +1,58 @@
+export class Trie {
+ constructor() {
+ this._root = this._createNode()
+ }
+
+ _createNode() {
+ return {
+ children: {}, // char -> node
+ value: null
+ }
+ }
+
+ set(key, value) {
+ if (key === '') {
+ throw new Error('key is empty')
+ }
+ let node = this._root
+ for (let char of key) {
+ let nextNode = node.children[char]
+ if (nextNode === undefined) {
+ nextNode = node.children[char] = this._createNode()
+ }
+ node = nextNode
+ }
+ node.value = value
+ }
+
+ get(key) {
+ let node = this._root
+ for (let char of key) {
+ let nextNode = node.children[char]
+ if (nextNode === undefined) {
+ return null
+ }
+ node = nextNode
+ }
+ return node.value
+ }
+
+ has(key) {
+ return this.get(key) !== null
+ }
+
+ greedyMatch(str) {
+ let node = this._root
+ for (let char of str) {
+ let nextNode = node.children[char]
+ if (nextNode === undefined) {
+ return null
+ }
+ if (nextNode.value !== null) {
+ return nextNode.value
+ }
+ node = nextNode
+ }
+ return null
+ }
+}
diff --git a/frontend/src/views/Home.vue b/frontend/src/views/Home.vue
index dec0237..dae4f8d 100644
--- a/frontend/src/views/Home.vue
+++ b/frontend/src/views/Home.vue
@@ -114,6 +114,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{$t('home.addEmoticon')}}
+
+
@@ -123,11 +149,11 @@
- {{$t('home.copy')}}
+
{{$t('home.enterRoom')}}
- {{$t('home.enterTestRoom')}}
+ {{$t('home.enterTestRoom')}}
{{$t('home.exportConfig')}}
{{$t('home.importConfig')}}
@@ -192,6 +218,20 @@ export default {
this.$message.error(`Failed to fetch server information: ${e}`)
}
},
+
+ addEmoticon() {
+ this.form.emoticons.push({
+ keyword: '[Kappa]',
+ url: ''
+ })
+ },
+ delEmoticon(index) {
+ this.form.emoticons.splice(index, 1)
+ },
+ uploadEmoticon() {
+ // TODO WIP
+ },
+
enterRoom() {
window.open(this.roomUrl, `room ${this.form.roomId}`, 'menubar=0,location=0,scrollbars=0,toolbar=0,width=600,height=600')
},
@@ -199,7 +239,7 @@ export default {
window.open(this.getRoomUrl(true), 'test room', 'menubar=0,location=0,scrollbars=0,toolbar=0,width=600,height=600')
},
getRoomUrl(isTestRoom) {
- if (isTestRoom && this.form.roomId === '') {
+ if (!isTestRoom && this.form.roomId === '') {
return ''
}
diff --git a/frontend/src/views/Room.vue b/frontend/src/views/Room.vue
index 0bd747f..62e8c47 100644
--- a/frontend/src/views/Room.vue
+++ b/frontend/src/views/Room.vue
@@ -5,6 +5,7 @@