Merge pull request #301 from ParisNeo/main

sync
This commit is contained in:
Saifeddine ALOUI 2023-06-17 23:53:52 +02:00 committed by GitHub
commit 12e21c62dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 533 additions and 279 deletions

View File

@ -591,7 +591,9 @@ class LoLLMsAPPI():
message = data["prompt"]
message_id = self.current_discussion.add_message(
"user", message, parent=self.message_id
"user",
message,
parent=self.message_id
)
self.current_user_message_id = message_id
@ -839,8 +841,9 @@ class LoLLMsAPPI():
self.personality.name,
"",
parent = self.current_user_message_id,
binding = self.config["binding_name"],
model = self.config["model_name"],
personality=self.config["personalities"][self.config["active_personality_id"]]
personality = self.config["personalities"][self.config["active_personality_id"]]
) # first the content is empty, but we'll fill it at the end
self.socketio.emit('infos',
{
@ -851,6 +854,7 @@ class LoLLMsAPPI():
"message":message,#markdown.markdown(message),
"user_message_id": self.current_user_message_id,
"ai_message_id": self.current_ai_message_id,
}, room=self.current_room_id
)
@ -876,7 +880,16 @@ class LoLLMsAPPI():
self.socketio.emit('final', {
'data': self.bot_says,
'ai_message_id':self.current_ai_message_id,
'parent':self.current_user_message_id, 'discussion_id':self.current_discussion.discussion_id
'parent':self.current_user_message_id, 'discussion_id':self.current_discussion.discussion_id,
"status":'model_not_ready',
"type": "input_message_infos",
'logo': "",
"bot": self.personality.name,
"user": self.personality.user_name,
"message":self.bot_says,
"user_message_id": self.current_user_message_id,
"ai_message_id": self.current_ai_message_id,
}, room=self.current_room_id
)

View File

@ -51,8 +51,8 @@ class DiscussionsDB:
type INT NOT NULL,
rank INT NOT NULL,
parent INT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
finished_generating_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
created_at TIMESTAMP,
finished_generating_at TIMESTAMP,
discussion_id INTEGER NOT NULL,
FOREIGN KEY (discussion_id) REFERENCES discussion(id),
FOREIGN KEY (parent) REFERENCES message(id)
@ -364,9 +364,18 @@ class Discussion:
message_id (int): The id of the message to be changed
new_content (str): The nex message content
"""
current_date_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
# print(f"{current_date_time}")
self.discussions_db.update(
f"UPDATE message SET content = ?, finished_generating_at = ? WHERE id = ?",(new_content, datetime.now().strftime('%Y-%m-%d %H:%M:%S'),message_id)
f"UPDATE message SET content = ?, finished_generating_at = ? WHERE id = ?",(new_content, current_date_time,message_id)
)
"""
stuff = self.discussions_db.select(
f"Select finished_generating_at from message WHERE id = ?",(message_id,)
)
print(stuff)
"""
def message_rank_up(self, message_id):
"""Increments the rank of the message

3
app.py
View File

@ -864,9 +864,7 @@ class LoLLMsWebUI(LoLLMsAPPI):
return "title renamed successfully"
def load_discussion(self):
print("- Loading discussion")
data = request.get_json()
print(" Recovered json data")
if "id" in data:
discussion_id = data["id"]
self.current_discussion = Discussion(discussion_id, self.db)
@ -876,7 +874,6 @@ class LoLLMsWebUI(LoLLMsAPPI):
self.current_discussion = Discussion(discussion_id, self.db)
else:
self.current_discussion = self.db.create_discussion()
print(f" Discussion id :{discussion_id}")
messages = self.current_discussion.get_messages()

1
web/dist/assets/index-1760585e.css vendored Normal file

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

BIN
web/dist/assets/logo-023c77a1.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 459 KiB

BIN
web/dist/favicon.ico vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 KiB

After

Width:  |  Height:  |  Size: 66 KiB

6
web/dist/index.html vendored
View File

@ -5,9 +5,9 @@
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GPT4All - WEBUI</title>
<script type="module" crossorigin src="/assets/index-76dfba09.js"></script>
<link rel="stylesheet" href="/assets/index-f4e7668c.css">
<title>LoLLMS WebUI - Welcome</title>
<script type="module" crossorigin src="/assets/index-47b6b817.js"></script>
<link rel="stylesheet" href="/assets/index-1760585e.css">
</head>
<body>
<div id="app"></div>

View File

@ -5,7 +5,7 @@
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GPT4All - WEBUI</title>
<title>LoLLMS WebUI - Welcome</title>
</head>
<body>
<div id="app"></div>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 KiB

After

Width:  |  Height:  |  Size: 66 KiB

BIN
web/src/assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 459 KiB

View File

@ -1,5 +1,5 @@
<template>
<div class=" items-start p-4 hover:bg-primary-light rounded-lg mb-2 shadow-lg border-2 cursor-pointer active:scale-95 duration-75 select-none"
<div class=" items-start p-4 hover:bg-primary-light rounded-lg mb-2 shadow-lg border-2 cursor-pointer select-none"
@click.stop="toggleSelected" :class="selected ? ' border-primary-light' : 'border-transparent'">
<div :class="isTemplate ? 'opacity-50' : ''">
@ -15,13 +15,24 @@
<div class="grow">
<!-- EMPTY SPACE FILLER -->
</div>
<!-- ADVANCED OPTIONS - NOT IMPLEMENTED -->
<div v-if="hasAdvancedSettings" class="flex-none">
<button type="button" title="Not implemented"
class="hover:text-secondary duration-75 active:scale-90 font-medium rounded-lg text-sm p-2 text-center inline-flex items-center " @click.stop="">
<i data-feather="sliders" class="w-5 m-1"></i>
<span class="sr-only">Icon description</span>
<!-- ADVANCED OPTIONS -->
<div class="flex-none gap-1">
<button type="button" title="Reinstall binding"
class="hover:text-secondary duration-75 active:scale-90 font-medium rounded-lg text-sm p-2 text-center inline-flex items-center " @click.stop="toggleReinstall">
<i data-feather="tool" class="w-5"></i>
<span class="sr-only">Reinstall binding</span>
</button>
<!-- - NOT IMPLEMENTED -->
<!-- <button type="button" title="Settings - Not implemented"
class="hover:text-secondary duration-75 active:scale-90 font-medium rounded-lg text-sm p-2 text-center inline-flex items-center " @click.stop="">
<i data-feather="sliders" class="w-5"></i>
<span class="sr-only">Settings</span>
</button>
<button type="button" title="Help - Not implemented"
class="hover:text-secondary duration-75 active:scale-90 font-medium rounded-lg text-sm p-2 text-center inline-flex items-center " @click.stop="">
<i data-feather="help-circle" class="w-5"></i>
<span class="sr-only">Help</span>
</button> -->
</div>
</div>
@ -49,12 +60,15 @@
<b>Version:&nbsp;</b>
{{ binding.version }}
</div>
<a :href="binding.link" target="_blank" class="flex items-center">
<div class="flex items-center">
<i data-feather="github" class="w-5 m-1"></i>
<b>Link:&nbsp;</b>
<a :href="binding.link" target="_blank" class="flex items-center hover:text-secondary duration-75 active:scale-90">
{{ binding.link }}
</a>
</div>
</div>
<div class="flex items-center">
<i data-feather="info" class="w-5 m-1"></i>
<b>Description:&nbsp;</b><br>
@ -77,13 +91,14 @@ export default {
props: {
binding: {},
onSelected: Function,
onReinstall: Function,
selected: Boolean,
},
data() {
return {
isTemplate: false,
hasAdvancedSettings: false,
};
},
mounted() {
@ -107,6 +122,9 @@ export default {
toggleSelected() {
this.onSelected(this)
},
toggleReinstall() {
this.onReinstall(this)
},
getStatus() {
if (this.binding.folder === 'backend_template' || this.binding.folder === 'binding_template') {
this.isTemplate = true

View File

@ -1,5 +1,5 @@
<template>
<div class="absolute bottom-0 w-96 justify-center text-center p-4 ">
<div class="absolute bottom-0 min-w-96 w-full justify-center text-center p-4 ">
<div v-if="loading" class="flex items-center justify-center w-full">
<div class="flex flex-row p-2 rounded-t-lg ">
@ -89,13 +89,17 @@
<!-- CHAT BOX -->
<div class="flex flex-row flex-grow items-center gap-2 ">
<!-- <div class="w-24">
<MountedPersonalitiesComponent />
<MountedPersonalities />
</div> -->
<div class="relative grow">
<textarea id="chat" rows="1" v-model="message"
class="block min-h-11 no-scrollbar p-2.5 w-full text-sm text-gray-900 bg-bg-light rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-bg-dark dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
<textarea id="chat" rows="1" v-model="message" title="Hold SHIFT + ENTER to add new line"
class="inline-block no-scrollbar p-2.5 w-full text-sm text-gray-900 bg-bg-light rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-bg-dark dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
placeholder="Send message..." @keydown.enter.exact="submitOnEnter($event)">
</textarea>
<input type="file" ref="fileDialog" style="display: none" @change="addFiles" multiple />
<button type="button" @click.stop="$refs.fileDialog.click()" title="Add files"
@ -162,15 +166,15 @@
position: absolute;
}
</style>
<script setup>
<!-- <script setup>
import MountedPersonalitiesComponent from './MountedPersonalitiesComponent.vue'
</script>
</script> -->
<script>
import { nextTick, TransitionGroup } from 'vue'
import feather from 'feather-icons'
import filesize from '../plugins/filesize'
import MountedPersonalities from './MountedPersonalities.vue'
export default {
name: 'ChatBox',
emits: ["messageSentEvent", "stopGenerating"],
@ -180,10 +184,12 @@ export default {
},
components: {
MountedPersonalitiesComponent
MountedPersonalities
},
setup() {
return {}
},
data() {
return {
@ -252,17 +258,15 @@ export default {
}
}
this.totalSize = filesize(total, false)
this.totalSize = filesize(total, true)
},
deep: true
},
},
computed: {
},
mounted() {
nextTick(() => {
feather.replace()
})

View File

@ -19,7 +19,8 @@
</p> -->
</div>
<div class="text-sm text-gray-400 font-thin" v-if="message.created_at" :title="message.created_at">
<div class="text-sm text-gray-400 font-thin" v-if="message.created_at"
:title="'Created at: ' + created_at_parsed">
{{ created_at }}
</div>
@ -105,6 +106,8 @@
<p v-if="message.binding">Binding: <span class="font-thin">{{ message.binding }}</span></p>
<p v-if="message.model">Model: <span class="font-thin">{{ message.model }}</span></p>
<p v-if="message.seed">Seed: <span class="font-thin">{{ message.seed }}</span></p>
<p v-if="time_spent">Time spent: <span class="font-thin"
:title="'Finished generating: ' + finished_generating_at_parsed">{{ time_spent }}</span></p>
</div>
</div>
@ -174,7 +177,7 @@ export default {
this.expanded = !this.expanded;
},
copyContentToClipboard() {
this.$emit('copy', this.message.content)
this.$emit('copy', this)
},
deleteMsg() {
@ -307,6 +310,65 @@ export default {
created_at() {
return this.prettyDate(this.message.created_at)
},
created_at_parsed() {
return new Date(Date.parse(this.message.created_at)).toLocaleString()
},
finished_generating_at_parsed() {
return new Date(Date.parse(this.message.finished_generating_at)).toLocaleString()
},
time_spent() {
const startTime = new Date(Date.parse(this.message.created_at))
const endTime = new Date(Date.parse(this.message.finished_generating_at))
//const spentTime = new Date(endTime - startTime)
const same = endTime.getTime() === startTime.getTime();
if(same){
return undefined
}
if(!endTime.getTime()){
return undefined
}
let timeDiff = endTime.getTime() - startTime.getTime();
const hours = Math.floor(timeDiff / (1000 * 60 * 60));
timeDiff -= hours * (1000 * 60 * 60);
const mins = Math.floor(timeDiff / (1000 * 60));
timeDiff -= mins * (1000 * 60);
const secs = Math.floor(timeDiff / 1000)
timeDiff -= secs * 1000;
// let spentTime = Math.floor((endTime.getTime() - startTime.getTime()) / 1000);
// const result = spentTime.getSeconds();
function addZero(i) {
if (i < 10) { i = "0" + i }
return i;
}
// const d = new Date();
// let h = addZero(spentTime.getHours());
// let m = addZero(spentTime.getMinutes());
// let s = addZero(spentTime.getSeconds());
const time = addZero(hours) + "h:" + addZero(mins) + "m:" + addZero(secs) + 's';
return time
}
}

View File

@ -1,42 +1,40 @@
<template>
<!-- LIST OF MOUNTED PERSONALITIES -->
<div
class=" text-base font-semibold cursor-pointer select-none items-center flex flex-row overflow-visible overflow-x-auto scrollbar-thin scrollbar-track-bg-light scrollbar-thumb-bg-light-tone hover:scrollbar-thumb-primary dark:scrollbar-track-bg-dark dark:scrollbar-thumb-bg-dark-tone dark:hover:scrollbar-thumb-primary active:scrollbar-thumb-secondary">
<!-- LIST -->
<div class="flex -space-x-4 items-center ">
<!-- ITEM -->
<div class="relative hover:-translate-y-2 duration-300 hover:z-10 shrink-0 "
v-for="(item, index) in mountedPersArr" :key="index + '-' + item.name" >
<div class="group items-center flex flex-row">
<button @click.stop="onPersonalitySelected(item)">
<!-- LIST OF MOUNTED PERSONALITIES -->
<div
class=" text-base font-semibold cursor-pointer select-none items-center flex flex-row overflow-visible overflow-x-auto scrollbar-thin scrollbar-track-bg-light scrollbar-thumb-bg-light-tone hover:scrollbar-thumb-primary dark:scrollbar-track-bg-dark dark:scrollbar-thumb-bg-dark-tone dark:hover:scrollbar-thumb-primary active:scrollbar-thumb-secondary">
<!-- LIST -->
<div class="flex -space-x-4 items-center ">
<!-- ITEM -->
<div class="relative hover:-translate-y-2 duration-300 hover:z-10 shrink-0 "
v-for="(item, index) in mountedPersArr" :key="index + '-' + item.name">
<div class="group items-center flex flex-row">
<button @click.stop="onPersonalitySelected(item)">
<img :src="bUrl + item.avatar" @error="personalityImgPlacehodler"
class="w-8 h-8 rounded-full object-fill text-red-700 border-2 active:scale-90 group-hover:border-secondary "
:class="configFile.active_personality_id == configFile.personalities.indexOf(item.full_path) ? 'border-secondary' : 'border-transparent z-0'"
:title="item.name">
</button>
<button @click.stop="onPersonalityMounted(item)">
<img :src="bUrl + item.avatar" @error="personalityImgPlacehodler"
class="w-8 h-8 rounded-full object-fill text-red-700 border-2 active:scale-90 group-hover:border-secondary "
:class="configFile.active_personality_id == configFile.personalities.indexOf(item.full_path) ? 'border-secondary' : 'border-transparent z-0'"
:title="item.name">
</button>
<button @click.stop="onPersonalityMounted(item)">
<span
class="hidden group-hover:block top-0 left-7 absolute active:scale-90 bg-bg-light dark:bg-bg-dark rounded-full border-2 border-transparent"
title="Unmount personality">
<!-- UNMOUNT BUTTON -->
<svg aria-hidden="true" class="w-4 h-4 text-red-600 hover:text-red-500 " fill="currentColor"
viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
clip-rule="evenodd"></path>
</svg>
<span
class="hidden group-hover:block top-0 left-7 absolute active:scale-90 bg-bg-light dark:bg-bg-dark rounded-full border-2 border-transparent"
title="Unmount personality">
<!-- UNMOUNT BUTTON -->
<svg aria-hidden="true" class="w-4 h-4 text-red-600 hover:text-red-500 " fill="currentColor"
viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
clip-rule="evenodd"></path>
</svg>
</span>
</button>
</div>
</span>
</button>
</div>
</div>
</div>
</div>
</template>
<script>
@ -46,40 +44,40 @@ import defaultPersonalityImgPlaceholder from "../assets/logo.svg"
const bUrl = import.meta.env.VITE_GPT4ALL_API_BASEURL
axios.defaults.baseURL = import.meta.env.VITE_GPT4ALL_API_BASEURL
export default {
name: 'MountedPersonalitiesComponent',
name: 'MountedPersonalities',
setup() {
return {
configFile: {},
mountedPersArr:[],
personalities:[],
bUrl:bUrl,
isMounted:false
mountedPersArr: [],
personalities: [],
bUrl: bUrl,
isMounted: false
}
},
async mounted(){
async mounted() {
await this.constructor()
this.isMounted=true
this.isMounted = true
},
async activated(){
if(this.isMounted){
async activated() {
if (this.isMounted) {
await this.constructor()
}
},
methods:{
async constructor(){
this.configFile = await this.api_get_req("get_config")
let personality_path_infos = await this.api_get_req("get_current_personality_path_infos")
this.configFile.personality_language = personality_path_infos["personality_language"]
this.configFile.personality_category = personality_path_infos["personality_category"]
this.configFile.personality_folder = personality_path_infos["personality_name"]
await this.getPersonalitiesArr().then(()=>{
this.getMountedPersonalities()
this.$forceUpdate()
})
},
methods: {
async constructor() {
this.configFile = await this.api_get_req("get_config")
let personality_path_infos = await this.api_get_req("get_current_personality_path_infos")
this.configFile.personality_language = personality_path_infos["personality_language"]
this.configFile.personality_category = personality_path_infos["personality_category"]
this.configFile.personality_folder = personality_path_infos["personality_name"]
await this.getPersonalitiesArr().then(() => {
this.getMountedPersonalities()
this.$forceUpdate()
})
},
async api_get_req(endpoint) {
try {
@ -169,15 +167,15 @@ export default {
}
this.isLoading=true
this.isLoading = true
},
async onPersonalitySelected(pers) {
// eslint-disable-next-line no-unused-vars
if (this.isLoading) {
this.$refs.toast.showToast("Loading... please wait", 4, false)
}
this.isLoading=true
console.log('ppa',pers)
this.isLoading = true
console.log('ppa', pers)
if (pers) {
if (pers.selected) {
@ -204,10 +202,10 @@ export default {
nextTick(() => {
})
this.isLoading=false
this.isLoading = false
}
},
@ -290,7 +288,7 @@ export default {
},
async mountPersonality(pers) {
this.isLoading=true
this.isLoading = true
console.log('mount pers', pers)
if (!pers) { return }
@ -317,11 +315,11 @@ export default {
pers.isMounted = false
this.$refs.toast.showToast("Could not mount personality\nError: " + res.error, 4, false)
}
this.isLoading=false
this.isLoading = false
},
async unmountPersonality(pers) {
this.isLoading=true
this.isLoading = true
if (!pers) { return }
const res = await this.unmount_personality(pers.personality || pers)
@ -366,7 +364,7 @@ export default {
this.$refs.toast.showToast("Could not unmount personality\nError: " + res.error, 4, false)
}
this.isLoading=false
this.isLoading = false
},
getMountedPersonalities() {
@ -381,7 +379,7 @@ export default {
if (pers) {
mountedPersArr.push(pers)
}
else{
else {
mountedPersArr.push(this.personalities[this.personalities.findIndex(item => item.full_path == "english/generic/lollms")])
}
}

View File

@ -4,28 +4,33 @@
<ul class="flex flex-col font-medium p-4 md:p-0 mt-4 md:flex-row md:space-x-8 md:mt-0 ">
<li>
<RouterLink :to="{ name: 'discussions' }" class="p-2" active-class="p-2 bg-bg-light-tone dark:bg-bg-dark-tone rounded-t-lg ">
<RouterLink :to="{ name: 'discussions' }" class="p-2"
active-class="p-2 bg-bg-light-tone dark:bg-bg-dark-tone rounded-t-lg ">
<a href="#" class=" hover:text-primary duration-150">Discussions</a>
</RouterLink>
</li>
<li>
<RouterLink :to="{ name: 'settings' }" class="p-2" active-class="p-2 bg-bg-light-tone dark:bg-bg-dark-tone rounded-t-lg ">
<RouterLink :to="{ name: 'settings' }" class="p-2"
active-class="p-2 bg-bg-light-tone dark:bg-bg-dark-tone rounded-t-lg ">
<a href="#" class=" hover:text-primary duration-150">Settings</a>
</RouterLink>
</li>
<li>
<RouterLink :to="{ name: 'extensions' }" class="p-2" active-class="p-2 bg-bg-light-tone dark:bg-bg-dark-tone rounded-t-lg ">
<RouterLink :to="{ name: 'extensions' }" class="p-2"
active-class="p-2 bg-bg-light-tone dark:bg-bg-dark-tone rounded-t-lg ">
<a href="#" class=" hover:text-primary duration-150">Extensions</a>
</RouterLink>
</li>
<li>
<RouterLink :to="{ name: 'training' }" class="p-2" active-class="p-2 bg-bg-light-tone dark:bg-bg-dark-tone rounded-t-lg ">
<RouterLink :to="{ name: 'training' }" class="p-2"
active-class="p-2 bg-bg-light-tone dark:bg-bg-dark-tone rounded-t-lg ">
<a href="#" class=" hover:text-primary duration-150">Training</a>
</RouterLink>
</li>
<li>
<RouterLink :to="{ name: 'help' }" class="p-2" active-class="p-2 bg-bg-light-tone dark:bg-bg-dark-tone rounded-t-lg ">
<RouterLink :to="{ name: 'help' }" class="p-2"
active-class="p-2 bg-bg-light-tone dark:bg-bg-dark-tone rounded-t-lg ">
<a href="#" class=" hover:text-primary duration-150">Help</a>
</RouterLink>
</li>
@ -35,7 +40,25 @@
</template>
<script setup>
import {nextTick} from 'vue'
import { nextTick } from 'vue'
import feather from 'feather-icons'
import { RouterLink } from 'vue-router'
</script>
<script>
export default {
data() {
return {
};
},
activated() {
},
methods: {
},
};
</script>

View File

@ -2,9 +2,9 @@
<div class="absolute bottom-16 right-2 z-20 flex flex-col gap-3 min-w-[300px]">
<TransitionGroup name="toastItem" tag="div">
<div v-for=" t in toastArr" :key="t.id" class="relative">
<div class="flex items-center w-full max-w-xs p-4 mb-4 text-gray-500 bg-white rounded-lg shadow dark:text-gray-400 dark:bg-gray-800"
<div class="flex flex-row items-center w-full max-w-xs p-4 mb-4 text-gray-500 bg-white rounded-lg shadow dark:text-gray-400 dark:bg-gray-800"
role="alert">
<div class="flex flex-row items-center">
<div class="flex flex-row flex-grow items-center">
<slot>
<div v-if="t.success"
@ -17,30 +17,31 @@
<i data-feather="x"></i>
<span class="sr-only">Cross icon</span>
</div>
<div class="ml-3 text-sm font-normal whitespace-pre-wrap">{{ t.message }}</div>
<div class="ml-3 text-sm font-normal whitespace-pre-wrap line-clamp-3" :title="t.message">{{ t.message }}</div>
</slot>
</div>
<div class="absolute top-2 right-2">
<div class="flex ">
<button type="button" @click.stop="t.copy(t.message)"
class=" bg-white text-gray-400 hover:text-gray-900 rounded-lg focus:ring-2 focus:ring-gray-300 p-1.5 hover:bg-gray-100 inline-flex h-8 w-8 dark:text-gray-500 dark:hover:text-white dark:bg-gray-800 dark:hover:bg-gray-700">
<span class="sr-only">Copy message</span>
<i data-feather="clipboard" class="w-5 h-5"></i>
</button>
<button type="button" @click="close(t.id)"
class=" bg-white text-gray-400 hover:text-gray-900 rounded-lg focus:ring-2 focus:ring-gray-300 p-1.5 hover:bg-gray-100 inline-flex h-8 w-8 dark:text-gray-500 dark:hover:text-white dark:bg-gray-800 dark:hover:bg-gray-700">
<span class="sr-only">Close</span>
<svg aria-hidden="true" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
clip-rule="evenodd"></path>
</svg>
</button>
</div>
<button type="button" @click.stop="copyToClipBoard(t.message)" title="Copy message"
class=" bg-white text-gray-400 hover:text-gray-900 rounded-lg focus:ring-2 focus:ring-gray-300 p-1.5 hover:bg-gray-100 inline-flex h-8 w-8 dark:text-gray-500 dark:hover:text-white dark:bg-gray-800 dark:hover:bg-gray-700">
<span class="sr-only">Copy message</span>
<i data-feather="clipboard" class="w-5 h-5"></i>
</button>
<button type="button" @click="close(t.id)" title="Close"
class=" bg-white text-gray-400 hover:text-gray-900 rounded-lg focus:ring-2 focus:ring-gray-300 p-1.5 hover:bg-gray-100 inline-flex h-8 w-8 dark:text-gray-500 dark:hover:text-white dark:bg-gray-800 dark:hover:bg-gray-700">
<span class="sr-only">Close</span>
<svg aria-hidden="true" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
clip-rule="evenodd"></path>
</svg>
</button>
</div>
</div>
</div>
@ -72,30 +73,14 @@ export default {
},
copyToClipBoard(content) {
// const id = parseInt(((new Date()).getTime() * Math.random()).toString()).toString()
// const toastObj = {
// id: id,
// success: true,
// message: "Copied to clipboard successfully",
// show: true,
// copy: this.copyToClipBoard(this.message)
// }
navigator.clipboard.writeText(content);
// this.toastArr.push(toastObj)
nextTick(() => {
feather.replace()
})
// setTimeout(() => {
// this.toastArr = this.toastArr.filter(item => item.id != id)
// }, duration_s * 1000);
},
@ -106,7 +91,7 @@ export default {
success: success,
message: message,
show: true,
copy: this.copyToClipBoard(message)
//copy: this.copyToClipBoard(message)
}

View File

@ -5,8 +5,12 @@
<!-- LOGO -->
<RouterLink :to="{ name: 'discussions' }">
<div class="flex items-center gap-3 flex-1">
<img class="w-12 hover:scale-95 duration-150 " title="lollms-webui" src="@/assets/logo.svg" alt="Logo">
<p class="text-2xl ">lollms-webui</p>
<img class="w-12 hover:scale-95 duration-150 " title="LoLLMS WebUI" src="@/assets/logo.png" alt="Logo">
<div class="flex flex-col">
<p class="text-2xl ">Lord of Large Language Models</p>
<p class="text-gray-400 ">One tool to rule them all</p>
</div>
</div>
</RouterLink>

View File

@ -2,16 +2,20 @@
<!-- DEFAULT FIRST PAGE LOAD VIEW -->
<div class="flex flex-col text-center">
<div class="flex flex-col text-center items-center">
<div class="flex items-center gap-3 text-5xl drop-shadow-md align-middle pt-24 ">
<img class="w-24 animate-bounce" title="lollms-webui" src="@/assets/logo.svg" alt="Logo">
<p class=" ">lollms-webui</p>
<img class="w-24 animate-bounce" title="LoLLMS WebUI" src="@/assets/logo.png" alt="Logo">
<div class="flex flex-col items-start">
<p class="text-2xl ">Lord of Large Language Models</p>
<p class="text-gray-400 text-base">One tool to rule them all</p>
</div>
</div>
<hr
class=" mt-1 w-96 h-1 mx-auto my-2 md:my-2 dark:bg-bg-dark-tone-panel bg-bg-light-tone-panel border-0 rounded ">
<p class="text-lg ">Welcome, please create a new discussion or select existing one to start</p>
<p class="text-2xl">Welcome</p>
<p class="text-lg ">Please create a new discussion or select existing one to start</p>
</div>

View File

@ -1,7 +1,7 @@
<template>
<div v-if="show" class="fixed top-0 left-0 right-0 bottom-0 flex items-center justify-center bg-black bg-opacity-50">
<div class="relative w-full max-w-md max-h-full">
<div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
<div class="relative w-full max-w-md max-h-full ">
<div class="relative bg-white rounded-lg shadow dark:bg-gray-700 ">
<button type="button" @click="hide(false)"
class="absolute top-3 right-2.5 text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm p-1.5 ml-auto inline-flex items-center dark:hover:bg-gray-800 dark:hover:text-white">
<svg aria-hidden="true" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20"
@ -21,11 +21,10 @@
<h3 class="mb-5 text-lg font-normal text-gray-500 dark:text-gray-400 select-none">{{ message }}</h3>
<button @click="hide(true)" type="button"
class="text-white bg-red-600 hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 dark:focus:ring-red-800 font-medium rounded-lg text-sm inline-flex items-center px-5 py-2.5 text-center mr-2">
Yes, I'm sure
{{ConfirmButtonText}}
</button>
<button @click="hide(false)" type="button"
class="text-gray-500 bg-white hover:bg-gray-100 focus:ring-4 focus:outline-none focus:ring-gray-200 rounded-lg border border-gray-200 text-sm font-medium px-5 py-2.5 hover:text-gray-900 focus:z-10 dark:bg-gray-700 dark:text-gray-300 dark:border-gray-500 dark:hover:text-white dark:hover:bg-gray-600 dark:focus:ring-gray-600">No,
cancel</button>
class="text-gray-500 bg-white hover:bg-gray-100 focus:ring-4 focus:outline-none focus:ring-gray-200 rounded-lg border border-gray-200 text-sm font-medium px-5 py-2.5 hover:text-gray-900 focus:z-10 dark:bg-gray-700 dark:text-gray-300 dark:border-gray-500 dark:hover:text-white dark:hover:bg-gray-600 dark:focus:ring-gray-600">{{DenyButtonText}}</button>
</div>
</div>
</div>
@ -39,6 +38,8 @@ export default {
show: false,
message: "",
resolve: null,
ConfirmButtonText: "Yes, I'm sure",
DenyButtonText: "No, cancel",
};
},
methods: {
@ -49,7 +50,9 @@ export default {
this.resolve = null;
}
},
askQuestion(message) {
askQuestion(message, ConfirmButtonText, DenyButtonText) {
this.ConfirmButtonText =ConfirmButtonText || this.ConfirmButtonText
this.DenyButtonText =DenyButtonText || this.DenyButtonText
return new Promise((resolve) => {
this.message = message;
this.show = true;

View File

@ -11,14 +11,15 @@ const app = createApp(App)
const store = createStore({
state () {
return {
count: 0,
mountedPersonalities: {}
// count: 0,
mountedPersonalities: {},
settingsChanged:false
}
},
mutations: {
increment (state) {
state.count++
}
// increment (state) {
// state.count++
// }
}
})

View File

@ -168,15 +168,15 @@
:class="isDragOverChat ? 'pointer-events-none' : ''">
<!-- CHAT AREA -->
<div class=" container pt-4 pb-10 mb-16" >
<div class=" container pt-4 pb-10 mb-16">
<TransitionGroup v-if="discussionArr.length > 0" name="list">
<Message v-for="(msg, index) in discussionArr" :key="msg.id" :message="msg" :id="'msg-' + msg.id"
ref="messages" @copy="copyToClipBoard" @delete="deleteMessage" @rankUp="rankUpMessage"
@rankDown="rankDownMessage" @updateMessage="updateMessage" @resendMessage="resendMessage"
:avatar="getAvatar(msg.sender)" />
<!-- REMOVED FOR NOW, NEED MORE TESTING -->
<!-- @click="scrollToElementInContainer($event.target, 'messages-list')" -->
<!-- REMOVED FOR NOW, NEED MORE TESTING -->
<!-- @click="scrollToElementInContainer($event.target, 'messages-list')" -->
</TransitionGroup>
@ -188,9 +188,8 @@
class="absolute w-full bottom-0 bg-transparent p-10 pt-16 bg-gradient-to-t from-bg-light dark:from-bg-dark from-5% via-bg-light dark:via-bg-dark via-10% to-transparent to-100%">
</div>
<div class=" bottom-0 container flex flex-row items-center justify-center ">
<ChatBox ref="chatBox" v-if="currentDiscussion.id" @messageSentEvent="sendMsg" :loading="isGenerating"
@stopGenerating="stopGenerating" />
<div class=" bottom-0 container flex flex-row items-center justify-center " v-if="currentDiscussion.id">
<ChatBox ref="chatBox" @messageSentEvent="sendMsg" :loading="isGenerating" @stopGenerating="stopGenerating" ></ChatBox>
</div>
<!-- CAN ADD FOOTER PANEL HERE -->
</div>
@ -199,6 +198,7 @@
<Toast ref="toast">
</Toast>
</template>
@ -496,7 +496,7 @@ export default {
nextTick(() => {
const discussionitem =document.getElementById('dis-'+this.currentDiscussion.id)
const discussionitem = document.getElementById('dis-' + this.currentDiscussion.id)
//this.scrollToElement(discussionitem)
@ -517,17 +517,17 @@ export default {
}
},
scrollToElementInContainer(el, containerId) {
const topPos = el.offsetTop ; //+ el.clientHeight
const topPos = el.offsetTop; //+ el.clientHeight
const container = document.getElementById(containerId)
// console.log(el.offsetTop , el.clientHeight, container.clientHeight)
// console.log(el.offsetTop , el.clientHeight, container.clientHeight)
container.scrollTo(
{
top: topPos,
behavior: "smooth",
}
)
{
top: topPos,
behavior: "smooth",
}
)
},
scrollBottom(el) {
@ -560,12 +560,14 @@ export default {
},
createUserMsg(msgObj) {
let usrMessage = {
content: msgObj.message,
id: msgObj.id,
//parent: 10,
rank: 0,
sender: msgObj.user
sender: msgObj.user,
created_at: msgObj.created_at
//type: 0
}
this.discussionArr.push(usrMessage)
@ -601,12 +603,14 @@ export default {
if (msgObj["status"] == "generation_started") {
this.updateLastUserMsg(msgObj)
// Create response message
let responseMessage = {
content: "✍ please stand by ...",//msgObj.message,
id: msgObj.ai_message_id,
parent: msgObj.user_message_id,
rank: 0,
sender: msgObj.bot,
created_at: new Date().toLocaleString(),
//type: msgObj.type
}
this.discussionArr.push(responseMessage)
@ -653,7 +657,9 @@ export default {
message: msg,
id: 0,
rank: 0,
user: "user"
user: "user",
created_at: new Date().toLocaleString(),
};
this.createUserMsg(usrMessage);
@ -834,14 +840,14 @@ export default {
if (item) {
if (item.id) {
const realTitle = item.title ? item.title === "untitled" ? "New discussion" : item.title : "New discussion"
document.title = 'GPT4ALL - WEBUI - ' + realTitle
document.title = 'LoLLMS WebUI - ' + realTitle
} else {
const title = item || "Welcome"
document.title = 'GPT4ALL - WEBUI - ' + title
document.title = 'LoLLMS WebUI - ' + title
}
} else {
const title = item || "Welcome"
document.title = 'GPT4ALL - WEBUI - ' + title
document.title = 'LoLLMS WebUI - ' + title
}
},
@ -887,7 +893,7 @@ export default {
this.setDiscussionLoading(this.currentDiscussion.id, this.isGenerating);
axios.get('/get_generation_status', {}).then((res) => {
if (res) {
//console.log(res.data.status);
console.log(res);
if (!res.data.status) {
socket.emit('generate_msg_from', { prompt: msg, id: msgId });
@ -934,9 +940,43 @@ export default {
this.setDiscussionLoading(this.currentDiscussion.id, this.isGenerating)
this.chime.play()
},
copyToClipBoard(content) {
copyToClipBoard(messageEntry) {
this.$refs.toast.showToast("Copied to clipboard successfully", 4, true)
navigator.clipboard.writeText(content);
let binding =""
if(messageEntry.message.binding){
binding= `Binding: ${messageEntry.message.binding}`
}
let personality=""
if(messageEntry.message.personality){
personality= `\nPersonality: ${messageEntry.message.personality}`
}
let time=""
if(messageEntry.created_at_parsed){
time= `\nCreated: ${messageEntry.created_at_parsed}`
}
let content=""
if(messageEntry.message.content){
content= messageEntry.message.content
}
let model=""
if(messageEntry.message.model){
model= `Model: ${messageEntry.message.model}`
}
let seed=""
if(messageEntry.message.seed){
seed= `Seed: ${messageEntry.message.seed}`
}
let time_spent=""
if(messageEntry.time_spent){
time_spent= `\nTime spent: ${messageEntry.time_spent}`
}
let bottomRow = ''
bottomRow = `${binding} ${model} ${seed} ${time_spent}`.trim()
const result = `${messageEntry.message.sender}${personality}${time}\n\n${content}\n\n${bottomRow}`
navigator.clipboard.writeText(result);
nextTick(() => {
feather.replace()
@ -1088,10 +1128,17 @@ export default {
setFileListChat(files) {
//this.fileList = files
this.$refs.chatBox.fileList = this.$refs.chatBox.fileList.concat(files)
try {
this.$refs.chatBox.fileList = this.$refs.chatBox.fileList.concat(files)
} catch (error) {
this.$refs.toast.showToast("Failed to set filelist in chatbox\n"+error.message, 4, false)
}
this.isDragOverChat = false
},
setDropZoneChat() {
@ -1149,14 +1196,17 @@ export default {
socket.on("final", this.finalMsgEvent)
},
mounted(){
//console.log('chatbox mnt',this.$refs)
},
async activated() {
console.log('settings changed',this.$store.state.mountedPersonalities)
//console.log('settings changed', this.$store.state.mountedPersonalities)
// This lifecycle hook runs every time you switch from other page back to this page (vue-router)
// To fix scrolling back to last message, this hook is needed.
// If anyone knows hor to fix scroll issue when changing pages, please do fix it :D
console.log("Websocket connected (activated)", this.socketConnected)
//console.log('settings changed acc', this.$store.state.settingsChanged)
await this.getPersonalityAvatars()
if (this.isCreated) {

View File

@ -75,11 +75,12 @@
<div class=" text-base font-semibold cursor-pointer select-none items-center">
<div class="flex gap-2 items-center ">
<svg class="flex-shrink-0" xmlns="http://www.w3.org/2000/svg" width="24" height="24"
<!-- <svg class="flex-shrink-0" xmlns="http://www.w3.org/2000/svg" width="24" height="24"
viewBox="0 0 24 24">
<path fill="currentColor"
d="M17 17H7V7h10m4 4V9h-2V7a2 2 0 0 0-2-2h-2V3h-2v2h-2V3H9v2H7c-1.11 0-2 .89-2 2v2H3v2h2v2H3v2h2v2a2 2 0 0 0 2 2h2v2h2v-2h2v2h2v-2h2a2 2 0 0 0 2-2v-2h2v-2h-2v-2m-6 2h-2v-2h2m2-2H9v6h6V9Z" />
</svg>
</svg> -->
<i data-feather="cpu" class="w-5 h-5 mx-1 flex-shrink-0"></i>
<h3 class="font-bold font-large text-lg">
<div>{{ ram_usage }} / {{ ram_total_space }}</div>
</h3>
@ -162,7 +163,8 @@
<div class="flex gap-1 items-center">
<img :src="imgBinding" class="w-8 h-8 rounded-full object-fill text-blue-700">
<h3 class="font-bold font-large text-lg line-clamp-1">
{{ configFile.binding_name }}
<!-- {{ configFile.binding_name }} -->
{{ binding_name }}
</h3>
</div>
</div>
@ -179,7 +181,8 @@
<TransitionGroup name="list">
<BindingEntry ref="bindingZoo" v-for="(binding, index) in bindings"
:key="'index-' + index + '-' + binding.folder" :binding="binding"
:on-selected="onSelectedBinding" :selected="binding.folder === configFile.binding_name">
:on-selected="onSelectedBinding" :on-reinstall="onReinstallBinding"
:selected="binding.folder === configFile.binding_name">
</BindingEntry>
</TransitionGroup>
</div>
@ -329,13 +332,19 @@
<div v-if="configFile.personalities" class="mr-2">|</div>
<!-- LIST OF MOUNTED PERSONALITIES -->
<div class="mr-2 font-bold font-large text-lg line-clamp-1">
{{ active_pesonality }}
</div>
<div v-if="configFile.personalities" class="mr-2">|</div>
<div v-if="configFile.personalities"
class=" text-base font-semibold cursor-pointer select-none items-center flex flex-row">
<!-- LIST -->
<div class="flex -space-x-4 items-center " v-if="mountedPersArr.length > 0" >
<div class="flex -space-x-4 items-center " v-if="mountedPersArr.length > 0">
<!-- ITEM -->
<div class="relative hover:-translate-y-2 duration-300 hover:z-10 shrink-0 "
v-for="(item, index) in mountedPersArr" :key="index + '-' + item.name" ref="mountedPersonalities">
v-for="(item, index) in mountedPersArr" :key="index + '-' + item.name"
ref="mountedPersonalities">
<div class="group items-center flex flex-row">
<button @click.stop="onPersonalitySelected(item)">
@ -614,7 +623,7 @@
</div>
<YesNoDialog ref="yesNoDialog" />
<YesNoDialog ref="yesNoDialog" class="z-20" />
<AddModelDialog ref="addmodeldialog" />
<MessageBox ref="messageBox" />
<Toast ref="toast" />
@ -831,17 +840,18 @@ export default {
if (this.isLoading) {
this.$refs.toast.showToast("Loading... please wait", 4, false)
}
this.isLoading=true
console.log('ppa',pers)
this.isLoading = true
console.log('ppa', pers)
if (pers) {
if (pers.selected) {
this.$refs.toast.showToast("Personality already selected", 4, true)
this.isLoading = false
return
}
this.settingsChanged = true
//this.settingsChanged = true
if (pers.isMounted) {
@ -862,7 +872,7 @@ export default {
feather.replace()
})
this.isLoading=false
this.isLoading = false
}
},
@ -1017,6 +1027,29 @@ export default {
//console.log('lol',binding_object)
}
},
onReinstallBinding(binding_object) {
this.isLoading = true
axios.post('/reinstall_binding', {name: binding_object.binding.folder}).then((res) => {
if (res) {
this.isLoading = false
console.log('reinstall_binding', res)
if(res.data.status){
this.$refs.toast.showToast("Reinstalled binding successfully!", 4, true)
}else{
this.$refs.toast.showToast("Could not reinstall binding", 4, false)
}
return res.data;
}
this.isLoading = false
})
// eslint-disable-next-line no-unused-vars
.catch(error => {
this.isLoading = false
this.$refs.toast.showToast("Could not reinstall binding\n"+error.message, 4, false)
return { 'status': false } });
},
// messagebox ok stuff
onMessageBoxOk() {
console.log("OK button clicked");
@ -1089,6 +1122,7 @@ export default {
this.showAccordion = !this.showAccordion;
},
update_setting(setting_name_val, setting_value_val, next) {
this.isLoading = true
const obj = {
setting_name: setting_name_val,
setting_value: setting_value_val
@ -1097,6 +1131,7 @@ export default {
axios.post('/update_setting', obj).then((res) => {
if (res) {
this.isLoading = false
console.log('update_setting', res)
if (next !== undefined) {
@ -1104,9 +1139,13 @@ export default {
}
return res.data;
}
this.isLoading = false
})
// eslint-disable-next-line no-unused-vars
.catch(error => { return { 'status': false } });
// eslint-disable-next-line no-unused-vars
.catch(error => {
this.isLoading = false
return { 'status': false } });
},
update_binding(value) {
@ -1143,23 +1182,16 @@ export default {
})
},
applyConfiguration() {
// if (!this.configFile.model_name) {
// this.$refs.toast.showToast("Configuration changed failed.\nPlease select model first", 4, false)
// nextTick(() => {
// feather.replace()
// })
// return
// }
this.isLoading = true;
axios.post('/apply_settings').then((res) => {
this.isLoading = false;
if (res.data.status === "succeeded") {
//console.log('apply-res',res)
if (res.data.status) {
this.$refs.toast.showToast("Configuration changed successfully.", 4, true)
this.settingsChanged = false
this.save_configuration()
//this.save_configuration()
} else {
this.$refs.toast.showToast("Configuration change failed.", 4, false)
@ -1368,19 +1400,21 @@ export default {
},
async mountPersonality(pers) {
this.isLoading=true
this.isLoading = true
console.log('mount pers', pers)
if (!pers) { return }
if (this.configFile.personalities.includes(pers.personality.full_path)) {
this.isLoading = false
this.$refs.toast.showToast("Personality already mounted", 4, false)
return
}
const res = await this.mount_personality(pers.personality)
console.log('mount_personality res', res)
if (res.status) {
if (res && res.status) {
this.configFile.personalities = res.personalities
this.$refs.toast.showToast("Personality mounted", 4, true)
pers.isMounted = true
@ -1395,11 +1429,11 @@ export default {
pers.isMounted = false
this.$refs.toast.showToast("Could not mount personality\nError: " + res.error, 4, false)
}
this.isLoading=false
this.isLoading = false
},
async unmountPersonality(pers) {
this.isLoading=true
this.isLoading = true
if (!pers) { return }
const res = await this.unmount_personality(pers.personality || pers)
@ -1444,7 +1478,7 @@ export default {
this.$refs.toast.showToast("Could not unmount personality\nError: " + res.error, 4, false)
}
this.isLoading=false
this.isLoading = false
},
getMountedPersonalities() {
@ -1454,13 +1488,13 @@ export default {
for (let i = 0; i < this.configFile.personalities.length; i++) {
const full_path_item = this.configFile.personalities[i]
const index = this.personalities.findIndex(item => item.full_path == full_path_item)
console.log('index',index)
console.log("i:",i)
console.log('index', index)
console.log("i:", i)
const pers = this.personalities[index]
if (pers) {
mountedPersArr.push(pers)
}
else{
else {
mountedPersArr.push(this.personalities[this.personalities.findIndex(item => item.full_path == "english/generic/lollms")])
}
}
@ -1469,14 +1503,14 @@ export default {
//this.mountedPersArr = mountedPersArr
console.log('getMountedPersonalities', mountedPersArr)
console.log('fig', this.configFile.personality_category)
nextTick(()=>{
console.log('accc',this.$refs.mountedPersonalities)
//this.$store.state.mountedPersonalities = this.$refs.mountedPersonalities
nextTick(() => {
console.log('accc', this.$refs.mountedPersonalities)
//this.$store.state.mountedPersonalities = this.$refs.mountedPersonalities
})
},
onPersonalityMounted(persItem) {
this.isLoading=true
this.isLoading = true
console.log('on sel ', persItem)
if (this.configFile.personalities.includes(persItem.full_path)) {
@ -1496,7 +1530,7 @@ export default {
}
this.isLoading=true
this.isLoading = false
},
personalityImgPlacehodler(event) {
event.target.src = defaultPersonalityImgPlaceholder
@ -1504,7 +1538,7 @@ export default {
}, async mounted() {
//this.$refs.mountedPersonalities
this.isLoading = true
nextTick(() => {
@ -1551,12 +1585,11 @@ export default {
this.ramUsage = await this.api_get_req("ram_usage")
this.getMountedPersonalities()
this.isMounted = true
},
activated(){
// console.log('accc',this.$refs.mountedPersonalities)
// this.$store.state.mountedPersonalities = this.$refs.mountedPersonalities
activated() {
},
computed: {
disk_available_space() {
@ -1609,17 +1642,34 @@ export default {
return defaultModelImgPlaceholder
}
},
// imgPersonality() {
// if (!this.isMounted) {
// return
// }
// try {
// return this.$refs.personalitiesZoo[this.$refs.personalitiesZoo.findIndex(item => item.personality.folder == this.configFile.personality_folder)].$refs.imgElement.src
// }
// catch (error) {
// return defaultPersonalityImgPlaceholder
// }
// },
binding_name() {
if (!this.isMounted) {
return
}
const index = this.bindingsArr.findIndex(item => item.folder === this.configFile.binding_name)
if (index > -1) {
return this.bindingsArr[index].name
} else {
return
}
},
active_pesonality() {
if (!this.isMounted) {
return
}
const index = this.personalities.findIndex(item => item.full_path === this.configFile.personalities[this.configFile.active_personality_id])
if (index > -1) {
return this.personalities[index].name
} else {
return
}
}
},
@ -1684,8 +1734,8 @@ export default {
})
},
settingsChanged(val) {
//this.$store.settingsChanged=val
this.$store.state.settingsChanged = val
nextTick(() => {
feather.replace()
@ -1698,7 +1748,23 @@ export default {
})
},
}
},
async beforeRouteLeave(to) {
// console.log('did settings?',this.settingsChanged)
await this.$router.isReady()
if (this.settingsChanged) {
const res = await this.$refs.yesNoDialog.askQuestion("You forgot to apply changes?\nYou need to apply changes before you leave, or else.", 'Apply configuration', 'Cancel')
if (res) {
this.applyConfiguration()
}
return false
}
},
}
</script>