调整聊天界面样式

This commit is contained in:
唐明明
2022-01-19 16:49:29 +08:00
parent 070c6c729e
commit d4d366a357
7 changed files with 330 additions and 243 deletions

View File

@@ -4,7 +4,7 @@
"configurations": [{ "configurations": [{
"app-plus" : "app-plus" :
{ {
"launchtype" : "local" "launchtype" : "remote"
}, },
"default" : "default" :
{ {

View File

@@ -1,12 +1,12 @@
<script> <script>
import { import { getVersions } from './apis/interfaces/versions'
getVersions
} from './apis/interfaces/versions'
import im from '@/utils/im/index.js' import im from '@/utils/im/index.js'
export default { export default {
onLaunch: function() { onLaunch: function() {
im.initIm('lmxuhwaglu76d') im.initIm('lmxuhwaglu76d')
return
//#ifdef APP-PLUS //#ifdef APP-PLUS
// 获取系统版本号 // 获取系统版本号

View File

@@ -375,9 +375,12 @@
} }
}, },
{ {
"path": "pages/im/private/index", "path": "pages/im/private/index",
"name": "imPrivate",
"style": { "style": {
"navigationBarTitleText": "聊", "navigationBarTitleText": "聊",
"navigationBarBackgroundColor":"#FFFFFF",
"disableScroll": true,
"app-plus": { "app-plus": {
"titleNView": { "titleNView": {
"type": "default", "type": "default",
@@ -393,36 +396,42 @@
}, },
{ {
"path": "pages/im/private/setting", "path": "pages/im/private/setting",
"name": "imPrivateSetting",
"style": { "style": {
"navigationBarTitleText": "设置" "navigationBarTitleText": "设置"
} }
}, },
{ {
"path": "pages/im/friends/index", "path": "pages/im/friends/index",
"name": "imFriends",
"style": { "style": {
"navigationBarTitleText": "我的好友" "navigationBarTitleText": "我的好友"
} }
}, },
{ {
"path": "pages/im/friends/pending", "path": "pages/im/friends/pending",
"name": "imFriendsPending",
"style": { "style": {
"navigationBarTitleText": "新的朋友" "navigationBarTitleText": "新的朋友"
} }
}, },
{ {
"path": "pages/im/friends/info", "path": "pages/im/friends/info",
"name": "imFriendsInfo",
"style": { "style": {
"navigationBarTitleText": "" "navigationBarTitleText": ""
} }
}, },
{ {
"path": "pages/im/friends/mine", "path": "pages/im/friends/mine",
"name": "imFriendsMine",
"style": { "style": {
"navigationBarTitleText": "我的资料" "navigationBarTitleText": "我的资料"
} }
}, },
{ {
"path": "pages/im/group/index", "path": "pages/im/group/index",
"name": "imGroup",
"style": { "style": {
"navigationBarTitleText": "我的群聊" "navigationBarTitleText": "我的群聊"
} }

View File

@@ -2,12 +2,12 @@
<div> <div>
<view class="list"> <view class="list">
<view class="list__item" @click="toPending"> <view class="list__item" @click="toPending">
<u-avatar shape="square" size="35" icon="man-add-fill" fontSize="26" randomBgColor></u-avatar> <u-avatar size="35" icon="plus-people-fill" fontSize="26" randomBgColor></u-avatar>
<text class="list__item__user-name">新的朋友</text> <text class="list__item__user-name">新的朋友</text>
</view> </view>
<u-line></u-line> <u-line></u-line>
<view class="list__item" @click="toGroup"> <view class="list__item" @click="toGroup">
<u-avatar shape="square" size="35" icon="chrome-circle-fill" fontSize="26" randomBgColor></u-avatar> <u-avatar size="35" icon="account-fill" fontSize="26" randomBgColor></u-avatar>
<text class="list__item__user-name">我的群聊</text> <text class="list__item__user-name">我的群聊</text>
</view> </view>
<u-line></u-line> <u-line></u-line>
@@ -24,7 +24,8 @@
<!-- #endif --> <!-- #endif -->
<view class="list" v-for="(item1, index1) in item" :key="index1"> <view class="list" v-for="(item1, index1) in item" :key="index1">
<view class="list__item" @click="toInfo"> <view class="list__item" @click="toInfo">
<image class="list__item__avatar" :src="item1.url"></image> <image class="list__item__avatar" :src="item1.url"></image>
<!-- <u-avatar size="35" icon="chrome-circle-fill" fontSize="26" randomBgColor></u-avatar> -->
<text class="list__item__user-name">{{item1.name}}</text> <text class="list__item__user-name">{{item1.name}}</text>
</view> </view>
<u-line></u-line> <u-line></u-line>
@@ -119,7 +120,7 @@
&__avatar { &__avatar {
height: 35px; height: 35px;
width: 35px; width: 35px;
border-radius: 3px; border-radius: 50%;
} }
&__user-name { &__user-name {

View File

@@ -1,43 +1,76 @@
<template> <template>
<div> <view class="content">
<div v-if="$store.state.token != ''"> <view v-if="$store.state.token != ''">
<div class="container"> <block v-if="conversations.length < 1">
<div class="msg-item u-border-bottom" v-for="(item, index) in conversations" @click="toDetail(item)"> <view class="vertical null-list">
<div class="avatar"> <u-empty
<u-badge numberType="ellipsis" max="99" shape="horn" absolute :offset="[-7, -7]" icon="http://cdn.uviewui.com/uview/empty/message.png"
:value="item.unreadMessageCount" /> textColor="#999"
<u-avatar shape="square" :src="friend(item.targetId).portraitUrl"></u-avatar> text="暂无好友消息"
</div> >
<div class="content "> <template>
<div class="name"> <view class="null-list-btn">开启聊天</view>
<h3>{{ friend(item.targetId).name }}</h3> </template>
<span class="time">{{ item.sentTime|timeCustomCN }}</span> </u-empty>
</div> </view>
<div class="u-line-1">{{ item.latestMessage.content }}</div> </block>
</div> <block v-else>
</div> <view v-for="(item, index) in conversations" :key="index" class="mssage-box" @click="toDetail(item)">
</div> <view class="mssage-action">
<u-loadmore status="nomore" /> <block v-if="!friend(item.targetId).portraitUrl">
</div> <u-avatar
<div v-else> clsss="mssage-action-cover"
<u-button @click="toLogin">去登录</u-button> size="44"
</div> :text="friend(item.targetId).name ? friend(item.targetId).name.substring(0,1) : '未'"
</div> font-size="14"
randomBgColor
></u-avatar>
</block>
<block v-else>
<u-avatar
clsss="mssage-action-cover"
:src="friend(item.targetId).portraitUrl"
size="44"
></u-avatar>
</block>
<view class="mssage-action-content">
<view class="mssage-header">
<view class="header-name">{{ friend(item.targetId).name || '未知用户' }}</view>
<view class="header-time">{{ item.sentTime|timeCustomCN }}</view>
</view>
<view class="mssage-msg">{{ item.latestMessage.content }}</view>
</view>
</view>
</view>
</block>
</view>
<!-- 未登录 -->
<view v-else class="vertical null-list">
<u-empty
icon="http://cdn.uviewui.com/uview/empty/permission.png"
textColor="#999"
text="登录后开启聊天吧~"
>
<template>
<view class="null-list-btn" @click="toLogin">去登录</view>
</template>
</u-empty>
</view>
</view>
</template> </template>
<script> <script>
import * as RongIMLib from '@rongcloud/imlib-uni' import * as RongIMLib from '@rongcloud/imlib-uni'
import im from '@/utils/im/index.js' import im from '@/utils/im/index.js'
import userAuth from '@/public/userAuth' import userAuth from '@/public/userAuth'
import { import { getImToken } from '@/apis/interfaces/im.js'
getImToken
} from '@/apis/interfaces/im.js'
export default { export default {
data() { data() {
return { return {
isShown: true, // 当前页面显示状态 isShown: true, // 当前页面显示状态
conversations: [] // 会话列表 conversations: [] ,// 会话列表
isImToken: '', // 是否已鉴权
} }
}, },
computed: { computed: {
@@ -47,30 +80,32 @@
} }
} }
}, },
onLoad() { onShow() {
getImToken().then(res => { if (this.$store.state.token !== '') {
im.syncFriends() if(this.isImToken === ''){
im.connect(res.token, res.userInfo) getImToken().then(res => {
im.syncFriends()
this.getConversationList() im.connect(res.token, res.userInfo)
}) this.isImToken = res.token
}, this.getConversationList()
onShow() { })
this.getConversationList() }
this.isShown = true this.getConversationList()
this.isShown = true
}
}, },
onHide() { onHide() {
this.isShown = false this.isShown = false
}, },
onNavigationBarButtonTap(e) { onNavigationBarButtonTap(e) {
if (e.index == 0) {} if (e.index == 0) {
if (e.index == 1) { uni.showToast({
uni.navigateTo({ title: '开发中暂未开放,敬请期待',
url: '/pages/im/friends/index', icon : 'none'
fail: (err) => { })
console.log(err); }
} if (e.index == 1) {
}) this.$Router.push({name: 'imFriends'})
} }
}, },
watch: { watch: {
@@ -96,7 +131,7 @@
getConversationList() { getConversationList() {
const count = 1000 const count = 1000
const timestamp = 0 // 会话的时间戳获取这个时间戳之前的会话列表0 表示从最新开始获取)会话类型 const timestamp = 0 // 会话的时间戳获取这个时间戳之前的会话列表0 表示从最新开始获取)会话类型
RongIMLib.getConversationList(undefined, count, timestamp, (res) => { RongIMLib.getConversationList(undefined, count, timestamp, (res) => {
if (res.code === 0 && res.conversations.length > 0) { if (res.code === 0 && res.conversations.length > 0) {
this.conversations = res.conversations this.conversations = res.conversations
} }
@@ -105,51 +140,81 @@
// 进入聊天的详情页面,清理未读消息数量 // 进入聊天的详情页面,清理未读消息数量
toDetail(item) { toDetail(item) {
uni.navigateTo({ uni.navigateTo({
url: '/pages/im/private/index?targetId=' + item.targetId + url: '/pages/im/private/index?targetId=' + item.targetId + '&conversationType=' + item.conversationType
'&conversationType=' + item.conversationType
}) })
} }
} }
} }
</script> </script>
<style scoped lang="scss"> <style lang="scss" scoped>
.container { .content{
padding: 0 $uni-spacing-col-lg $uni-spacing-col-lg $uni-spacing-col-lg; background-color: $window-color;
} min-height: 100vh;
.null-list{
.msg-item { height: 100vh;
display: flex; text-align: center;
align-items: center; &-btn{
padding: $uni-spacing-col-lg 0; margin-top: $margin * 2;
line-height: 70rpx;
.avatar { color: $main-color;
position: relative; border:solid 1rpx $main-color;
margin-right: $uni-spacing-col-lg; padding: 0 ($padding*3);
font-size: $title-size-m;
.u-badge { border-radius: 35rpx;
z-index: 9; box-sizing: border-box;
} }
} }
.mssage-box{
.content { background: white;
flex: 1; .mssage-action{
position: relative;
.name { padding: 20rpx $padding;
display: flex; &::after{
justify-content: space-between; position: absolute;
font-size: $uni-font-size-base; left: $padding + 108;
right: 0;
.time { bottom: 0;
font-size: $uni-font-size-sm; content: " ";
color: $uni-text-color-grey; height: 1rpx;
} background: $border-color;
} }
&-content{
.u-line-1 { position: absolute;
color: $u-info; top: 20rpx;
font-size: $uni-font-size-sm; height: 44px;
} left: $padding + 108;
} right: $margin;
} display: flex;
flex-direction: column;
justify-content: center;
.mssage-header{
display: flex;
font-size: $title-size;
line-height: 40rpx;
justify-content: space-between;
.header-name{
flex: 1;
@extend .nowrap;
}
.header-time{
padding-left: $padding;
font-size: $title-size-sm - 2;
color: $text-gray;
}
}
.mssage-msg{
font-size: $title-size-sm - 2;
color: $text-gray;
@extend .nowrap;
}
}
}
&-item:last-child{
.mssage-action::after{
display: none;
}
}
}
}
</style> </style>

View File

@@ -1,41 +1,33 @@
<template> <template>
<div> <view class="chat-content">
<scroll-view ref="scrollview" :scroll-y="true" class="scroll" :scroll-into-view="scrollIntoID" <scroll-view class="chat-scrool" :scroll-y="true" :scroll-into-view="scrollIntoID" :scroll-with-animation="false">
:scroll-with-animation="false"> <!-- 聊天窗口 -->
<view v-for="(item,index) in messages" :id="'chatId_'+index"> <view class="chat-item" v-for="(item,index) in messages" :key="index" :id="'chatId_'+index">
<div :class="item.messageDirection == 1 ? 'right' : 'left'"> <view class="chat-item-time">
<div class="avatar" v-if="item.messageDirection == 2"> <text>{{ item.sentTime|timeCustomCN }}</text>
<u-avatar :src="userInfo.portraitUrl" @click="showFriend" shape="square" /> </view>
</div> <view class="chat-item-article" :class="item.messageDirection == 1 ? 'right' : 'left'">
<div class="msg"> <view class="chat-msg">
{{ item.content.content }} <view class="chat-msg-text">{{ item.content.content }}</view>
<div class="status" v-if="item.messageDirection == 1"> <!-- 预留一些图片语音表情包等位置 -->
<u-icon v-if="item.sentStatus == 50" name="checkbox-mark" /> </view>
<span v-else>未读</span> <view class="chat-status" :class="{'hide': item.sentStatus == 50}" v-if="item.messageDirection == 1">{{ item.sentStatus == 50 ? '已读': '未读'}}</view>
</div> <view class="chat-avatar">
</div> <!-- <u-avatar :src="userInfo.portraitUrl" @click="showFriend"></u-avatar> -->
<div class="avatar" v-if="item.messageDirection == 1"> <u-avatar
<u-avatar text="Me" @click="showMine" shape="square" /> text="无"
</div> fontSize="14"
</div> bg-color="rgba(0,0,0,.2)"
></u-avatar>
<div class="time">{{ item.sentTime|timeCustomCN }}</div> </view>
</view> </view>
</scroll-view> </view>
</scroll-view>
<div class="footer"> <view class="chat-footer">
<div class="left"> <input class="chat-input" type="text" v-model="inputTxt" confirm-type="发送" @confirm="send" cursor-spacing="10"/>
<u-icon name="volume" /> <button class="chat-push" size="mini" @click="send">发送</button>
</div> </view>
<div class="middle"> </view>
<u--input autoBlur confirmHold confirmType="send" @confirm="send" v-model="inputTxt" />
</div>
<div class="right">
<u-button type="primary" v-if="showSendButton" class="custom-style" text="发送" @click="send"></u-button>
<u-icon v-else name="plus" />
</div>
</div>
</div>
</template> </template>
<script> <script>
@@ -82,7 +74,7 @@
this.getMessageList() this.getMessageList()
// 监听消息回执 // 监听消息回执
RongIMLib.addReadReceiptReceivedListener((result) => { RongIMLib.addReadReceiptReceivedListener((result) => {
const res = result.data.message const res = result.data.message
if (res.targetId == this.targetId) { if (res.targetId == this.targetId) {
this.getMessageList() this.getMessageList()
@@ -106,7 +98,7 @@
} }
}, },
watch: { watch: {
'$store.getters.newMessage': function(msg) { '$store.getters.newMessage': function(msg) {
if (msg.targetId == this.targetId) { if (msg.targetId == this.targetId) {
RongIMLib.clearMessagesUnreadStatus(msg.conversationType, msg.targetId, msg.sentTime) RongIMLib.clearMessagesUnreadStatus(msg.conversationType, msg.targetId, msg.sentTime)
RongIMLib.sendReadReceiptMessage(msg.conversationType, msg.targetId, msg.sentTime) RongIMLib.sendReadReceiptMessage(msg.conversationType, msg.targetId, msg.sentTime)
@@ -140,7 +132,7 @@
({ ({
code, code,
messages messages
}) => { }) => {
if (code === 0) { if (code === 0) {
this.messages = messages.reverse() this.messages = messages.reverse()
this.scrollBottom() this.scrollBottom()
@@ -188,98 +180,117 @@
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
$footer-height: 55px; .chat-content{
height: 100vh;
.scroll { background: $window-color;
height: calc(100vh - 55px); .chat-scrool{
width: 100vw; height: calc(100vh - 140rpx);
padding: 0 $uni-spacing-col-lg; box-sizing: border-box;
} padding-bottom: $padding;
.chat-item{
.footer { .chat-item-time{
width: 100%; text-align: center;
display: flex; padding: $padding/2 $padding;
position: fixed; text{
bottom: 0; background: rgba($color: #000000, $alpha: .2);
left: 0; color: white;
align-items: center; font-size: $title-size-sm - 4;
height: $footer-height; line-height: 40rpx;
background-color: $uni-bg-color-grey; padding: 0 15rpx;
display: inline-block;
.u-icon { border-radius: $radius-lg;
padding: $uni-spacing-col-sm; }
border: 1px solid $u-content-color; }
border-radius: $uni-border-radius-circle; .chat-item-article{
} position: relative;
padding: 10rpx ($padding + 110) 0;
.left { overflow: hidden;
padding: 0 $uni-spacing-col-lg; min-height: 40px;
justify-content: center; .chat-msg{
} overflow: hidden;
.chat-msg-text{
.middle { display: inline-block;
flex: 1; padding: ($padding - 10) $padding;
color: $text-color;
.u-input { box-sizing: border-box;
background-color: $uni-bg-color; font-size: $title-size-lg;
} }
} }
.chat-status{
.right { color: $text-gray;
padding: 0 $uni-spacing-col-lg; font-size: $title-size-sm;
justify-content: center; text-align: right;
} &.hide{
} color: $text-gray-m;
}
.custom-style { }
height: 36px; .chat-avatar{
} position: absolute;
top: 0;
.time { }
text-align: center; &.left{
font-size: $uni-font-size-sm; .chat-avatar{
color: $u-light-color; left: $margin;
} }
.chat-msg{
.left, .chat-msg-text{
.right { background-color: white;
display: flex; border-radius: 0 $radius*2 $radius*2 $radius*2;
align-items: top; }
}
.avatar { }
margin-top: $uni-spacing-col-base; &.right{
} .chat-avatar{
right: $margin;
.msg { }
font-size: $uni-font-size-base; .chat-msg{
margin: $uni-spacing-col-base; text-align: right;
padding: $uni-spacing-col-base; .chat-msg-text{
word-wrap: break-word; border-radius: $radius*2 0 $radius*2 $radius*2;
width: 60%; background: $main-color;
border-radius: $uni-border-radius-base; color: white;
position: relative; }
}
.status { }
position: absolute; }
right: 8rpx; }
bottom: 5rpx; }
font-size: $uni-font-size-base / 1.5; .chat-footer{
color: $uni-text-color-grey; position: fixed;
} bottom: 0;
} left: 0;
} right: 0;
height: 140rpx;
.left { padding: 20rpx ($padding + 150rpx) 40rpx $padding;
.msg { background: white;
background-color: $uni-bg-color-grey; box-sizing: border-box;
} z-index: 99;
} .chat-input{
background: $window-color;
.right { height: 80rpx;
justify-content: flex-end; border-radius: $radius-lg;
font-size: $title-size-m;
.msg { padding: 0 $padding;
background-color: $u-primary-disabled; box-sizing: border-box;
} }
} .chat-push[size='mini']{
position: absolute;
right: $margin;
top: 20rpx;
height: 80rpx;
line-height: 80rpx;
padding: 0;
margin: 0;
width: 120rpx;
background: $main-color;
color: white;
border-radius: $radius-lg;
font-size: $title-size-m;
font-weight: bold;
&::after{
display: none;
}
}
}
}
</style> </style>

View File

@@ -3,7 +3,7 @@
会话设置 {{ targetId}} 会话设置 {{ targetId}}
<div @click="setStatus">免打扰开关 {{status}}</div> <div @click="setStatus">免打扰开关 {{status}}</div>
<div @click="setTop">置顶会话 {{isTop}}</div> <div @click="setTop">置顶会话 {{isTop}}</div>
<u-button @click="toIndex">会首页</u-button> <u-button @click="toIndex">会首页</u-button>
</div> </div>
</template> </template>
@@ -64,5 +64,6 @@
} }
</script> </script>
<style> <style>
</style> </style>