im-ui-mobile 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/im-avatar/im-avatar.vue +7 -7
- package/components/im-badge/im-badge.vue +326 -0
- package/components/im-button/im-button.vue +71 -34
- package/components/im-card/im-card.vue +563 -0
- package/components/im-chat-item/im-chat-item.vue +5 -4
- package/components/im-col/im-col.vue +191 -0
- package/components/im-dialog/im-dialog.vue +543 -0
- package/components/im-double-tap-view/im-double-tap-view.vue +93 -0
- package/components/im-emoji-picker/im-emoji-picker.vue +1143 -0
- package/components/im-friend-item/im-friend-item.vue +1 -1
- package/components/im-group-item/im-group-item.vue +1 -1
- package/components/im-group-member-selector/im-group-member-selector.vue +5 -5
- package/components/im-group-rtc-join/im-group-rtc-join.vue +8 -8
- package/components/im-icon/im-icon.vue +593 -0
- package/components/im-image-upload/im-image-upload.vue +0 -2
- package/components/im-link/im-link.vue +628 -0
- package/components/im-loading/im-loading.vue +13 -4
- package/components/im-mention-picker/im-mention-picker.vue +8 -7
- package/components/im-message-action/im-message-action.vue +678 -0
- package/components/im-message-item/im-message-item.vue +28 -26
- package/components/im-message-list/im-message-list.vue +1108 -0
- package/components/im-modal/im-modal.vue +373 -0
- package/components/im-nav-bar/im-nav-bar.vue +689 -75
- package/components/im-parse/im-parse.vue +1054 -0
- package/components/im-popup/im-popup.vue +467 -0
- package/components/im-read-receipt/im-read-receipt.vue +10 -10
- package/components/im-row/im-row.vue +189 -0
- package/components/im-search/im-search.vue +762 -0
- package/components/im-sku/im-sku.vue +720 -0
- package/components/im-sku/utils/helper.ts +182 -0
- package/components/im-stepper/im-stepper.vue +585 -0
- package/components/im-stepper/utils/helper.ts +167 -0
- package/components/im-tabs/im-tabs.vue +1022 -0
- package/components/im-tabs/tabs-navigation.vue +489 -0
- package/components/im-tabs/utils/helper.ts +181 -0
- package/components/im-tabs-tab-pane/im-tabs-tab-pane.vue +145 -0
- package/components/im-upload/im-upload.vue +1236 -0
- package/components/im-voice-input/im-voice-input.vue +1 -1
- package/index.js +3 -5
- package/index.scss +19 -0
- package/libs/emoji-data.ts +229 -0
- package/libs/index.ts +16 -16
- package/package.json +1 -2
- package/styles/button.scss +33 -33
- package/theme.scss +2 -2
- package/types/components/badge.d.ts +42 -0
- package/types/components/button.d.ts +2 -1
- package/types/components/card.d.ts +122 -0
- package/types/components/col.d.ts +37 -0
- package/types/components/dialog.d.ts +125 -0
- package/types/components/double-tap-view.d.ts +31 -0
- package/types/components/emoji-picker.d.ts +121 -0
- package/types/components/group-rtc-join.d.ts +1 -1
- package/types/components/icon.d.ts +77 -0
- package/types/components/link.d.ts +55 -0
- package/types/components/loading.d.ts +1 -0
- package/types/components/message-action.d.ts +96 -0
- package/types/components/message-item.d.ts +2 -2
- package/types/components/message-list.d.ts +136 -0
- package/types/components/modal.d.ts +106 -0
- package/types/components/nav-bar.d.ts +125 -0
- package/types/components/parse.d.ts +90 -0
- package/types/components/popup.d.ts +58 -0
- package/types/components/row.d.ts +31 -0
- package/types/components/search.d.ts +54 -0
- package/types/components/sku.d.ts +195 -0
- package/types/components/stepper.d.ts +99 -0
- package/types/components/tabs-tab-pane.d.ts +27 -0
- package/types/components/tabs.d.ts +117 -0
- package/types/components/upload.d.ts +137 -0
- package/types/components.d.ts +19 -1
- package/types/index.d.ts +38 -1
- package/types/libs/index.d.ts +10 -10
- package/types/utils/base64.d.ts +5 -0
- package/types/utils/dom.d.ts +3 -0
- package/types/utils/enums.d.ts +4 -5
- package/types/utils/validator.d.ts +74 -0
- package/utils/base64.js +18 -0
- package/utils/dom.js +353 -1
- package/utils/enums.js +4 -5
- package/utils/validator.js +230 -0
- package/components/im-file-upload/im-file-upload.vue +0 -309
- package/plugins/uview-plus.js +0 -29
- package/types/components/arrow-bar.d.ts +0 -14
- package/types/components/file-upload.d.ts +0 -58
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
</view>
|
|
17
17
|
<view class="rc-tip">{{ recordTip }}</view>
|
|
18
18
|
<view class="cancel-btn" @click="onCancel">
|
|
19
|
-
<
|
|
19
|
+
<im-icon name="close" :color="moveToCancel ? 'red' : 'black'" :size="moveToCancel ? 45 : 40" />
|
|
20
20
|
</view>
|
|
21
21
|
<view class="opt-tip" :class="moveToCancel ? 'red' : 'black'">{{ moveToCancel ? '松手取消' : '松手发送,上划取消' }}
|
|
22
22
|
</view>
|
package/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { nextTick } from 'vue';
|
|
2
|
-
import { UViewPlusPlugin } from './plugins/uview-plus.js'
|
|
3
2
|
import eventBus from "./utils/eventBus.js";
|
|
4
3
|
import datetime from "./utils/datetime.js";
|
|
5
4
|
import Emoji from "./utils/emoji.js";
|
|
@@ -13,6 +12,7 @@ import { useDynamicRefs } from "./utils/useDynamicRefs.js";
|
|
|
13
12
|
import WebSocket from "./utils/websocket.js";
|
|
14
13
|
import { MESSAGE_TYPE, RTC_STATE, TERMINAL_TYPE, MESSAGE_STATUS } from "./utils/enums.js";
|
|
15
14
|
import { configManager } from './utils/config.js'
|
|
15
|
+
import validator from './utils/validator.js'
|
|
16
16
|
|
|
17
17
|
const importComponents = import.meta.glob('./components/im-*/im-*.vue', { eager: true })
|
|
18
18
|
const components = [];
|
|
@@ -39,7 +39,7 @@ for (const key in importComponents) {
|
|
|
39
39
|
|
|
40
40
|
// 全局配置对象
|
|
41
41
|
let config = {}
|
|
42
|
-
let emoji =
|
|
42
|
+
let emoji = {}
|
|
43
43
|
|
|
44
44
|
const install = (app, upuiParams = '') => {
|
|
45
45
|
// 初始化自定义配置
|
|
@@ -52,9 +52,6 @@ const install = (app, upuiParams = '') => {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
// 安装插件
|
|
56
|
-
app.use(UViewPlusPlugin)
|
|
57
|
-
|
|
58
55
|
// 注册组件
|
|
59
56
|
components.forEach(component => {
|
|
60
57
|
app.component(component.name || '', component)
|
|
@@ -83,6 +80,7 @@ export {
|
|
|
83
80
|
useDynamicRefs,
|
|
84
81
|
WebSocket,
|
|
85
82
|
webSocket,
|
|
83
|
+
validator,
|
|
86
84
|
|
|
87
85
|
// Enums
|
|
88
86
|
MESSAGE_TYPE,
|
package/index.scss
CHANGED
|
@@ -3,3 +3,22 @@
|
|
|
3
3
|
@import "./styles/button.scss";
|
|
4
4
|
|
|
5
5
|
@import "./styles/emoji.scss";
|
|
6
|
+
|
|
7
|
+
:root {
|
|
8
|
+
--button-height: 40rpx;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
:global(.im-parse-link) {
|
|
12
|
+
color: #007AFF !important;
|
|
13
|
+
text-decoration: underline !important;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
:global(.im-parse-email) {
|
|
17
|
+
color: #007AFF !important;
|
|
18
|
+
text-decoration: underline !important;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
:global(.im-parse-phone) {
|
|
22
|
+
color: #007AFF !important;
|
|
23
|
+
text-decoration: underline !important;
|
|
24
|
+
}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { EmojiType as Emoji, EmojiCategoryType as EmojiCategory } from '../types/components/emoji-picker'
|
|
2
|
+
|
|
3
|
+
// 表情数据工具类
|
|
4
|
+
export class EmojiData {
|
|
5
|
+
private static instance: EmojiData
|
|
6
|
+
private emojiMap: Map<string, Emoji> = new Map()
|
|
7
|
+
private categoryMap: Map<string, EmojiCategory> = new Map()
|
|
8
|
+
|
|
9
|
+
// 常用表情分类
|
|
10
|
+
public static readonly CATEGORIES: EmojiCategory[] = [
|
|
11
|
+
{ id: 'recent', name: '最近', icon: '🕒', order: 0 },
|
|
12
|
+
{ id: 'smileys', name: '表情', icon: '😀', order: 1 },
|
|
13
|
+
{ id: 'people', name: '人物', icon: '👨', order: 2 },
|
|
14
|
+
{ id: 'gestures', name: '手势', icon: '👋', order: 3 },
|
|
15
|
+
{ id: 'objects', name: '物品', icon: '💡', order: 4 },
|
|
16
|
+
{ id: 'nature', name: '自然', icon: '🌳', order: 5 },
|
|
17
|
+
{ id: 'food', name: '食物', icon: '🍎', order: 6 },
|
|
18
|
+
{ id: 'activities', name: '活动', icon: '⚽', order: 7 },
|
|
19
|
+
{ id: 'travel', name: '旅行', icon: '🚗', order: 8 },
|
|
20
|
+
{ id: 'symbols', name: '符号', icon: '💖', order: 9 },
|
|
21
|
+
{ id: 'flags', name: '旗帜', icon: '🇨🇳', order: 10 }
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
// 默认表情数据
|
|
25
|
+
public static readonly DEFAULT_EMOJIS: Emoji[] = [
|
|
26
|
+
// 笑脸和情感
|
|
27
|
+
{ key: 'grinning', char: '😀', name: '大笑', category: 'smileys', type: 'unicode', keywords: ['笑', '开心', '大笑'] },
|
|
28
|
+
{ key: 'smiley', char: '😃', name: '微笑', category: 'smileys', type: 'unicode', keywords: ['微笑', '开心'] },
|
|
29
|
+
{ key: 'smile', char: '😄', name: '开心', category: 'smileys', type: 'unicode', keywords: ['开心', '笑'] },
|
|
30
|
+
{ key: 'grin', char: '😁', name: '咧嘴笑', category: 'smileys', type: 'unicode', keywords: ['咧嘴', '笑'] },
|
|
31
|
+
{ key: 'laughing', char: '😆', name: '大笑', category: 'smileys', type: 'unicode', keywords: ['大笑', '哈哈'] },
|
|
32
|
+
{ key: 'wink', char: '😉', name: '眨眼', category: 'smileys', type: 'unicode', keywords: ['眨眼', '调皮'] },
|
|
33
|
+
{ key: 'blush', char: '😊', name: '害羞', category: 'smileys', type: 'unicode', keywords: ['害羞', '脸红'] },
|
|
34
|
+
{ key: 'heart_eyes', char: '😍', name: '爱心眼', category: 'smileys', type: 'unicode', keywords: ['爱', '喜欢', '爱心'] },
|
|
35
|
+
{ key: 'kissing_heart', char: '😘', name: '飞吻', category: 'smileys', type: 'unicode', keywords: ['飞吻', '亲'] },
|
|
36
|
+
{ key: 'kissing', char: '😗', name: '亲吻', category: 'smileys', type: 'unicode', keywords: ['亲吻'] },
|
|
37
|
+
|
|
38
|
+
// 手势
|
|
39
|
+
{ key: 'thumbsup', char: '👍', name: '点赞', category: 'gestures', type: 'unicode', keywords: ['赞', '好', '同意'] },
|
|
40
|
+
{ key: 'thumbsdown', char: '👎', name: '点踩', category: 'gestures', type: 'unicode', keywords: ['踩', '不好', '反对'] },
|
|
41
|
+
{ key: 'clap', char: '👏', name: '鼓掌', category: 'gestures', type: 'unicode', keywords: ['鼓掌', '表扬', '赞'] },
|
|
42
|
+
{ key: 'pray', char: '🙏', name: '祈祷', category: 'gestures', type: 'unicode', keywords: ['祈祷', '拜托', '感谢'] },
|
|
43
|
+
{ key: 'handshake', char: '🤝', name: '握手', category: 'gestures', type: 'unicode', keywords: ['握手', '合作', '协议'] },
|
|
44
|
+
{ key: 'victory', char: '✌️', name: '胜利', category: 'gestures', type: 'unicode', keywords: ['胜利', '耶', '和平'] },
|
|
45
|
+
{ key: 'ok_hand', char: '👌', name: 'OK', category: 'gestures', type: 'unicode', keywords: ['OK', '好的', '同意'] },
|
|
46
|
+
{ key: 'v', char: '✌', name: '剪刀手', category: 'gestures', type: 'unicode', keywords: ['剪刀手', '耶'] },
|
|
47
|
+
|
|
48
|
+
// 物品
|
|
49
|
+
{ key: 'heart', char: '❤️', name: '红心', category: 'symbols', type: 'unicode', keywords: ['心', '爱', '喜欢'] },
|
|
50
|
+
{ key: 'star', char: '⭐', name: '星星', category: 'symbols', type: 'unicode', keywords: ['星星', '收藏'] },
|
|
51
|
+
{ key: 'fire', char: '🔥', name: '火焰', category: 'symbols', type: 'unicode', keywords: ['火', '热', '厉害'] },
|
|
52
|
+
{ key: 'rocket', char: '🚀', name: '火箭', category: 'travel', type: 'unicode', keywords: ['火箭', '快', '发射'] },
|
|
53
|
+
{ key: 'bulb', char: '💡', name: '灯泡', category: 'objects', type: 'unicode', keywords: ['灯泡', '想法', '主意'] },
|
|
54
|
+
{ key: 'gift', char: '🎁', name: '礼物', category: 'objects', type: 'unicode', keywords: ['礼物', '惊喜'] },
|
|
55
|
+
{ key: 'bell', char: '🔔', name: '铃铛', category: 'objects', type: 'unicode', keywords: ['铃铛', '通知'] },
|
|
56
|
+
{ key: 'lock', char: '🔒', name: '锁', category: 'objects', type: 'unicode', keywords: ['锁', '安全', '保密'] },
|
|
57
|
+
|
|
58
|
+
// 自然
|
|
59
|
+
{ key: 'sun', char: '☀️', name: '太阳', category: 'nature', type: 'unicode', keywords: ['太阳', '晴天', '热'] },
|
|
60
|
+
{ key: 'moon', char: '🌙', name: '月亮', category: 'nature', type: 'unicode', keywords: ['月亮', '夜晚'] },
|
|
61
|
+
{ key: 'star2', char: '🌟', name: '闪星', category: 'nature', type: 'unicode', keywords: ['星星', '闪', '亮'] },
|
|
62
|
+
{ key: 'cloud', char: '☁️', name: '云', category: 'nature', type: 'unicode', keywords: ['云', '天气'] },
|
|
63
|
+
{ key: 'rainbow', char: '🌈', name: '彩虹', category: 'nature', type: 'unicode', keywords: ['彩虹', '希望', '美好'] },
|
|
64
|
+
{ key: 'flower', char: '🌹', name: '玫瑰', category: 'nature', type: 'unicode', keywords: ['玫瑰', '花', '爱情'] },
|
|
65
|
+
{ key: 'tree', char: '🌳', name: '树', category: 'nature', type: 'unicode', keywords: ['树', '自然'] },
|
|
66
|
+
|
|
67
|
+
// 食物
|
|
68
|
+
{ key: 'pizza', char: '🍕', name: '披萨', category: 'food', type: 'unicode', keywords: ['披萨', '美食'] },
|
|
69
|
+
{ key: 'hamburger', char: '🍔', name: '汉堡', category: 'food', type: 'unicode', keywords: ['汉堡', '快餐'] },
|
|
70
|
+
{ key: 'coffee', char: '☕', name: '咖啡', category: 'food', type: 'unicode', keywords: ['咖啡', '提神'] },
|
|
71
|
+
{ key: 'beer', char: '🍺', name: '啤酒', category: 'food', type: 'unicode', keywords: ['啤酒', '喝酒'] },
|
|
72
|
+
{ key: 'cake', char: '🎂', name: '蛋糕', category: 'food', type: 'unicode', keywords: ['蛋糕', '生日', '庆祝'] },
|
|
73
|
+
{ key: 'icecream', char: '🍦', name: '冰淇淋', category: 'food', type: 'unicode', keywords: ['冰淇淋', '冷饮'] },
|
|
74
|
+
|
|
75
|
+
// 活动
|
|
76
|
+
{ key: 'soccer', char: '⚽', name: '足球', category: 'activities', type: 'unicode', keywords: ['足球', '运动'] },
|
|
77
|
+
{ key: 'basketball', char: '🏀', name: '篮球', category: 'activities', type: 'unicode', keywords: ['篮球', '运动'] },
|
|
78
|
+
{ key: 'tennis', char: '🎾', name: '网球', category: 'activities', type: 'unicode', keywords: ['网球', '运动'] },
|
|
79
|
+
{ key: 'music', char: '🎵', name: '音乐', category: 'activities', type: 'unicode', keywords: ['音乐', '音符'] },
|
|
80
|
+
{ key: 'movie', char: '🎬', name: '电影', category: 'activities', type: 'unicode', keywords: ['电影', '导演'] },
|
|
81
|
+
|
|
82
|
+
// 自定义表情(图片类型)
|
|
83
|
+
{ key: 'custom_001', char: '', name: '自定义1', category: 'custom', type: 'image', url: '/static/emoji/custom/001.png' },
|
|
84
|
+
{ key: 'custom_002', char: '', name: '自定义2', category: 'custom', type: 'image', url: '/static/emoji/custom/002.png' }
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
private constructor() {
|
|
88
|
+
this.initData()
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
public static getInstance(): EmojiData {
|
|
92
|
+
if (!EmojiData.instance) {
|
|
93
|
+
EmojiData.instance = new EmojiData()
|
|
94
|
+
}
|
|
95
|
+
return EmojiData.instance
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
private initData(): void {
|
|
99
|
+
// 初始化分类
|
|
100
|
+
EmojiData.CATEGORIES.forEach(category => {
|
|
101
|
+
this.categoryMap.set(category.id, category)
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
// 初始化表情
|
|
105
|
+
EmojiData.DEFAULT_EMOJIS.forEach(emoji => {
|
|
106
|
+
this.emojiMap.set(emoji.key, emoji)
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// 获取所有表情
|
|
111
|
+
public getAllEmojis(): Emoji[] {
|
|
112
|
+
return Array.from(this.emojiMap.values())
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// 获取所有分类
|
|
116
|
+
public getAllCategories(): EmojiCategory[] {
|
|
117
|
+
return Array.from(this.categoryMap.values())
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// 根据分类获取表情
|
|
121
|
+
public getEmojisByCategory(categoryId: string): Emoji[] {
|
|
122
|
+
return this.getAllEmojis().filter(emoji => emoji.category === categoryId)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// 搜索表情
|
|
126
|
+
public searchEmojis(keyword: string): Emoji[] {
|
|
127
|
+
const kw = keyword.toLowerCase().trim()
|
|
128
|
+
if (!kw) return []
|
|
129
|
+
|
|
130
|
+
return this.getAllEmojis().filter(emoji => {
|
|
131
|
+
// 搜索名称
|
|
132
|
+
if (emoji.name.toLowerCase().includes(kw)) return true
|
|
133
|
+
|
|
134
|
+
// 搜索关键词
|
|
135
|
+
if (emoji.keywords?.some(k => k.toLowerCase().includes(kw))) return true
|
|
136
|
+
|
|
137
|
+
// 搜索 key
|
|
138
|
+
if (emoji.key.toLowerCase().includes(kw)) return true
|
|
139
|
+
|
|
140
|
+
// 搜索字符
|
|
141
|
+
if (emoji.char.includes(kw)) return true
|
|
142
|
+
|
|
143
|
+
return false
|
|
144
|
+
})
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// 根据key获取表情
|
|
148
|
+
public getEmojiByKey(key: string): Emoji | undefined {
|
|
149
|
+
return this.emojiMap.get(key)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// 根据字符获取表情
|
|
153
|
+
public getEmojiByChar(char: string): Emoji | undefined {
|
|
154
|
+
return this.getAllEmojis().find(emoji => emoji.char === char)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// 添加自定义表情
|
|
158
|
+
public addCustomEmoji(emoji: Emoji): void {
|
|
159
|
+
if (!emoji.category) {
|
|
160
|
+
emoji.category = 'custom'
|
|
161
|
+
}
|
|
162
|
+
this.emojiMap.set(emoji.key, emoji)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// 移除表情
|
|
166
|
+
public removeEmoji(key: string): boolean {
|
|
167
|
+
return this.emojiMap.delete(key)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// 获取最近使用的表情(从本地存储)
|
|
171
|
+
public getRecentEmojis(maxCount: number = 36): Emoji[] {
|
|
172
|
+
try {
|
|
173
|
+
const data = uni.getStorageSync('im_emoji_recent')
|
|
174
|
+
if (data) {
|
|
175
|
+
const keys = JSON.parse(data) as string[]
|
|
176
|
+
const emojis = keys
|
|
177
|
+
.map(key => this.getEmojiByKey(key))
|
|
178
|
+
.filter(Boolean) as Emoji[]
|
|
179
|
+
return emojis.slice(0, maxCount)
|
|
180
|
+
}
|
|
181
|
+
} catch (error) {
|
|
182
|
+
console.error('获取最近表情失败:', error)
|
|
183
|
+
}
|
|
184
|
+
return []
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// 添加到最近使用
|
|
188
|
+
public addToRecent(key: string): void {
|
|
189
|
+
try {
|
|
190
|
+
const data = uni.getStorageSync('im_emoji_recent')
|
|
191
|
+
let recentKeys: string[] = []
|
|
192
|
+
|
|
193
|
+
if (data) {
|
|
194
|
+
recentKeys = JSON.parse(data) as string[]
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// 移除重复项
|
|
198
|
+
const index = recentKeys.indexOf(key)
|
|
199
|
+
if (index > -1) {
|
|
200
|
+
recentKeys.splice(index, 1)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// 添加到开头
|
|
204
|
+
recentKeys.unshift(key)
|
|
205
|
+
|
|
206
|
+
// 限制数量
|
|
207
|
+
if (recentKeys.length > 50) {
|
|
208
|
+
recentKeys = recentKeys.slice(0, 50)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
uni.setStorageSync('im_emoji_recent', JSON.stringify(recentKeys))
|
|
212
|
+
} catch (error) {
|
|
213
|
+
console.error('保存最近表情失败:', error)
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// 清空最近使用
|
|
218
|
+
public clearRecentEmojis(): void {
|
|
219
|
+
try {
|
|
220
|
+
uni.removeStorageSync('im_emoji_recent')
|
|
221
|
+
} catch (error) {
|
|
222
|
+
console.error('清空最近表情失败:', error)
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// 导出单例和类型
|
|
228
|
+
export const emojiData = EmojiData.getInstance()
|
|
229
|
+
export type { Emoji, EmojiCategory }
|
package/libs/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RTC_STATE, MESSAGE_TYPE } from '../types/utils/enums.d.ts'
|
|
1
|
+
import type { RTC_STATE, MESSAGE_TYPE, MESSAGE_STATUS } from '../types/utils/enums.d.ts'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* 通话模式类型
|
|
@@ -22,8 +22,8 @@ export interface Chat {
|
|
|
22
22
|
id?: string | number
|
|
23
23
|
targetId: number
|
|
24
24
|
type: 'PRIVATE' | 'GROUP'
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
displayName: string
|
|
26
|
+
avatar: string
|
|
27
27
|
isDnd: boolean
|
|
28
28
|
lastContent: string
|
|
29
29
|
lastSendTime?: number
|
|
@@ -49,15 +49,15 @@ export interface Message {
|
|
|
49
49
|
content: string
|
|
50
50
|
sendTime?: number
|
|
51
51
|
selfSend?: boolean
|
|
52
|
-
status?:
|
|
52
|
+
status?: MESSAGE_STATUS
|
|
53
53
|
sendNickName?: string
|
|
54
54
|
atUserIds?: number[]
|
|
55
55
|
sendId?: number
|
|
56
|
-
|
|
56
|
+
receiveId?: number
|
|
57
57
|
groupId?: number
|
|
58
58
|
receipt?: boolean
|
|
59
59
|
receiptOk?: boolean
|
|
60
|
-
|
|
60
|
+
readCount?: number
|
|
61
61
|
quoteMessage?: Message
|
|
62
62
|
fileId?: string
|
|
63
63
|
}
|
|
@@ -68,7 +68,7 @@ export interface Message {
|
|
|
68
68
|
export interface Friend {
|
|
69
69
|
id: number
|
|
70
70
|
nickName: string
|
|
71
|
-
|
|
71
|
+
avatar?: string
|
|
72
72
|
online: boolean
|
|
73
73
|
onlineWeb: boolean
|
|
74
74
|
onlineApp: boolean
|
|
@@ -112,7 +112,7 @@ export interface GroupMember {
|
|
|
112
112
|
id?: number
|
|
113
113
|
userId: number
|
|
114
114
|
showNickName: string
|
|
115
|
-
|
|
115
|
+
avatar?: string
|
|
116
116
|
quit?: boolean
|
|
117
117
|
[key: string]: any
|
|
118
118
|
}
|
|
@@ -126,14 +126,14 @@ export interface Group {
|
|
|
126
126
|
isBanned?: boolean
|
|
127
127
|
reason?: string
|
|
128
128
|
name: string
|
|
129
|
-
|
|
129
|
+
avatar: string
|
|
130
130
|
isDnd: boolean
|
|
131
131
|
quit?: boolean
|
|
132
132
|
topMessage?: string
|
|
133
133
|
memberCount?: number
|
|
134
134
|
createTime?: number
|
|
135
135
|
showGroupName: string
|
|
136
|
-
|
|
136
|
+
avatarThumb?: string
|
|
137
137
|
remarkGroupName?: string
|
|
138
138
|
remarkNickName?: string
|
|
139
139
|
notice?: string
|
|
@@ -206,8 +206,8 @@ export interface RecorderFile {
|
|
|
206
206
|
export interface UserInfo {
|
|
207
207
|
id: number
|
|
208
208
|
nickName: string
|
|
209
|
-
|
|
210
|
-
|
|
209
|
+
avatar: string
|
|
210
|
+
avatarThumb?: string
|
|
211
211
|
email?: string
|
|
212
212
|
phone?: string
|
|
213
213
|
gender?: number
|
|
@@ -221,9 +221,9 @@ export interface UserInfo {
|
|
|
221
221
|
}
|
|
222
222
|
|
|
223
223
|
export interface Response<T> {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
224
|
+
code: number
|
|
225
|
+
message: string
|
|
226
|
+
result: T
|
|
227
|
+
success: boolean
|
|
228
228
|
}
|
|
229
229
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "im-ui-mobile",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "A Vue3.0 + Typescript instant messaging component library for Uniapp",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -38,7 +38,6 @@
|
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
40
|
"@dcloudio/uni-app": "3.0.0-4070520250711001",
|
|
41
|
-
"uview-plus": "^3.1.0",
|
|
42
41
|
"vue": "^3.3.0",
|
|
43
42
|
"pinia": "^2.1.7"
|
|
44
43
|
},
|
package/styles/button.scss
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
1
|
|
|
2
2
|
// #ifdef MP-WEIXIN
|
|
3
3
|
// wx小程序只有button,没有uni-botton
|
|
4
|
-
button {
|
|
5
|
-
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
button[type='primary'] {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
button[type='primary'][plain] {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
button[type='warn'] {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
button[type='warn'][plain] {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
button[size='mini'] {
|
|
31
|
-
|
|
32
|
-
}
|
|
4
|
+
// button {
|
|
5
|
+
// font-size: $im-font-size !important;
|
|
6
|
+
// }
|
|
7
|
+
|
|
8
|
+
// button[type='primary'] {
|
|
9
|
+
// color: #fff !important;
|
|
10
|
+
// background: linear-gradient(135deg, $im-color-primary, lighten($im-color-primary, 15%)) !important;
|
|
11
|
+
// }
|
|
12
|
+
|
|
13
|
+
// button[type='primary'][plain] {
|
|
14
|
+
// color: $im-color-primary !important;
|
|
15
|
+
// border: 2px solid $im-color-primary;
|
|
16
|
+
// background: transparent;
|
|
17
|
+
// }
|
|
18
|
+
|
|
19
|
+
// button[type='warn'] {
|
|
20
|
+
// color: #fff !important;
|
|
21
|
+
// background: linear-gradient(135deg, $im-color-danger, lighten($im-color-danger, 15%)) !important;
|
|
22
|
+
// }
|
|
23
|
+
|
|
24
|
+
// button[type='warn'][plain] {
|
|
25
|
+
// color: $im-color-danger !important;
|
|
26
|
+
// border: 1px solid $im-color-danger !important;
|
|
27
|
+
// background: transparent !important;
|
|
28
|
+
// }
|
|
29
|
+
|
|
30
|
+
// button[size='mini'] {
|
|
31
|
+
// font-size: $im-font-size-small !important;
|
|
32
|
+
// }
|
|
33
33
|
|
|
34
34
|
// #endif
|
|
35
35
|
|
|
36
|
-
.button-hover[type='primary'] {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
36
|
+
// .button-hover[type='primary'] {
|
|
37
|
+
// color: #fff !important;
|
|
38
|
+
// background-color: $im-color-primary-dark-1 !important;
|
|
39
|
+
// }
|
package/theme.scss
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// 颜色
|
|
2
|
-
$im-color-primary:
|
|
2
|
+
$im-color-primary: rgb(134 4 155);
|
|
3
3
|
$im-color-primary-light-1: mix(#fff, $im-color-primary, 10%);
|
|
4
4
|
$im-color-primary-light-2: mix(#fff, $im-color-primary, 20%);
|
|
5
5
|
$im-color-primary-light-3: mix(#fff, $im-color-primary, 30%);
|
|
@@ -58,4 +58,4 @@ $im-title-size: 26px;
|
|
|
58
58
|
$im-title-size-1: 22px;
|
|
59
59
|
$im-title-size-2: 18px;
|
|
60
60
|
|
|
61
|
-
$im-nav-bar-height: 50px;
|
|
61
|
+
$im-nav-bar-height: 50px;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { AllowedComponentProps, VNodeProps } from '../common'
|
|
2
|
+
|
|
3
|
+
declare interface BadgeProps {
|
|
4
|
+
/** 徽标显示的值,可以是数字或字符串 */
|
|
5
|
+
value?: string | number
|
|
6
|
+
/** 最大值,超过会显示 {max}+,为0时不做限制 */
|
|
7
|
+
max?: number
|
|
8
|
+
/** 是否显示为小圆点 */
|
|
9
|
+
isDot?: boolean
|
|
10
|
+
/** 是否隐藏徽标 */
|
|
11
|
+
hidden?: boolean
|
|
12
|
+
/** 徽标类型 */
|
|
13
|
+
type?: 'primary' | 'success' | 'warning' | 'danger' | 'info'
|
|
14
|
+
/** 自定义背景色 */
|
|
15
|
+
bgColor?: string
|
|
16
|
+
/** 自定义文字颜色 */
|
|
17
|
+
textColor?: string
|
|
18
|
+
/** 徽标尺寸 */
|
|
19
|
+
size?: 'small' | 'medium' | 'large'
|
|
20
|
+
/** 徽标形状 */
|
|
21
|
+
shape?: 'circle' | 'square' | 'rounded'
|
|
22
|
+
/** 是否绝对定位(需要子元素时生效) */
|
|
23
|
+
absolute?: boolean
|
|
24
|
+
/** 绝对定位的偏移量 [x, y] */
|
|
25
|
+
offset?: [number, number]
|
|
26
|
+
/** 当value为0时是否显示徽标 */
|
|
27
|
+
showZero?: boolean
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
declare interface _Badge {
|
|
31
|
+
new(): {
|
|
32
|
+
$props: AllowedComponentProps & VNodeProps & BadgeProps
|
|
33
|
+
$emit: {
|
|
34
|
+
/** 点击事件 */
|
|
35
|
+
click: (event: MouseEvent) => void
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/** 获取当前值 */
|
|
39
|
+
getValue: () => string | number
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export declare const Badge: _Badge
|
|
@@ -3,7 +3,7 @@ import { AllowedComponentProps, VNodeProps } from 'vue'
|
|
|
3
3
|
declare interface ButtonProps {
|
|
4
4
|
// 基础属性
|
|
5
5
|
text?: string
|
|
6
|
-
type?: 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info'
|
|
6
|
+
type?: 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info' // 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info'
|
|
7
7
|
size?: 'mini' | 'small' | 'medium' | 'large'
|
|
8
8
|
shape?: 'square' | 'round' | 'circle'
|
|
9
9
|
disabled?: boolean
|
|
@@ -26,6 +26,7 @@ declare interface ButtonProps {
|
|
|
26
26
|
color?: string
|
|
27
27
|
bgColor?: string
|
|
28
28
|
borderColor?: string
|
|
29
|
+
border: boolean
|
|
29
30
|
textColor?: string
|
|
30
31
|
textSize?: 'small' | 'medium' | 'large'
|
|
31
32
|
width?: string
|