mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-11 02:12:53 +00:00
feat: 添加emoji表情删除按钮
This commit is contained in:
parent
0fb66358cc
commit
1b30582dd9
@ -16,13 +16,26 @@
|
||||
</div>
|
||||
<Scrollbar>
|
||||
<ul :class="[type, 'no-dark-content']">
|
||||
<li v-for="item in list" @click="onSelect($event, item)">
|
||||
<li v-for="(item, index) in list" :key="index" @click="onSelect($event, item)">
|
||||
<Imgs v-if="item.type === 'emoticon'" :src="item.src" :title="item.name" :alt="item.name"/>
|
||||
<span v-else v-html="item.html" :title="item.name"></span>
|
||||
</li>
|
||||
<template v-if="type === 'emoji'">
|
||||
<li class="delete-placeholder"></li>
|
||||
<li class="delete-placeholder"></li>
|
||||
</template>
|
||||
</ul>
|
||||
</Scrollbar>
|
||||
</div>
|
||||
<div
|
||||
v-if="showEmojiDelete && type === 'emoji'"
|
||||
class="chat-emoji-delete-btn"
|
||||
@click="onDelete">
|
||||
<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="64" height="64" stroke="currentColor" fill="currentColor">
|
||||
<path d="M889.202 167.878H343.626c-22.574 0-45.15 11.28-60.202 26.322L76.484 457.442c-22.576 30.084-22.576 67.688 0 94.016l206.94 263.236c15.052 18.802 37.628 30.084 60.202 30.084h545.572c41.39 0 75.252-33.842 75.252-75.208V243.092c-0.002-41.37-33.864-75.214-75.248-75.214z m3.76 601.69H347.39l-206.94-263.24 203.176-263.236h549.336v526.476z"></path>
|
||||
<path d="M410.164 641.746c0 11.292 3.764 18.822 11.306 26.352 15.07 11.292 33.918 11.292 45.224 0l113.06-112.934 113.058 112.934c7.536 3.766 11.306 7.526 22.612 7.526s18.842-7.526 22.612-11.292c3.77-7.53 7.536-15.06 7.536-22.588 0-7.53 0-15.06-7.536-22.586l-113.058-112.94 113.058-112.934c3.77-3.766 7.536-11.296 7.536-18.822 0-15.062-15.072-26.352-22.612-30.118l-3.766-3.764h-3.77c-7.536 0-15.076 0-22.612 7.53l-113.058 112.934-116.83-120.466c-3.77-3.766-11.306-7.532-18.842-7.532-11.306 0-18.846 3.766-26.382 11.296-3.766 7.532-7.536 15.056-7.536 22.588 0 11.296 3.764 18.822 7.536 22.588l113.06 120.466-113.06 112.934c-3.766 3.772-7.536 11.298-7.536 18.828z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div v-if="!onlyEmoji" class="chat-emoji-menu-wrap">
|
||||
<span v-show="showEmojiMenuScrollLeftBtn" class="left-btn" @click="onEmojiMenuScroll('left')"><i class="taskfont"></i></span>
|
||||
<ul ref="chatEmojiMenuRef" class="chat-emoji-menu" @scroll="onHandleScroll">
|
||||
@ -32,7 +45,7 @@
|
||||
<li :class="{active: type === 'emoji'}" @click="type='emoji'">
|
||||
<span class="no-dark-content">😀</span>
|
||||
</li>
|
||||
<li v-for="item in emoticonData" :class="{active: type === 'emoticon' && emoticonPath == item.path}" @click="onEmoticon(item.path)">
|
||||
<li v-for="(item, index) in emoticonData" :key="index" :class="{active: type === 'emoticon' && emoticonPath == item.path}" @click="onEmoticon(item.path)">
|
||||
<Imgs :title="item.name" :alt="item.name" :src="item.src"/>
|
||||
</li>
|
||||
</ul>
|
||||
@ -52,6 +65,11 @@ export default {
|
||||
onlyEmoji: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 是否显示 emoji 删除按钮
|
||||
showEmojiDelete: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@ -222,6 +240,10 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
onDelete() {
|
||||
this.$emit('on-delete');
|
||||
},
|
||||
|
||||
onMonitorWheel() {
|
||||
const container = this.$refs['chatEmojiMenuRef'];
|
||||
container?.addEventListener("wheel", (event) =>{
|
||||
|
||||
@ -227,7 +227,12 @@
|
||||
</div>
|
||||
|
||||
<!-- 移动端表情(底部) -->
|
||||
<ChatEmoji v-if="emojiBottom && showEmoji" @on-select="onSelectEmoji" :searchKey="emojiQuickKey"/>
|
||||
<ChatEmoji
|
||||
v-if="emojiBottom && showEmoji"
|
||||
@on-select="onSelectEmoji"
|
||||
@on-delete="onEmojiDelete"
|
||||
:searchKey="emojiQuickKey"
|
||||
showEmojiDelete/>
|
||||
|
||||
<!-- 录音浮窗 -->
|
||||
<transition name="fade">
|
||||
@ -414,6 +419,7 @@ export default {
|
||||
quill: null,
|
||||
isFocus: false,
|
||||
rangeIndex: 0,
|
||||
rangeLength: 0,
|
||||
_content: '',
|
||||
_options: {},
|
||||
|
||||
@ -868,9 +874,13 @@ export default {
|
||||
if (this.quill) {
|
||||
const range = this.quill.selection.savedRange;
|
||||
this.rangeIndex = range ? range.index : 0
|
||||
this.rangeLength = range ? range.length : 0
|
||||
}
|
||||
} else {
|
||||
this.rangeLength = 0;
|
||||
if (this.rangeIndex > 0) {
|
||||
this.quill.setSelection(this.rangeIndex)
|
||||
}
|
||||
} else if (this.rangeIndex > 0) {
|
||||
this.quill.setSelection(this.rangeIndex)
|
||||
}
|
||||
},
|
||||
|
||||
@ -1741,6 +1751,8 @@ export default {
|
||||
if (item.type === 'emoji') {
|
||||
this.quill.insertText(this.rangeIndex, item.text);
|
||||
this.rangeIndex += item.text.length
|
||||
this.rangeLength = 0;
|
||||
this.quill.setSelection(this.rangeIndex, 0, 'silent');
|
||||
if (this.windowLandscape && !this.isModKey) {
|
||||
this.showEmoji = false;
|
||||
}
|
||||
@ -1755,6 +1767,58 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
onEmojiDelete() {
|
||||
if (!this.quill) {
|
||||
return;
|
||||
}
|
||||
const savedRange = this.quill.selection?.savedRange || this.quill.getSelection();
|
||||
if (savedRange && typeof savedRange.index === 'number') {
|
||||
this.rangeIndex = savedRange.index;
|
||||
this.rangeLength = savedRange.length || 0;
|
||||
}
|
||||
if (this.rangeLength > 0) {
|
||||
this.quill.deleteText(this.rangeIndex, this.rangeLength);
|
||||
this.rangeLength = 0;
|
||||
} else if (this.rangeIndex > 0) {
|
||||
const deleteLength = this.getPreviousGraphemeLength(this.rangeIndex);
|
||||
if (deleteLength > 0) {
|
||||
this.quill.deleteText(this.rangeIndex - deleteLength, deleteLength);
|
||||
this.rangeIndex -= deleteLength;
|
||||
}
|
||||
}
|
||||
this.quill.setSelection(this.rangeIndex, 0, 'silent');
|
||||
},
|
||||
|
||||
getPreviousGraphemeLength(index) {
|
||||
if (!this.quill || index <= 0) {
|
||||
return 0;
|
||||
}
|
||||
const textBeforeCursor = this.quill.getText(0, index);
|
||||
if (!textBeforeCursor) {
|
||||
return 0;
|
||||
}
|
||||
if (typeof Intl !== 'undefined' && typeof Intl.Segmenter === 'function') {
|
||||
if (!this.graphemeSegmenter) {
|
||||
this.graphemeSegmenter = new Intl.Segmenter(undefined, {granularity: 'grapheme'});
|
||||
}
|
||||
let lastSegment;
|
||||
for (const segment of this.graphemeSegmenter.segment(textBeforeCursor)) {
|
||||
lastSegment = segment;
|
||||
}
|
||||
if (lastSegment && lastSegment.segment) {
|
||||
return lastSegment.segment.length;
|
||||
}
|
||||
}
|
||||
const fallbackWindow = Math.min(index, 8);
|
||||
const fallbackText = this.quill.getText(index - fallbackWindow, fallbackWindow);
|
||||
if (!fallbackText) {
|
||||
return 0;
|
||||
}
|
||||
const fallbackGraphemes = Array.from(fallbackText);
|
||||
const lastGrapheme = fallbackGraphemes.pop();
|
||||
return lastGrapheme ? lastGrapheme.length : 0;
|
||||
},
|
||||
|
||||
onToolbar(action) {
|
||||
this.hidePopover();
|
||||
switch (action) {
|
||||
|
||||
@ -511,6 +511,28 @@
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
|
||||
.chat-emoji-delete-btn {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
bottom: 60px;
|
||||
border: none;
|
||||
padding: 10px 14px;
|
||||
border-radius: 8px;
|
||||
background: #eee;
|
||||
color: #666;
|
||||
font-size: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
|
||||
> svg {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.chat-emoji-emosearch {
|
||||
flex-shrink: 0;
|
||||
padding: 8px 8px 0;
|
||||
@ -1298,6 +1320,10 @@ body.window-portrait {
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
font-size: 28px;
|
||||
|
||||
&.delete-placeholder {
|
||||
height: 60px;
|
||||
}
|
||||
}
|
||||
&.emosearch,
|
||||
&.emoticon {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user