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 = data["prompt"]
message_id = self.current_discussion.add_message( 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 self.current_user_message_id = message_id
@ -839,6 +841,7 @@ class LoLLMsAPPI():
self.personality.name, self.personality.name,
"", "",
parent = self.current_user_message_id, parent = self.current_user_message_id,
binding = self.config["binding_name"],
model = self.config["model_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 ) # first the content is empty, but we'll fill it at the end
@ -851,6 +854,7 @@ class LoLLMsAPPI():
"message":message,#markdown.markdown(message), "message":message,#markdown.markdown(message),
"user_message_id": self.current_user_message_id, "user_message_id": self.current_user_message_id,
"ai_message_id": self.current_ai_message_id, "ai_message_id": self.current_ai_message_id,
}, room=self.current_room_id }, room=self.current_room_id
) )
@ -876,7 +880,16 @@ class LoLLMsAPPI():
self.socketio.emit('final', { self.socketio.emit('final', {
'data': self.bot_says, 'data': self.bot_says,
'ai_message_id':self.current_ai_message_id, '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 }, room=self.current_room_id
) )

View File

@ -51,8 +51,8 @@ class DiscussionsDB:
type INT NOT NULL, type INT NOT NULL,
rank INT NOT NULL, rank INT NOT NULL,
parent INT, parent INT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, created_at TIMESTAMP,
finished_generating_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, finished_generating_at TIMESTAMP,
discussion_id INTEGER NOT NULL, discussion_id INTEGER NOT NULL,
FOREIGN KEY (discussion_id) REFERENCES discussion(id), FOREIGN KEY (discussion_id) REFERENCES discussion(id),
FOREIGN KEY (parent) REFERENCES message(id) FOREIGN KEY (parent) REFERENCES message(id)
@ -364,9 +364,18 @@ class Discussion:
message_id (int): The id of the message to be changed message_id (int): The id of the message to be changed
new_content (str): The nex message content 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( 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): def message_rank_up(self, message_id):
"""Increments the rank of the message """Increments the rank of the message

3
app.py
View File

@ -864,9 +864,7 @@ class LoLLMsWebUI(LoLLMsAPPI):
return "title renamed successfully" return "title renamed successfully"
def load_discussion(self): def load_discussion(self):
print("- Loading discussion")
data = request.get_json() data = request.get_json()
print(" Recovered json data")
if "id" in data: if "id" in data:
discussion_id = data["id"] discussion_id = data["id"]
self.current_discussion = Discussion(discussion_id, self.db) self.current_discussion = Discussion(discussion_id, self.db)
@ -876,7 +874,6 @@ class LoLLMsWebUI(LoLLMsAPPI):
self.current_discussion = Discussion(discussion_id, self.db) self.current_discussion = Discussion(discussion_id, self.db)
else: else:
self.current_discussion = self.db.create_discussion() self.current_discussion = self.db.create_discussion()
print(f" Discussion id :{discussion_id}")
messages = self.current_discussion.get_messages() 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"> <link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GPT4All - WEBUI</title> <title>LoLLMS WebUI - Welcome</title>
<script type="module" crossorigin src="/assets/index-76dfba09.js"></script> <script type="module" crossorigin src="/assets/index-47b6b817.js"></script>
<link rel="stylesheet" href="/assets/index-f4e7668c.css"> <link rel="stylesheet" href="/assets/index-1760585e.css">
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>

View File

@ -5,7 +5,7 @@
<link rel="icon" href="/favicon.ico"> <link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GPT4All - WEBUI</title> <title>LoLLMS WebUI - Welcome</title>
</head> </head>
<body> <body>
<div id="app"></div> <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> <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'"> @click.stop="toggleSelected" :class="selected ? ' border-primary-light' : 'border-transparent'">
<div :class="isTemplate ? 'opacity-50' : ''"> <div :class="isTemplate ? 'opacity-50' : ''">
@ -15,13 +15,24 @@
<div class="grow"> <div class="grow">
<!-- EMPTY SPACE FILLER --> <!-- EMPTY SPACE FILLER -->
</div> </div>
<!-- ADVANCED OPTIONS - NOT IMPLEMENTED --> <!-- ADVANCED OPTIONS -->
<div v-if="hasAdvancedSettings" class="flex-none"> <div class="flex-none gap-1">
<button type="button" title="Not implemented" <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=""> 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="sliders" class="w-5 m-1"></i> <i data-feather="tool" class="w-5"></i>
<span class="sr-only">Icon description</span> <span class="sr-only">Reinstall binding</span>
</button> </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>
</div> </div>
@ -49,12 +60,15 @@
<b>Version:&nbsp;</b> <b>Version:&nbsp;</b>
{{ binding.version }} {{ binding.version }}
</div> </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> <i data-feather="github" class="w-5 m-1"></i>
<b>Link:&nbsp;</b> <b>Link:&nbsp;</b>
<a :href="binding.link" target="_blank" class="flex items-center hover:text-secondary duration-75 active:scale-90">
{{ binding.link }} {{ binding.link }}
</a> </a>
</div> </div>
</div>
<div class="flex items-center"> <div class="flex items-center">
<i data-feather="info" class="w-5 m-1"></i> <i data-feather="info" class="w-5 m-1"></i>
<b>Description:&nbsp;</b><br> <b>Description:&nbsp;</b><br>
@ -77,13 +91,14 @@ export default {
props: { props: {
binding: {}, binding: {},
onSelected: Function, onSelected: Function,
onReinstall: Function,
selected: Boolean, selected: Boolean,
}, },
data() { data() {
return { return {
isTemplate: false, isTemplate: false,
hasAdvancedSettings: false,
}; };
}, },
mounted() { mounted() {
@ -107,6 +122,9 @@ export default {
toggleSelected() { toggleSelected() {
this.onSelected(this) this.onSelected(this)
}, },
toggleReinstall() {
this.onReinstall(this)
},
getStatus() { getStatus() {
if (this.binding.folder === 'backend_template' || this.binding.folder === 'binding_template') { if (this.binding.folder === 'backend_template' || this.binding.folder === 'binding_template') {
this.isTemplate = true this.isTemplate = true

View File

@ -1,5 +1,5 @@
<template> <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 v-if="loading" class="flex items-center justify-center w-full">
<div class="flex flex-row p-2 rounded-t-lg "> <div class="flex flex-row p-2 rounded-t-lg ">
@ -89,13 +89,17 @@
<!-- CHAT BOX --> <!-- CHAT BOX -->
<div class="flex flex-row flex-grow items-center gap-2 "> <div class="flex flex-row flex-grow items-center gap-2 ">
<!-- <div class="w-24"> <!-- <div class="w-24">
<MountedPersonalitiesComponent /> <MountedPersonalities />
</div> --> </div> -->
<div class="relative grow"> <div class="relative grow">
<textarea id="chat" rows="1" v-model="message" <textarea id="chat" rows="1" v-model="message" title="Hold SHIFT + ENTER to add new line"
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" 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)"> placeholder="Send message..." @keydown.enter.exact="submitOnEnter($event)">
</textarea> </textarea>
<input type="file" ref="fileDialog" style="display: none" @change="addFiles" multiple /> <input type="file" ref="fileDialog" style="display: none" @change="addFiles" multiple />
<button type="button" @click.stop="$refs.fileDialog.click()" title="Add files" <button type="button" @click.stop="$refs.fileDialog.click()" title="Add files"
@ -162,15 +166,15 @@
position: absolute; position: absolute;
} }
</style> </style>
<script setup> <!-- <script setup>
import MountedPersonalitiesComponent from './MountedPersonalitiesComponent.vue' import MountedPersonalitiesComponent from './MountedPersonalitiesComponent.vue'
</script> </script> -->
<script> <script>
import { nextTick, TransitionGroup } from 'vue' import { nextTick, TransitionGroup } from 'vue'
import feather from 'feather-icons' import feather from 'feather-icons'
import filesize from '../plugins/filesize' import filesize from '../plugins/filesize'
import MountedPersonalities from './MountedPersonalities.vue'
export default { export default {
name: 'ChatBox', name: 'ChatBox',
emits: ["messageSentEvent", "stopGenerating"], emits: ["messageSentEvent", "stopGenerating"],
@ -180,10 +184,12 @@ export default {
}, },
components: { components: {
MountedPersonalitiesComponent MountedPersonalities
}, },
setup() { setup() {
return {}
}, },
data() { data() {
return { return {
@ -252,17 +258,15 @@ export default {
} }
} }
this.totalSize = filesize(total, false) this.totalSize = filesize(total, true)
}, },
deep: true deep: true
}, },
},
computed: {
}, },
mounted() { mounted() {
nextTick(() => { nextTick(() => {
feather.replace() feather.replace()
}) })

View File

@ -19,7 +19,8 @@
</p> --> </p> -->
</div> </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 }} {{ created_at }}
</div> </div>
@ -105,6 +106,8 @@
<p v-if="message.binding">Binding: <span class="font-thin">{{ message.binding }}</span></p> <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.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="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>
</div> </div>
@ -174,7 +177,7 @@ export default {
this.expanded = !this.expanded; this.expanded = !this.expanded;
}, },
copyContentToClipboard() { copyContentToClipboard() {
this.$emit('copy', this.message.content) this.$emit('copy', this)
}, },
deleteMsg() { deleteMsg() {
@ -307,6 +310,65 @@ export default {
created_at() { created_at() {
return this.prettyDate(this.message.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,5 +1,4 @@
<template> <template>
<!-- LIST OF MOUNTED PERSONALITIES --> <!-- LIST OF MOUNTED PERSONALITIES -->
<div <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"> 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">
@ -36,7 +35,6 @@
</div> </div>
</div> </div>
</template> </template>
<script> <script>
@ -46,7 +44,7 @@ import defaultPersonalityImgPlaceholder from "../assets/logo.svg"
const bUrl = import.meta.env.VITE_GPT4ALL_API_BASEURL const bUrl = import.meta.env.VITE_GPT4ALL_API_BASEURL
axios.defaults.baseURL = import.meta.env.VITE_GPT4ALL_API_BASEURL axios.defaults.baseURL = import.meta.env.VITE_GPT4ALL_API_BASEURL
export default { export default {
name: 'MountedPersonalitiesComponent', name: 'MountedPersonalities',
setup() { setup() {

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 "> <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> <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> <a href="#" class=" hover:text-primary duration-150">Discussions</a>
</RouterLink> </RouterLink>
</li> </li>
<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> <a href="#" class=" hover:text-primary duration-150">Settings</a>
</RouterLink> </RouterLink>
</li> </li>
<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> <a href="#" class=" hover:text-primary duration-150">Extensions</a>
</RouterLink> </RouterLink>
</li> </li>
<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> <a href="#" class=" hover:text-primary duration-150">Training</a>
</RouterLink> </RouterLink>
</li> </li>
<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> <a href="#" class=" hover:text-primary duration-150">Help</a>
</RouterLink> </RouterLink>
</li> </li>
@ -38,4 +43,22 @@
import { nextTick } from 'vue' import { nextTick } from 'vue'
import feather from 'feather-icons' import feather from 'feather-icons'
import { RouterLink } from 'vue-router' import { RouterLink } from 'vue-router'
</script>
<script>
export default {
data() {
return {
};
},
activated() {
},
methods: {
},
};
</script> </script>

View File

@ -2,9 +2,9 @@
<div class="absolute bottom-16 right-2 z-20 flex flex-col gap-3 min-w-[300px]"> <div class="absolute bottom-16 right-2 z-20 flex flex-col gap-3 min-w-[300px]">
<TransitionGroup name="toastItem" tag="div"> <TransitionGroup name="toastItem" tag="div">
<div v-for=" t in toastArr" :key="t.id" class="relative"> <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"> role="alert">
<div class="flex flex-row items-center"> <div class="flex flex-row flex-grow items-center">
<slot> <slot>
<div v-if="t.success" <div v-if="t.success"
@ -17,20 +17,21 @@
<i data-feather="x"></i> <i data-feather="x"></i>
<span class="sr-only">Cross icon</span> <span class="sr-only">Cross icon</span>
</div> </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> </slot>
</div> </div>
<div class="absolute top-2 right-2">
<div class="flex ">
<button type="button" @click.stop="t.copy(t.message)" <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"> 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> <span class="sr-only">Copy message</span>
<i data-feather="clipboard" class="w-5 h-5"></i> <i data-feather="clipboard" class="w-5 h-5"></i>
</button> </button>
<button type="button" @click="close(t.id)" <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"> 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> <span class="sr-only">Close</span>
<svg aria-hidden="true" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" <svg aria-hidden="true" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20"
@ -72,30 +73,14 @@ export default {
}, },
copyToClipBoard(content) { 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); navigator.clipboard.writeText(content);
// this.toastArr.push(toastObj)
nextTick(() => { nextTick(() => {
feather.replace() feather.replace()
}) })
// setTimeout(() => {
// this.toastArr = this.toastArr.filter(item => item.id != id)
// }, duration_s * 1000);
}, },
@ -106,7 +91,7 @@ export default {
success: success, success: success,
message: message, message: message,
show: true, show: true,
copy: this.copyToClipBoard(message) //copy: this.copyToClipBoard(message)
} }

View File

@ -5,8 +5,12 @@
<!-- LOGO --> <!-- LOGO -->
<RouterLink :to="{ name: 'discussions' }"> <RouterLink :to="{ name: 'discussions' }">
<div class="flex items-center gap-3 flex-1"> <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"> <img class="w-12 hover:scale-95 duration-150 " title="LoLLMS WebUI" src="@/assets/logo.png" alt="Logo">
<p class="text-2xl ">lollms-webui</p> <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> </div>
</RouterLink> </RouterLink>

View File

@ -4,14 +4,18 @@
<div class="flex flex-col text-center items-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 "> <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>
</div>
<hr <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 "> 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> </div>

View File

@ -21,11 +21,10 @@
<h3 class="mb-5 text-lg font-normal text-gray-500 dark:text-gray-400 select-none">{{ message }}</h3> <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" <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"> 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>
<button @click="hide(false)" type="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, 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>
cancel</button>
</div> </div>
</div> </div>
</div> </div>
@ -39,6 +38,8 @@ export default {
show: false, show: false,
message: "", message: "",
resolve: null, resolve: null,
ConfirmButtonText: "Yes, I'm sure",
DenyButtonText: "No, cancel",
}; };
}, },
methods: { methods: {
@ -49,7 +50,9 @@ export default {
this.resolve = null; this.resolve = null;
} }
}, },
askQuestion(message) { askQuestion(message, ConfirmButtonText, DenyButtonText) {
this.ConfirmButtonText =ConfirmButtonText || this.ConfirmButtonText
this.DenyButtonText =DenyButtonText || this.DenyButtonText
return new Promise((resolve) => { return new Promise((resolve) => {
this.message = message; this.message = message;
this.show = true; this.show = true;

View File

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

View File

@ -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%"> 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>
<div class=" bottom-0 container flex flex-row items-center justify-center "> <div class=" bottom-0 container flex flex-row items-center justify-center " v-if="currentDiscussion.id">
<ChatBox ref="chatBox" v-if="currentDiscussion.id" @messageSentEvent="sendMsg" :loading="isGenerating" <ChatBox ref="chatBox" @messageSentEvent="sendMsg" :loading="isGenerating" @stopGenerating="stopGenerating" ></ChatBox>
@stopGenerating="stopGenerating" />
</div> </div>
<!-- CAN ADD FOOTER PANEL HERE --> <!-- CAN ADD FOOTER PANEL HERE -->
</div> </div>
@ -199,6 +198,7 @@
<Toast ref="toast"> <Toast ref="toast">
</Toast> </Toast>
</template> </template>
@ -560,12 +560,14 @@ export default {
}, },
createUserMsg(msgObj) { createUserMsg(msgObj) {
let usrMessage = { let usrMessage = {
content: msgObj.message, content: msgObj.message,
id: msgObj.id, id: msgObj.id,
//parent: 10, //parent: 10,
rank: 0, rank: 0,
sender: msgObj.user sender: msgObj.user,
created_at: msgObj.created_at
//type: 0 //type: 0
} }
this.discussionArr.push(usrMessage) this.discussionArr.push(usrMessage)
@ -601,12 +603,14 @@ export default {
if (msgObj["status"] == "generation_started") { if (msgObj["status"] == "generation_started") {
this.updateLastUserMsg(msgObj) this.updateLastUserMsg(msgObj)
// Create response message // Create response message
let responseMessage = { let responseMessage = {
content: "✍ please stand by ...",//msgObj.message, content: "✍ please stand by ...",//msgObj.message,
id: msgObj.ai_message_id, id: msgObj.ai_message_id,
parent: msgObj.user_message_id, parent: msgObj.user_message_id,
rank: 0, rank: 0,
sender: msgObj.bot, sender: msgObj.bot,
created_at: new Date().toLocaleString(),
//type: msgObj.type //type: msgObj.type
} }
this.discussionArr.push(responseMessage) this.discussionArr.push(responseMessage)
@ -653,7 +657,9 @@ export default {
message: msg, message: msg,
id: 0, id: 0,
rank: 0, rank: 0,
user: "user" user: "user",
created_at: new Date().toLocaleString(),
}; };
this.createUserMsg(usrMessage); this.createUserMsg(usrMessage);
@ -834,14 +840,14 @@ export default {
if (item) { if (item) {
if (item.id) { if (item.id) {
const realTitle = item.title ? item.title === "untitled" ? "New discussion" : item.title : "New discussion" const realTitle = item.title ? item.title === "untitled" ? "New discussion" : item.title : "New discussion"
document.title = 'GPT4ALL - WEBUI - ' + realTitle document.title = 'LoLLMS WebUI - ' + realTitle
} else { } else {
const title = item || "Welcome" const title = item || "Welcome"
document.title = 'GPT4ALL - WEBUI - ' + title document.title = 'LoLLMS WebUI - ' + title
} }
} else { } else {
const title = item || "Welcome" 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); this.setDiscussionLoading(this.currentDiscussion.id, this.isGenerating);
axios.get('/get_generation_status', {}).then((res) => { axios.get('/get_generation_status', {}).then((res) => {
if (res) { if (res) {
//console.log(res.data.status); console.log(res);
if (!res.data.status) { if (!res.data.status) {
socket.emit('generate_msg_from', { prompt: msg, id: msgId }); socket.emit('generate_msg_from', { prompt: msg, id: msgId });
@ -934,9 +940,43 @@ export default {
this.setDiscussionLoading(this.currentDiscussion.id, this.isGenerating) this.setDiscussionLoading(this.currentDiscussion.id, this.isGenerating)
this.chime.play() this.chime.play()
}, },
copyToClipBoard(content) { copyToClipBoard(messageEntry) {
this.$refs.toast.showToast("Copied to clipboard successfully", 4, true) 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(() => { nextTick(() => {
feather.replace() feather.replace()
@ -1088,10 +1128,17 @@ export default {
setFileListChat(files) { setFileListChat(files) {
//this.fileList = files try {
this.$refs.chatBox.fileList = this.$refs.chatBox.fileList.concat(files) 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 this.isDragOverChat = false
}, },
setDropZoneChat() { setDropZoneChat() {
@ -1149,14 +1196,17 @@ export default {
socket.on("final", this.finalMsgEvent) socket.on("final", this.finalMsgEvent)
}, },
mounted(){
//console.log('chatbox mnt',this.$refs)
},
async activated() { 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) // 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. // 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 // 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("Websocket connected (activated)", this.socketConnected)
//console.log('settings changed acc', this.$store.state.settingsChanged)
await this.getPersonalityAvatars() await this.getPersonalityAvatars()
if (this.isCreated) { if (this.isCreated) {

View File

@ -75,11 +75,12 @@
<div class=" text-base font-semibold cursor-pointer select-none items-center"> <div class=" text-base font-semibold cursor-pointer select-none items-center">
<div class="flex gap-2 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"> viewBox="0 0 24 24">
<path fill="currentColor" <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" /> 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"> <h3 class="font-bold font-large text-lg">
<div>{{ ram_usage }} / {{ ram_total_space }}</div> <div>{{ ram_usage }} / {{ ram_total_space }}</div>
</h3> </h3>
@ -162,7 +163,8 @@
<div class="flex gap-1 items-center"> <div class="flex gap-1 items-center">
<img :src="imgBinding" class="w-8 h-8 rounded-full object-fill text-blue-700"> <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"> <h3 class="font-bold font-large text-lg line-clamp-1">
{{ configFile.binding_name }} <!-- {{ configFile.binding_name }} -->
{{ binding_name }}
</h3> </h3>
</div> </div>
</div> </div>
@ -179,7 +181,8 @@
<TransitionGroup name="list"> <TransitionGroup name="list">
<BindingEntry ref="bindingZoo" v-for="(binding, index) in bindings" <BindingEntry ref="bindingZoo" v-for="(binding, index) in bindings"
:key="'index-' + index + '-' + binding.folder" :binding="binding" :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> </BindingEntry>
</TransitionGroup> </TransitionGroup>
</div> </div>
@ -329,13 +332,19 @@
<div v-if="configFile.personalities" class="mr-2">|</div> <div v-if="configFile.personalities" class="mr-2">|</div>
<!-- LIST OF MOUNTED PERSONALITIES --> <!-- 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" <div v-if="configFile.personalities"
class=" text-base font-semibold cursor-pointer select-none items-center flex flex-row"> class=" text-base font-semibold cursor-pointer select-none items-center flex flex-row">
<!-- LIST --> <!-- 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 --> <!-- ITEM -->
<div class="relative hover:-translate-y-2 duration-300 hover:z-10 shrink-0 " <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"> <div class="group items-center flex flex-row">
<button @click.stop="onPersonalitySelected(item)"> <button @click.stop="onPersonalitySelected(item)">
@ -614,7 +623,7 @@
</div> </div>
<YesNoDialog ref="yesNoDialog" /> <YesNoDialog ref="yesNoDialog" class="z-20" />
<AddModelDialog ref="addmodeldialog" /> <AddModelDialog ref="addmodeldialog" />
<MessageBox ref="messageBox" /> <MessageBox ref="messageBox" />
<Toast ref="toast" /> <Toast ref="toast" />
@ -837,11 +846,12 @@ export default {
if (pers.selected) { if (pers.selected) {
this.$refs.toast.showToast("Personality already selected", 4, true) this.$refs.toast.showToast("Personality already selected", 4, true)
this.isLoading = false
return return
} }
this.settingsChanged = true //this.settingsChanged = true
if (pers.isMounted) { if (pers.isMounted) {
@ -1017,6 +1027,29 @@ export default {
//console.log('lol',binding_object) //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 // messagebox ok stuff
onMessageBoxOk() { onMessageBoxOk() {
console.log("OK button clicked"); console.log("OK button clicked");
@ -1089,6 +1122,7 @@ export default {
this.showAccordion = !this.showAccordion; this.showAccordion = !this.showAccordion;
}, },
update_setting(setting_name_val, setting_value_val, next) { update_setting(setting_name_val, setting_value_val, next) {
this.isLoading = true
const obj = { const obj = {
setting_name: setting_name_val, setting_name: setting_name_val,
setting_value: setting_value_val setting_value: setting_value_val
@ -1097,6 +1131,7 @@ export default {
axios.post('/update_setting', obj).then((res) => { axios.post('/update_setting', obj).then((res) => {
if (res) { if (res) {
this.isLoading = false
console.log('update_setting', res) console.log('update_setting', res)
if (next !== undefined) { if (next !== undefined) {
@ -1104,9 +1139,13 @@ export default {
} }
return res.data; return res.data;
} }
this.isLoading = false
}) })
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
.catch(error => { return { 'status': false } });
.catch(error => {
this.isLoading = false
return { 'status': false } });
}, },
update_binding(value) { update_binding(value) {
@ -1143,23 +1182,16 @@ export default {
}) })
}, },
applyConfiguration() { 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; this.isLoading = true;
axios.post('/apply_settings').then((res) => { axios.post('/apply_settings').then((res) => {
this.isLoading = false; this.isLoading = false;
//console.log('apply-res',res)
if (res.data.status === "succeeded") { if (res.data.status) {
this.$refs.toast.showToast("Configuration changed successfully.", 4, true) this.$refs.toast.showToast("Configuration changed successfully.", 4, true)
this.settingsChanged = false this.settingsChanged = false
this.save_configuration() //this.save_configuration()
} else { } else {
this.$refs.toast.showToast("Configuration change failed.", 4, false) this.$refs.toast.showToast("Configuration change failed.", 4, false)
@ -1373,14 +1405,16 @@ export default {
if (!pers) { return } if (!pers) { return }
if (this.configFile.personalities.includes(pers.personality.full_path)) { if (this.configFile.personalities.includes(pers.personality.full_path)) {
this.isLoading = false
this.$refs.toast.showToast("Personality already mounted", 4, false) this.$refs.toast.showToast("Personality already mounted", 4, false)
return return
} }
const res = await this.mount_personality(pers.personality) const res = await this.mount_personality(pers.personality)
console.log('mount_personality res', res) console.log('mount_personality res', res)
if (res.status) { if (res && res.status) {
this.configFile.personalities = res.personalities this.configFile.personalities = res.personalities
this.$refs.toast.showToast("Personality mounted", 4, true) this.$refs.toast.showToast("Personality mounted", 4, true)
pers.isMounted = true pers.isMounted = true
@ -1496,7 +1530,7 @@ export default {
} }
this.isLoading=true this.isLoading = false
}, },
personalityImgPlacehodler(event) { personalityImgPlacehodler(event) {
event.target.src = defaultPersonalityImgPlaceholder event.target.src = defaultPersonalityImgPlaceholder
@ -1555,8 +1589,7 @@ export default {
}, },
activated() { activated() {
// console.log('accc',this.$refs.mountedPersonalities)
// this.$store.state.mountedPersonalities = this.$refs.mountedPersonalities
}, },
computed: { computed: {
disk_available_space() { disk_available_space() {
@ -1609,17 +1642,34 @@ export default {
return defaultModelImgPlaceholder return defaultModelImgPlaceholder
} }
}, },
// imgPersonality() { binding_name() {
// if (!this.isMounted) { if (!this.isMounted) {
// return return
// } }
// try { const index = this.bindingsArr.findIndex(item => item.folder === this.configFile.binding_name)
// return this.$refs.personalitiesZoo[this.$refs.personalitiesZoo.findIndex(item => item.personality.folder == this.configFile.personality_folder)].$refs.imgElement.src if (index > -1) {
// } return this.bindingsArr[index].name
// catch (error) {
// return defaultPersonalityImgPlaceholder } 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
}
}
}, },
@ -1685,7 +1735,7 @@ export default {
}, },
settingsChanged(val) { settingsChanged(val) {
//this.$store.settingsChanged=val this.$store.state.settingsChanged = val
nextTick(() => { nextTick(() => {
feather.replace() 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> </script>