mirror of
https://github.com/ParisNeo/lollms-webui.git
synced 2025-01-31 08:25:24 +00:00
added long awaited controls
This commit is contained in:
parent
e2972250b3
commit
f3f241c759
@ -11,14 +11,29 @@
|
|||||||
</div>
|
</div>
|
||||||
<p class="drop-shadow-sm py-0 px-2 text-lg text-opacity-95 font-bold ">{{ message.sender }}</p>
|
<p class="drop-shadow-sm py-0 px-2 text-lg text-opacity-95 font-bold ">{{ message.sender }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="-mt-4 ml-10 mr-0 pt-1 px-2 max-w-screen-2xl ">
|
<div class="-mt-4 ml-10 mr-0 pt-1 px-2 ">
|
||||||
<!-- CONTENT/MESSAGE -->
|
<!-- CONTENT/MESSAGE -->
|
||||||
<markdown-renderer :markdown-text="message.content"></markdown-renderer>
|
<markdown-renderer v-if="!editMsgMode" :markdown-text="message.content"></markdown-renderer>
|
||||||
|
<textarea v-if="editMsgMode" rows="4"
|
||||||
|
class="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
||||||
|
placeholder="Enter message here..." v-model="new_message_content"></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div class="invisible group-hover:visible flex flex-row mt-3 -mb-2">
|
<div class="invisible group-hover:visible flex flex-row mt-3 -mb-2">
|
||||||
<!-- MESSAGE CONTROLS -->
|
<!-- MESSAGE CONTROLS -->
|
||||||
<div class="text-lg hover:text-secondary duration-75 active:scale-90 p-2" title="Edit message">
|
<!-- EDIT CONFIRMATION -->
|
||||||
|
<div v-if="editMsgMode" class="flex items-center duration-75">
|
||||||
|
<button class="text-2xl hover:text-red-600 duration-75 active:scale-90 p-2" title="Cancel edit" type="button"
|
||||||
|
@click.stop="editMsgMode = false">
|
||||||
|
<i data-feather="x"></i>
|
||||||
|
</button>
|
||||||
|
<button class="text-2xl hover:text-secondary duration-75 active:scale-90 p-2" title="Update message"
|
||||||
|
type="button" @click.stop="updateMessage">
|
||||||
|
<i data-feather="check"></i>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div v-if="!editMsgMode" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2" title="Edit message"
|
||||||
|
@click.stop="editMsgMode =true">
|
||||||
<i data-feather="edit"></i>
|
<i data-feather="edit"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-lg hover:text-secondary duration-75 active:scale-90 p-2" title="Copy message to clipboard"
|
<div class="text-lg hover:text-secondary duration-75 active:scale-90 p-2" title="Copy message to clipboard"
|
||||||
@ -28,14 +43,28 @@
|
|||||||
<div class="text-lg hover:text-secondary duration-75 active:scale-90 p-2" title="Resend message">
|
<div class="text-lg hover:text-secondary duration-75 active:scale-90 p-2" title="Resend message">
|
||||||
<i data-feather="refresh-cw"></i>
|
<i data-feather="refresh-cw"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-lg hover:text-red-600 duration-75 active:scale-90 p-2" title="Remove message">
|
<!-- DELETE CONFIRMATION -->
|
||||||
|
<div v-if="deleteMsgMode" class="flex items-center duration-75">
|
||||||
|
<button class="text-2xl hover:text-red-600 duration-75 active:scale-90 p-2" title="Cancel removal" type="button"
|
||||||
|
@click.stop="deleteMsgMode = false">
|
||||||
|
<i data-feather="x"></i>
|
||||||
|
</button>
|
||||||
|
<button class="text-2xl hover:text-secondary duration-75 active:scale-90 p-2" title="Confirm removal"
|
||||||
|
type="button" @click.stop="deleteMsg()">
|
||||||
|
<i data-feather="check"></i>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div v-if="!deleteMsgMode" class="text-lg hover:text-red-600 duration-75 active:scale-90 p-2"
|
||||||
|
title="Remove message" @click="deleteMsgMode = true">
|
||||||
<i data-feather="trash"></i>
|
<i data-feather="trash"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-lg hover:text-secondary duration-75 active:scale-90 p-2" title="Upvote">
|
<div class="text-lg hover:text-secondary duration-75 active:scale-90 p-2" title="Upvote" @click.stop="rankUp()">
|
||||||
<i data-feather="thumbs-up"></i>
|
<i data-feather="thumbs-up"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-row items-center">
|
<div class="flex flex-row items-center">
|
||||||
<div class="text-lg hover:text-red-600 duration-75 active:scale-90 p-2" title="Downvote">
|
<div class="text-lg hover:text-red-600 duration-75 active:scale-90 p-2" title="Downvote"
|
||||||
|
@click.stop="rankDown()">
|
||||||
<i data-feather="thumbs-down"></i>
|
<i data-feather="thumbs-down"></i>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="message.rank != 0" class="rounded-full px-2 text-sm flex items-center justify-center font-bold"
|
<div v-if="message.rank != 0" class="rounded-full px-2 text-sm flex items-center justify-center font-bold"
|
||||||
@ -54,7 +83,7 @@ import feather from 'feather-icons'
|
|||||||
import MarkdownRenderer from './MarkdownRenderer.vue';
|
import MarkdownRenderer from './MarkdownRenderer.vue';
|
||||||
export default {
|
export default {
|
||||||
name: 'Message',
|
name: 'Message',
|
||||||
emits: ['copy'],
|
emits: ['copy', 'delete', 'rankUp', 'rankDown','updateMessage'],
|
||||||
components: {
|
components: {
|
||||||
MarkdownRenderer
|
MarkdownRenderer
|
||||||
},
|
},
|
||||||
@ -64,10 +93,16 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
||||||
senderImg: ''
|
senderImg: '',
|
||||||
|
new_message_content: '',
|
||||||
|
showConfirmation: false,
|
||||||
|
editMsgMode: false,
|
||||||
|
deleteMsgMode: false,
|
||||||
|
|
||||||
}
|
}
|
||||||
}, mounted() {
|
}, mounted() {
|
||||||
this.senderImg = botImgPlaceholder
|
this.senderImg = botImgPlaceholder
|
||||||
|
this.new_message_content = this.message.content
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
feather.replace()
|
feather.replace()
|
||||||
|
|
||||||
@ -77,6 +112,22 @@ export default {
|
|||||||
this.$emit('copy', this.message.content)
|
this.$emit('copy', this.message.content)
|
||||||
navigator.clipboard.writeText(this.message.content);
|
navigator.clipboard.writeText(this.message.content);
|
||||||
},
|
},
|
||||||
|
deleteMsg() {
|
||||||
|
this.$emit('delete', this.message.id)
|
||||||
|
this.deleteMsgMode = false
|
||||||
|
},
|
||||||
|
rankUp() {
|
||||||
|
this.$emit('rankUp', this.message.id)
|
||||||
|
|
||||||
|
},
|
||||||
|
rankDown() {
|
||||||
|
this.$emit('rankDown', this.message.id)
|
||||||
|
|
||||||
|
},
|
||||||
|
updateMessage() {
|
||||||
|
this.$emit('updateMessage', this.message.id, this.new_message_content)
|
||||||
|
this.editMsgMode = false
|
||||||
|
},
|
||||||
getImgUrl() {
|
getImgUrl() {
|
||||||
|
|
||||||
if (this.message.sender == "user") {
|
if (this.message.sender == "user") {
|
||||||
@ -87,7 +138,38 @@ export default {
|
|||||||
return botImgPlaceholder;
|
return botImgPlaceholder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}, watch: {
|
||||||
|
showConfirmation() {
|
||||||
|
nextTick(() => {
|
||||||
|
feather.replace()
|
||||||
|
|
||||||
|
})
|
||||||
|
},
|
||||||
|
content(val) {
|
||||||
|
this.new_message_content = this.message.content
|
||||||
|
|
||||||
|
},
|
||||||
|
editMsgMode(val){
|
||||||
|
if(!val){
|
||||||
|
this.new_message_content = this.message.content
|
||||||
|
}
|
||||||
|
nextTick(() => {
|
||||||
|
feather.replace()
|
||||||
|
|
||||||
|
})
|
||||||
|
},
|
||||||
|
deleteMsgMode(){
|
||||||
|
nextTick(() => {
|
||||||
|
feather.replace()
|
||||||
|
|
||||||
|
})
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
content() {
|
||||||
|
return this.message.content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
@ -109,8 +109,10 @@
|
|||||||
|
|
||||||
<!-- CHAT AREA -->
|
<!-- CHAT AREA -->
|
||||||
<div class="flex flex-col flex-grow">
|
<div class="flex flex-col flex-grow">
|
||||||
|
<!-- REMOVED @click="scrollToElement($event.target)" -->
|
||||||
<Message v-for="(msg, index) in discussionArr" :key="index" :message="msg"
|
<Message v-for="(msg, index) in discussionArr" :key="index" :message="msg"
|
||||||
@click="scrollToElement($event.target)" :id="'msg-' + msg.id" ref="messages" @copy="copyToClipBoard" />
|
:id="'msg-' + msg.id" ref="messages" @copy="copyToClipBoard"
|
||||||
|
@delete="deleteMessage" @rankUp="rankUpMessage" @rankDown="rankDownMessage" @updateMessage="updateMessage"/>
|
||||||
|
|
||||||
<WelcomeComponent v-if="!currentDiscussion.id" />
|
<WelcomeComponent v-if="!currentDiscussion.id" />
|
||||||
|
|
||||||
@ -256,6 +258,18 @@ export default {
|
|||||||
this.setDiscussionLoading(id, this.loading)
|
this.setDiscussionLoading(id, this.loading)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async delete_message(id) {
|
||||||
|
try {
|
||||||
|
const res = await axios.get('/delete_message', { params: { id: id } })
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
return res.data
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Error: Could delete message", error)
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
async stop_gen() {
|
async stop_gen() {
|
||||||
try {
|
try {
|
||||||
const res = await axios.get('/stop_gen')
|
const res = await axios.get('/stop_gen')
|
||||||
@ -268,6 +282,42 @@ export default {
|
|||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async message_rank_up(id) {
|
||||||
|
try {
|
||||||
|
const res = await axios.get('/message_rank_up', { params: { id: id } })
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
return res.data
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Error: Could not rank up message", error)
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async message_rank_down(id) {
|
||||||
|
try {
|
||||||
|
const res = await axios.get('/message_rank_down', { params: { id: id } })
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
return res.data
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Error: Could not rank down message", error)
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async update_message(id, message) {
|
||||||
|
try {
|
||||||
|
const res = await axios.get('/update_message', { params: { id: id, message:message } })
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
return res.data
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Error: Could not update message", error)
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
filterDiscussions() {
|
filterDiscussions() {
|
||||||
// Search bar in for filtering discussions by title (serch)
|
// Search bar in for filtering discussions by title (serch)
|
||||||
|
|
||||||
@ -422,7 +472,7 @@ export default {
|
|||||||
this.tempList = this.list
|
this.tempList = this.list
|
||||||
await this.edit_title(id, msg)
|
await this.edit_title(id, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
async createNewDiscussion() {
|
async createNewDiscussion() {
|
||||||
// Creates new discussion on backend,
|
// Creates new discussion on backend,
|
||||||
@ -489,6 +539,18 @@ export default {
|
|||||||
this.isCheckbox = false
|
this.isCheckbox = false
|
||||||
console.log("Multi delete done")
|
console.log("Multi delete done")
|
||||||
},
|
},
|
||||||
|
async deleteMessage(msgId) {
|
||||||
|
|
||||||
|
await this.delete_message(msgId).then(() => {
|
||||||
|
|
||||||
|
this.discussionArr.splice(this.discussionArr.findIndex(item => item.id == msgId), 1)
|
||||||
|
|
||||||
|
}).catch(() => {
|
||||||
|
|
||||||
|
console.log("Error: Could not delete message")
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
async editTitle(newTitleObj) {
|
async editTitle(newTitleObj) {
|
||||||
|
|
||||||
const index = this.list.findIndex((x) => x.id == newTitleObj.id)
|
const index = this.list.findIndex((x) => x.id == newTitleObj.id)
|
||||||
@ -557,6 +619,40 @@ export default {
|
|||||||
document.title = 'GPT4ALL - WEBUI - ' + title
|
document.title = 'GPT4ALL - WEBUI - ' + title
|
||||||
}
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
async rankUpMessage(msgId) {
|
||||||
|
await this.message_rank_up(msgId).then((res) => {
|
||||||
|
|
||||||
|
const message = this.discussionArr[this.discussionArr.findIndex(item => item.id == msgId)]
|
||||||
|
message.rank= res.new_rank
|
||||||
|
}).catch(() => {
|
||||||
|
|
||||||
|
console.log("Error: Could not rank up message")
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
async rankDownMessage(msgId) {
|
||||||
|
await this.message_rank_down(msgId).then((res) => {
|
||||||
|
|
||||||
|
const message = this.discussionArr[this.discussionArr.findIndex(item => item.id == msgId)]
|
||||||
|
message.rank= res.new_rank
|
||||||
|
}).catch(() => {
|
||||||
|
|
||||||
|
console.log("Error: Could not rank down message")
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
async updateMessage(msgId, msg) {
|
||||||
|
await this.update_message(msgId, msg).then(() => {
|
||||||
|
|
||||||
|
const message = this.discussionArr[this.discussionArr.findIndex(item => item.id == msgId)]
|
||||||
|
message.content= msg
|
||||||
|
|
||||||
|
}).catch(() => {
|
||||||
|
|
||||||
|
console.log("Error: Could not update message")
|
||||||
|
})
|
||||||
|
|
||||||
},
|
},
|
||||||
stopGenerating() {
|
stopGenerating() {
|
||||||
this.stop_gen()
|
this.stop_gen()
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- SAVE AND RESET -->
|
<!-- SAVE AND RESET -->
|
||||||
<div v-if="!showConfirmation" class="flex gap-3 flex-1 items-center ">
|
<div v-if="!showConfirmation" class="flex gap-3 flex-1 items-center ">
|
||||||
|
|
||||||
|
|
||||||
<button title="Save configuration" class="text-2xl hover:text-secondary duration-75 active:scale-90"
|
<button title="Save configuration" class="text-2xl hover:text-secondary duration-75 active:scale-90"
|
||||||
@click="showConfirmation=true">
|
@click="showConfirmation=true">
|
||||||
<i data-feather="save"></i>
|
<i data-feather="save"></i>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user