Upgrade prettier to v3.5.3 (#1011)

This commit is contained in:
Peter Dave Hello
2025-05-20 09:33:32 -07:00
committed by GitHub
parent c5691e2d14
commit 42113749db
54 changed files with 763 additions and 804 deletions
+4 -4
View File
@@ -66,7 +66,7 @@
"husky": "^8.0.3",
"lint-staged": "^15.5.1",
"md5": "^2.3.0",
"prettier": "^3.4.2",
"prettier": "^3.5.3",
"prettier-plugin-vue": "^1.1.6",
"sse.js": "^2.6.0"
}
@@ -19183,9 +19183,9 @@
}
},
"node_modules/prettier": {
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz",
"integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==",
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz",
"integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==",
"dev": true,
"license": "MIT",
"bin": {
+1 -1
View File
@@ -84,7 +84,7 @@
"husky": "^8.0.3",
"lint-staged": "^15.5.1",
"md5": "^2.3.0",
"prettier": "^3.4.2",
"prettier": "^3.5.3",
"prettier-plugin-vue": "^1.1.6",
"sse.js": "^2.6.0"
},
+50 -48
View File
@@ -1,14 +1,14 @@
<template>
<v-app>
<v-container fluid style="padding: 0">
<ChatDrawer
<v-app
> <v-container fluid style="padding: 0"
> <ChatDrawer
ref="chatDrawerRef"
v-model:open="isChatDrawerOpen"
@focus-textarea="focusPromptTextarea"
></ChatDrawer>
<v-main class="content" :class="{ paddingTopZero: !isShowAppBar }">
<v-slide-y-transition>
<v-app-bar
></ChatDrawer
> <v-main class="content" :class="{ paddingTopZero: !isShowAppBar }"
> <v-slide-y-transition
> <v-app-bar
:id="SHORTCUT_APP_BAR.elementId"
@shortkey="
isShowAppBar = !isShowAppBar;
@@ -20,29 +20,28 @@
transform: isShowAppBar ? 'translateY(0)' : 'translateY(-100%)',
}"
class="header-content pa-0"
>
<!-- Start Header -->
> <!-- Start Header -->
<div class="header-content" v-show="isSelectedResponsesEmpty">
<v-app-bar-nav-icon
<v-app-bar-nav-icon
:id="SHORTCUT_CHAT_DRAWER.elementId"
variant="text"
@click.stop="isChatDrawerOpen = !isChatDrawerOpen"
@shortkey="isChatDrawerOpen = !isChatDrawerOpen"
v-shortkey="SHORTCUT_CHAT_DRAWER.key"
>
</v-app-bar-nav-icon>
<img
> </v-app-bar-nav-icon
> <img
:class="{ 'dark-png': store.state.theme === Theme.DARK }"
class="logo"
src="@/assets/logo-banner.png"
alt="ChatALL"
/>
</div>
<div
class="column-icons header-content"
v-show="isSelectedResponsesEmpty"
>
<img
<img
v-for="columnCount in 3"
:id="`column-${columnCount}`"
:key="columnCount"
@@ -56,20 +55,21 @@
}"
/>
</div>
<div
class="header-content"
style="padding-right: 16px"
v-show="isSelectedResponsesEmpty"
>
<v-icon
<v-icon
:id="SHORTCUT_FIND.elementId"
class="cursor-pointer"
color="primary"
icon="mdi-magnify"
size="x-large"
@click="openFind()"
></v-icon>
<v-icon
></v-icon
> <v-icon
v-shortkey="SHORTCUT_CLEAR_MESSAGES.key"
@shortkey="clearMessages"
:id="SHORTCUT_CLEAR_MESSAGES.elementId"
@@ -78,8 +78,8 @@
icon="mdi-broom"
size="x-large"
@click="clearMessages()"
></v-icon>
<v-icon
></v-icon
> <v-icon
v-shortkey="SHORTCUT_SETTINGS.key"
@shortkey="openSettingsModal"
:id="SHORTCUT_SETTINGS.elementId"
@@ -88,8 +88,8 @@
icon="mdi-cog"
size="x-large"
@click="openSettingsModal()"
></v-icon>
<v-icon
></v-icon
> <v-icon
v-shortkey="SHORTCUT_SHORTCUT_GUIDE.key"
@shortkey="toggleShortcutGuide"
:id="SHORTCUT_SHORTCUT_GUIDE.elementId"
@@ -98,64 +98,65 @@
icon="mdi-help"
size="x-large"
@click="toggleShortcutGuide()"
></v-icon>
></v-icon
>
</div>
<!-- End Header -->
<!-- Start Selected Responses -->
<!-- End Header --> <!-- Start Selected Responses -->
<div
class="header-content pr-3"
style="text-wrap: nowrap"
v-show="!isSelectedResponsesEmpty"
>
<v-btn icon color="primary" @click="deselectAll">
<v-icon>mdi-arrow-left</v-icon>
</v-btn>
{{
<v-btn icon color="primary" @click="deselectAll"
> <v-icon>mdi-arrow-left</v-icon> </v-btn
> {{
$t("header.selectedResponsesCount", {
selectedCount: store.state.selectedResponses.length,
})
}}
</div>
<div
class="header-content overflow-auto"
v-show="!isSelectedResponsesEmpty"
>
<v-btn
<v-btn
v-for="action in userActions"
color="primary"
class="no-text-transform"
:text="action.name"
:key="action.index"
@click="callAction(action)"
></v-btn>
></v-btn
>
</div>
<!-- End Selected Responses -->
</v-app-bar>
</v-slide-y-transition>
<FindModal ref="findRef"></FindModal>
<ChatMessages :chat="currentChat" :columns="columns"></ChatMessages>
<FooterBar
<!-- End Selected Responses --> </v-app-bar
> </v-slide-y-transition
> <FindModal ref="findRef"></FindModal> <ChatMessages
:chat="currentChat"
:columns="columns"
></ChatMessages
> <FooterBar
ref="footerBarRef"
:chat="currentChat"
@update-active-bots="(bots) => (activeBots = bots)"
></FooterBar>
</v-main>
<SettingsModal v-model:open="isSettingsOpen" />
<ConfirmModal ref="confirmModal" />
<UpdateNotification></UpdateNotification>
<ShortcutGuide
></FooterBar
> </v-main
> <SettingsModal v-model:open="isSettingsOpen" /> <ConfirmModal
ref="confirmModal"
/> <UpdateNotification></UpdateNotification> <ShortcutGuide
ref="shortcutGuideRef"
v-model:open="isShortcutGuideOpen"
></ShortcutGuide>
<ChatAction
></ShortcutGuide
> <ChatAction
v-model:open="isChatActionOpen"
:action="action"
:responses="store.state.selectedResponses"
:activeBots="activeBots"
></ChatAction>
</v-container>
</v-app>
></ChatAction
> </v-container
> </v-app
>
</template>
<script setup>
@@ -421,3 +422,4 @@ img.selected {
padding-top: 0!important;
}
</style>
+4 -2
View File
@@ -1,10 +1,11 @@
<template>
<CommonBotSettings
<CommonBotSettings
:settings="settings"
:brand-id="brandId"
mutation-type="setXaiApi"
:watcher="watcher"
></CommonBotSettings>
></CommonBotSettings
>
</template>
<script>
@@ -63,3 +64,4 @@ export default {
},
};
</script>
@@ -1,10 +1,11 @@
<template>
<CommonBotSettings
<CommonBotSettings
:settings="settings"
:brand-id="brandId"
mutation-type="setAzureOpenaiApi"
:watcher="watcher"
></CommonBotSettings>
></CommonBotSettings
>
</template>
<script>
@@ -78,3 +79,4 @@ export default {
},
};
</script>
@@ -1,6 +1,4 @@
<template>
<login-setting :bot="bot"></login-setting>
</template>
<template> <login-setting :bot="bot"></login-setting> </template>
<script>
import Bot from "@/bots/google/BardBot";
@@ -17,3 +15,4 @@ export default {
},
};
</script>
@@ -1,6 +1,4 @@
<template>
<login-setting :bot="bot"></login-setting>
</template>
<template> <login-setting :bot="bot"></login-setting> </template>
<script>
import Bot from "@/bots/microsoft/BingChatBot";
@@ -17,3 +15,4 @@ export default {
},
};
</script>
@@ -1,10 +1,10 @@
<template>
<login-setting :bot="bot"></login-setting>
<CommonBotSettings
<login-setting :bot="bot"></login-setting> <CommonBotSettings
:settings="settings"
:brand-id="brandId"
mutation-type="setCharacterAI"
></CommonBotSettings>
></CommonBotSettings
>
</template>
<script>
@@ -37,3 +37,4 @@ export default {
},
};
</script>
@@ -1,6 +1,4 @@
<template>
<login-setting :bot="bot"></login-setting>
</template>
<template> <login-setting :bot="bot"></login-setting> </template>
<script>
import Bot from "@/bots/zhipu/ChatGLMBot";
@@ -28,3 +26,4 @@ export default {
},
};
</script>
@@ -1,20 +1,20 @@
<template>
<v-list-item>
<v-alert type="info" outlined>{{ $t("chatGpt.notice") }} </v-alert>
</v-list-item>
<login-setting :bot="bot"></login-setting>
<v-list-item>
<v-list-item-title>{{ $t("chatGpt.autoRefresh") }}</v-list-item-title>
<v-list-item-subtitle>{{
<v-list-item
> <v-alert type="info" outlined>{{ $t("chatGpt.notice") }} </v-alert>
</v-list-item
> <login-setting :bot="bot"></login-setting> <v-list-item
> <v-list-item-title>{{ $t("chatGpt.autoRefresh") }}</v-list-item-title
> <v-list-item-subtitle>{{
$t("chatGpt.autoRefreshPrompt")
}}</v-list-item-subtitle>
<v-checkbox
}}</v-list-item-subtitle
> <v-checkbox
v-model="autoRefresh"
color="primary"
hideDetails="auto"
:label="$t('settings.enable')"
></v-checkbox>
</v-list-item>
></v-checkbox
> </v-list-item
>
</template>
<script>
@@ -56,3 +56,4 @@ export default {
},
};
</script>
@@ -1,6 +1,4 @@
<template>
<login-setting :bot="bot"></login-setting>
</template>
<template> <login-setting :bot="bot"></login-setting> </template>
<script>
import Bot from "@/bots/ClaudeAIBot";
@@ -28,3 +26,4 @@ export default {
},
};
</script>
@@ -1,10 +1,11 @@
<template>
<CommonBotSettings
<CommonBotSettings
:settings="settings"
:brand-id="brandId"
mutation-type="setClaudeApi"
:watcher="watcher"
></CommonBotSettings>
></CommonBotSettings
>
</template>
<script>
@@ -61,3 +62,4 @@ export default {
},
};
</script>
@@ -1,11 +1,11 @@
<template>
<CommonBotSettings
<CommonBotSettings
:settings="settings"
:brand-id="brandId"
mutation-type="setCohereApi"
:watcher="watcher"
> </CommonBotSettings
>
</CommonBotSettings>
</template>
<script>
@@ -64,3 +64,4 @@ export default {
},
};
</script>
@@ -1,16 +1,13 @@
<template>
<v-list-item>
<template v-for="setting in settings" :key="setting.name">
<v-list-item-title v-if="setting.title">
<!-- falcon.temperature -->
{{ $t(setting.title) }}</v-list-item-title
>
<v-list-item-subtitle v-if="setting.description">
<!-- falcon.temperaturePrompt -->
{{ $t(setting.description) }}</v-list-item-subtitle
>
<v-text-field
<v-list-item
> <template v-for="setting in settings" :key="setting.name"
> <v-list-item-title v-if="setting.title"
> <!-- falcon.temperature --> {{ $t(setting.title) }}</v-list-item-title
> <v-list-item-subtitle v-if="setting.description"
> <!-- falcon.temperaturePrompt --> {{
$t(setting.description)
}}</v-list-item-subtitle
> <v-text-field
v-if="setting.type === Type.Text"
v-model="settingState[setting.name]"
outlined
@@ -22,8 +19,8 @@
/* setFalcon({ temperature: $event }) */
store.commit(mutationType, { [setting.name]: $event })
"
></v-text-field>
<v-select
></v-text-field
> <v-select
v-else-if="setting.type === Type.Select"
v-model="settingState[setting.name]"
outlined
@@ -36,8 +33,8 @@
/* setFalcon({ temperature: $event }) */
store.commit(mutationType, { [setting.name]: $event })
"
></v-select>
<v-slider
></v-select
> <v-slider
v-else-if="setting.type === Type.Slider"
v-model="settingState[setting.name] /* falcon.temperature */"
color="primary"
@@ -54,9 +51,8 @@
/* setFalcon({ temperature: $event }) */
store.commit(mutationType, { [setting.name]: $event })
"
>
<template v-slot:append>
<v-text-field
> <template v-slot:append
> <v-text-field
v-model="settingState[setting.name] /* falcon.temperature */"
:ref="
(el) => {
@@ -74,10 +70,10 @@
[setting.name]: validateSliderInput(setting, $event),
})
"
></v-text-field>
</template>
</v-slider>
<v-combobox
></v-text-field
> </template
> </v-slider
> <v-combobox
v-else-if="setting.type === Type.Combobox"
v-model="settingState[setting.name]"
outlined
@@ -89,8 +85,8 @@
@update:model-value="
store.commit(mutationType, { [setting.name]: $event })
"
></v-combobox>
<v-checkbox
></v-combobox
> <v-checkbox
v-else-if="setting.type === Type.Checkbox"
v-model="settingState[setting.name]"
outlined
@@ -102,9 +98,10 @@
@update:model-value="
store.commit(mutationType, { [setting.name]: $event })
"
></v-checkbox>
</template>
</v-list-item>
></v-checkbox
> </template
> </v-list-item
>
</template>
<script setup>
@@ -188,3 +185,4 @@ function getInputElement(ref) {
return ref.$el.querySelector("input");
}
</script>
@@ -1,10 +1,11 @@
<template>
<CommonBotSettings
<CommonBotSettings
:settings="settings"
:brand-id="brandId"
mutation-type="setGemini"
:watcher="watcher"
></CommonBotSettings>
></CommonBotSettings
>
</template>
<script>
@@ -78,3 +79,4 @@ export default {
},
};
</script>
@@ -1,9 +1,10 @@
<template>
<CommonBotSettings
<CommonBotSettings
:settings="settings"
:brand-id="brandId"
mutation-type="setGradio"
></CommonBotSettings>
></CommonBotSettings
>
</template>
<script>
@@ -43,3 +44,4 @@ export default {
},
};
</script>
@@ -1,10 +1,11 @@
<template>
<CommonBotSettings
<CommonBotSettings
:settings="settings"
:brand-id="brandId"
mutation-type="setGroqApi"
:watcher="watcher"
></CommonBotSettings>
></CommonBotSettings
>
</template>
<script>
@@ -63,3 +64,4 @@ export default {
},
};
</script>
@@ -1,6 +1,4 @@
<template>
<login-setting :bot="bot"></login-setting>
</template>
<template> <login-setting :bot="bot"></login-setting> </template>
<script>
import Bot from "@/bots/huggingface/HuggingChatBot";
@@ -17,3 +15,4 @@ export default {
},
};
</script>
@@ -1,6 +1,4 @@
<template>
<login-setting :bot="bot"></login-setting>
</template>
<template> <login-setting :bot="bot"></login-setting> </template>
<script>
const electron = window.require("electron");
@@ -30,3 +28,4 @@ export default {
},
};
</script>
@@ -1,6 +1,4 @@
<template>
<login-setting :bot="bot"></login-setting>
</template>
<template> <login-setting :bot="bot"></login-setting> </template>
<script>
import Bot from "@/bots/lmsys/LMSYSBot";
@@ -17,3 +15,4 @@ export default {
},
};
</script>
+9 -8
View File
@@ -1,13 +1,13 @@
<template>
<v-list-item>
<v-list-item-title>{{ $t("settings.loginOrOut") }}</v-list-item-title>
<v-list-item-subtitle>{{
<v-list-item
> <v-list-item-title>{{ $t("settings.loginOrOut") }}</v-list-item-title
> <v-list-item-subtitle>{{
$t("settings.loginOrOutPrompt")
}}</v-list-item-subtitle>
<a :href="bot.getLoginUrl()" target="_blank" @click="openLoginWindow">
{{ bot.getLoginUrl() }}
</a>
</v-list-item>
}}</v-list-item-subtitle
> <a :href="bot.getLoginUrl()" target="_blank" @click="openLoginWindow"
> {{ bot.getLoginUrl() }} </a
> </v-list-item
>
</template>
<script>
@@ -35,3 +35,4 @@ export default {
},
};
</script>
@@ -1,6 +1,4 @@
<template>
<login-setting :bot="bot"></login-setting>
</template>
<template> <login-setting :bot="bot"></login-setting> </template>
<script>
const electron = window.require("electron");
@@ -34,3 +32,4 @@ export default {
},
};
</script>
@@ -1,10 +1,10 @@
<template>
<login-setting :bot="bot"></login-setting>
<CommonBotSettings
<login-setting :bot="bot"></login-setting> <CommonBotSettings
:settings="settings"
:brand-id="brandId"
mutation-type="setMistral"
></CommonBotSettings>
></CommonBotSettings
>
</template>
<script>
@@ -35,3 +35,4 @@ export default {
},
};
</script>
@@ -1,10 +1,11 @@
<template>
<CommonBotSettings
<CommonBotSettings
:settings="settings"
:brand-id="brandId"
mutation-type="setOpenaiApi"
:watcher="watcher"
></CommonBotSettings>
></CommonBotSettings
>
</template>
<script>
@@ -70,3 +71,4 @@ export default {
},
};
</script>
@@ -1,10 +1,10 @@
<template>
<login-setting :bot="bot"></login-setting>
<CommonBotSettings
<login-setting :bot="bot"></login-setting> <CommonBotSettings
:settings="settings"
:brand-id="brandId"
mutation-type="setPerplexity"
></CommonBotSettings>
></CommonBotSettings
>
</template>
<script>
@@ -35,3 +35,4 @@ export default {
},
};
</script>
@@ -1,9 +1,10 @@
<template>
<CommonBotSettings
<CommonBotSettings
:settings="settings"
:brand-id="brandId"
mutation-type="setPhind"
></CommonBotSettings>
></CommonBotSettings
>
</template>
<script>
@@ -31,3 +32,4 @@ export default {
},
};
</script>
+2 -3
View File
@@ -1,6 +1,4 @@
<template>
<login-setting :bot="bot"></login-setting>
</template>
<template> <login-setting :bot="bot"></login-setting> </template>
<script>
import Bot from "@/bots/PiBot";
@@ -17,3 +15,4 @@ export default {
},
};
</script>
@@ -1,6 +1,4 @@
<template>
<login-setting :bot="bot"></login-setting>
</template>
<template> <login-setting :bot="bot"></login-setting> </template>
<script>
import Bot from "@/bots/poe/PoeBot";
@@ -28,3 +26,4 @@ export default {
},
};
</script>
@@ -1,6 +1,4 @@
<template>
<login-setting :bot="bot"></login-setting>
</template>
<template> <login-setting :bot="bot"></login-setting> </template>
<script>
const electron = window.require("electron");
@@ -30,3 +28,4 @@ export default {
},
};
</script>
@@ -1,6 +1,4 @@
<template>
<login-setting :bot="bot"></login-setting>
</template>
<template> <login-setting :bot="bot"></login-setting> </template>
<script>
import Bot from "@/bots/Qihoo360AIBrainBot";
@@ -17,3 +15,4 @@ export default {
},
};
</script>
@@ -1,6 +1,4 @@
<template>
<login-setting :bot="bot"></login-setting>
</template>
<template> <login-setting :bot="bot"></login-setting> </template>
<script>
const electron = window.require("electron");
@@ -30,3 +28,4 @@ export default {
},
};
</script>
@@ -1,6 +1,4 @@
<template>
<login-setting :bot="bot"></login-setting>
</template>
<template> <login-setting :bot="bot"></login-setting> </template>
<script>
import Bot from "@/bots/SparkBot";
@@ -17,3 +15,4 @@ export default {
},
};
</script>
@@ -1,9 +1,10 @@
<template>
<CommonBotSettings
<CommonBotSettings
:settings="settings"
:brand-id="brandId"
mutation-type="setWenxinQianfan"
></CommonBotSettings>
></CommonBotSettings
>
</template>
<script>
@@ -49,3 +50,4 @@ export default {
},
};
</script>
@@ -1,6 +1,4 @@
<template>
<login-setting :bot="bot"></login-setting>
</template>
<template> <login-setting :bot="bot"></login-setting> </template>
<script>
import Bot from "@/bots/YouChatBot";
@@ -17,3 +15,4 @@ export default {
},
};
</script>
@@ -1,10 +1,11 @@
<template>
<CommonBotSettings
<CommonBotSettings
:settings="settings"
:brand-id="brandId"
mutation-type="setxAIApi"
:watcher="watcher"
></CommonBotSettings>
></CommonBotSettings
>
</template>
<script>
@@ -50,3 +51,4 @@ export default {
},
};
</script>
+34 -39
View File
@@ -1,44 +1,41 @@
<template>
<v-dialog
<v-dialog
height="75%"
width="80%"
:model-value="props.open"
@update:model-value="closeDialog"
>
<v-card height="100%">
<v-card-title>
<v-row>
<v-col class="d-flex align-center">
{{ props.action.name }}
<v-btn
> <v-card height="100%"
> <v-card-title
> <v-row
> <v-col class="d-flex align-center"
> {{ props.action.name }} <v-btn
flat
@click="isEdit = !isEdit"
:icon="isEdit ? 'mdi-eye' : 'mdi-pencil-outline'"
></v-btn>
</v-col>
<v-col class="d-flex align-center justify-end">
<v-label>{{ previewTextarea.length }}</v-label>
</v-col>
</v-row>
</v-card-title>
<v-card-text class="pt-0 overflow-auto">
<v-textarea
></v-btn
> </v-col
> <v-col class="d-flex align-center justify-end"
> <v-label>{{ previewTextarea.length }}</v-label
> </v-col
> </v-row
> </v-card-title
> <v-card-text class="pt-0 overflow-auto"
> <v-textarea
hide-details
rows="20"
v-show="isEdit"
v-model="previewTextarea"
@input="previewText = previewTextarea"
>
</v-textarea>
<chat-prompt
> </v-textarea
> <chat-prompt
v-show="!isEdit"
:message="{ content: previewText }"
:isThread="false"
:columns="3"
></chat-prompt>
</v-card-text>
<v-card-actions class="justify-end pr-6 pt-0" style="gap: 0.3rem">
<v-btn
></chat-prompt
> </v-card-text
> <v-card-actions class="justify-end pr-6 pt-0" style="gap: 0.3rem"
> <v-btn
class="send-prompt-btn"
elevation="2"
:disabled="
@@ -47,11 +44,10 @@
!chatRef
"
@click="send"
> {{ $t("footer.sendPrompt") }} </v-btn
>
{{ $t("footer.sendPrompt") }}
</v-btn>
<div class="bot-logos">
<BotLogo
<BotLogo
v-for="(bot, index) in favBots"
:id="`fav-bot-${index + 1}`"
:key="index"
@@ -62,18 +58,16 @@
@click="bot.selected = !bot.selected"
/>
</div>
<v-form class="d-flex">
<v-radio-group v-model="chatRef" density="compact" hide-details>
<v-radio :label="$t('chat.inNewChat')" value="new"></v-radio>
<v-radio
:label="$t('chat.inCurrentChat')"
value="current"
></v-radio>
</v-radio-group>
</v-form>
</v-card-actions>
</v-card>
</v-dialog>
<v-form class="d-flex"
> <v-radio-group v-model="chatRef" density="compact" hide-details
> <v-radio :label="$t('chat.inNewChat')" value="new"></v-radio>
<v-radio :label="$t('chat.inCurrentChat')" value="current"></v-radio
> </v-radio-group
> </v-form
> </v-card-actions
> </v-card
> </v-dialog
>
</template>
<script setup>
@@ -196,3 +190,4 @@ function deselectAllResponses() {
border-radius: 4px !important;
}
</style>
+15 -16
View File
@@ -1,7 +1,7 @@
<template>
<v-navigation-drawer permanent :model-value="props.open">
<v-list nav>
<v-list-item
<v-navigation-drawer permanent :model-value="props.open"
> <v-list nav
> <v-list-item
:id="SHORTCUT_NEW_CHAT.elementId"
density="comfortable"
class="mb-1 border"
@@ -9,15 +9,12 @@
@click="onAddChat"
@shortkey="onAddChat"
v-shortkey="SHORTCUT_NEW_CHAT.key"
>
<template v-slot:prepend>
<v-icon color="primary"> mdi-plus </v-icon>
</template>
</v-list-item>
</v-list>
<template v-for="chat in drawerItems">
<ChatDrawerItem
> <template v-slot:prepend
> <v-icon color="primary"> mdi-plus </v-icon> </template
> </v-list-item
> </v-list
> <template v-for="chat in drawerItems"
> <ChatDrawerItem
v-if="!chat.hide"
:key="chat.index"
:chat="chat"
@@ -26,10 +23,10 @@
@select-chat="selectChat"
@edit-chat-title="editChatTitle"
@focus-textarea="focusTextarea"
></ChatDrawerItem>
</template>
</v-navigation-drawer>
<ConfirmModal ref="confirmModal" />
></ChatDrawerItem
> </template
> </v-navigation-drawer
> <ConfirmModal ref="confirmModal" />
</template>
<script setup>
@@ -105,8 +102,10 @@ function focusTextarea() {
});
}
</script>
<style scoped>
:deep() .v-list-item-title {
font-size: 1rem !important;
}
</style>
+22 -23
View File
@@ -1,5 +1,5 @@
<template>
<v-list-item
<v-list-item
density="comfortable"
v-if="!isEditMode"
:key="`chat-${props.chat.index}`"
@@ -9,28 +9,27 @@
class="pa-3 pr-0"
:style="{ cursor: isCursorWait ? 'wait' : 'pointer' }"
@click="onSelectChat"
>
<template v-slot:prepend>
<v-icon color="primary" class="mr-4"> mdi-message-outline </v-icon>
</template>
<template #append v-if="props.currentChatIndex === props.chat.index">
<v-btn
> <template v-slot:prepend
> <v-icon color="primary" class="mr-4"> mdi-message-outline </v-icon>
</template
> <template #append v-if="props.currentChatIndex === props.chat.index"
> <v-btn
flat
size="x-small"
icon="mdi-pencil-outline"
@click="editChat"
style="background-color: transparent"
></v-btn>
<v-btn
></v-btn
> <v-btn
flat
size="x-small"
icon="mdi-delete-outline"
@click="confirmHideChat"
style="margin: 0; background-color: transparent"
></v-btn>
</template>
</v-list-item>
<v-text-field
></v-btn
> </template
> </v-list-item
> <v-text-field
autofocus
:key="`chat-${index}`"
v-if="isEditMode"
@@ -42,20 +41,19 @@
style="padding: 6px"
class="pl-3 pr-0"
hide-details
>
<template v-slot:prepend>
<v-icon color="primary"> mdi-message-outline </v-icon>
</template>
<template v-slot:append>
<v-btn flat size="x-small" icon="mdi-check" @click="confirmEdit"></v-btn>
<v-btn
> <template v-slot:prepend
> <v-icon color="primary"> mdi-message-outline </v-icon> </template
> <template v-slot:append
> <v-btn flat size="x-small" icon="mdi-check" @click="confirmEdit"></v-btn
> <v-btn
flat
size="x-small"
icon="mdi-close"
@click="isEditMode = false"
></v-btn>
</template>
</v-text-field>
></v-btn
> </template
> </v-text-field
>
</template>
<script setup>
@@ -132,3 +130,4 @@ function onPressEnter(event) {
display: block;
}
</style>
+86 -101
View File
@@ -1,112 +1,108 @@
<template>
<CommonBotSettings
<CommonBotSettings
:settings="settings"
:brand-id="brandId"
mutation-type="setChat"
></CommonBotSettings>
<v-list>
<v-list-item>
<v-btn
></CommonBotSettings
> <v-list
> <v-list-item
> <v-btn
color="primary"
variant="outlined"
:text="$t('chat.deleteAllChatHistory')"
@click="deleteChats"
></v-btn>
</v-list-item>
<br />
<v-list-item>
<v-list-item-title style="font-size: 1.5rem" class="pb-2">
{{ $t("chat.exportImport") }}</v-list-item-title
>
<v-list-item-subtitle>
{{ $t("chat.exportImportDesc") }}</v-list-item-subtitle
></v-btn
> </v-list-item
> <br /> <v-list-item
> <v-list-item-title style="font-size: 1.5rem" class="pb-2"
> {{ $t("chat.exportImport") }}</v-list-item-title
> <v-list-item-subtitle
> {{ $t("chat.exportImportDesc") }}</v-list-item-subtitle
>
<div class="pt-2">
<v-btn
<v-btn
color="primary"
variant="outlined"
:text="$t('chat.export')"
@click="exportData"
></v-btn>
<v-btn
></v-btn
> <v-btn
color="primary"
variant="outlined"
:text="$t('chat.import')"
@click="importData"
style="margin-left: 10px"
> </v-btn
>
</v-btn>
</div>
</v-list-item>
<br />
<v-list-item>
<v-row>
<v-col class="align-baseline d-flex" style="font-size: 1.5rem">
<label class="pr-3">{{ $t("chat.actions") }}</label>
<v-btn
</v-list-item
> <br /> <v-list-item
> <v-row
> <v-col class="align-baseline d-flex" style="font-size: 1.5rem"
> <label class="pr-3">{{ $t("chat.actions") }}</label
> <v-btn
class="mt-1"
color="primary"
variant="outlined"
prepend-icon="mdi-plus"
:text="$t('chat.addAction')"
@click="add"
></v-btn>
</v-col>
</v-row>
</v-list-item>
<v-list-item
></v-btn
> </v-col
> </v-row
> </v-list-item
> <v-list-item
v-for="action in userActions"
density="comfortable"
:key="action.index"
:value="action.index"
:ripple="false"
>
>
<div class="align-center d-flex">
<v-list-item-title class="pr-5">{{ action.name }}</v-list-item-title>
<v-btn
<v-list-item-title class="pr-5">{{ action.name }}</v-list-item-title
> <v-btn
flat
size="x-small"
icon="mdi-pencil-outline"
@click="edit(action)"
style="background-color: transparent"
></v-btn>
<v-btn
></v-btn
> <v-btn
flat
size="x-small"
icon="mdi-delete-outline"
@click="deleteAction(action)"
style="margin: 0; background-color: transparent"
></v-btn>
></v-btn
>
</div>
</v-list-item>
</v-list>
<v-dialog
</v-list-item
> </v-list
> <v-dialog
persistent
width="90%"
height="90%"
:model-value="isOpenAddEditAction"
@update:model-value="isOpenAddEditAction = $event"
>
<v-card>
<v-form ref="formRef" class="pa-3" @submit.prevent>
<v-text-field
> <v-card
> <v-form ref="formRef" class="pa-3" @submit.prevent
> <v-text-field
required
autofocus
v-model="actionName"
placeholder="Summarize"
:label="$t('chat.actionName')"
:rules="[required]"
></v-text-field>
<v-textarea
></v-text-field
> <v-textarea
required
rows="3"
v-model="prefix"
:placeholder="prefixPlaceholder"
:label="$t('chat.prefix')"
@input="onInputTemplate"
>
</v-textarea>
<v-textarea
> </v-textarea
> <v-textarea
required
rows="4"
v-model="template"
@@ -114,9 +110,8 @@
:label="$t('chat.actionTemplate')"
:rules="[required]"
@input="onInputTemplate"
>
<template v-slot:append-inner>
<v-btn
> <template v-slot:append-inner
> <v-btn
flat
size="x-small"
icon="mdi-help"
@@ -124,87 +119,75 @@
@click="
isShowTemplateParametersDialog = !isShowTemplateGuideTooltip
"
>
</v-btn>
</template>
</v-textarea>
<v-textarea
> </v-btn
> </template
> </v-textarea
> <v-textarea
required
rows="3"
v-model="suffix"
:placeholder="suffixPlaceholder"
:label="$t('chat.suffix')"
@input="onInputTemplate"
>
</v-textarea>
<label class="pl-4" style="font-size: 1.2rem">{{
> </v-textarea
> <label class="pl-4" style="font-size: 1.2rem">{{
$t("chat.preview")
}}</label>
<chat-prompt
}}</label
> <chat-prompt
class="w-100"
:message="{ content: previewRef }"
:isThread="false"
:columns="3"
></chat-prompt>
</v-form>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
></chat-prompt
> </v-form
> <v-card-actions
> <v-spacer></v-spacer> <v-btn
variant="outlined"
color="primary"
@click="isOpenAddEditAction = false"
>{{ $t("modal.cancel") }}</v-btn
>
<v-btn variant="flat" class="bg-primary" @click="addEditAction">{{
> <v-btn variant="flat" class="bg-primary" @click="addEditAction">{{
$t("modal.done")
}}</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-dialog
}}</v-btn
> </v-card-actions
> </v-card
> </v-dialog
> <v-dialog
width="auto"
:model-value="isShowTemplateParametersDialog"
v-on:after-leave="isShowTemplateParametersDialog = false"
>
<v-card>
<v-md-preview class="pa-4" :text="templateParametersInfo" />
</v-card>
</v-dialog>
<ConfirmModal ref="confirmModal" />
<v-snackbar
> <v-card
> <v-md-preview class="pa-4" :text="templateParametersInfo" /> </v-card
> </v-dialog
> <ConfirmModal ref="confirmModal" /> <v-snackbar
v-model="snackbar.show"
:timeout="snackbar.timeout"
:color="snackbar.color"
>
{{ snackbar.text }}
<template v-slot:actions>
<v-btn variant="text" @click="snackbar.show = false">
{{ $t("updates.close") }}
</v-btn>
</template>
</v-snackbar>
<v-dialog width="85vw" :model-value="isShowImportProgressDialog" persistent>
<v-card>
<v-card-title> {{ $t("chat.importLog") }} </v-card-title>
<v-textarea
> {{ snackbar.text }} <template v-slot:actions
> <v-btn variant="text" @click="snackbar.show = false"
> {{ $t("updates.close") }} </v-btn
> </template
> </v-snackbar
> <v-dialog width="85vw" :model-value="isShowImportProgressDialog" persistent
> <v-card
> <v-card-title> {{ $t("chat.importLog") }} </v-card-title> <v-textarea
readonly
hide-details
rows="20"
v-model="importProgressText"
id="import-log-textarea"
:loading="isImportCompleted === false"
></v-textarea>
<v-card-actions class="justify-end pr-6 pt-0" style="gap: 0.3rem">
<v-btn
></v-textarea
> <v-card-actions class="justify-end pr-6 pt-0" style="gap: 0.3rem"
> <v-btn
variant="text"
@click="isShowImportProgressDialog = false"
:disabled="isImportCompleted === false"
>
{{ $t("modal.done") }}
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
> {{ $t("modal.done") }} </v-btn
> </v-card-actions
> </v-card
> </v-dialog
>
</template>
<script setup>
@@ -807,6 +790,7 @@ async function deleteAction(item) {
}
}
</script>
<style scoped>
.no-text-transform {
text-transform: none !important;
@@ -820,3 +804,4 @@ async function deleteAction(item) {
padding: 0;
}
</style>
+17 -15
View File
@@ -1,30 +1,31 @@
<template>
<v-dialog
<v-dialog
v-model="dialog"
width="auto"
max-width="80%"
@click:outside="close(false)"
>
<v-card :title="_title">
<v-card-text>
> <v-card :title="_title"
> <v-card-text
>
<div v-html="_text"></div>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn variant="outlined" color="primary" @click="close(false)">{{
$t("header.no")
}}</v-btn>
<v-btn
</v-card-text
> <v-card-actions
> <v-spacer></v-spacer> <v-btn
variant="outlined"
color="primary"
@click="close(false)"
>{{ $t("header.no") }}</v-btn
> <v-btn
ref="defaultButton"
variant="flat"
color="primary"
class="bg-primary"
@click="close(true)"
>{{ $t("header.yes") }}</v-btn
>
</v-card-actions>
</v-card>
</v-dialog>
> </v-card-actions
> </v-card
> </v-dialog
>
</template>
<script setup>
@@ -67,3 +68,4 @@ defineExpose({
close,
});
</script>
+34 -36
View File
@@ -1,5 +1,5 @@
<template>
<v-form
<v-form
ref="formRef"
@submit.prevent="true"
v-shortkey="SHORTCUT_FIND.key"
@@ -12,8 +12,7 @@
min-width: 200px;
padding-top: 0.5rem;
"
>
<v-text-field
> <v-text-field
id="find-text-field"
@keydown.enter="() => find()"
@keydown.esc="closeFindTextField"
@@ -28,62 +27,60 @@
v-model="findTextModel"
v-show="isShowFindText"
prepend-inner-icon="mdi-magnify"
>
<template v-slot:append-inner>
<v-btn-group>
<v-btn
> <template v-slot:append-inner
> <v-btn-group
> <v-btn
size="x-small"
icon="mdi-chevron-up"
@click="find(true)"
></v-btn>
<v-btn
></v-btn
> <v-btn
size="x-small"
icon="mdi-chevron-down"
@click="find(false)"
></v-btn>
</v-btn-group>
<v-tooltip
></v-btn
> </v-btn-group
> <v-tooltip
:text="$t('find.matchCase')"
location="bottom"
v-model="isShowMatchCaseTooltip"
>
<template v-slot:activator="{ props }">
<v-btn-toggle v-model="matchCaseToggle">
<v-btn
> <template v-slot:activator="{ props }"
> <v-btn-toggle v-model="matchCaseToggle"
> <v-btn
:value="MATCH_CASE_VALUE"
v-bind="props"
size="x-small"
icon="mdi-format-letter-case"
></v-btn>
</v-btn-toggle>
</template>
</v-tooltip>
<v-tooltip
></v-btn
> </v-btn-toggle
> </template
> </v-tooltip
> <v-tooltip
:text="$t('find.wrapAround')"
location="bottom"
v-model="isShowWrapAroundTooltip"
>
<template v-slot:activator="{ props }">
<v-btn-toggle v-model="wrapAroundToggle">
<v-btn
> <template v-slot:activator="{ props }"
> <v-btn-toggle v-model="wrapAroundToggle"
> <v-btn
:value="WRAP_AROUND_VALUE"
v-bind="props"
size="x-small"
icon="mdi-autorenew"
></v-btn>
</v-btn-toggle>
</template>
</v-tooltip>
<v-btn-group>
<v-btn
></v-btn
> </v-btn-toggle
> </template
> </v-tooltip
> <v-btn-group
> <v-btn
size="x-small"
icon="mdi-close"
@click="closeFindTextField"
></v-btn>
</v-btn-group>
</template>
</v-text-field>
</v-form>
></v-btn
> </v-btn-group
> </template
> </v-text-field
> </v-form
>
</template>
<script setup>
@@ -149,3 +146,4 @@ defineExpose({
padding-right: 0;
}
</style>
+4 -2
View File
@@ -1,11 +1,12 @@
<template>
<v-avatar
<v-avatar
rounded="rounded"
:class="{ active: active, invert: isLogoInverted }"
:image="bot.getLogo()"
:alt="bot.getFullname()"
:title="bot.getFullname()"
></v-avatar>
></v-avatar
>
</template>
<script setup>
@@ -36,3 +37,4 @@ const isLogoInverted = computed(() => {
filter: invert(100%);
}
</style>
+38 -45
View File
@@ -1,62 +1,54 @@
<template>
<div class="text-center">
<v-menu
<v-menu
v-model="menu"
:close-on-content-click="false"
location="top"
scroll-strategy="block"
offset="12"
>
<template v-slot:activator="{ props }">
<v-btn
> <template v-slot:activator="{ props }"
> <v-btn
v-bind="props"
size="36"
color="primary"
flat
icon="mdi-dots-horizontal"
>
</v-btn>
</template>
<v-card>
<v-list
> </v-btn
> </template
> <v-card
> <v-list
class="bots-list"
density="compact"
:selected="favorited"
select-strategy="classic"
nav
>
<v-list-item
> <v-list-item
v-for="(bot, index) in shownBots"
:key="index"
:value="bot.getClassname()"
color="primary"
@click="toggleFavorite(bot)"
>
<template v-slot:prepend="{ isActive }">
<v-list-item-action start>
<v-checkbox-btn
> <template v-slot:prepend="{ isActive }"
> <v-list-item-action start
> <v-checkbox-btn
color="primary"
:model-value="isActive"
></v-checkbox-btn>
</v-list-item-action>
</template>
<v-list-item-title>
<BotLogo :bot="bot" active="true" size="24"></BotLogo>&nbsp;
<span>{{ bot.getFullname() }}</span>
</v-list-item-title>
</v-list-item>
</v-list>
<v-divider></v-divider>
<v-list>
<v-list-item>
<v-list-item-title class="font-weight-black">
{{ $t("footer.chooseFavorite") }}
</v-list-item-title>
<template v-slot:append>
<v-btn-toggle
></v-checkbox-btn
> </v-list-item-action
> </template
> <v-list-item-title
> <BotLogo :bot="bot" active="true" size="24"></BotLogo>&nbsp;
<span>{{ bot.getFullname() }}</span
> </v-list-item-title
> </v-list-item
> </v-list
> <v-divider></v-divider> <v-list
> <v-list-item
> <v-list-item-title class="font-weight-black"
> {{ $t("footer.chooseFavorite") }} </v-list-item-title
> <template v-slot:append
> <v-btn-toggle
v-model="selectedTags"
divided
color="primary"
@@ -64,17 +56,17 @@
variant="outlined"
rounded="xl"
@update:model-value="filterBots($event)"
>
<v-btn v-for="(tag, index) in tags" :key="index" :value="tag">
{{ $t(`footer.${tag}`) }}
</v-btn>
</v-btn-toggle>
</template>
</v-list-item>
</v-list>
</v-card>
</v-menu>
> <v-btn v-for="(tag, index) in tags" :key="index" :value="tag"
> {{ $t(`footer.${tag}`) }} </v-btn
> </v-btn-toggle
> </template
> </v-list-item
> </v-list
> </v-card
> </v-menu
>
</div>
</template>
<script setup>
@@ -143,3 +135,4 @@ defineExpose({
text-transform: none !important;
}
</style>
+34 -36
View File
@@ -1,12 +1,12 @@
<template>
<v-bottom-navigation
<v-bottom-navigation
class="footer"
v-shortkey="{
focusPromptTextarea: SHORTCUT_PROMPT_TEXTAREA.key,
toggleBotsMenu: SHORTCUT_BOTS_MENU.key,
}"
@shortkey="handleShortcut"
>
>
<div
style="
width: 100%;
@@ -16,7 +16,7 @@
flex-wrap: wrap;
"
>
<v-textarea
<v-textarea
:id="SHORTCUT_PROMPT_TEXTAREA.elementId"
v-model="prompt"
ref="promptTextArea"
@@ -30,9 +30,8 @@
autofocus
@keydown="filterEnterKey"
style="min-width: 390px"
>
<template v-slot:append-inner>
<v-btn
> <template v-slot:append-inner
> <v-btn
:id="SHORTCUT_PROMPT_MANAGEMENT.elementId"
@click="isPromptManagementOpen = !isPromptManagementOpen"
color="primary"
@@ -40,10 +39,10 @@
class="h-100 w-100"
style="border-radius: 4px; min-width: unset !important"
icon="mdi-creation-outline"
></v-btn>
</template>
</v-textarea>
<v-btn
></v-btn
> </template
> </v-textarea
> <v-btn
class="send-prompt-btn"
elevation="2"
:disabled="
@@ -51,39 +50,37 @@
favBots.filter((favBot) => activeBots[favBot.classname]).length === 0
"
@click="sendPromptToBots"
> {{ $t("footer.sendPrompt") }} </v-btn
>
{{ $t("footer.sendPrompt") }}
</v-btn>
<div
class="bot-logos"
ref="favBotLogosRef"
:key="rerenderFavBotLogos"
@contextmenu="show"
>
<v-menu
<v-menu
v-model="showMenu"
class="position-fixed"
:style="{ left: `${x}px`, top: `${y}px` }"
>
<v-list>
<v-list-item @click="disableAllBots">
<v-list-item-title>{{
> <v-list
> <v-list-item @click="disableAllBots"
> <v-list-item-title>{{
$t("footer.disableAll")
}}</v-list-item-title>
</v-list-item>
<v-list-item @click="enableAllBots">
<v-list-item-title>{{
}}</v-list-item-title
> </v-list-item
> <v-list-item @click="enableAllBots"
> <v-list-item-title>{{
$t("footer.enableAll")
}}</v-list-item-title>
</v-list-item>
<v-list-item @click="removeAllBots">
<v-list-item-title>{{
}}</v-list-item-title
> </v-list-item
> <v-list-item @click="removeAllBots"
> <v-list-item-title>{{
$t("footer.removeAll")
}}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
<BotLogo
}}</v-list-item-title
> </v-list-item
> </v-list
> </v-menu
> <BotLogo
v-for="(bot, index) in favBots"
:id="`fav-bot-${index + 1}`"
:key="index"
@@ -96,22 +93,22 @@
@shortkey="toggleSelected(bot.instance)"
/>
</div>
<BotsMenu
<BotsMenu
style="padding-bottom: 0.5rem; padding-left: 4px"
:id="SHORTCUT_BOTS_MENU.elementId"
ref="botsMenuRef"
:favBots="favBots"
/>
</div>
<MakeAvailableModal v-model:open="isMakeAvailableOpen" :bot="clickedBot" />
<ConfirmModal ref="confirmModal" />
<PromptModal
<MakeAvailableModal v-model:open="isMakeAvailableOpen" :bot="clickedBot" />
<ConfirmModal ref="confirmModal" /> <PromptModal
v-shortkey="SHORTCUT_PROMPT_MANAGEMENT.key"
@shortkey="isPromptManagementOpen = !isPromptManagementOpen"
v-model:open="isPromptManagementOpen"
@after-leave="usePrompt"
></PromptModal>
</v-bottom-navigation>
></PromptModal
> </v-bottom-navigation
>
</template>
<script setup>
@@ -529,3 +526,4 @@ textarea::placeholder {
padding-top: 0;
}
</style>
+11 -9
View File
@@ -1,13 +1,14 @@
<template>
<v-dialog :model-value="open" persistent width="auto">
<v-list v-if="botSettings !== null">
<component :is="botSettings" />
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="primary" @click="onDone">{{ $t("modal.done") }}</v-btn>
</v-card-actions>
</v-list>
</v-dialog>
<v-dialog :model-value="open" persistent width="auto"
> <v-list v-if="botSettings !== null"
> <component :is="botSettings" /> <v-card-actions
> <v-spacer></v-spacer> <v-btn color="primary" @click="onDone">{{
$t("modal.done")
}}</v-btn
> </v-card-actions
> </v-list
> </v-dialog
>
</template>
<script setup>
@@ -35,3 +36,4 @@ const onDone = () => {
</script>
<style scoped></style>
+16 -10
View File
@@ -1,29 +1,34 @@
<template>
<v-container v-if="loading" class="ma-0 position-fixed" style="z-index: 1">
<v-label class="bg-background" style="opacity: 1">{{
<v-container v-if="loading" class="ma-0 position-fixed" style="z-index: 1"
> <v-label class="bg-background" style="opacity: 1">{{
$t("chat.loading")
}}</v-label>
</v-container>
}}</v-label
> </v-container
>
<div class="messages">
<div
class="message-grid"
:style="{ gridTemplateColumns: gridTemplateColumns }"
>
<template v-for="(message, index) in currentChatMessages" :key="index">
<chat-prompt
<template v-for="(message, index) in currentChatMessages" :key="index"
> <chat-prompt
v-if="message.type === 'prompt'"
:columns="columns"
:message="message"
></chat-prompt>
<chat-response
></chat-prompt
> <chat-response
v-else
:chat="chat"
:columns="columns"
:messages="message"
></chat-response>
</template>
></chat-response
> </template
>
</div>
</div>
</template>
<script setup>
@@ -138,3 +143,4 @@ onMounted(async () => {
padding: 2rem;
}
</style>
+5 -3
View File
@@ -1,11 +1,12 @@
<template>
<v-card
<v-card
ref="root"
class="message prompt"
:class="isThread ? 'thread-prompt' : ''"
>
>
<pre>{{ message ? message.content : "" }}</pre>
</v-card>
</v-card
>
</template>
<script setup>
@@ -64,3 +65,4 @@ onMounted(() => {
margin-bottom: 1rem;
}
</style>
+50 -70
View File
@@ -1,5 +1,5 @@
<template>
<v-card
<v-card
ref="root"
:class="[
'message',
@@ -12,16 +12,12 @@
:flat="props.isThread"
:ripple="!isSelectedResponsesEmpty"
@click="!isSelectedResponsesEmpty && select($event)"
>
<v-card-title class="title">
<img
> <v-card-title class="title"
> <img
:src="botLogo"
:class="{ invert: isBotLogoInverted }"
:alt="botFullname"
/>
{{ botFullname }}
<v-spacer></v-spacer>
<v-btn
/> {{ botFullname }} <v-spacer></v-spacer> <v-btn
flat
size="x-small"
icon
@@ -29,74 +25,65 @@
:color="isHighlighted ? 'primary' : ''"
:class="getButtonClass"
v-show="isSelectedResponsesEmpty"
>
<v-icon>mdi-lightbulb-on-outline</v-icon>
</v-btn>
<v-btn
> <v-icon>mdi-lightbulb-on-outline</v-icon> </v-btn
> <v-btn
flat
size="x-small"
icon
@click="copyToClipboard"
v-show="isSelectedResponsesEmpty"
:class="getButtonClass"
>
<v-icon>mdi-content-copy</v-icon>
</v-btn>
<v-btn
> <v-icon>mdi-content-copy</v-icon> </v-btn
> <v-btn
flat
size="x-small"
v-show="isSelectedResponsesEmpty"
icon
@click="hide"
:class="getButtonClass"
>
<v-icon>mdi-delete</v-icon>
</v-btn>
<v-btn
> <v-icon>mdi-delete</v-icon> </v-btn
> <v-btn
flat
size="x-small"
icon
:class="getSelectButtonClass"
@click="select($event)"
>
<v-icon>{{
> <v-icon>{{
isSelected ? "mdi-check-circle" : "mdi-check-circle-outline"
}}</v-icon>
</v-btn>
</v-card-title>
<template v-if="messages && messages.length === 1">
<v-md-preview :text="messages[0].content" @click="handleClick" />
<template v-if="!isThread && messages.length && messages[0].hasThread">
<chat-thread
}}</v-icon
> </v-btn
> </v-card-title
> <template v-if="messages && messages.length === 1"
> <v-md-preview :text="messages[0].content" @click="handleClick" />
<template v-if="!isThread && messages.length && messages[0].hasThread"
> <chat-thread
:chat="chat"
:messageIndex="messages[0].index"
:messagePromptIndex="messages[0].promptIndex"
></chat-thread>
</template>
</template>
<v-carousel
></chat-thread
> </template
> </template
> <v-carousel
v-else
hide-delimiter-background
:hide-delimiters="true"
height="auto"
:show-arrows="false"
v-model="carouselModel"
>
<v-carousel-item v-for="(message, i) in messages" :key="i">
<v-md-preview :text="message.content" @click="handleClick" />
<template v-if="!isThread && message && message.hasThread">
<chat-thread
> <v-carousel-item v-for="(message, i) in messages" :key="i"
> <v-md-preview :text="message.content" @click="handleClick" />
<template v-if="!isThread && message && message.hasThread"
> <chat-thread
:chat="chat"
:messageIndex="message.index"
:messagePromptIndex="messages[0].promptIndex"
></chat-thread>
</template>
</v-carousel-item>
</v-carousel>
<v-card class="response" style="padding: 0; margin-top: 0.5rem" flat>
<v-card-title style="display: flex; padding: 0">
<v-spacer></v-spacer>
<v-btn
></chat-thread
> </template
> </v-carousel-item
> </v-carousel
> <v-card class="response" style="padding: 0; margin-top: 0.5rem" flat
> <v-card-title style="display: flex; padding: 0"
> <v-spacer></v-spacer> <v-btn
flat
icon
size="x-small"
@@ -104,10 +91,8 @@
v-if="isShowPagingButton"
@click="pageLeft"
:disabled="carouselModel === 0"
>
<v-icon>mdi-menu-left</v-icon>
</v-btn>
<v-btn
> <v-icon>mdi-menu-left</v-icon> </v-btn
> <v-btn
flat
icon
size="x-small"
@@ -115,20 +100,16 @@
v-if="isShowPagingButton"
@click="pageRight"
:disabled="carouselModel === maxPage"
>
<v-icon>mdi-menu-right</v-icon>
</v-btn>
<v-btn
> <v-icon>mdi-menu-right</v-icon> </v-btn
> <v-btn
flat
icon
size="x-small"
v-if="!(!isShowResendButton && !isShowReplyButton)"
:style="{ visibility: isShowResendButton ? 'visible' : 'hidden' }"
@click="resendPrompt(messages[0])"
>
<v-icon>mdi-refresh</v-icon>
</v-btn>
<v-btn
> <v-icon>mdi-refresh</v-icon> </v-btn
> <v-btn
flat
icon
size="x-small"
@@ -136,15 +117,14 @@
:style="{ visibility: isShowReplyButton ? 'visible' : 'hidden' }"
:color="isShowReplyTextField ? 'primary' : ''"
@click="toggleReplyButton"
>
<v-icon>mdi-reply</v-icon>
</v-btn>
</v-card-title>
> <v-icon>mdi-reply</v-icon> </v-btn
> </v-card-title
>
<div
v-show="isShowReplyTextField && isShowReplyButton"
style="display: flex; align-items: flex-end; margin-top: 1rem"
>
<v-textarea
<v-textarea
style="
padding-left: 0.1rem;
padding-right: 0.5rem;
@@ -160,19 +140,18 @@
variant="solo"
:placeholder="`${$t('footer.sendPrompt')} ${botFullname}`"
@keydown="filterEnterKey"
></v-textarea>
<v-btn
></v-textarea
> <v-btn
:disabled="replyModel.trim() === ''"
color="primary"
size="small"
@click="sendPromptToBot"
> <v-icon>mdi-send</v-icon> </v-btn
>
<v-icon>mdi-send</v-icon>
</v-btn>
</div>
</v-card>
</v-card>
<ConfirmModal ref="confirmModal" />
</v-card
> </v-card
> <ConfirmModal ref="confirmModal" />
</template>
<script setup>
@@ -623,3 +602,4 @@ function pageRight() {
overflow-y: overlay;
}
</style>
+8 -6
View File
@@ -1,20 +1,21 @@
<template>
<template v-for="(message, index) in currentChatMessages" :key="index">
<chat-prompt
<template v-for="(message, index) in currentChatMessages" :key="index"
> <chat-prompt
v-if="message.type === 'prompt'"
:message="message"
:columns="1"
:isThread="true"
></chat-prompt>
<chat-response
></chat-prompt
> <chat-response
v-else
:chat="chat"
:columns="1"
:messages="message"
:messagePromptIndex="messagePromptIndex"
:isThread="true"
></chat-response>
</template>
></chat-response
> </template
>
</template>
<script setup>
@@ -81,3 +82,4 @@ const currentChatMessages = useObservable(
}),
);
</script>
@@ -1,34 +1,31 @@
<template>
<div id="snackbar" class="text-center">
<v-snackbar :vertical="true" :timeout="-1" multi-line v-model="snackbar">
<span class="text-center font-weight-bold">
{{ $t("updates.updateAvailable") }}
</span>
<span class="text-center">
{{ $t("updates.currentVersion") }}: {{ versions.current }}
</span>
<span class="text-center">
{{ $t("updates.latestVersion") }}: {{ versions.latest }}
</span>
<v-btn
<v-snackbar :vertical="true" :timeout="-1" multi-line v-model="snackbar"
> <span class="text-center font-weight-bold"
> {{ $t("updates.updateAvailable") }} </span
> <span class="text-center"
> {{ $t("updates.currentVersion") }}: {{ versions.current }} </span
> <span class="text-center"
> {{ $t("updates.latestVersion") }}: {{ versions.latest }} </span
> <v-btn
prepend-icon="mdi-github"
color="primary"
variant="tonal"
@click="openReleasePage"
>
{{ $t("updates.downloadFromGitHub") }}
</v-btn>
<template v-slot:actions>
<v-btn color="primary" @click="skip">
{{ $t("updates.skipThisVersion") }}
</v-btn>
<v-btn color="primary" @click="snackbar = false">
{{ $t("updates.close") }}
</v-btn>
</template>
</v-snackbar>
> {{ $t("updates.downloadFromGitHub") }} </v-btn
> <template v-slot:actions
> <v-btn color="primary" @click="skip"
> {{ $t("updates.skipThisVersion") }} </v-btn
> <v-btn color="primary" @click="snackbar = false"
> {{ $t("updates.close") }} </v-btn
> </template
> </v-snackbar
>
</div>
</template>
<script setup>
import { ref } from "vue";
import { compare } from "compare-versions";
@@ -63,6 +60,7 @@ function openReleasePage() {
shell.openExternal(`https://github.com/ai-shifu/ChatALL/releases/latest`);
}
</script>
<style scoped>
:deep() .v-btn {
text-transform: none;
@@ -89,3 +87,4 @@ span {
color: rgb(var(--v-theme-font));
}
</style>
+54 -51
View File
@@ -1,13 +1,13 @@
<template>
<div>
<v-dialog
<v-dialog
:model-value="props.open"
@update:model-value="closeDialog"
@after-leave="onDialogCloseTransitionEnded"
>
<v-card class="justify-center">
<v-card-title>
<v-text-field
> <v-card class="justify-center"
> <v-card-title
> <v-text-field
clearable
v-model="search"
density="compact"
@@ -16,18 +16,16 @@
single-line
hide-details
autofocus
></v-text-field>
></v-text-field
>
<div class="pt-2 d-flex justify-space-between">
<v-btn
<v-btn
class="mt-1"
prepend-icon="mdi-plus"
:text="$t('prompt.addPrompt')"
@click="add"
></v-btn>
<v-spacer></v-spacer>
<v-spacer></v-spacer>
<v-select
></v-btn
> <v-spacer></v-spacer> <v-spacer></v-spacer> <v-select
color="primary"
density="compact"
:items="prompts.languages"
@@ -36,10 +34,11 @@
item-value="code"
:model-value="language"
@update:model-value="setPromptLanguage($event)"
></v-select>
></v-select
>
</div>
</v-card-title>
<v-data-table
</v-card-title
> <v-data-table
:headers="headers"
:items="data"
:search="search"
@@ -48,89 +47,92 @@
hover
:no-data-text="$t('find.noMatches')"
items-per-page="10"
>
<template v-slot:item="{ item }">
> <template v-slot:item="{ item }"
>
<tr>
<td
@click="usePrompt(item)"
@mouseover="showFullText($event)"
@mouseleave="hideFullText($event)"
>
{{ item.title }}
{{ item.title }}
</td>
<td
@click="usePrompt(item)"
@mouseover="showFullText($event)"
@mouseleave="hideFullText($event)"
>
{{ item.prompt }}
{{ item.prompt }}
</td>
<td>
<v-btn
<v-btn
flat
size="x-small"
:icon="item.isPin ? 'mdi-star' : 'mdi-star-outline'"
@click="pin(item)"
></v-btn>
<v-btn
></v-btn
> <v-btn
flat
size="x-small"
icon="mdi-pencil"
@click="edit(item)"
v-if="item.index"
></v-btn>
<v-btn
></v-btn
> <v-btn
flat
size="x-small"
icon="mdi-delete-outline"
@click="deletePrompt(item)"
v-if="item.index"
></v-btn>
></v-btn
>
</td>
</tr>
</template>
</v-data-table>
</v-card>
</v-dialog>
<v-dialog
</tr>
</template
> </v-data-table
> </v-card
> </v-dialog
> <v-dialog
persistent
width="50%"
:model-value="isOpenAddEditPrompt"
@update:model-value="isOpenAddEditPrompt = $event"
>
<v-card>
<v-form ref="formRef" class="pa-3" @submit.prevent>
<v-text-field
> <v-card
> <v-form ref="formRef" class="pa-3" @submit.prevent
> <v-text-field
required
:placeholder="$t('prompt.title')"
v-model="title"
:rules="requiredRule"
></v-text-field>
<v-textarea
></v-text-field
> <v-textarea
required
:placeholder="$t('prompt.prompt')"
v-model="prompt"
:rules="requiredRule"
></v-textarea>
</v-form>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
></v-textarea
> </v-form
> <v-card-actions
> <v-spacer></v-spacer> <v-btn
variant="outlined"
color="primary"
@click="isOpenAddEditPrompt = false"
>{{ $t("modal.cancel") }}</v-btn
>
<!-- color="primary" not working for nested dialog button -->
<v-btn variant="flat" class="bg-primary" @click="addEditPrompt">{{
$t("modal.done")
}}</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<ConfirmModal ref="confirmModal" />
> <!-- color="primary" not working for nested dialog button --> <v-btn
variant="flat"
class="bg-primary"
@click="addEditPrompt"
>{{ $t("modal.done") }}</v-btn
> </v-card-actions
> </v-card
> </v-dialog
> <ConfirmModal ref="confirmModal" />
</div>
</template>
<script setup>
@@ -313,3 +315,4 @@ td:nth-child(2) {
background-color: transparent;
}
</style>
+69 -90
View File
@@ -1,132 +1,110 @@
<template>
<v-list>
<v-list-item>
<v-list-item-title>{{ $t("proxy.enableProxy") }}</v-list-item-title>
<v-checkbox
<v-list
> <v-list-item
> <v-list-item-title>{{ $t("proxy.enableProxy") }}</v-list-item-title
> <v-checkbox
:label="$t('settings.enable')"
v-model="proxySettings.enableProxy"
hide-details
></v-checkbox>
</v-list-item>
<v-list-item>
<v-list-item-title>{{ $t("proxy.proxyMode") }} </v-list-item-title>
<v-radio-group inline hide-details v-model="proxySettings.proxyMode">
<v-radio :label="$t('proxy.globalMode')" value="normal"></v-radio>
></v-checkbox
> </v-list-item
> <v-list-item
> <v-list-item-title>{{ $t("proxy.proxyMode") }} </v-list-item-title>
<v-radio-group inline hide-details v-model="proxySettings.proxyMode"
> <v-radio :label="$t('proxy.globalMode')" value="normal"></v-radio>
<v-radio :label="$t('proxy.pacFileMode')" value="pacFile"></v-radio>
<v-radio :label="$t('proxy.pacUrlMode')" value="pacUrl"></v-radio>
</v-radio-group>
</v-list-item>
<v-list-item v-if="proxySettings.proxyMode == 'normal'">
<v-list-item-title>{{ $t("proxy.address") }}</v-list-item-title>
<v-text-field
</v-radio-group
> </v-list-item
> <v-list-item v-if="proxySettings.proxyMode == 'normal'"
> <v-list-item-title>{{ $t("proxy.address") }}</v-list-item-title
> <v-text-field
v-model="proxySettings.proxyServer"
:hint="
$t('settings.forExample', { example: $t('proxy.addressExample') })
"
persistent-hint
></v-text-field>
<v-list-item-title>{{ $t("proxy.byPass") }}</v-list-item-title>
<v-tabs fixed-tabs v-model="bypassSetMode">
<v-tab value="quickSet">
{{ $t("proxy.quickSet") }}
</v-tab>
<v-tab value="fullSet">
{{ $t("proxy.fullSet") }}
</v-tab>
</v-tabs>
<v-card>
<v-row
></v-text-field
> <v-list-item-title>{{ $t("proxy.byPass") }}</v-list-item-title
> <v-tabs fixed-tabs v-model="bypassSetMode"
> <v-tab value="quickSet"> {{ $t("proxy.quickSet") }} </v-tab> <v-tab
value="fullSet"
> {{ $t("proxy.fullSet") }} </v-tab
> </v-tabs
> <v-card
> <v-row
class="align-content-start"
v-if="bypassSetMode == 'quickSet'"
dense
>
<template v-for="(bot, index) in bots" :key="index">
<v-col cols="auto" class="pt-2">
<v-checkbox
> <template v-for="(bot, index) in bots" :key="index"
> <v-col cols="auto" class="pt-2"
> <v-checkbox
v-model="botsProxy"
:label="bot.name"
:value="bot.name"
hide-details
></v-checkbox>
</v-col>
</template>
</v-row>
</v-card>
<v-card v-if="bypassSetMode == 'fullSet'">
<v-textarea
></v-checkbox
> </v-col
> </template
> </v-row
> </v-card
> <v-card v-if="bypassSetMode == 'fullSet'"
> <v-textarea
v-model="proxySettings.proxyBypassList"
:hint="$t('proxy.byPassHint')"
persistent-hint
></v-textarea>
</v-card>
</v-list-item>
<v-list-item v-if="proxySettings.proxyMode == 'pacFile'">
<v-list-item-title>{{ $t("proxy.pacFile") }}</v-list-item-title>
<v-text-field
></v-textarea
> </v-card
> </v-list-item
> <v-list-item v-if="proxySettings.proxyMode == 'pacFile'"
> <v-list-item-title>{{ $t("proxy.pacFile") }}</v-list-item-title
> <v-text-field
v-model="proxySettings.pacFile"
:label="$t('proxy.pacFileUsing')"
disabled
></v-text-field>
<v-file-input
></v-text-field
> <v-file-input
:label="$t('proxy.pacFileNew')"
@change="onFileChange"
></v-file-input>
</v-list-item>
<v-list-item v-if="proxySettings.proxyMode == 'pacUrl'">
<v-list-item-title>{{ $t("proxy.pacUrl") }}</v-list-item-title>
<v-text-field
></v-file-input
> </v-list-item
> <v-list-item v-if="proxySettings.proxyMode == 'pacUrl'"
> <v-list-item-title>{{ $t("proxy.pacUrl") }}</v-list-item-title
> <v-text-field
v-model="proxySettings.pacUrl"
:label="$t('proxy.pacUrl')"
></v-text-field>
</v-list-item>
<v-list-item>
<v-btn color="primary" @click="saveAndActive" class="ma-2 pa-2">
{{ $t("proxy.saveAndApply") }}
</v-btn>
<v-btn variant="outlined" color="primary" @click="onlySave">
{{ $t("proxy.onlySave") }}
</v-btn>
<v-btn
></v-text-field
> </v-list-item
> <v-list-item
> <v-btn color="primary" @click="saveAndActive" class="ma-2 pa-2"
> {{ $t("proxy.saveAndApply") }} </v-btn
> <v-btn variant="outlined" color="primary" @click="onlySave"
> {{ $t("proxy.onlySave") }} </v-btn
> <v-btn
variant="outlined"
color="primary"
@click="reload"
class="ma-2 pa-2"
>
{{ $t("proxy.reload") }}
</v-btn>
<v-btn variant="outlined" color="primary" @click="resetAll">
{{ $t("proxy.reset") }}
</v-btn>
</v-list-item>
<v-list-item>
<v-divider></v-divider>
</v-list-item>
<v-list-item>
<v-list-item-title>{{ $t("proxy.proxyFilePath") }}</v-list-item-title>
<v-text-field
> {{ $t("proxy.reload") }} </v-btn
> <v-btn variant="outlined" color="primary" @click="resetAll"
> {{ $t("proxy.reset") }} </v-btn
> </v-list-item
> <v-list-item> <v-divider></v-divider> </v-list-item> <v-list-item
> <v-list-item-title>{{ $t("proxy.proxyFilePath") }}</v-list-item-title
> <v-text-field
v-model="userDataPath"
disabled
:hint="$t('proxy.proxyFilePathHint')"
persistent-hint
></v-text-field>
</v-list-item>
</v-list>
<v-snackbar
></v-text-field
> </v-list-item
> </v-list
> <v-snackbar
v-model="snackbar.show"
:timeout="snackbar.timeout"
:color="snackbar.color"
>
{{ snackbar.text }}
</v-snackbar>
<ConfirmModal ref="confirmModal" />
> {{ snackbar.text }} </v-snackbar
> <ConfirmModal ref="confirmModal" />
</template>
<script setup>
@@ -311,3 +289,4 @@ defineExpose({
onFileChange,
});
</script>
+49 -50
View File
@@ -1,91 +1,89 @@
<template>
<v-dialog
<v-dialog
:model-value="props.open"
fullscreen
:scrim="false"
transition="dialog-bottom-transition"
>
<v-card class="overflow-hidden">
> <v-card class="overflow-hidden"
>
<div class="d-flex flex-column h-screen">
<v-toolbar height="100px" dark color="primary">
<v-toolbar-title>{{ $t("settings.title") }}</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn icon dark @click="closeDialog">
<v-icon>mdi-close</v-icon>
</v-btn>
</v-toolbar>
<v-row style="height: calc(100% - 100px)">
<v-col cols="2" class="h-100 overflow-auto pr-0">
<v-tabs v-model="tab" direction="vertical" color="primary">
<v-tab value="general">{{ $t("settings.general") }}</v-tab>
<v-tab value="proxy">{{ $t("proxy.name") }}</v-tab>
<v-tab value="chat">{{ $t("chat.name") }}</v-tab>
<v-tab
<v-toolbar height="100px" dark color="primary"
> <v-toolbar-title>{{ $t("settings.title") }}</v-toolbar-title
> <v-spacer></v-spacer> <v-btn icon dark @click="closeDialog"
> <v-icon>mdi-close</v-icon> </v-btn
> </v-toolbar
> <v-row style="height: calc(100% - 100px)"
> <v-col cols="2" class="h-100 overflow-auto pr-0"
> <v-tabs v-model="tab" direction="vertical" color="primary"
> <v-tab value="general">{{ $t("settings.general") }}</v-tab
> <v-tab value="proxy">{{ $t("proxy.name") }}</v-tab
> <v-tab value="chat">{{ $t("chat.name") }}</v-tab
> <v-tab
v-for="(setting, index) in botSettings"
:key="index"
:value="index"
> {{ $t(`${setting.brand}.name`) }} </v-tab
> </v-tabs
> </v-col
> <v-col class="h-100 overflow-auto"
> <v-list lines="two" subheader
>
{{ $t(`${setting.brand}.name`) }}
</v-tab>
</v-tabs>
</v-col>
<v-col class="h-100 overflow-auto">
<v-list lines="two" subheader>
<div v-if="tab == 'general'">
<v-list-item>
<v-list-item-title>{{
<v-list-item
> <v-list-item-title>{{
$t("settings.language")
}}</v-list-item-title>
<v-select
}}</v-list-item-title
> <v-select
:items="languages"
item-title="name"
item-value="code"
hide-details
:model-value="lang"
@update:model-value="setCurrentLanguage($event)"
></v-select>
</v-list-item>
<v-list-item>
<v-list-item-title>{{
></v-select
> </v-list-item
> <v-list-item
> <v-list-item-title>{{
$t("settings.theme")
}}</v-list-item-title>
<v-select
}}</v-list-item-title
> <v-select
:items="modes"
item-title="name"
item-value="code"
hide-details
:model-value="currentMode"
@update:model-value="setCurrentMode($event)"
></v-select>
</v-list-item>
<CommonBotSettings
></v-select
> </v-list-item
> <CommonBotSettings
:settings="settings"
brand-id="general"
mutation-type="setGeneral"
></CommonBotSettings>
></CommonBotSettings
>
</div>
<div v-if="tab == 'proxy'">
<component :is="proxy"></component>
<component :is="proxy"></component>
</div>
<div v-if="tab == 'chat'">
<component :is="chat" @close-dialog="closeDialog"></component>
<component :is="chat" @close-dialog="closeDialog"></component>
</div>
<template v-for="(setting, index) in botSettings" :key="index">
<component
<template v-for="(setting, index) in botSettings" :key="index"
> <component
v-if="tab == index"
:is="setting.component"
></component>
</template>
</v-list>
</v-col>
</v-row>
></component
> </template
> </v-list
> </v-col
> </v-row
>
</div>
</v-card>
</v-dialog>
</v-card
> </v-dialog
>
</template>
<script setup>
@@ -242,3 +240,4 @@ watch(
text-transform: none !important;
}
</style>
@@ -1,20 +1,23 @@
<template>
<v-overlay
<v-overlay
:scrim="true"
:model-value="props.open"
v-on:after-leave="closeShortcutGuide"
@click="closeShortcutGuide"
>
>
<div
style="position: absolute; top: 0; left: 0; width: 100vw; height: 100vh"
>
<div
ref="shortcutGuideContentRef"
style="position: relative"
class="markdown-body"
></div>
</div>
</v-overlay>
</v-overlay
>
</template>
<script setup>
@@ -93,6 +96,7 @@ defineExpose({
toggleShortcutGuide,
});
</script>
<style scoped>
:deep() .shortcut-label {
position: absolute;
@@ -126,3 +130,4 @@ defineExpose({
box-shadow: inset 0 -1px 0 rgba(110, 118, 129, 0.4);
}
</style>