Compare commits
4 Commits
267bc814cb
...
6878ad5834
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6878ad5834 | ||
| 62b03f8343 | |||
| 91db27cca7 | |||
| 1058af4f84 |
@ -1,6 +1,6 @@
|
||||
// SCSS 变量定义
|
||||
$font-size-text: 28rpx;
|
||||
$font-size-tip: 24rpx;
|
||||
$font-size-text: 30rpx;
|
||||
$font-size-tip: 28rpx;
|
||||
$font-size-title: 32rpx;
|
||||
$text-color-sub: #999;
|
||||
$primary-color: #0877F1;
|
||||
@ -15,7 +15,8 @@ $primary-color: #0877F1;
|
||||
|
||||
/* 患者信息栏样式 */
|
||||
.patient-info-bar {
|
||||
position: relative;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
background: #fff;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
padding: 20rpx 32rpx;
|
||||
@ -112,6 +113,7 @@ $primary-color: #0877F1;
|
||||
flex: 1;
|
||||
box-sizing: border-box;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
@ -356,7 +358,7 @@ $primary-color: #0877F1;
|
||||
}
|
||||
|
||||
.message-text {
|
||||
font-size: $font-size-text;
|
||||
font-size: 30rpx;
|
||||
line-height: 1.4;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
|
||||
@ -524,6 +524,7 @@ const initTIMCallbacks = async () => {
|
||||
})
|
||||
.then(() => {
|
||||
console.log("✓ 收到新消息后已标记为已读");
|
||||
// 标记为已读后,刷新 tabBar 徽章
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("✗ 标记已读失败:", error);
|
||||
@ -677,6 +678,7 @@ const loadMessageList = async () => {
|
||||
})
|
||||
.then(() => {
|
||||
console.log("✓ 会话已标记为已读:", chatInfo.value.conversationID);
|
||||
// 标记为已读后,刷新 tabBar 徽章
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("✗ 标记会话已读失败:", error);
|
||||
@ -825,6 +827,12 @@ onShow(() => {
|
||||
checkLoginAndInitTIM();
|
||||
} else if (timChatManager.tim && !timChatManager.isLoggedIn) {
|
||||
timChatManager.ensureIMConnection();
|
||||
} else if (timChatManager.tim && timChatManager.isLoggedIn && chatInfo.value.conversationID) {
|
||||
|
||||
messageList.value = [];
|
||||
isCompleted.value = false;
|
||||
lastFirstMessageId.value = "";
|
||||
loadMessageList();
|
||||
}
|
||||
|
||||
startIMMonitoring(30000);
|
||||
|
||||
@ -1,5 +1,10 @@
|
||||
<template>
|
||||
<view class="message-page">
|
||||
<!-- 标题栏 -->
|
||||
<view class="message-header">
|
||||
<text class="header-title">咨询</text>
|
||||
</view>
|
||||
|
||||
<!-- 消息列表 -->
|
||||
<scroll-view
|
||||
class="message-list"
|
||||
@ -49,7 +54,7 @@
|
||||
</view>
|
||||
<view class="message-preview">
|
||||
<text class="preview-text">{{
|
||||
conversation.lastMessage || "暂无消息"
|
||||
cleanMessageText(conversation.lastMessage) || "暂无消息"
|
||||
}}</text>
|
||||
</view>
|
||||
</view>
|
||||
@ -75,7 +80,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ref, computed } from "vue";
|
||||
import { onLoad, onShow, onHide } from "@dcloudio/uni-app";
|
||||
import { storeToRefs } from "pinia";
|
||||
import useAccountStore from "@/store/account.js";
|
||||
@ -98,6 +103,57 @@ const refreshing = ref(false);
|
||||
// 群聊头像管理
|
||||
const { loadGroupAvatars, getAvatarList } = useGroupAvatars();
|
||||
|
||||
// 计算总未读消息数
|
||||
const totalUnreadCount = computed(() => {
|
||||
return conversationList.value.reduce(
|
||||
(sum, conv) => sum + (conv.unreadCount || 0),
|
||||
0
|
||||
);
|
||||
});
|
||||
|
||||
// 立即更新未读徽章
|
||||
const updateUnreadBadgeImmediately = async () => {
|
||||
try {
|
||||
if (!globalTimChatManager || !globalTimChatManager.tim) {
|
||||
console.warn("TIM实例不存在,无法更新徽章");
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await globalTimChatManager.tim.getConversationList();
|
||||
|
||||
if (!response || !response.data || !response.data.conversationList) {
|
||||
console.warn("获取会话列表返回数据异常");
|
||||
return;
|
||||
}
|
||||
|
||||
// 计算群聊总未读数
|
||||
const totalUnreadCount = response.data.conversationList
|
||||
.filter(
|
||||
(conv) => conv.conversationID && conv.conversationID.startsWith("GROUP")
|
||||
)
|
||||
.reduce((sum, conv) => sum + (conv.unreadCount || 0), 0);
|
||||
try {
|
||||
if (totalUnreadCount > 0) {
|
||||
uni.setTabBarBadge({
|
||||
index: 1,
|
||||
text: totalUnreadCount > 99 ? "99+" : String(totalUnreadCount),
|
||||
});
|
||||
console.log("已更新 tabBar 徽章:", totalUnreadCount);
|
||||
} else {
|
||||
uni.setTabBarBadge({
|
||||
index: 1,
|
||||
text: "",
|
||||
});
|
||||
console.log("已清除 tabBar 徽章");
|
||||
}
|
||||
} catch (badgeError) {
|
||||
console.error("更新TabBar徽章失败:", badgeError);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("更新未读徽章失败:", error);
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化IM
|
||||
const initIM = async () => {
|
||||
console.log("=== message.vue initIM 开始 ===");
|
||||
@ -110,22 +166,12 @@ const initIM = async () => {
|
||||
);
|
||||
|
||||
if (!isIMInitialized.value) {
|
||||
uni.showLoading({
|
||||
title: "连接中...",
|
||||
});
|
||||
|
||||
console.log("开始调用 initIMAfterLogin");
|
||||
const success = await initIMAfterLogin();
|
||||
console.log("initIMAfterLogin 返回:", success);
|
||||
|
||||
uni.hideLoading();
|
||||
|
||||
if (!success) {
|
||||
console.error("initIMAfterLogin 失败");
|
||||
uni.showToast({
|
||||
title: "IM连接失败,请重试",
|
||||
icon: "none",
|
||||
});
|
||||
console.log("initIMAfterLogin 失败,跳过 IM 初始化");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -141,14 +187,10 @@ const initIM = async () => {
|
||||
);
|
||||
} else if (globalTimChatManager && !globalTimChatManager.isLoggedIn) {
|
||||
console.log("IM 已初始化但未登录,尝试重连");
|
||||
uni.showLoading({
|
||||
title: "重连中...",
|
||||
});
|
||||
const reconnected = await globalTimChatManager.ensureIMConnection();
|
||||
uni.hideLoading();
|
||||
|
||||
if (!reconnected) {
|
||||
console.error("重连失败");
|
||||
console.log("重连失败");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -167,19 +209,22 @@ const loadConversationList = async () => {
|
||||
|
||||
// 验证 IM 管理器和 TIM 实例是否存在
|
||||
if (!globalTimChatManager) {
|
||||
throw new Error("IM管理器未初始化");
|
||||
console.log("IM管理器未初始化,跳过加载");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!globalTimChatManager.tim) {
|
||||
console.error("TIM实例不存在,尝试重新初始化");
|
||||
console.log("TIM实例不存在,尝试重新初始化");
|
||||
const imReady = await initIM();
|
||||
if (!imReady || !globalTimChatManager.tim) {
|
||||
throw new Error("TIM实例初始化失败");
|
||||
console.log("TIM实例初始化失败,跳过加载");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!globalTimChatManager.getGroupList) {
|
||||
throw new Error("getGroupList 方法不存在");
|
||||
console.log("getGroupList 方法不存在,跳过加载");
|
||||
return;
|
||||
}
|
||||
|
||||
// 直接调用getGroupList,它会自动等待SDK就绪
|
||||
@ -198,18 +243,10 @@ const loadConversationList = async () => {
|
||||
// 加载所有群聊的头像
|
||||
await loadGroupAvatars(conversationList.value);
|
||||
} else {
|
||||
console.error("加载群聊列表失败:", result);
|
||||
uni.showToast({
|
||||
title: "加载失败,请重试",
|
||||
icon: "none",
|
||||
});
|
||||
console.log("加载群聊列表失败或返回数据为空");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("加载会话列表失败:", error);
|
||||
uni.showToast({
|
||||
title: error.message || "加载失败,请重试",
|
||||
icon: "none",
|
||||
});
|
||||
console.log("加载会话列表异常:", error.message);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
@ -221,11 +258,9 @@ let updateTimer = null;
|
||||
// 设置会话列表监听,实时更新列表
|
||||
const setupConversationListener = () => {
|
||||
if (!globalTimChatManager) return;
|
||||
|
||||
// 监听会话列表更新事件
|
||||
globalTimChatManager.setCallback("onConversationListUpdated", (eventData) => {
|
||||
console.log("会话列表更新事件:", eventData);
|
||||
|
||||
// 处理单个会话更新(标记已读的情况)
|
||||
if (eventData && !Array.isArray(eventData) && eventData.conversationID) {
|
||||
const conversationID = eventData.conversationID;
|
||||
@ -414,16 +449,13 @@ const formatMessageTime = (timestamp) => {
|
||||
};
|
||||
|
||||
// 点击会话
|
||||
const handleClickConversation = (conversation) => {
|
||||
const handleClickConversation = async (conversation) => {
|
||||
console.log("点击会话:", conversation);
|
||||
|
||||
// 立即清空本地未读数(优化用户体验)
|
||||
const conversationIndex = conversationList.value.findIndex(
|
||||
(conv) => conv.conversationID === conversation.conversationID
|
||||
);
|
||||
if (conversationIndex !== -1) {
|
||||
conversationList.value[conversationIndex].unreadCount = 0;
|
||||
console.log("已清空本地未读数:", conversation.name);
|
||||
}
|
||||
|
||||
// 跳转到聊天页面
|
||||
@ -459,24 +491,26 @@ onLoad(() => {
|
||||
console.log("消息列表页面加载");
|
||||
});
|
||||
|
||||
// 清理消息文本(移除换行符)
|
||||
const cleanMessageText = (text) => {
|
||||
if (!text) return "";
|
||||
return text.replace(/[\r\n]+/g, " ").trim();
|
||||
};
|
||||
|
||||
// 页面显示
|
||||
onShow(async () => {
|
||||
try {
|
||||
console.log("消息列表页面显示,开始初始化");
|
||||
|
||||
// 初始化IM
|
||||
const imReady = await initIM();
|
||||
if (!imReady) initIMAfterLogin();
|
||||
if (!imReady) {
|
||||
console.log("IM初始化失败,继续加载列表");
|
||||
}
|
||||
// 先加载初始会话列表
|
||||
await loadConversationList();
|
||||
// 再设置监听器,后续通过事件更新列表
|
||||
setupConversationListener();
|
||||
} catch (error) {
|
||||
console.error("页面初始化失败:", error);
|
||||
uni.showToast({
|
||||
title: error.message || "初始化失败,请重试",
|
||||
icon: "none",
|
||||
});
|
||||
console.log("页面初始化异常:", error.message);
|
||||
}
|
||||
});
|
||||
|
||||
@ -487,8 +521,6 @@ onHide(() => {
|
||||
clearTimeout(updateTimer);
|
||||
updateTimer = null;
|
||||
}
|
||||
|
||||
// 移除消息监听
|
||||
if (globalTimChatManager) {
|
||||
globalTimChatManager.setCallback("onConversationListUpdated", null);
|
||||
globalTimChatManager.setCallback("onMessageReceived", null);
|
||||
@ -501,11 +533,46 @@ onHide(() => {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.message-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 24rpx 32rpx;
|
||||
background-color: #fff;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: 600;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.total-unread-badge {
|
||||
min-width: 40rpx;
|
||||
height: 40rpx;
|
||||
padding: 0 12rpx;
|
||||
background-color: #ff4d4f;
|
||||
border-radius: 20rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.badge-text {
|
||||
font-size: 24rpx;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.message-list {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.loading-container,
|
||||
|
||||
@ -58,7 +58,7 @@ export default defineStore("accountStore", () => {
|
||||
// 使用 openid 作为 userID 初始化 IM
|
||||
const userID = openid.value || uni.getStorageSync('openid');
|
||||
if (!userID) {
|
||||
console.error('无法获取 openid,IM 初始化失败');
|
||||
console.log('未获取到有效的 userId,跳过 IM 初始化');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -66,13 +66,13 @@ export default defineStore("accountStore", () => {
|
||||
const success = await initGlobalTIM(userID);
|
||||
|
||||
if (!success) {
|
||||
console.error('initGlobalTIM 返回失败');
|
||||
console.log('initGlobalTIM 返回失败,跳过 IM 初始化');
|
||||
return false;
|
||||
}
|
||||
|
||||
// 验证 TIM 实例是否真正创建成功
|
||||
if (!globalTimChatManager || !globalTimChatManager.tim) {
|
||||
console.error('IM 初始化后 TIM 实例不存在');
|
||||
console.log('IM 初始化后 TIM 实例不存在,跳过 IM 初始化');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -80,7 +80,7 @@ export default defineStore("accountStore", () => {
|
||||
console.log('IM 初始化成功');
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('IM初始化失败:', error);
|
||||
console.log('IM初始化异常,跳过 IM 初始化:', error.message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
135
utils/global-unread-listener.js
Normal file
135
utils/global-unread-listener.js
Normal file
@ -0,0 +1,135 @@
|
||||
import { globalTimChatManager } from './tim-chat.js';
|
||||
|
||||
/**
|
||||
* 全局未读消息监听管理器
|
||||
* 负责监听会话列表更新和消息接收事件,实时更新 tabBar 徽章
|
||||
*/
|
||||
class GlobalUnreadListenerManager {
|
||||
constructor() {
|
||||
this.isInitialized = false;
|
||||
this.originalConversationListCallback = null;
|
||||
this.originalMessageReceivedCallback = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化全局未读消息监听
|
||||
* 监听会话列表更新、消息接收和消息已读事件
|
||||
*/
|
||||
setup() {
|
||||
if (this.isInitialized) {
|
||||
console.warn('全局未读消息监听已初始化,跳过重复初始化');
|
||||
return;
|
||||
}
|
||||
if (!globalTimChatManager) {
|
||||
console.warn('globalTimChatManager 未初始化');
|
||||
return;
|
||||
}
|
||||
|
||||
// 保存原始回调(在覆盖前保存)
|
||||
this.originalConversationListCallback = globalTimChatManager.callbacks.onConversationListUpdated;
|
||||
this.originalMessageReceivedCallback = globalTimChatManager.callbacks.onMessageReceived;
|
||||
|
||||
console.log('保存原始回调:', {
|
||||
hasConversationListCallback: !!this.originalConversationListCallback,
|
||||
hasMessageReceivedCallback: !!this.originalMessageReceivedCallback
|
||||
});
|
||||
|
||||
// 监听会话列表更新事件(包括消息接收和已读状态变化)
|
||||
globalTimChatManager.setCallback('onConversationListUpdated', (eventData) => {
|
||||
console.log('onConversationListUpdated 触发,调用原始回调');
|
||||
// 调用原始回调(如果存在)
|
||||
if (this.originalConversationListCallback && typeof this.originalConversationListCallback === 'function') {
|
||||
this.originalConversationListCallback(eventData);
|
||||
}
|
||||
// 更新 tabBar 徽章
|
||||
this.updateTabBarBadge();
|
||||
});
|
||||
|
||||
// 监听消息接收事件
|
||||
globalTimChatManager.setCallback('onMessageReceived', (message) => {
|
||||
console.log('onMessageReceived 触发,调用原始回调');
|
||||
// 调用原始回调(如果存在)
|
||||
if (this.originalMessageReceivedCallback && typeof this.originalMessageReceivedCallback === 'function') {
|
||||
this.originalMessageReceivedCallback(message);
|
||||
}
|
||||
// 更新 tabBar 徽章
|
||||
this.updateTabBarBadge();
|
||||
});
|
||||
|
||||
this.isInitialized = true;
|
||||
console.log('全局未读消息监听已设置');
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新 tabBar 徽章
|
||||
* 获取所有群聊会话的未读数,并更新对应的 tabBar 徽章
|
||||
*/
|
||||
async updateTabBarBadge() {
|
||||
try {
|
||||
if (!globalTimChatManager || !globalTimChatManager.tim) {
|
||||
console.warn('globalTimChatManager 或 tim 未初始化');
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await globalTimChatManager.tim.getConversationList();
|
||||
|
||||
if (!response || !response.data || !response.data.conversationList) {
|
||||
console.warn('获取会话列表返回数据异常');
|
||||
return;
|
||||
}
|
||||
|
||||
const totalUnreadCount = this.calculateGroupUnreadCount(response.data.conversationList);
|
||||
this.setTabBarBadge(totalUnreadCount);
|
||||
} catch (error) {
|
||||
console.error('更新 tabBar 徽章失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算群聊会话的总未读数
|
||||
* @param {Array} conversationList - 会话列表
|
||||
* @returns {number} 总未读数
|
||||
*/
|
||||
calculateGroupUnreadCount(conversationList) {
|
||||
return conversationList
|
||||
.filter((conv) => conv.conversationID && conv.conversationID.startsWith('GROUP'))
|
||||
.reduce((sum, conv) => sum + (conv.unreadCount || 0), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 tabBar 徽章
|
||||
* @param {number} count - 未读数
|
||||
* @param {number} tabIndex - tabBar 索引,默认为 1(消息页)
|
||||
*/
|
||||
setTabBarBadge(count, tabIndex = 1) {
|
||||
if (count > 0) {
|
||||
uni.setTabBarBadge({
|
||||
index: tabIndex,
|
||||
text: count > 99 ? '99+' : String(count)
|
||||
});
|
||||
console.log(`已更新 tabBar 徽章(索引 ${tabIndex}):`, count);
|
||||
} else {
|
||||
// uni.removeTabBarBadge({
|
||||
// index: tabIndex
|
||||
// });
|
||||
console.log(`已移除 tabBar 徽章(索引 ${tabIndex})`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async refreshBadge() {
|
||||
console.log('手动刷新 tabBar 徽章');
|
||||
await this.updateTabBarBadge();
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除监听(可选)
|
||||
*/
|
||||
destroy() {
|
||||
this.isInitialized = false;
|
||||
console.log('全局未读消息监听已清除');
|
||||
}
|
||||
}
|
||||
|
||||
// 导出单例
|
||||
export const globalUnreadListenerManager = new GlobalUnreadListenerManager();
|
||||
@ -193,7 +193,12 @@ class TimChatManager {
|
||||
|
||||
// 获取用户信息并登录
|
||||
console.log('开始获取用户信息并登录...')
|
||||
await this.getUserInfoAndLogin(userID)
|
||||
const loginSuccess = await this.getUserInfoAndLogin(userID)
|
||||
if (!loginSuccess) {
|
||||
console.log('获取用户信息失败,跳过 IM 初始化')
|
||||
await this.cleanupOldInstance()
|
||||
return false
|
||||
}
|
||||
console.log('用户信息获取并登录成功')
|
||||
|
||||
// 等待SDK Ready
|
||||
@ -206,11 +211,7 @@ class TimChatManager {
|
||||
return true
|
||||
|
||||
} catch (error) {
|
||||
console.error('=== IM初始化失败 ===', error)
|
||||
console.error('错误详情:', error.message || error)
|
||||
console.error('错误堆栈:', error.stack)
|
||||
this.triggerCallback('onError', `初始化失败: ${error.message || error}`)
|
||||
|
||||
console.log('=== IM初始化异常 ===', error.message)
|
||||
// 初始化失败时清理资源
|
||||
console.log('初始化失败,开始清理资源...')
|
||||
await this.cleanupOldInstance()
|
||||
@ -390,7 +391,8 @@ class TimChatManager {
|
||||
console.log('本地存储的 userInfo:', userInfo)
|
||||
|
||||
if (!userInfo?.userID) {
|
||||
throw new Error('未找到用户信息,请先登录')
|
||||
console.log('未找到用户信息,跳过 IM 初始化')
|
||||
return false
|
||||
}
|
||||
this.currentUserID = userInfo.userID
|
||||
console.log('从本地存储获取到 userID:', this.currentUserID)
|
||||
@ -403,11 +405,10 @@ class TimChatManager {
|
||||
console.log('开始登录 TIM...')
|
||||
await this.loginTIM()
|
||||
console.log('TIM 登录成功')
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('获取用户信息失败:', error)
|
||||
console.error('错误详情:', error.message || error)
|
||||
this.triggerCallback('onError', `登录失败: ${error.message || error}`)
|
||||
throw error // 重新抛出错误,让调用者知道登录失败
|
||||
console.log('获取用户信息异常:', error.message)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@ -2729,7 +2730,7 @@ class TimChatManager {
|
||||
console.log('⚠️ TIM未初始化或未登录,无法标记会话已读');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
let formattedConversationID = conversationID
|
||||
if (!conversationID.startsWith('GROUP')) {
|
||||
@ -2739,11 +2740,14 @@ class TimChatManager {
|
||||
conversationID: formattedConversationID,
|
||||
unreadCount: 0
|
||||
})
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.error('✗ 标记会话已读异常:', error)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 更新会话列表
|
||||
updateConversationListOnNewMessage(message) {
|
||||
try {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user