first commit

This commit is contained in:
编码猿
2024-09-27 02:06:13 +08:00
commit 852d94fbb9
36760 changed files with 3274413 additions and 0 deletions

View File

@@ -0,0 +1 @@
9a38ff25-ce1f-4bc0-bb92-8bda10572882

View File

@@ -0,0 +1,545 @@
<template>
<view class="index" :class="{ shake: isShake }">
<uni-nav-bar
right-icon="more"
:statusBar="true"
@clickRight="OpenChatSetting"
:title="`${UserInfo.room}(${RoomOnlineUser.length})`"
>
</uni-nav-bar>
<!-- 聊天记录显示窗口 -->
<scroll-view
id="scrollview"
class="chat_record"
scroll-y
:scroll-with-animation="true"
:scroll-top="scrollTop"
:style="{ height: style.contentViewHeight + 'px' }"
>
<view v-for="(item, index) in ChatRecord" :key="index">
<view
class="news"
v-if="item.from != 'system'"
:class="item.from == 'me' ? 'right' : ''"
>
<image class="news_img" :src="item.img"></image>
<view class="news_text">
<view v-if="status" class="news_name">{{ item.name }}</view>
<view v-if="item.message.includes('gif')" class="news_content">
<image
@click="previewImage(index)"
class="content_img"
:src="item.message"
></image>
</view>
<view v-else v-html="item.message"></view>
</view>
</view>
<view class="news" v-else>
<view class="system">{{ item.message }}</view>
</view>
</view>
</scroll-view>
<!-- 底部输入框 -->
<view class="bottom_operation" :style="{ height: operationHeight + 'rpx' }">
<view class="input_list">
<input
class="uni-input"
type="text"
v-model="UserMessage"
:cursor="cursorPosition"
confirm-type="send"
@confirm="SendMessage('text')"
@touchend.stop="touchendPrevent"
@focus="FocusEvent"
@blur="BlurEvent"
:cursor-spacing="10"
placeholder="请输入内容"
/>
</view>
<view class="menu">
<text
v-for="(item, index) in menuList"
:key="index"
@touchend.stop.prevent="menuItemClick(item, index)"
class="iconfont"
:class="[index == clickMenuIndex ? 'active' : '', item.icon]"
>
</text>
</view>
<view class="menu_popup" v-show="isShow">
<!--表情的菜单键盘-->
<view class="popup smiling_popup" v-show="popupStatus == 1">
<view v-for="(v, i) in emojis" :key="i">
<text
v-for="(item, index) in v"
:key="index"
@click="setInputText(item)"
>{{ item }}</text
>
</view>
</view>
<!--图片的菜单键盘-->
<view class="popup gallery_popup" v-show="popupStatus == 2">
<image
v-for="i in 13"
@click="SendMessage('img', i - 1)"
:src="`../../static/gif/${i - 1}.gif`"
:key="i - 1"
>
</image>
</view>
<!--气泡的菜单键盘-->
<view class="popup qipao_popup" v-show="popupStatus == 3">
<view
class="theme_item"
@click="selectTheme(v)"
:style="{ color: v.textColor, backgroundColor: v.background }"
v-for="(v, i) in theme"
:key="i"
>
{{ v.text }}
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import config from "@/config/index.js";
import { mapMutations, mapGetters } from "vuex";
export default {
data() {
return {
newsContentStyle: {
backgroundColor: "",
color: "",
},
theme: config.theme,
cursorPosition: 0, // 光标的位置
isShake: false, // 是否抖动
scrollTop: "", // 页面滚动距离
style: {
contentViewHeight: 0,
itemHeight: 0,
},
UserInfo: {}, // 用户登录信息
UserMessage: "", // 用户输入的消息内容
emojis: config.emoji, // 表情
RoomOnlineUser: [], // 在线用户数
operationHeight: 160,
isShow: false, // 是否显示 底部弹出菜单
popupStatus: 1, // 1 表情,2 图片,3 气泡
clickMenuIndex: -1, // 点击后的下标
menuList: [
{
icon: "icon-smiling",
status: 1,
},
{
icon: "icon-gallery",
status: 2,
},
{
icon: "icon-xinbaniconshangchuan_huaban",
status: 3,
},
{
icon: "icon-shake",
status: 4,
},
],
};
},
onBackPress(options) {
uni.showModal({
title: "提示",
content: "确定退出当前群聊吗?",
success: (res) => {
if (res.confirm) {
this._.socket.emit("UserDisconnect", this.UserInfo);
plus.runtime.quit();
}
},
});
return true;
// this.backButtonPress++;
// if (this.backButtonPress > 1) {
// console.log("退出")
//
// } else {
// plus.nativeUI.toast("1111再按一次退出应用");
// }
// setTimeout(function () {
// this.backButtonPress = 0;
// }, 1000);
// return true;
},
onLoad() {
this.UserInfo = uni.getStorageSync("UserInfo");
},
created() {
const res = uni.getSystemInfoSync(); //获取手机可使用窗口高度 api为获取系统信息同步接口
this.style.contentViewHeight =
res.windowHeight - (uni.getSystemInfoSync().screenWidth / 750) * 100 - 70; //像素 因为给出的是像素高度 然后我们用的是upx 所以换算一下
this.emitSocket();
this.onSocket();
},
methods: {
...mapMutations({
saveOnLineUser: "SetOnLineUser",
saveChatRecord: "SetChatRecord",
}),
OpenChatSetting() {
uni.navigateTo({
url: "/pages/ChatSetting/ChatSetting",
});
},
previewImage(index) {
// 获取消息数组中你点击的图片地址
var url = this.ChatRecord[index].message;
// 存储过滤后的聊天记录,保存纯图片地址数组
var imgArr = [];
this.ChatRecord.filter((v) => {
v.message.includes(".gif") ? imgArr.push(v.message) : null;
});
// 从新imgArr数组中获取地址的新下标
uni.previewImage({
current: imgArr.indexOf(url),
urls: imgArr,
});
},
selectTheme(item) {
this.newsContentStyle.backgroundColor = item.background;
this.newsContentStyle.color = item.textColor;
uni.showToast({
icon: "none",
title: `${item.text} 切换成功`,
duration: 1000,
});
},
// 发送图片
SendMessage(type, imgindex) {
// 解决浅拷贝导致发最新消息时候改变历史消息的问题
var obj = JSON.parse(JSON.stringify(this.UserInfo));
if (type == "text") {
if (this.UserMessage.length != 0) {
obj.message = `<div class="news_content" style="color: ${this.newsContentStyle.color}; background: ${this.newsContentStyle.backgroundColor}">${this.UserMessage}</div>`;
}
} else {
obj.message = `../../static/gif/${imgindex}.gif`;
}
obj.from = "me";
this._.socket.emit("SendMessage", obj);
this.saveChatRecord(obj);
this.UserMessage = "";
this.scrollToBottom(); //创建后调用回到底部方法
},
scrollToBottom() {
let that = this;
let query = uni.createSelectorQuery();
query.selectAll(".news").boundingClientRect();
query.select("#scrollview").boundingClientRect();
query.exec((res) => {
that.style.itemHeight = 0;
res[0].forEach(
(rect) =>
(that.style.itemHeight =
that.style.itemHeight + rect.height + 99999)
); //获取所有内部子元素的高度
setTimeout(() => {
if (that.style.itemHeight > that.style.contentViewHeight - 100) {
//判断子元素高度是否大于显示高度
that.scrollTop =
that.style.itemHeight - that.style.contentViewHeight; //用子元素的高度减去显示的高度就获益获得序言滚动的高度
}
}, 100);
});
},
onSocket() {
this._.socket.on("WelcomeUser", (res) => {
var obj = JSON.parse(JSON.stringify(this.UserInfo));
obj.from = "system";
obj.message = res;
this.saveChatRecord(obj);
this.scrollToBottom();
});
this._.socket.on("RoomOnline", (res) => {
this.saveOnLineUser(res);
this.RoomOnlineUser = res;
});
this._.socket.on("SetMessage", (res) => {
console.log("收到的消息为:", res);
res.from = "other";
this.saveChatRecord(res);
this.scrollToBottom();
});
this._.socket.on("StartShake", (res) => {
this.isShake = true;
setTimeout(() => {
this.isShake = false;
}, 2000);
});
},
emitSocket() {
this._.socket.emit("JoinRoom", this.UserInfo);
},
touchendPrevent() {
if (this.isShow) {
this.closedMenu();
}
},
setInputText(emoji) {
console.log(emoji);
let str = this.UserMessage.substring(0, this.cursorPosition);
this.UserMessage = this.UserMessage.replace(str, str + emoji);
this.cursorPosition += 2;
},
// 获取焦点的时候
FocusEvent(event) {
this.closedMenu();
},
// 失去焦点
BlurEvent(event) {
this.cursorPosition = event.target.cursor;
console.log("失去焦点 this.cursorPosition : ", this.cursorPosition);
},
menuItemClick(item, index) {
if (item.status <= 3) {
this.popupStatus = item.status;
if (index != this.clickMenuIndex) {
uni.hideKeyboard();
this.clickMenuIndex = index;
this.isShow = true;
this.operationHeight = 620;
} else {
this.closedMenu();
}
} else {
this.closedMenu();
uni.showToast({
icon: "none",
title: "正在发送抖动..",
duration: 1000,
});
this._.socket.emit("Shake", this.UserInfo);
console.log("发送抖动");
}
},
closedMenu() {
this.isShow = false;
this.operationHeight = 160;
this.clickMenuIndex = -1;
},
},
computed: {
...mapGetters({
ChatRecord: "GetChatRecord",
status: "GetIsShowUserName",
}),
},
};
</script>
<style lang="less" scoped>
@keyframes test {
0% {
transform: translateX(0);
}
25% {
transform: translateX(50px);
}
50% {
transform: translateX(0);
}
75% {
transform: translateX(-50px);
}
100% {
transform: translateX(0);
}
}
.shake {
animation: test 0.1s reverse infinite;
}
.index {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
.chat_record {
flex: 1;
overflow-y: scroll;
padding: 40rpx;
box-sizing: border-box;
.right {
flex-direction: row-reverse;
.news_name {
text-align: right;
}
.news_img {
margin-left: 20rpx;
}
/deep/ .news_content {
background: #def3fc;
}
}
.news {
display: flex;
margin-bottom: 50rpx;
.system {
text-align: center;
margin: 0 auto;
color: #878d98;
font-size: 26rpx;
}
.news_img {
width: 80rpx;
height: 80rpx;
border-radius: 100%;
margin-right: 20rpx;
}
.news_text {
.news_name {
margin-bottom: 18rpx;
color: #606061;
font-size: 28rpx;
}
/deep/ .content_img {
max-width: calc(100vw - 348rpx);
}
/deep/ .news_content {
font-size: 32rpx;
padding: 24rpx;
border-radius: 24rpx;
box-sizing: border-box;
background: #f3f3f4;
max-width: calc(100vw - 288rpx);
}
}
}
}
.bottom_operation {
display: flex;
flex-direction: column;
box-sizing: border-box;
// height: 160rpx;
// height: 620rpx;
.input_list {
height: 80rpx;
display: flex;
align-items: center;
justify-content: space-between;
background: #ebeef0;
padding: 0 20rpx;
padding-top: 10rpx;
.uni-input {
background: #fff;
flex: 1;
height: 90%;
border-radius: 30rpx;
font-size: 28rpx;
box-sizing: border-box;
padding-left: 30rpx;
}
}
.menu {
height: 80rpx;
display: flex;
justify-content: space-between;
align-items: center;
background: #ebeef0;
padding: 0 20rpx;
.active {
color: #fea674 !important;
}
.iconfont {
font-size: 40rpx;
}
}
.menu_popup {
flex: 1;
background: #fff;
padding: 20rpx 20rpx;
overflow-y: scroll;
.popup {
width: 100%;
height: 100%;
}
.qipao_popup {
display: flex;
flex-wrap: wrap;
align-content: flex-start;
overflow-y: scroll;
.theme_item {
text-align: center;
line-height: 90rpx;
border-radius: 12rpx;
font-size: 26rpx;
width: 30%;
height: 90rpx;
margin-right: 20rpx;
margin-bottom: 20rpx;
box-sizing: border-box;
box-shadow: 6rpx 8rpx 14rpx #929292;
}
}
.gallery_popup {
display: flex;
flex-wrap: wrap;
image {
width: 160rpx;
height: 160rpx;
margin-right: 10rpx;
}
}
}
}
}
/deep/ .uni-navbar--border {
border: none;
}
</style>