合并merchant文件
This commit is contained in:
@@ -1,11 +1,17 @@
|
||||
<!-- 商家端 - 聊天页面 -->
|
||||
<template>
|
||||
<view class="chat-page">
|
||||
<<<<<<< HEAD
|
||||
<view class="chat-header">
|
||||
=======
|
||||
<!-- 聊天头部 -->
|
||||
<view class="chat-header" :style="{ paddingTop: navPaddingTop }">
|
||||
>>>>>>> local-backup-root-cyj
|
||||
<view class="header-back" @click="goBack">
|
||||
<text class="back-icon">‹</text>
|
||||
</view>
|
||||
<view class="header-info">
|
||||
<<<<<<< HEAD
|
||||
<text class="chat-title">{{ chatTitle }}</text>
|
||||
<text class="chat-status">在线</text>
|
||||
</view>
|
||||
@@ -32,25 +38,141 @@
|
||||
</view>
|
||||
</view>
|
||||
<image class="avatar me" src="/static/images/default-shop.png" mode="aspectFill" />
|
||||
=======
|
||||
<view class="header-info-text-wrapper">
|
||||
<text class="chat-title">{{ chatTitle }}</text>
|
||||
<text class="chat-status">在线</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="header-actions">
|
||||
<view class="action-icon" @click="showMoreActions">
|
||||
<text class="action-icon-text">⋯</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 聊天内容 -->
|
||||
<scroll-view
|
||||
scroll-y="true"
|
||||
class="chat-content"
|
||||
:scroll-into-view="scrollToView"
|
||||
:scroll-with-animation="true"
|
||||
:show-scrollbar="false"
|
||||
>
|
||||
<view class="chat-messages">
|
||||
<!-- 系统消息 -->
|
||||
<view class="message-item system">
|
||||
<text class="system-text">已接入客户对话</text>
|
||||
</view>
|
||||
|
||||
<!-- 消息列表 -->
|
||||
<view
|
||||
v-for="message in chatMessages"
|
||||
:key="message.id"
|
||||
:class="['message-item', message.is_from_user ? 'received' : 'sent']"
|
||||
:id="message.viewId"
|
||||
>
|
||||
<!-- 客户消息 -->
|
||||
<view v-if="message.is_from_user" class="message-wrapper">
|
||||
<image
|
||||
class="avatar"
|
||||
:src="userAvatar"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<view class="message-content-wrapper">
|
||||
<text class="sender-name">{{ chatTitle }}</text>
|
||||
<view class="message-bubble received-bubble" :class="{ 'image-bubble': message.msg_type === 'image' || message.content.includes('/chat_images/') }">
|
||||
<text v-if="!(message.msg_type === 'image' || message.content.includes('/chat_images/'))" class="message-text">{{ message.content }}</text>
|
||||
<image v-else mode="widthFix" class="message-image" :src="message.content" @click="previewImage(message.content)" />
|
||||
<text class="message-time">{{ message.time }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 我的消息 -->
|
||||
<view v-else class="message-wrapper me">
|
||||
<view class="message-content-wrapper">
|
||||
<view class="message-bubble me" :class="{ 'image-bubble': message.msg_type === 'image' || message.content.includes('/chat_images/') }">
|
||||
<text v-if="!(message.msg_type === 'image' || message.content.includes('/chat_images/'))" class="message-text">{{ message.content }}</text>
|
||||
<image v-else mode="widthFix" class="message-image" :src="message.content" @click="previewImage(message.content)" />
|
||||
<text class="message-time">{{ message.time }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<image
|
||||
class="avatar me"
|
||||
:src="shopAvatar"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
>>>>>>> local-backup-root-cyj
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<<<<<<< HEAD
|
||||
<view class="chat-input">
|
||||
<input v-model="inputText" class="input-field" placeholder="请输入消息..." confirm-type="send" @confirm="sendMessage" />
|
||||
<view class="send-btn" @click="sendMessage">
|
||||
<text class="send-icon">➤</text>
|
||||
</view>
|
||||
</view>
|
||||
=======
|
||||
<!-- 聊天输入区 -->
|
||||
<view class="chat-input">
|
||||
<view class="input-tools">
|
||||
<text class="tool-icon" @click="showEmojiPicker">😊</text>
|
||||
<text class="tool-icon" @click="showImagePicker">📷</text>
|
||||
</view>
|
||||
|
||||
<view class="input-wrapper">
|
||||
<input
|
||||
class="message-input"
|
||||
v-model="inputText"
|
||||
placeholder="请输入消息..."
|
||||
:focus="inputFocus"
|
||||
@confirm="sendMessage"
|
||||
confirm-type="send"
|
||||
/>
|
||||
<button
|
||||
class="send-button"
|
||||
:class="{ active: inputText.trim() != '' }"
|
||||
@click="sendMessage"
|
||||
>
|
||||
发送
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 表情选择器 -->
|
||||
<scroll-view v-if="showEmoji" class="emoji-picker" direction="vertical">
|
||||
<view class="emoji-category">
|
||||
<text
|
||||
v-for="emoji in emojiList"
|
||||
:key="emoji"
|
||||
class="emoji-item"
|
||||
@click="insertEmoji(emoji)"
|
||||
>
|
||||
{{ emoji }}
|
||||
</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
>>>>>>> local-backup-root-cyj
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="uts">
|
||||
import supa from '@/components/supadb/aksupainstance.uts'
|
||||
<<<<<<< HEAD
|
||||
|
||||
type ChatMessageType = {
|
||||
id: string
|
||||
=======
|
||||
import type { AkSupaRealtimeChannel } from '@/components/supadb/aksupa.uts'
|
||||
|
||||
type ChatMessageType = {
|
||||
id: string
|
||||
viewId: string
|
||||
>>>>>>> local-backup-root-cyj
|
||||
session_id: string
|
||||
sender_id: string
|
||||
receiver_id: string
|
||||
@@ -59,6 +181,10 @@
|
||||
is_read: boolean
|
||||
is_from_user: boolean
|
||||
created_at: string
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
time: string
|
||||
>>>>>>> local-backup-root-cyj
|
||||
}
|
||||
|
||||
export default {
|
||||
@@ -70,11 +196,35 @@
|
||||
inputText: '',
|
||||
chatMessages: [] as ChatMessageType[],
|
||||
scrollToView: '',
|
||||
<<<<<<< HEAD
|
||||
merchantId: ''
|
||||
=======
|
||||
merchantId: '',
|
||||
userAvatar: '/static/images/default-avatar.png',
|
||||
shopAvatar: '/static/images/default-shop.png',
|
||||
navPaddingTop: '30px',
|
||||
showEmoji: false,
|
||||
inputFocus: false,
|
||||
realtimeChannel: null as AkSupaRealtimeChannel | null
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
emojiList(): string[] {
|
||||
return ['😊', '😂', '🤣', '😍', '😘', '🥰', '😭', '😡', '👍', '👏', '🙏', '🎉', '❤️', '🔥', '⭐']
|
||||
>>>>>>> local-backup-root-cyj
|
||||
}
|
||||
},
|
||||
|
||||
onLoad(options: any) {
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
const sysInfo = uni.getSystemInfoSync()
|
||||
const statusBarH = sysInfo.statusBarHeight
|
||||
this.navPaddingTop = (statusBarH + 10) + 'px'
|
||||
|
||||
console.log('chat page onLoad options:', options)
|
||||
>>>>>>> local-backup-root-cyj
|
||||
if (options.session_id) {
|
||||
this.sessionId = options.session_id
|
||||
}
|
||||
@@ -88,13 +238,33 @@
|
||||
},
|
||||
|
||||
onShow() {
|
||||
<<<<<<< HEAD
|
||||
this.loadChatMessages()
|
||||
=======
|
||||
console.log('chat page onShow, chatUserId:', this.chatUserId, 'merchantId:', this.merchantId)
|
||||
if (this.merchantId) {
|
||||
this.loadChatMessages()
|
||||
this.setupRealtimeSubscription()
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
this.loadChatMessages()
|
||||
this.setupRealtimeSubscription()
|
||||
}, 300)
|
||||
}
|
||||
},
|
||||
|
||||
onUnload() {
|
||||
if (this.realtimeChannel != null) {
|
||||
supa.removeChannel(this.realtimeChannel!)
|
||||
}
|
||||
>>>>>>> local-backup-root-cyj
|
||||
},
|
||||
|
||||
methods: {
|
||||
async initMerchantId() {
|
||||
try {
|
||||
const session = supa.getSession()
|
||||
<<<<<<< HEAD
|
||||
this.merchantId = session?.user?.getString('id') || uni.getStorageSync('user_id') || ''
|
||||
} catch (e) {}
|
||||
},
|
||||
@@ -141,18 +311,195 @@
|
||||
|
||||
this.markAsRead()
|
||||
}
|
||||
=======
|
||||
if (session != null && session.user != null) {
|
||||
this.merchantId = session.user.getString('id') || ''
|
||||
}
|
||||
if (!this.merchantId) {
|
||||
this.merchantId = uni.getStorageSync('user_id') || ''
|
||||
}
|
||||
|
||||
// 加载店铺头像
|
||||
this.loadShopAvatar()
|
||||
} catch (e) {
|
||||
console.error('获取商户ID失败:', e)
|
||||
}
|
||||
},
|
||||
|
||||
async loadShopAvatar() {
|
||||
try {
|
||||
const response = await supa
|
||||
.from('ml_shops')
|
||||
.select('shop_logo')
|
||||
.eq('merchant_id', this.merchantId)
|
||||
.limit(1)
|
||||
.execute()
|
||||
|
||||
if (response.data && (response.data as any[]).length > 0) {
|
||||
const shopData = (response.data as any[])[0] as UTSJSONObject
|
||||
const logo = shopData.getString('shop_logo')
|
||||
if (logo && logo != '') {
|
||||
this.shopAvatar = logo
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('加载店铺头像失败:', e)
|
||||
}
|
||||
},
|
||||
|
||||
async loadChatMessages() {
|
||||
if (!this.chatUserId) {
|
||||
console.error('chatUserId 为空')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await supa
|
||||
.from('ml_chat_messages')
|
||||
.select('*')
|
||||
.or(`sender_id.eq.${this.chatUserId},receiver_id.eq.${this.chatUserId}`)
|
||||
.order('created_at', { ascending: true })
|
||||
.limit(200)
|
||||
.execute()
|
||||
|
||||
console.log('聊天记录查询结果:', response.data, 'error:', response.error)
|
||||
|
||||
if (response.error != null) {
|
||||
console.error('查询聊天记录失败:', response.error)
|
||||
return
|
||||
}
|
||||
|
||||
if (response.data && (response.data as any[]).length > 0) {
|
||||
const rawData = response.data as any[]
|
||||
const messages: ChatMessageType[] = []
|
||||
|
||||
for (let i = 0; i < rawData.length; i++) {
|
||||
const item = rawData[i] as UTSJSONObject
|
||||
const senderId = item.getString('sender_id') || ''
|
||||
const isFromUser = senderId === this.chatUserId
|
||||
const createdAt = item.getString('created_at') || ''
|
||||
const msgId = item.getString('id') || ''
|
||||
const safeViewId = 'msg_' + msgId.replace(/[^a-zA-Z0-9]/g, '_')
|
||||
|
||||
const date = new Date(createdAt)
|
||||
const timeStr = date.getHours().toString().padStart(2, '0') + ':' + date.getMinutes().toString().padStart(2, '0')
|
||||
|
||||
messages.push({
|
||||
id: msgId,
|
||||
viewId: safeViewId,
|
||||
session_id: item.getString('session_id') || '',
|
||||
sender_id: senderId,
|
||||
receiver_id: item.getString('receiver_id') || '',
|
||||
content: item.getString('content') || '',
|
||||
msg_type: item.getString('msg_type') || 'text',
|
||||
is_read: item.getBoolean('is_read') || false,
|
||||
is_from_user: isFromUser,
|
||||
created_at: createdAt,
|
||||
time: timeStr
|
||||
} as ChatMessageType)
|
||||
}
|
||||
|
||||
this.chatMessages = messages
|
||||
this.scrollToBottom()
|
||||
this.markAsRead()
|
||||
} else {
|
||||
console.log('没有找到聊天记录')
|
||||
this.chatMessages = []
|
||||
>>>>>>> local-backup-root-cyj
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('加载聊天记录失败:', e)
|
||||
}
|
||||
},
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
setupRealtimeSubscription(): void {
|
||||
console.log('开始建立聊天实时订阅...')
|
||||
|
||||
this.realtimeChannel = supa.channel('merchant-chat-' + Date.now().toString())
|
||||
.on('postgres_changes', {
|
||||
event: 'INSERT',
|
||||
schema: 'public',
|
||||
table: 'ml_chat_messages'
|
||||
}, (payload: any) => {
|
||||
console.log('收到实时消息:', payload)
|
||||
const payloadObj = (payload instanceof UTSJSONObject) ? (payload as UTSJSONObject) : (JSON.parse(JSON.stringify(payload ?? {})) as UTSJSONObject)
|
||||
const newMsgAny = payloadObj.get('new')
|
||||
if (newMsgAny == null) return
|
||||
|
||||
const newMsg = (newMsgAny instanceof UTSJSONObject) ? (newMsgAny as UTSJSONObject) : (JSON.parse(JSON.stringify(newMsgAny)) as UTSJSONObject)
|
||||
|
||||
const senderId = newMsg.getString('sender_id') ?? ''
|
||||
const receiverId = newMsg.getString('receiver_id') ?? ''
|
||||
const msgId = newMsg.getString('id') ?? ''
|
||||
const content = newMsg.getString('content') ?? ''
|
||||
|
||||
// 检查是否与当前聊天相关
|
||||
if (senderId != this.chatUserId && receiverId != this.chatUserId) {
|
||||
return
|
||||
}
|
||||
|
||||
// 检查消息是否已存在
|
||||
for (let i = 0; i < this.chatMessages.length; i++) {
|
||||
if (this.chatMessages[i].id == msgId) return
|
||||
}
|
||||
|
||||
const isFromUser = senderId === this.chatUserId
|
||||
const createdAt = newMsg.getString('created_at') ?? new Date().toISOString()
|
||||
const date = new Date(createdAt)
|
||||
const timeStr = date.getHours().toString().padStart(2, '0') + ':' + date.getMinutes().toString().padStart(2, '0')
|
||||
const safeViewId = 'msg_' + msgId.replace(/[^a-zA-Z0-9]/g, '_')
|
||||
|
||||
this.chatMessages.push({
|
||||
id: msgId,
|
||||
viewId: safeViewId,
|
||||
session_id: newMsg.getString('session_id') || '',
|
||||
sender_id: senderId,
|
||||
receiver_id: receiverId,
|
||||
content: content,
|
||||
msg_type: newMsg.getString('msg_type') || 'text',
|
||||
is_read: false,
|
||||
is_from_user: isFromUser,
|
||||
created_at: createdAt,
|
||||
time: timeStr
|
||||
} as ChatMessageType)
|
||||
|
||||
this.scrollToBottom()
|
||||
|
||||
if (isFromUser) {
|
||||
this.markAsRead()
|
||||
}
|
||||
})
|
||||
.subscribe((status: string, err: any | null) => {
|
||||
console.log('订阅状态:', status)
|
||||
if (err != null) {
|
||||
console.log('订阅错误:', err)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
scrollToBottom(): void {
|
||||
if (this.chatMessages.length === 0) return
|
||||
|
||||
const lastMsg = this.chatMessages[this.chatMessages.length - 1]
|
||||
const targetId = lastMsg.viewId
|
||||
|
||||
this.scrollToView = ''
|
||||
|
||||
setTimeout(() => {
|
||||
this.scrollToView = targetId
|
||||
}, 100)
|
||||
},
|
||||
|
||||
>>>>>>> local-backup-root-cyj
|
||||
async markAsRead() {
|
||||
try {
|
||||
await supa
|
||||
.from('ml_chat_messages')
|
||||
.update({ is_read: true })
|
||||
.eq('receiver_id', this.merchantId)
|
||||
<<<<<<< HEAD
|
||||
.eq('is_read', false)
|
||||
.execute()
|
||||
} catch (e) {}
|
||||
@@ -163,6 +510,22 @@
|
||||
|
||||
const content = this.inputText.trim()
|
||||
this.inputText = ''
|
||||
=======
|
||||
.eq('sender_id', this.chatUserId)
|
||||
.eq('is_read', false)
|
||||
.execute()
|
||||
} catch (e) {
|
||||
console.error('标记已读失败:', e)
|
||||
}
|
||||
},
|
||||
|
||||
async sendMessage() {
|
||||
const content = this.inputText.trim()
|
||||
if (content == '') return
|
||||
|
||||
this.inputText = ''
|
||||
this.showEmoji = false
|
||||
>>>>>>> local-backup-root-cyj
|
||||
|
||||
try {
|
||||
const newMessage = {
|
||||
@@ -180,6 +543,7 @@
|
||||
.insert([newMessage])
|
||||
.execute()
|
||||
|
||||
<<<<<<< HEAD
|
||||
if (!response.error) {
|
||||
this.loadChatMessages()
|
||||
}
|
||||
@@ -198,12 +562,73 @@
|
||||
const hours = date.getHours().toString().padStart(2, '0')
|
||||
const minutes = date.getMinutes().toString().padStart(2, '0')
|
||||
return `${hours}:${minutes}`
|
||||
=======
|
||||
if (response.error != null) {
|
||||
console.error('发送消息失败:', response.error)
|
||||
uni.showToast({ title: '发送失败', icon: 'none' })
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('发送消息异常:', e)
|
||||
uni.showToast({ title: '发送失败', icon: 'none' })
|
||||
}
|
||||
},
|
||||
|
||||
showEmojiPicker(): void {
|
||||
this.showEmoji = !this.showEmoji
|
||||
if (this.showEmoji) {
|
||||
uni.hideKeyboard()
|
||||
}
|
||||
},
|
||||
|
||||
insertEmoji(emoji: string): void {
|
||||
this.inputText += emoji
|
||||
this.showEmoji = false
|
||||
this.inputFocus = true
|
||||
},
|
||||
|
||||
showImagePicker(): void {
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
success: (res) => {
|
||||
console.log('选择图片:', res.tempFilePaths)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
showMoreActions(): void {
|
||||
uni.showActionSheet({
|
||||
itemList: ['结束对话', '清除记录'],
|
||||
success: (res) => {
|
||||
switch (res.tapIndex) {
|
||||
case 0:
|
||||
uni.navigateBack()
|
||||
break
|
||||
case 1:
|
||||
this.chatMessages = []
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
previewImage(url : string) {
|
||||
if (url == '') return
|
||||
uni.previewImage({
|
||||
urls: [url],
|
||||
current: 0
|
||||
})
|
||||
},
|
||||
|
||||
goBack() {
|
||||
uni.navigateBack()
|
||||
>>>>>>> local-backup-root-cyj
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
<<<<<<< HEAD
|
||||
.chat-page { display: flex; flex-direction: column; height: 100vh; background-color: #f5f5f5; }
|
||||
.chat-header { display: flex; align-items: center; padding: 20rpx 30rpx; background-color: #fff; border-bottom: 1rpx solid #eee; }
|
||||
.header-back { padding: 10rpx 20rpx 10rpx 0; }
|
||||
@@ -229,4 +654,51 @@
|
||||
.input-field { flex: 1; height: 72rpx; background-color: #f5f5f5; border-radius: 36rpx; padding: 0 30rpx; font-size: 28rpx; }
|
||||
.send-btn { margin-left: 20rpx; width: 72rpx; height: 72rpx; background-color: #007AFF; border-radius: 50%; display: flex; align-items: center; justify-content: center; }
|
||||
.send-icon { font-size: 32rpx; color: #fff; }
|
||||
=======
|
||||
.chat-page { width: 100%; flex: 1; background-color: #f5f5f5; display: flex; flex-direction: column; overflow: hidden; }
|
||||
|
||||
.chat-header { background-color: white; padding-left: 15px; padding-right: 15px; padding-bottom: 10px; display: flex; flex-direction: row; align-items: center; justify-content: space-between; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #eee; flex-shrink: 0; }
|
||||
.header-back { width: 40px; }
|
||||
.back-icon { font-size: 24px; color: #333; }
|
||||
.header-info { flex: 1; }
|
||||
.header-info-text-wrapper { display: flex; flex-direction: column; align-items: center; }
|
||||
.chat-title { font-size: 16px; font-weight: bold; color: #333; margin-bottom: 2px; }
|
||||
.chat-status { font-size: 12px; color: #34c759; }
|
||||
.header-actions .action-icon { font-size: 20px; color: #333; width: 40px; }
|
||||
.action-icon-text { text-align: right; width: 100%; }
|
||||
|
||||
.chat-content { flex: 1; height: 0; padding: 10px; padding-bottom: 20px; }
|
||||
.chat-messages { display: flex; flex-direction: column; padding-bottom: 80px; }
|
||||
|
||||
.message-item.system { display: flex; flex-direction: row; justify-content: center; margin-bottom: 20px; }
|
||||
.system-text { font-size: 12px; color: #999; background-color: #f0f0f0; padding-top: 5px; padding-bottom: 5px; padding-left: 15px; padding-right: 15px; border-radius: 15px; text-align: center; }
|
||||
|
||||
.message-wrapper { display: flex; flex-direction: row; margin-bottom: 15px; }
|
||||
.message-wrapper.me { justify-content: flex-end; }
|
||||
.avatar { width: 40px; height: 40px; border-radius: 20px; margin-right: 10px; flex-shrink: 0; background-color: #e0e0e0; }
|
||||
.avatar.me { margin-right: 0; margin-left: 10px; }
|
||||
.message-content-wrapper { width: 260px; display: flex; flex-direction: column; }
|
||||
.message-bubble { background-color: white; padding-top: 10px; padding-bottom: 10px; padding-left: 15px; padding-right: 15px; border-radius: 12px; }
|
||||
.received-bubble { align-self: flex-start; border-top-left-radius: 2px; }
|
||||
.message-bubble.me { background-color: #95ec69; align-self: flex-end; border-top-right-radius: 2px; }
|
||||
.sender-name { font-size: 11px; color: #999; margin-bottom: 2px; align-self: flex-start; }
|
||||
.message-text { font-size: 15px; color: #333; line-height: 1.4; margin-bottom: 5px; }
|
||||
.message-time { font-size: 11px; color: #999; text-align: right; }
|
||||
|
||||
.chat-input { background-color: white; border-top-width: 1px; border-top-style: solid; border-top-color: #eee; padding-top: 10px; padding-bottom: 20px; padding-left: 15px; padding-right: 15px; position: fixed; bottom: 0; left: 0; right: 0; flex-shrink: 0; }
|
||||
.input-tools { display: flex; flex-direction: row; margin-bottom: 10px; }
|
||||
.tool-icon { font-size: 20px; margin-right: 15px; color: #666; }
|
||||
.input-wrapper { display: flex; flex-direction: row; align-items: center; }
|
||||
.message-input { flex: 1; background-color: #f5f5f5; border-radius: 20px; padding-top: 10px; padding-bottom: 10px; padding-left: 15px; padding-right: 15px; font-size: 15px; margin-right: 10px; min-height: 40px; max-height: 100px; }
|
||||
.send-button { background-color: #ccc; color: white; border-radius: 20px; padding-top: 8px; padding-bottom: 8px; padding-left: 20px; padding-right: 20px; font-size: 14px; min-width: 60px; }
|
||||
.send-button.active { background-color: #ff5000; }
|
||||
|
||||
.emoji-picker { background-color: white; border-top-width: 1px; border-top-style: solid; border-top-color: #eee; padding: 10px; height: 200px; position: fixed; bottom: 80px; left: 0; right: 0; }
|
||||
.emoji-category { display: flex; flex-direction: row; flex-wrap: wrap; }
|
||||
.emoji-item { font-size: 24px; padding: 8px; width: 45px; height: 45px; display: flex; align-items: center; justify-content: center; }
|
||||
|
||||
.image-bubble { padding: 0 !important; background-color: transparent !important; }
|
||||
.image-bubble .message-time { margin-top: 5px; text-align: right; }
|
||||
.message-image { width: 150px; border-radius: 8px; }
|
||||
>>>>>>> local-backup-root-cyj
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user