This commit is contained in:
kuaifan 2022-05-26 15:57:43 +08:00
parent 173f5c84db
commit ac45ba633b
21 changed files with 512 additions and 365 deletions

View File

@ -96,5 +96,8 @@
"url": "https://t.hitosea.com/desktop/publish"
}
}
]
],
"dependencies": {
"grapheme-splitter": "^1.0.4"
}
}

2
public/css/app.css vendored

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

2
public/js/app.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
98d215c910f5969e
6c5499276179e032

View File

@ -1,54 +1,63 @@
<template>
<div class="chat-input-wrapper" :class="modeClass" @click.stop="focus">
<div ref="editor" class="no-dark-content" :style="editorStyle" @click.stop="" @paste="handlePaste"></div>
<div class="chat-input-toolbar" @click.stop="">
<slot name="toolbarBefore"/>
<div class="chat-input-box">
<div class="chat-input-wrapper" :class="modeClass" @click.stop="focus">
<div ref="editor" class="no-dark-content" :style="editorStyle" @click.stop="" @paste="handlePaste"></div>
<div class="chat-input-toolbar" @click.stop="">
<slot name="toolbarBefore"/>
<EPopover
v-model="showEmoji"
:visibleArrow="false"
placement="top"
popperClass="chat-input-emoji-popover">
<ETooltip slot="reference" ref="emojiTip" :disabled="!$isDesktop || showEmoji" placement="top" :content="$L('表情')">
<i class="taskfont" @click="onToolbar('emoji')">&#xe7ad;</i>
<EPopover
v-if="$isDesktop"
v-model="showEmoji"
:visibleArrow="false"
placement="top"
popperClass="chat-input-emoji-popover">
<ETooltip slot="reference" ref="emojiTip" :disabled="!$isDesktop || showEmoji" placement="top" :content="$L('表情')">
<i class="taskfont">&#xe7ad;</i>
</ETooltip>
<ChatEmoji @on-select="onSelectEmoji"/>
</EPopover>
<ETooltip v-else ref="emojiTip" :disabled="!$isDesktop || showEmoji" placement="top" :content="$L('表情')">
<i class="taskfont" @click="showEmoji=!showEmoji">&#xe7ad;</i>
</ETooltip>
<ChatEmoji @on-select="onSelectEmoji"/>
</EPopover>
<ETooltip placement="top" :disabled="!$isDesktop" :content="$L('选择会员')">
<i class="taskfont" @click="onToolbar('user')">&#xe78f;</i>
</ETooltip>
<ETooltip placement="top" :disabled="!$isDesktop" :content="$L('选择任务')">
<i class="taskfont" @click="onToolbar('task')">&#xe7d6;</i>
</ETooltip>
<EPopover
v-model="showMore"
:visibleArrow="false"
placement="top"
popperClass="chat-input-more-popover">
<ETooltip slot="reference" ref="moreTip" :disabled="!$isDesktop || showMore" placement="top" :content="$L('展开')">
<i class="taskfont" @click="onToolbar('more')">&#xe790;</i>
<ETooltip placement="top" :disabled="!$isDesktop" :content="$L('选择会员')">
<i class="taskfont" @click="onToolbar('user')">&#xe78f;</i>
</ETooltip>
<div class="chat-input-popover-item" @click="onToolbar('image')">
<i class="taskfont">&#xe64a;</i>
{{$L('图片')}}
<ETooltip placement="top" :disabled="!$isDesktop" :content="$L('选择任务')">
<i class="taskfont" @click="onToolbar('task')">&#xe7d6;</i>
</ETooltip>
<EPopover
v-model="showMore"
:visibleArrow="false"
placement="top"
popperClass="chat-input-more-popover">
<ETooltip slot="reference" ref="moreTip" :disabled="!$isDesktop || showMore" placement="top" :content="$L('展开')">
<i class="taskfont">&#xe790;</i>
</ETooltip>
<div class="chat-input-popover-item" @click="onToolbar('image')">
<i class="taskfont">&#xe64a;</i>
{{$L('图片')}}
</div>
<div class="chat-input-popover-item" @click="onToolbar('file')">
<i class="taskfont">&#xe786;</i>
{{$L('文件')}}
</div>
</EPopover>
<div class="chat-send" :class="[value ? '' : 'disabled']" v-touchmouse="send">
<Loading v-if="loading"/>
<ETooltip v-else placement="top" :disabled="!$isDesktop" :content="$L('发送')">
<Icon type="md-send"/>
</ETooltip>
</div>
<div class="chat-input-popover-item" @click="onToolbar('file')">
<i class="taskfont">&#xe786;</i>
{{$L('文件')}}
</div>
</EPopover>
<div class="chat-send" :class="[value ? '' : 'disabled']" v-touchmouse="send">
<Loading v-if="loading"/>
<ETooltip v-else placement="top" :disabled="!$isDesktop" :content="$L('发送')">
<Icon type="md-send"/>
</ETooltip>
<slot name="toolbarAfter"/>
</div>
<slot name="toolbarAfter"/>
</div>
<template v-if="!$isDesktop">
<ChatEmoji v-if="showEmoji" @on-select="onSelectEmoji"/>
</template>
</div>
</template>
@ -109,6 +118,7 @@ export default {
data() {
return {
quill: null,
rangeIndex: 0,
_content: '',
_options: {},
@ -124,7 +134,6 @@ export default {
wrapperWidth: 0,
editorHeight: 0,
timerScroll: null,
isSpecVersion: this.checkIOSVersion(),
};
},
@ -144,7 +153,6 @@ export default {
this.observer.observe(this.$refs.editor);
},
beforeDestroy() {
this.inputCache(this.dialogId, this.value);
if (this.quill) {
this.quill = null
}
@ -171,15 +179,16 @@ export default {
},
watch: {
// Watch content change
value(newVal) {
value(val) {
if (this.quill) {
if (newVal && newVal !== this._content) {
this._content = newVal
this.setContent(newVal)
} else if(!newVal) {
if (val && val !== this._content) {
this._content = val
this.setContent(val)
} else if(!val) {
this.quill.setText('')
}
}
this.setInputCache(val)
},
// Watch disabled change
@ -190,11 +199,10 @@ export default {
},
// Reset lists
dialogId(id1, id2) {
dialogId() {
this.userList = null;
this.taskList = null;
this.inputCache(id2, this.value)
this.$emit('input', this.inputCache(id1))
this.$emit('input', this.getInputCache())
},
taskId() {
this.userList = null;
@ -202,19 +210,29 @@ export default {
},
showEmoji(val) {
if (val) {
this.showMore = false;
if (this.quill) {
const range = this.quill.selection.savedRange;
this.rangeIndex = range ? range.index : 0
}
}
if (!val && this.$refs.emojiTip) {
this.$refs.emojiTip.updatePopper()
}
},
showMore(val) {
if (val) {
this.showEmoji = false;
}
if (!val && this.$refs.moreTip) {
this.$refs.moreTip.updatePopper()
}
},
dialogInputCache() {
this.$emit('input', this.inputCache(this.dialogId))
this.$emit('input', this.getInputCache())
}
},
methods: {
@ -302,7 +320,7 @@ export default {
if (this.value) {
this.setContent(this.value)
} else {
this.$emit('input', this.inputCache(this.dialogId))
this.$emit('input', this.getInputCache())
}
// Disabled editor
@ -312,25 +330,17 @@ export default {
// Mark model as touched if editor lost focus
this.quill.on('selection-change', range => {
if (this.timerScroll) {
clearInterval(this.timerScroll);
}
if (!range) {
this.$emit('on-blur', this.quill)
this.inputCache(this.dialogId, this.value)
} else {
this.$emit('on-focus', this.quill)
this.showEmoji = false
this.showMore = false
this.hidePopover()
if (this.isSpecVersion) {
// ios11.0-11.3 scrollTopscrolIntoViewbug
//
} else {
setTimeout(() => {
$A.scrollToView(this.$refs.editor, true)
this.timerScroll = setInterval(() => {
$A.scrollToView(this.$refs.editor, true)
}, 300);
}, 300);
}
}
@ -378,11 +388,14 @@ export default {
}
},
inputCache(key, cache) {
if (cache === undefined) {
const item = this.dialogInputCache.find(item => item.key == key);
return item ? item.cache : '';
}
getInputCache() {
const key = this.dialogId;
const item = this.dialogInputCache.find(item => item.key == key);
return item ? item.cache : '';
},
setInputCache(cache) {
const key = this.dialogId;
const index = this.dialogInputCache.findIndex(item => item.key == key);
const data = {key, cache}
if (index > -1) {
@ -390,9 +403,10 @@ export default {
} else {
this.$store.state.dialogInputCache.push(data)
}
setTimeout(_ => {
this.__setInputCache && clearTimeout(this.__setInputCache);
this.__setInputCache = setTimeout(_ => {
$A.setStorage("cacheDialogInput", this.$store.state.dialogInputCache);
})
}, 600)
},
focus() {
@ -412,7 +426,11 @@ export default {
return;
}
this.$emit('on-send')
this.inputCache(this.dialogId, null)
},
hidePopover() {
this.showEmoji = false;
this.showMore = false;
},
onSelectEmoji(item) {
@ -422,21 +440,21 @@ export default {
if (item.type === 'emoji') {
let element = document.createElement('span');
element.innerHTML = item.html;
this.quill.insertText(this.quill.getSelection(true).index, element.innerHTML);
this.quill.insertText(this.rangeIndex, element.innerHTML);
this.rangeIndex += element.innerHTML.length
element = null;
if (this.$isDesktop) {
this.showEmoji = false;
this.quill.setSelection(this.rangeIndex)
}
} else if (item.type === 'emoticon') {
this.$emit('on-send', `<img class="emoticon" data-asset="${item.asset}" data-name="${item.name}" src="${item.src}"/>`)
this.showEmoji = false;
}
this.showEmoji = false;
},
onToolbar(action) {
if (action !== 'emoji') {
this.showEmoji = false;
}
if (action !== 'more') {
this.showMore = false;
}
this.hidePopover();
switch (action) {
case 'user':
this.openMenu("@");

View File

@ -400,6 +400,7 @@
<div class="no-tip">{{$L('暂无消息')}}</div>
<div class="no-input">
<ChatInput
ref="chatInput"
:task-id="taskId"
v-model="msgText"
:disabled="sendLoad > 0"
@ -408,7 +409,7 @@
:placeholder="$L('输入消息...')"
@on-more="onEventMore"
@on-file="onSelectFile"
@on-send="msgDialog">
@on-send="onSend">
<Badge slot="toolbarAfter" :count="taskDetail.msg_num"/>
</ChatInput>
</div>
@ -744,6 +745,7 @@ export default {
this.receiveShow = false;
this.$refs.owner && this.$refs.owner.handleClose();
this.$refs.assist && this.$refs.assist.handleClose();
this.$refs.chatInput && this.$refs.chatInput.hidePopover();
}
},
immediate: true
@ -1172,6 +1174,11 @@ export default {
this.msgDialog()
},
onSend() {
this.$refs.chatInput && this.$refs.chatInput.hidePopover();
this.msgDialog();
},
deleteFile(file) {
this.$set(file, '_show_menu', false);
this.$store.dispatch("forgetTaskFile", file.id)

View File

@ -410,18 +410,20 @@ body.dark-mode-reverse {
}
}
.chat-input-wrapper {
.ql-container {
.ql-editor {
color: #ccc;
&.ql-blank {
&::before {
.chat-input-box {
.chat-input-wrapper {
.ql-container {
.ql-editor {
color: #ccc;
&.ql-blank {
&::before {
color: #333;
}
}
.mention {
color: #333;
}
}
.mention {
color: #333;
}
}
}
}

View File

@ -1,314 +1,373 @@
@import "~quill/dist/quill.bubble.css";
@import "~quill-mention/dist/quill.mention.min.css";
.chat-input-wrapper {
display: inline-block;
.chat-input-box {
display: flex;
flex-direction: column;
width: 100%;
&.task-mention {
.chat-input-wrapper {
display: inline-block;
width: 100%;
&.task-mention {
.ql-container {
.ql-mention-list-container {
.ql-mention-list {
> li {
&:first-child {
margin-top: 0;
}
}
}
.ql-mention-list-item {
line-height: 36px;
.mention-item-disabled {
padding: 8px 4px 0;
}
}
}
}
}
.ql-container {
display: block;
float: left;
width: auto;
max-width: 100%;
min-width: calc(100% - 170px);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
.ql-editor {
font-size: 14px;
max-height: 200px;
padding: 0;
margin: 4px 7px;
img {
max-width: 150px;
max-height: 150px;
}
ol,
ul {
padding-left: 0;
li {
&:before {
color: #0088ff;
text-align: left;
margin-right: 0.2em;
}
}
}
ul {
li {
&:before {
font-weight: 900;
}
}
}
&.ql-blank {
&::before {
left: 7px;
right: 7px;
color: #ccc;
font-style: normal;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
}
.ql-mention-list-container {
width: auto;
min-width: 220px;
max-width: 350px;
max-height: 360px;
overflow-y: overlay;
&::-webkit-scrollbar {
width: 10px;
height: 10px;
}
&::-webkit-scrollbar-thumb {
border-radius: 10px;
background: rgba(0, 0, 0, 0);
}
&::-webkit-scrollbar-thumb:active {
border-radius: 10px;
background: rgba(0, 0, 0, .5);
}
&:hover::-webkit-scrollbar-thumb {
border: 2px solid transparent;
background: rgba(0, 0, 0, .2);
background-clip: content-box;
}
&:hover::-webkit-scrollbar-thumb:hover {
border-top-width: 0;
border-bottom-width: 0;
}
&::-webkit-scrollbar-track {
border-radius: 10px;
background: rgba(0, 0, 0, 0);
}
.ql-mention-list {
> li {
&:first-child {
margin-top: 0;
margin-top: 8px;
}
&:last-child {
margin-bottom: 8px;
}
}
}
.ql-mention-list-item {
line-height: 36px;
.mention-item-disabled {
padding: 8px 4px 0;
}
}
}
}
}
.ql-container {
display: block;
float: left;
width: auto;
max-width: 100%;
min-width: calc(100% - 170px);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
.ql-editor {
font-size: 14px;
max-height: 200px;
padding: 0;
margin: 4px 7px;
img {
max-width: 150px;
max-height: 150px;
}
ol,
ul {
padding-left: 0;
li {
&:before {
color: #0088ff;
text-align: left;
margin-right: 0.2em;
}
}
}
ul {
li {
&:before {
font-weight: 900;
}
}
}
&.ql-blank {
&::before {
left: 7px;
right: 7px;
color: #ccc;
font-style: normal;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
}
.ql-mention-list-container {
width: auto;
min-width: 220px;
max-width: 350px;
max-height: 360px;
overflow-y: overlay;
&::-webkit-scrollbar {
width: 10px;
height: 10px;
}
&::-webkit-scrollbar-thumb {
border-radius: 10px;
background: rgba(0, 0, 0, 0);
}
&::-webkit-scrollbar-thumb:active {
border-radius: 10px;
background: rgba(0, 0, 0, .5);
}
&:hover::-webkit-scrollbar-thumb {
border: 2px solid transparent;
background: rgba(0, 0, 0, .2);
background-clip: content-box;
}
&:hover::-webkit-scrollbar-thumb:hover {
border-top-width: 0;
border-bottom-width: 0;
}
&::-webkit-scrollbar-track {
border-radius: 10px;
background: rgba(0, 0, 0, 0);
}
.ql-mention-list {
> li {
&:first-child {
margin-top: 8px;
}
&:last-child {
margin-bottom: 8px;
}
}
}
.ql-mention-list-item {
padding: 0 8px;
display: flex;
align-items: center;
margin: 0 8px;
&.selected {
border-radius: 4px;
}
.mention-item-at {
width: 28px;
height: 28px;
line-height: 28px;
border-radius: 50%;
text-align: center;
color: #ffffff;
background-color: $primary-color;
overflow: hidden;
}
.mention-item-img {
position: relative;
padding: 0 8px;
display: flex;
align-items: center;
justify-content: center;
margin: 0 8px;
> img {
&.selected {
border-radius: 4px;
}
.mention-item-at {
width: 28px;
height: 28px;
line-height: 28px;
border-radius: 50%;
text-align: center;
color: #ffffff;
background-color: $primary-color;
overflow: hidden;
}
> em {
position: absolute;
right: 0;
bottom: 0;
width: 8px;
height: 8px;
border-radius: 50%;
background-color: #ff9900;
border: 1px solid #ffffff;
transform-origin: right bottom;
z-index: 1;
}
.mention-item-img {
position: relative;
display: flex;
align-items: center;
justify-content: center;
> img {
width: 28px;
height: 28px;
border-radius: 50%;
overflow: hidden;
}
&.online {
> em {
background-color: $primary-color;
position: absolute;
right: 0;
bottom: 0;
width: 8px;
height: 8px;
border-radius: 50%;
background-color: #ff9900;
border: 1px solid #ffffff;
transform-origin: right bottom;
z-index: 1;
}
&.online {
> em {
background-color: $primary-color;
}
}
}
}
.mention-item-name {
padding: 0 8px;
font-size: 14px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.mention-item-name {
padding: 0 8px;
font-size: 14px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.mention-item-tip {
color: #8f8f8e;
font-size: 12px;
font-style: normal;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.mention-item-tip {
color: #8f8f8e;
font-size: 12px;
font-style: normal;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.mention-item-disabled {
color: #aaa;
font-size: 12px;
padding: 0 4px;
line-height: 40px;
.mention-item-disabled {
color: #aaa;
font-size: 12px;
padding: 0 4px;
line-height: 40px;
}
}
}
}
}
.ql-bubble {
.ql-tooltip {
z-index: 1;
}
}
.chat-input-toolbar {
display: flex;
align-items: center;
justify-content: flex-end;
float: right;
width: 170px;
height: 28px;
padding: 0 2px;
> i {
display: inline-block;
cursor: pointer;
padding: 0 5px;
font-size: 20px;
line-height: 28px;
&.disabled {
opacity: 0.5;
.ql-bubble {
.ql-tooltip {
z-index: 1;
}
}
.chat-send {
.chat-input-toolbar {
display: flex;
align-items: center;
justify-content: flex-end;
cursor: pointer;
font-size: 20px;
padding-right: 16px;
margin: 0 -16px 0 7px;
height: 48px;
width: 48px;
position: relative;
.common-loading {
width: 18px;
height: 18px;
padding: 0;
margin: 0 1px;
}
float: right;
width: 170px;
height: 28px;
padding: 0 2px;
> i {
position: static;
z-index: 2;
display: flex;
align-items: center;
color: #ffffff;
display: inline-block;
cursor: pointer;
padding: 0 5px;
font-size: 20px;
line-height: 28px;
transition: all 0.3s;
&.disabled {
opacity: 0.5;
}
}
&:after {
position: absolute;
content: "";
left: 0;
z-index: 1;
width: 1px;
height: 14px;
background-color: #cccccc;
transition: all 0.3s ease;
transform: scale(0);
opacity: 0;
}
&:before {
position: absolute;
content: "";
left: 2px;
z-index: 1;
border-radius: 50%;
background-color: $primary-color;
.chat-send {
display: flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
transition: all 0.3s ease;
transform: scale(1);
opacity: 1;
}
&.disabled {
justify-content: flex-end;
cursor: pointer;
font-size: 20px;
padding-right: 16px;
margin: 0 -16px 0 7px;
height: 48px;
width: 48px;
position: relative;
.common-loading {
width: 18px;
height: 18px;
padding: 0;
margin: 0 1px;
}
> i {
color: rgba($primary-text-color, 0.5);
position: static;
z-index: 2;
display: flex;
align-items: center;
color: #ffffff;
line-height: 28px;
transition: all 0.3s;
}
&:after {
transform: scale(1);
opacity: 1;
}
&:before {
position: absolute;
content: "";
left: 0;
z-index: 1;
width: 1px;
height: 14px;
background-color: #cccccc;
transition: all 0.3s ease;
transform: scale(0);
opacity: 0;
}
&:before {
position: absolute;
content: "";
left: 2px;
z-index: 1;
border-radius: 50%;
background-color: $primary-color;
display: flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
transition: all 0.3s ease;
transform: scale(1);
opacity: 1;
}
&.disabled {
> i {
color: rgba($primary-text-color, 0.5);
}
&:after {
transform: scale(1);
opacity: 1;
}
&:before {
transform: scale(0);
opacity: 0;
}
}
}
.el-tooltip.taskfont {
display: inline-block;
cursor: pointer;
padding: 0 5px;
font-size: 20px;
line-height: 28px;
}
}
.el-tooltip.taskfont {
display: inline-block;
cursor: pointer;
padding: 0 5px;
font-size: 20px;
line-height: 28px;
}
.chat-emoji-wrapper {
.chat-emoji-box {
width: auto;
padding: 8px 2px;
display: flex;
justify-content: space-around;
flex-wrap: wrap;
&::after {
content: "";
flex: auto;
}
> li {
transition: none;
&:hover {
transform: none;
}
}
}
.chat-emoji-menu {
width: 100%;
padding: 3px 0;
border-radius: 8px;
box-sizing: content-box;
> li {
position: relative;
&:before {
display: none;
content: "";
position: absolute;
top: 50%;
left: 50%;
width: 36px;
height: 36px;
border-radius: 8px;
transform: translate(-50%, -50%);
background-color: #ffffff;
z-index: 1;
}
> span,
> img {
position: static;
z-index: 2;
}
&.active {
background-color: transparent;
&:before {
display: block;
}
}
}
}
}
}
.chat-input-emoji-popover {
padding: 0;
overflow: hidden;
@ -414,3 +473,47 @@
}
}
}
@media (max-width: 768px) {
.chat-input-box {
.chat-input-wrapper {
padding-left: 6px;
padding-right: 6px;
background-color: #ffffff;
}
.chat-emoji-wrapper {
margin-top: 8px;
margin-left: -10px;
margin-bottom: -8px;
width: calc(100% + 20px);
background-color: #ffffff;
.chat-emoji-box {
height: 246px;
> li {
width: 50px;
height: 50px;
line-height: 50px;
font-size: 28px;
}
&.emoticon > li {
width: 80px;
height: 80px;
padding: 8px;
}
}
.chat-emoji-menu {
border-radius: 0;
background-color: #f8f8f8;
padding: 4px;
width: calc(100% - 8px);
> li {
&.active {
&:before {
background-color: #e1e1e1;
}
}
}
}
}
}
}

View File

@ -687,12 +687,16 @@
display: flex;
align-items: center;
.chat-input-wrapper {
.chat-input-box {
flex: 1;
width: 0;
background-color: #F4F5F7;
padding: 10px 12px;
border-radius: 10px;
display: flex;
flex-direction: column;
.chat-input-wrapper {
background-color: #F4F5F7;
padding: 10px 12px;
border-radius: 10px;
}
}
}
@ -918,10 +922,12 @@
padding: 8px 10px;
margin-bottom: 0;
.dialog-input {
.chat-input-wrapper {
padding-left: 6px;
padding-right: 8px;
background-color: #ffffff;
.chat-input-box {
.chat-input-wrapper {
padding-left: 6px;
padding-right: 6px;
background-color: #ffffff;
}
}
}
}

View File

@ -570,15 +570,23 @@
align-items: center;
margin: 22px 0 0 36px;
background-color: #F4F5F7;
padding: 10px 12px;
padding: 10px 11px;
border-radius: 10px;
.chat-input-box {
.chat-input-wrapper {
padding: 0;
background-color: #F4F5F7;
}
}
.chat-input-toolbar {
position: relative;
.ivu-badge {
position: absolute;
transform: scale(0.6);
top: -6px;
right: 14px;
transform: scale(0.6) translateX(100%);
transform-origin: right center;
top: -8px;
right: 10px;
z-index: 1;
}
}
}