From 6a1b71de0fdd0b52b84457425e979f831086dbaf Mon Sep 17 00:00:00 2001
From: Tim <135014430+nagisa77@users.noreply.github.com>
Date: Wed, 6 Aug 2025 18:59:08 +0800
Subject: [PATCH 1/5] feat: add tieba emoji support
---
frontend/src/utils/markdown.js | 24 ++++++++++++++++++++++++
frontend/src/utils/tiebaEmoji.js | 10 ++++++++++
frontend/src/utils/vditor.js | 9 ++++++++-
3 files changed, 42 insertions(+), 1 deletion(-)
create mode 100644 frontend/src/utils/tiebaEmoji.js
diff --git a/frontend/src/utils/markdown.js b/frontend/src/utils/markdown.js
index a3ed32ec7..579a6749c 100644
--- a/frontend/src/utils/markdown.js
+++ b/frontend/src/utils/markdown.js
@@ -2,6 +2,7 @@ import MarkdownIt from 'markdown-it'
import hljs from 'highlight.js'
import 'highlight.js/styles/github.css'
import { toast } from '../main'
+import { tiebaEmoji, TIEBA_EMOJI_CDN } from './tiebaEmoji'
function mentionPlugin(md) {
const mentionReg = /^@\[([^\]]+)\]/
@@ -27,6 +28,28 @@ function mentionPlugin(md) {
md.inline.ruler.before('emphasis', 'mention', mention)
}
+function tiebaEmojiPlugin(md) {
+ md.renderer.rules['tieba-emoji'] = (tokens, idx) => {
+ const name = tokens[idx].content
+ const file = tiebaEmoji[name]
+ return `
`
+ }
+ md.inline.ruler.before('emphasis', 'tieba-emoji', (state, silent) => {
+ const pos = state.pos
+ if (state.src.charCodeAt(pos) !== 0x3a) return false
+ const match = state.src.slice(pos).match(/^:tieba(\d+):/)
+ if (!match) return false
+ const key = `tieba${match[1]}`
+ if (!tiebaEmoji[key]) return false
+ if (!silent) {
+ const token = state.push('tieba-emoji', '', 0)
+ token.content = key
+ }
+ state.pos += match[0].length
+ return true
+ })
+}
+
const md = new MarkdownIt({
html: false,
linkify: true,
@@ -43,6 +66,7 @@ const md = new MarkdownIt({
})
md.use(mentionPlugin)
+md.use(tiebaEmojiPlugin)
export function renderMarkdown(text) {
return md.render(text || '')
diff --git a/frontend/src/utils/tiebaEmoji.js b/frontend/src/utils/tiebaEmoji.js
new file mode 100644
index 000000000..da413d0e9
--- /dev/null
+++ b/frontend/src/utils/tiebaEmoji.js
@@ -0,0 +1,10 @@
+export const TIEBA_EMOJI_CDN = 'https://cdn.jsdelivr.net/gh/microlong666/tieba_mobile_emotions@master/'
+
+export const tiebaEmoji = (() => {
+ const map = { tieba1: 'image_emoticon.png' }
+ for (let i = 2; i <= 124; i++) {
+ if (i > 50 && i < 62) continue
+ map[`tieba${i}`] = `image_emoticon${i}.png`
+ }
+ return map
+})()
diff --git a/frontend/src/utils/vditor.js b/frontend/src/utils/vditor.js
index 2e9a2628c..a7fabe346 100644
--- a/frontend/src/utils/vditor.js
+++ b/frontend/src/utils/vditor.js
@@ -3,6 +3,7 @@ import 'vditor/dist/index.css'
import { API_BASE_URL } from '../main'
import { getToken, authState } from './auth'
import { searchUsers, fetchFollowings, fetchAdmins } from './user'
+import { tiebaEmoji, TIEBA_EMOJI_CDN } from './tiebaEmoji'
export function getEditorTheme() {
return document.documentElement.dataset.theme === 'dark' ? 'dark' : 'classic'
@@ -42,8 +43,14 @@ export function createVditor(editorId, options = {}) {
placeholder,
height: 'auto',
theme: getEditorTheme(),
- preview: Object.assign({ theme: { current: getPreviewTheme() } }, preview),
+ preview: Object.assign({
+ theme: { current: getPreviewTheme() },
+ customEmoji: tiebaEmoji,
+ emojiPath: TIEBA_EMOJI_CDN
+ }, preview),
hint: {
+ emoji: tiebaEmoji,
+ emojiPath: TIEBA_EMOJI_CDN,
extend: [
{
key: '@',
From 05dbeccdd716e146cba96e25344090161919cda5 Mon Sep 17 00:00:00 2001
From: tim
Date: Wed, 6 Aug 2025 19:26:35 +0800
Subject: [PATCH 2/5] fix: emoji fix
---
frontend/src/assets/global.css | 10 ++++++++++
frontend/src/utils/markdown.js | 4 ++--
frontend/src/utils/tiebaEmoji.js | 5 +++--
frontend/src/utils/vditor.js | 5 +----
4 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/frontend/src/assets/global.css b/frontend/src/assets/global.css
index 77be29063..1997730f4 100644
--- a/frontend/src/assets/global.css
+++ b/frontend/src/assets/global.css
@@ -71,6 +71,16 @@ body {
top: var(--header-height) !important;
}
+.vditor-panel {
+ min-width: 400px;
+}
+
+.emoji {
+ width: 20px;
+ height: 20px;
+ vertical-align: middle;
+}
+
/* .vditor {
--textarea-background-color: transparent;
border: none !important;
diff --git a/frontend/src/utils/markdown.js b/frontend/src/utils/markdown.js
index 579a6749c..dbcd352b7 100644
--- a/frontend/src/utils/markdown.js
+++ b/frontend/src/utils/markdown.js
@@ -2,7 +2,7 @@ import MarkdownIt from 'markdown-it'
import hljs from 'highlight.js'
import 'highlight.js/styles/github.css'
import { toast } from '../main'
-import { tiebaEmoji, TIEBA_EMOJI_CDN } from './tiebaEmoji'
+import { tiebaEmoji } from './tiebaEmoji'
function mentionPlugin(md) {
const mentionReg = /^@\[([^\]]+)\]/
@@ -32,7 +32,7 @@ function tiebaEmojiPlugin(md) {
md.renderer.rules['tieba-emoji'] = (tokens, idx) => {
const name = tokens[idx].content
const file = tiebaEmoji[name]
- return `
`
+ return `
`
}
md.inline.ruler.before('emphasis', 'tieba-emoji', (state, silent) => {
const pos = state.pos
diff --git a/frontend/src/utils/tiebaEmoji.js b/frontend/src/utils/tiebaEmoji.js
index da413d0e9..ce91ea0ff 100644
--- a/frontend/src/utils/tiebaEmoji.js
+++ b/frontend/src/utils/tiebaEmoji.js
@@ -1,10 +1,11 @@
export const TIEBA_EMOJI_CDN = 'https://cdn.jsdelivr.net/gh/microlong666/tieba_mobile_emotions@master/'
+// export const TIEBA_EMOJI_CDN = 'https://openisle-1307107697.cos.ap-guangzhou.myqcloud.com/assert/vditor/dist/images/emoji/'
export const tiebaEmoji = (() => {
- const map = { tieba1: 'image_emoticon.png' }
+ const map = { tieba1: TIEBA_EMOJI_CDN + 'image_emoticon.png' }
for (let i = 2; i <= 124; i++) {
if (i > 50 && i < 62) continue
- map[`tieba${i}`] = `image_emoticon${i}.png`
+ map[`tieba${i}`] = TIEBA_EMOJI_CDN + `image_emoticon${i}.png`
}
return map
})()
diff --git a/frontend/src/utils/vditor.js b/frontend/src/utils/vditor.js
index a7fabe346..f0a83214a 100644
--- a/frontend/src/utils/vditor.js
+++ b/frontend/src/utils/vditor.js
@@ -3,7 +3,7 @@ import 'vditor/dist/index.css'
import { API_BASE_URL } from '../main'
import { getToken, authState } from './auth'
import { searchUsers, fetchFollowings, fetchAdmins } from './user'
-import { tiebaEmoji, TIEBA_EMOJI_CDN } from './tiebaEmoji'
+import { tiebaEmoji } from './tiebaEmoji'
export function getEditorTheme() {
return document.documentElement.dataset.theme === 'dark' ? 'dark' : 'classic'
@@ -45,12 +45,9 @@ export function createVditor(editorId, options = {}) {
theme: getEditorTheme(),
preview: Object.assign({
theme: { current: getPreviewTheme() },
- customEmoji: tiebaEmoji,
- emojiPath: TIEBA_EMOJI_CDN
}, preview),
hint: {
emoji: tiebaEmoji,
- emojiPath: TIEBA_EMOJI_CDN,
extend: [
{
key: '@',
From fbaa05f146012b637b3c19248574c1008409f7e3 Mon Sep 17 00:00:00 2001
From: Tim <135014430+nagisa77@users.noreply.github.com>
Date: Wed, 6 Aug 2025 19:32:56 +0800
Subject: [PATCH 3/5] feat: show compact vditor toolbar on mobile
---
frontend/src/assets/global.css | 2 +-
frontend/src/utils/vditor.js | 41 +++++++++++++++++++---------------
2 files changed, 24 insertions(+), 19 deletions(-)
diff --git a/frontend/src/assets/global.css b/frontend/src/assets/global.css
index 1997730f4..97e58f834 100644
--- a/frontend/src/assets/global.css
+++ b/frontend/src/assets/global.css
@@ -235,7 +235,7 @@ body {
}
.vditor-toolbar {
- display: none;
+ overflow-x: auto;
}
.about-content h1,
diff --git a/frontend/src/utils/vditor.js b/frontend/src/utils/vditor.js
index f0a83214a..9888c1d2b 100644
--- a/frontend/src/utils/vditor.js
+++ b/frontend/src/utils/vditor.js
@@ -38,6 +38,28 @@ export function createVditor(editorId, options = {}) {
return searchUsers(value)
}
+ const isMobile = window.innerWidth <= 768
+ const toolbar = isMobile
+ ? ['emoji', 'bold', 'italic', 'strike', '|', 'link', 'upload']
+ : [
+ 'emoji',
+ 'bold',
+ 'italic',
+ 'strike',
+ '|',
+ 'list',
+ 'line',
+ 'quote',
+ 'code',
+ 'inline-code',
+ '|',
+ 'undo',
+ 'redo',
+ '|',
+ 'link',
+ 'upload'
+ ]
+
let vditor
vditor = new Vditor(editorId, {
placeholder,
@@ -62,24 +84,7 @@ export function createVditor(editorId, options = {}) {
],
},
cdn: 'https://openisle-1307107697.cos.ap-guangzhou.myqcloud.com/assert/vditor',
- toolbar: [
- 'emoji',
- 'bold',
- 'italic',
- 'strike',
- '|',
- 'list',
- 'line',
- 'quote',
- 'code',
- 'inline-code',
- '|',
- 'undo',
- 'redo',
- '|',
- 'link',
- 'upload'
- ],
+ toolbar,
upload: {
accept: 'image/*,video/*',
multiple: false,
From 3de6b89cc4ae40187b50f66e31b74010f44e9346 Mon Sep 17 00:00:00 2001
From: tim
Date: Wed, 6 Aug 2025 19:47:51 +0800
Subject: [PATCH 4/5] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Dvditor=E9=AB=98?=
=?UTF-8?q?=E5=BA=A6=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
frontend/src/components/PostEditor.vue | 8 +++++++-
frontend/src/utils/vditor.js | 2 +-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/frontend/src/components/PostEditor.vue b/frontend/src/components/PostEditor.vue
index 85b1ca9c5..63644222d 100644
--- a/frontend/src/components/PostEditor.vue
+++ b/frontend/src/components/PostEditor.vue
@@ -123,7 +123,6 @@ export default {
diff --git a/frontend/src/utils/vditor.js b/frontend/src/utils/vditor.js
index 9888c1d2b..93564b7d0 100644
--- a/frontend/src/utils/vditor.js
+++ b/frontend/src/utils/vditor.js
@@ -40,7 +40,7 @@ export function createVditor(editorId, options = {}) {
const isMobile = window.innerWidth <= 768
const toolbar = isMobile
- ? ['emoji', 'bold', 'italic', 'strike', '|', 'link', 'upload']
+ ? ['emoji', 'upload']
: [
'emoji',
'bold',
From b4f85989d05ee1a20d184b9354603c420528da3c Mon Sep 17 00:00:00 2001
From: tim
Date: Wed, 6 Aug 2025 20:10:25 +0800
Subject: [PATCH 5/5] =?UTF-8?q?feat:=20=E7=A7=BB=E5=8A=A8=E7=AB=AF=20vdito?=
=?UTF-8?q?r=20=E6=94=AF=E6=8C=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
frontend/src/assets/global.css | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/frontend/src/assets/global.css b/frontend/src/assets/global.css
index 97e58f834..48188a8e0 100644
--- a/frontend/src/assets/global.css
+++ b/frontend/src/assets/global.css
@@ -255,6 +255,11 @@ body {
margin-bottom: 3px;
}
+
+ .vditor-toolbar--pin {
+ top: 0 !important;
+ }
+
.about-content li,
.info-content-text li {
font-size: 14px;