Skip to content

Commit

Permalink
Refine Midjourney UX layout (#59)
Browse files Browse the repository at this point in the history
Co-authored-by: Germey <germey@acedata.cloud>
Co-authored-by: AceDataCloud <office@acedata.cloud>
  • Loading branch information
3 people authored Jun 27, 2024
1 parent 4938f09 commit 74cec8e
Show file tree
Hide file tree
Showing 50 changed files with 5,793 additions and 5,829 deletions.
186 changes: 93 additions & 93 deletions CHANGELOG.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Update mj new layout",
"packageName": "@acedatacloud/nexior",
"email": "germey@acedata.cloud",
"dependentChangeType": "patch"
}
4 changes: 4 additions & 0 deletions src/assets/scss/_markdown.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
box-shadow: 0px 0px 3px 0px var(--color-border-muted);
}

.markdown-body table tr {
background-color: var(--el-color-info-light-2) !important;
}

pre {
position: relative;
}
Expand Down
76 changes: 56 additions & 20 deletions src/components/chat/Message.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,41 @@
}"
:role="message.role"
>
<div class="content">
<markdown-renderer v-if="!Array.isArray(message.content)" :content="message?.content" />
<div v-else>
<div v-for="(item, index) in message.content" :key="index">
<img v-if="item.type === 'image_url'" :src="item.image_url?.url" fit="cover" class="image" />
<markdown-renderer v-if="item.type === 'text'" :key="index" :content="item.text" />
<div class="author">
<el-image
v-if="message.role === 'assistant'"
src="https://cdn.acedata.cloud/7dljuv.png"
fit="cover"
class="avatar"
/>
</div>
<div class="main">
<div class="content">
<markdown-renderer v-if="!Array.isArray(message.content)" :content="message?.content" />
<div v-else>
<div v-for="(item, index) in message.content" :key="index">
<img v-if="item.type === 'image_url'" :src="item.image_url?.url" fit="cover" class="image" />
<markdown-renderer v-if="item.type === 'text'" :key="index" :content="item.text" />
</div>
</div>
<answering-mark v-if="message.state === messageState.PENDING" />
</div>
<div class="operations">
<copy-to-clipboard v-if="!Array.isArray(message.content)" :content="message.content!" class="btn-copy" />
</div>
<answering-mark v-if="message.state === messageState.PENDING" />
</div>
<div class="operations">
<copy-to-clipboard v-if="!Array.isArray(message.content)" :content="message.content!" class="btn-copy" />
</div>
<el-alert v-if="errorText" class="error" :title="errorText" type="error" :closable="false" />
<el-button v-if="showBuyMore" round type="primary" class="btn btn-buy" size="small" @click="onBuyMore">
{{ $t('common.button.buyMore') }}
</el-button>
</div>
<el-alert v-if="errorText" class="error" :title="errorText" type="error" :closable="false" />
<el-button v-if="showBuyMore" round type="primary" class="btn btn-buy" size="small" @click="onBuyMore">
{{ $t('common.button.buyMore') }}
</el-button>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import AnsweringMark from './AnsweringMark.vue';
import copy from 'copy-to-clipboard';
import { ElAlert, ElButton } from 'element-plus';
import { ElAlert, ElButton, ElImage } from 'element-plus';
import MarkdownRenderer from '@/components/common/MarkdownRenderer.vue';
import { IApplication, IChatMessage, IChatMessageState } from '@/models';
import CopyToClipboard from '../common/CopyToClipboard.vue';
Expand Down Expand Up @@ -60,7 +70,8 @@ export default defineComponent({
AnsweringMark,
MarkdownRenderer,
ElAlert,
ElButton
ElButton,
ElImage
},
props: {
message: {
Expand Down Expand Up @@ -145,31 +156,56 @@ export default defineComponent({
}
.message {
display: flex;
flex-direction: column;
flex-direction: row;
margin-bottom: 15px;
&[role='system'] {
display: none;
}
&.hidden {
display: none;
}
.author {
width: 50px;
padding: 10px;
.avatar {
width: 30px;
height: 30px;
border-radius: 50%;
border: 1px solid var(--el-border-color);
}
}
.main {
flex: 1;
width: calc(100% - 50px);
display: flex;
flex-direction: column;
}
&.assistant {
align-items: start;
.content {
background-color: var(--el-bg-color-page);
color: var(--el-text-color-primary);
}
}
&.user {
align-items: end;
.main {
align-items: end;
}
.content {
background-color: var(--el-bg-color-page);
color: var(--el-text-color-primary);
width: fit-content;
text-align: right;
padding: 8px 15px;
}
}
.content {
border-radius: 20px;
padding: 8px 15px;
padding: 8px;
width: 100%;
max-width: 800px;
.image {
Expand Down
189 changes: 189 additions & 0 deletions src/components/midjourney/InputBox.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
<template>
<div class="input-box">
<el-tooltip class="box-item" effect="dark" :content="$t('midjourney.message.operation')" placement="top">
<span class="btn btn-upload" @click="$emit('toggle-panel')" @mouseenter="$emit('open-panel')">
<font-awesome-icon icon="fa-solid fa-plus" class="icon icon-operation" />
</span>
</el-tooltip>
<span
:class="{
btn: true,
'btn-send': true,
disabled: !promptValue
}"
@click="onSubmit"
>
<font-awesome-icon icon="fa-solid fa-location-arrow" class="icon icon-send" />
</span>
<!-- add this textarea -->
<textarea
ref="textarea"
v-model="promptValue"
class="input"
:placeholder="$t('midjourney.message.promptPlaceholder')"
:style="{ height: inputHeight }"
@keydown.enter.exact.prevent="onSubmit"
@focus="$emit('close-panel')"
@input="adjustTextareaHeight"
></textarea>
</div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import { ElTooltip } from 'element-plus';
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
export default defineComponent({
name: 'InputBox',
components: {
ElTooltip,
FontAwesomeIcon
},
props: {
prompt: {
type: String,
required: true
}
},
emits: ['update:prompt', 'submit', 'open-panel', 'toggle-panel', 'close-panel'],
data() {
return {
inputHeight: '35px', //add inputHeight
promptValue: this.prompt
};
},
watch: {
promptValue(val: string) {
this.$emit('update:prompt', val);
},
prompt(val: string) {
if (val !== this.promptValue) {
this.promptValue = val;
}
}
},
methods: {
// add textarea method
adjustTextareaHeight() {
this.$nextTick(() => {
const textarea = this.$refs.textarea;
if (textarea) {
// @ts-ignore
textarea.style.height = '35px';
// @ts-ignore
if (this.prompt) {
textarea.style.height = textarea.scrollHeight + 'px';
}
}
});
},
onSubmit() {
if (!this.prompt) {
return;
}
this.$emit('submit');
}
}
});
</script>

<style lang="scss">
textarea.input {
font-size: 14px;
min-height: 35px;
max-height: 350px;
border: none;
background: none;
box-shadow: none;
resize: none;
line-height: 25px;
width: calc(100% - 80px);
margin-left: 30px;
font-family: var(--el-font-family);
padding-top: 6px;
}
textarea.input:focus {
outline: none;
}
.input-box {
position: relative;
.input {
textarea {
max-height: 100px;
border: none;
background: none;
box-shadow: none;
resize: none;
line-height: 35px;
}
}
.el-textarea.is-disabled .el-textarea__inner {
background-color: initial;
}
}
</style>

<style lang="scss" scoped>
.input-box {
width: 100%;
max-width: 100%;
margin: auto;
position: relative;
border-radius: 10px;
background: var(--el-color-info-light-9);
padding: 5px;
.upload {
display: inline-block;
&.disabled {
.btn-upload {
cursor: not-allowed;
.icon-attachment {
color: var(--el-text-color-disabled);
}
}
}
}
.input {
border: none;
width: calc(100% - 80px);
margin-left: 35px;
line-height: 28px;
}
.btn {
display: block;
z-index: 100;
cursor: pointer;
bottom: 15px;
position: absolute;
&.btn-upload {
left: 15px;
background: var(--el-color-info-light-5);
border-radius: 50%;
width: 20px;
height: 20px;
font-size: 12px;
text-align: center;
padding-top: 2px;
.icon-attachment {
font-size: 16px;
color: var(--el-text-color-primary);
}
}
&.btn-send {
right: 15px;
&.disabled {
.icon-send {
color: var(--el-text-color-disabled);
}
cursor: not-allowed;
}
.icon-send {
font-size: 16px;
color: var(--el-text-color-primary);
}
}
}
}
</style>
Loading

0 comments on commit 74cec8e

Please sign in to comment.