im-ui-mobile 0.0.82 → 0.0.84

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.
Files changed (42) hide show
  1. package/LICENSE +21 -0
  2. package/components/{im-head-image/im-head-image.vue → im-avatar/im-avatar.vue} +2 -2
  3. package/components/im-button/im-button.vue +603 -38
  4. package/components/im-cell/im-cell.vue +462 -0
  5. package/components/{im-bar-group/im-bar-group.vue → im-cell-group/im-cell-group.vue} +4 -4
  6. package/components/im-cell-switch/im-cell-switch.vue +223 -0
  7. package/components/im-chat-item/im-chat-item.vue +4 -5
  8. package/components/{im-long-press-menu/im-long-press-menu.vue → im-context-menu/im-context-menu.vue} +2 -2
  9. package/components/im-file-upload/im-file-upload.vue +9 -2
  10. package/components/im-friend-item/im-friend-item.vue +2 -2
  11. package/components/im-group-item/im-group-item.vue +2 -2
  12. package/components/im-group-member-selector/im-group-member-selector.vue +3 -3
  13. package/components/im-group-rtc-join/im-group-rtc-join.vue +3 -3
  14. package/components/im-image-upload/im-image-upload.vue +3 -2
  15. package/components/{im-chat-at-box/im-chat-at-box.vue → im-mention-picker/im-mention-picker.vue} +5 -5
  16. package/components/{im-chat-message-item/im-chat-message-item.vue → im-message-item/im-message-item.vue} +19 -21
  17. package/components/{im-chat-group-readed/im-chat-group-readed.vue → im-read-receipt/im-read-receipt.vue} +5 -5
  18. package/components/im-virtual-list/im-virtual-list.vue +444 -0
  19. package/components/{im-chat-record/im-chat-record.vue → im-voice-input/im-voice-input.vue} +11 -11
  20. package/index.js +7 -13
  21. package/package.json +4 -4
  22. package/types/components/{head-image.d.ts → avatar.d.ts} +4 -4
  23. package/types/components/button.d.ts +73 -3
  24. package/types/components/{bar-group.d.ts → cell-group.d.ts} +4 -4
  25. package/types/components/cell-switch.d.ts +31 -0
  26. package/types/components/cell.d.ts +46 -0
  27. package/types/components/context-menu.d.ts +23 -0
  28. package/types/components/{chat-at-box.d.ts → mention-picker.d.ts} +6 -6
  29. package/types/components/{chat-message-item.d.ts → message-item.d.ts} +6 -6
  30. package/types/components/{chat-group-readed.d.ts → read-receipt.d.ts} +6 -6
  31. package/types/components/virtual-list.d.ts +148 -0
  32. package/types/components/{chat-record.d.ts → voice-input.d.ts} +4 -4
  33. package/types/components.d.ts +9 -10
  34. package/types/index.d.ts +4 -2
  35. package/utils/config.js +17 -0
  36. package/utils/datetime.js +1 -1
  37. package/utils/emoji.js +9 -4
  38. package/components/im-arrow-bar/im-arrow-bar.vue +0 -59
  39. package/components/im-sample/im-sample.vue +0 -192
  40. package/components/im-switch-bar/im-switch-bar.vue +0 -62
  41. package/types/components/long-press-menu.d.ts +0 -23
  42. package/types/components/switch-bar.d.ts +0 -19
@@ -3,7 +3,7 @@
3
3
  <!--rich-text中的表情包会屏蔽事件,所以这里用一个遮罩层捕获点击事件 -->
4
4
  <view class="mask" @tap="showChatBox()"></view>
5
5
  <view class="left">
6
- <im-head-image :url="chat.headImage" :name="chat.showName" :online="online" />
6
+ <im-avatar :url="chat.headImage" :name="chat.showName" :online="online" />
7
7
  </view>
8
8
  <view class="chat-right">
9
9
  <view class="chat-name">
@@ -26,8 +26,8 @@
26
26
 
27
27
  <script setup lang="ts">
28
28
  import { computed } from 'vue'
29
- import ImHeadImage from '../im-head-image/im-head-image.vue'
30
- import { datetime, dom, messageType } from '../../index'
29
+ import ImAvatar from '../im-avatar/im-avatar.vue'
30
+ import { datetime, dom, messageType, emoji } from '../../index'
31
31
  import { MESSAGE_TYPE } from '../../index'
32
32
 
33
33
  interface Props {
@@ -35,7 +35,6 @@ interface Props {
35
35
  index?: number;
36
36
  active?: boolean;
37
37
  online: boolean;
38
- emoji: any;
39
38
  }
40
39
 
41
40
  const $datetime = datetime
@@ -83,7 +82,7 @@ const isTextMessage = computed(() => {
83
82
 
84
83
  const nodesText = computed(() => {
85
84
  const text = dom.html2Escape(props.chat?.lastContent || '');
86
- return props.emoji.transform(text, 'emoji-small');
85
+ return emoji.transform(text, 'emoji-small');
87
86
  });
88
87
 
89
88
  // TODO:组件化(换为props.online)
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <view class="long-press-menu none-pointer-events">
2
+ <view class="context-menu none-pointer-events">
3
3
  <view @longpress.prevent.stop="onLongPress($event)" @touchmove="onTouchMove" @touchend="onTouchEnd">
4
4
  <slot></slot>
5
5
  </view>
@@ -97,7 +97,7 @@ const itemStyle = (item: any) => {
97
97
  </script>
98
98
 
99
99
  <style lang="scss" scoped>
100
- .long-press-menu {
100
+ .context-menu {
101
101
  .menu-mask {
102
102
  position: fixed;
103
103
  left: 0;
@@ -181,7 +181,7 @@ const uploadFileToServer = (file: AfterReadFile, uploadFile: UploadFile, fileId:
181
181
  const headers = {
182
182
  'Authorization': `Bearer ${props.token}`,
183
183
  'AccessToken': props.token,
184
- 'Content-Type': 'multipart/form-data'
184
+ // 'Content-Type': 'multipart/form-data' // Commented by Joncky becauce of error "Failed to read the request form. Missing content-type boundary."
185
185
  }
186
186
 
187
187
  uni.uploadFile({
@@ -203,7 +203,14 @@ const uploadFileToServer = (file: AfterReadFile, uploadFile: UploadFile, fileId:
203
203
  ...res,
204
204
  status: 'success'
205
205
  })
206
- emit('success', file, JSON.parse(res.data).data)
206
+
207
+ const data = JSON.parse(res.data)
208
+ let url = data.data
209
+ if (!url && data.result) {
210
+ url = data.result?.url
211
+ }
212
+
213
+ emit('success', file, url)
207
214
  } catch (error) {
208
215
  uploadFile.status = 'error'
209
216
  console.error(error)
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <view class="friend-item" @click="showFriendInfo()">
3
- <im-head-image :name="friend.nickName" :online="friend.online" :url="friend.headImage" size="small"/>
3
+ <im-avatar :name="friend.nickName" :online="friend.online" :url="friend.headImage" size="small" />
4
4
  <view class="friend-info">
5
5
  <view class="friend-name">{{ friend.nickName }}</view>
6
6
  <view class="friend-online">
@@ -13,7 +13,7 @@
13
13
  </template>
14
14
 
15
15
  <script setup lang="ts">
16
- import ImHeadImage from '../im-head-image/im-head-image.vue'
16
+ import ImAvatar from '../im-avatar/im-avatar.vue'
17
17
 
18
18
  interface Props {
19
19
  friend?: any;
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <view class="group-item" @click="showGroupInfo()">
3
- <im-head-image :name="group.showGroupName" :url="group.headImageThumb" size="small"/>
3
+ <im-avatar :name="group.showGroupName" :url="group.headImageThumb" size="small" />
4
4
  <view class="group-name">
5
5
  <view>{{ group.showGroupName }}</view>
6
6
  </view>
@@ -8,7 +8,7 @@
8
8
  </template>
9
9
 
10
10
  <script setup lang="ts">
11
- import ImHeadImage from '../im-head-image/im-head-image.vue'
11
+ import ImAvatar from '../im-avatar/im-avatar.vue'
12
12
 
13
13
  interface Props {
14
14
  group?: any;
@@ -10,7 +10,7 @@
10
10
  <scroll-view v-show="checkedIds.length > 0" scroll-x="true" scroll-left="120">
11
11
  <view class="checked-users">
12
12
  <view v-for="m in checkedMembers" class="user-item" :key="m.userId">
13
- <im-head-image :name="m.showNickName" :url="m.headImage" :size="60" />
13
+ <im-avatar :name="m.showNickName" :url="m.headImage" :size="60" />
14
14
  </view>
15
15
  </view>
16
16
  </scroll-view>
@@ -21,7 +21,7 @@
21
21
  <im-virtual-scroller :items="showMembers">
22
22
  <template v-slot="{ item }">
23
23
  <view class="member-item" @click="onSwitchChecked(item)">
24
- <im-head-image :name="item.showNickName" :online="item.online" :url="item.headImage"
24
+ <im-avatar :name="item.showNickName" :online="item.online" :url="item.headImage"
25
25
  :size="90" />
26
26
  <view class="member-name">{{ item.showNickName }}
27
27
  </view>
@@ -40,7 +40,7 @@
40
40
 
41
41
  <script setup lang="ts">
42
42
  import { ref, computed } from 'vue'
43
- import ImHeadImage from '../im-head-image/im-head-image.vue'
43
+ import ImAvatar from '../im-avatar/im-avatar.vue'
44
44
  import ImVirtualScroller from '../im-virtual-scroller/im-virtual-scroller.vue'
45
45
 
46
46
  interface Props {
@@ -4,14 +4,14 @@
4
4
  <div class="group-rtc-join">
5
5
  <div class="host-info">
6
6
  <div>发起人</div>
7
- <im-head-image :name="rtcInfo.host.nickName" :url="rtcInfo.host.headImage" :size="80" />
7
+ <im-avatar :name="rtcInfo.host.nickName" :url="rtcInfo.host.headImage" :size="80" />
8
8
  </div>
9
9
  <div class="user-info">
10
10
  <div>{{ rtcInfo.userInfos.length + '人正在通话中' }}</div>
11
11
  <scroll-view scroll-x="true" scroll-left="120">
12
12
  <view class="user-list">
13
13
  <view v-for="user in rtcInfo.userInfos" class="user-item" :key="user.id">
14
- <im-head-image :name="user.nickName" :url="user.headImage" :size="80" />
14
+ <im-avatar :name="user.nickName" :url="user.headImage" :size="80" />
15
15
  </view>
16
16
  </view>
17
17
  </scroll-view>
@@ -22,7 +22,7 @@
22
22
  </template>
23
23
 
24
24
  <script setup lang="ts">
25
- import ImHeadImage from '../im-head-image/im-head-image.vue'
25
+ import ImAvatar from '../im-avatar/im-avatar.vue'
26
26
  import { ref } from 'vue';
27
27
  import { UserInfo } from '../../libs';
28
28
 
@@ -60,9 +60,10 @@ const uploadImage = (file: any) => {
60
60
  uploadUrl += `&isPermanent=${props.isPermanent}&thumbSize=${props.thumbSize}`
61
61
 
62
62
  uni.uploadFile({
63
- url: uploadUrl, //env.BaseApiUrl + action,
63
+ url: uploadUrl,
64
64
  header: {
65
- accessToken: props.token // getToken()
65
+ accessToken: props.token,
66
+ authorization: `Bearer ${props.token}`
66
67
  },
67
68
  filePath: file.path,
68
69
  name: 'file',
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <u-popup ref="popup" mode="bottom" @open="onChange" @close="onChange">
3
- <view class="chat-at-box">
3
+ <view class="mention-picker">
4
4
  <view class="chat-at-top">
5
5
  <view class="chat-at-tip"> 选择要提醒的人</view>
6
6
  <button class="chat-at-btn" size="mini" @click="onClean()">清空 </button>
@@ -10,7 +10,7 @@
10
10
  <scroll-view v-show="atUserIds.length > 0" scroll-x="true" scroll-left="120">
11
11
  <view class="at-user-items">
12
12
  <view v-for="m in checkedMembers" class="at-user-item" :key="m.userId">
13
- <im-head-image :name="m.showNickName" :url="m.headImage" size="mini" />
13
+ <im-avatar :name="m.showNickName" :url="m.headImage" size="mini" />
14
14
  </view>
15
15
  </view>
16
16
  </scroll-view>
@@ -21,7 +21,7 @@
21
21
  <im-virtual-scroller :items="memberItems">
22
22
  <template v-slot="{ item }">
23
23
  <view class="member-item" @click="onSwitchChecked(item)">
24
- <im-head-image :name="item.showNickName" :online="item.online" :url="item.headImage"
24
+ <im-avatar :name="item.showNickName" :online="item.online" :url="item.headImage"
25
25
  size="small" />
26
26
  <view class="member-name">{{ item.showNickName }}</view>
27
27
  <radio :checked="item.checked" :disabled="item.locked"
@@ -36,7 +36,7 @@
36
36
 
37
37
  <script setup lang="ts">
38
38
  import { ref, computed } from 'vue'
39
- import ImHeadImage from '../im-head-image/im-head-image.vue'
39
+ import ImAvatar from '../im-avatar/im-avatar.vue'
40
40
  import ImVirtualScroller from '../im-virtual-scroller/im-virtual-scroller.vue'
41
41
  import { GroupMember } from '../../libs';
42
42
 
@@ -123,7 +123,7 @@ defineExpose({
123
123
  </script>
124
124
 
125
125
  <style lang="scss" scoped>
126
- .chat-at-box {
126
+ .mention-picker {
127
127
  position: relative;
128
128
  display: flex;
129
129
  flex-direction: column;
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <view class="chat-message-item">
2
+ <view class="message-item">
3
3
  <view class="message-tip" v-if="msgInfo.type == MESSAGE_TYPE.TIP_TEXT">
4
4
  {{ msgInfo.content }}
5
5
  </view>
@@ -7,7 +7,7 @@
7
7
  {{ $datetime.toTimeText(msgInfo.sendTime) }}
8
8
  </view>
9
9
  <view class="message-normal" v-else-if="isNormal" :class="{ 'message-mine': msgInfo.selfSend }">
10
- <im-head-image class="avatar" @longpress.prevent="$emit('longPressHead')" :id="msgInfo.sendId" :url="avatar"
10
+ <im-avatar class="avatar" @longpress.prevent="$emit('longPressHead')" :id="msgInfo.sendId" :url="avatar"
11
11
  :name="showName" size="small" />
12
12
  <view class="content">
13
13
  <view v-if="msgInfo.groupId && !msgInfo.selfSend" class="top">
@@ -16,27 +16,27 @@
16
16
  <view class="bottom">
17
17
  <view class="message-content-wrapper">
18
18
  <view v-if="msgInfo.type == MESSAGE_TYPE.TEXT">
19
- <im-long-press-menu :items="menuItems" @select="onSelectMenu">
19
+ <im-context-menu :items="menuItems" @select="onSelectMenu">
20
20
  <!-- up-parse支持点击a标签,但是不支持显示emo表情,也不支持换行 -->
21
21
  <up-parse
22
22
  v-if="$url.containUrl(msgInfo.content) && !emoji.containEmoji(msgInfo.content)"
23
23
  class="message-text" :showImgMenu="false" :content="nodesText" />
24
24
  <!-- rich-text支持显示emo表情以及消息换行,但是不支持点击a标签 -->
25
25
  <rich-text v-else class="message-text" :nodes="nodesText" />
26
- </im-long-press-menu>
26
+ </im-context-menu>
27
27
  </view>
28
28
  <view class="message-image" v-else-if="msgInfo.type == MESSAGE_TYPE.IMAGE">
29
- <im-long-press-menu :items="menuItems" @select="onSelectMenu">
29
+ <im-context-menu :items="menuItems" @select="onSelectMenu">
30
30
  <view class="image-box">
31
31
  <image class="send-image" :style="imageStyle" mode="aspectFill"
32
32
  :src="contentData.thumbUrl" lazy-load="true" @click.stop="onShowFullImage()">
33
33
  </image>
34
34
  <im-loading v-if="sending"></im-loading>
35
35
  </view>
36
- </im-long-press-menu>
36
+ </im-context-menu>
37
37
  </view>
38
38
  <view class="message-file" v-else-if="msgInfo.type == MESSAGE_TYPE.FILE">
39
- <im-long-press-menu :items="menuItems" @select="onSelectMenu">
39
+ <im-context-menu :items="menuItems" @select="onSelectMenu">
40
40
  <view class="file-box">
41
41
  <view class="file-info" style="overflow: hidden;">
42
42
  <u-link class="file-name" :under-line="true" color="#007BFF"
@@ -46,9 +46,9 @@
46
46
  <view class="file-icon iconfont icon-file"></view>
47
47
  <im-loading v-if="sending"></im-loading>
48
48
  </view>
49
- </im-long-press-menu>
49
+ </im-context-menu>
50
50
  </view>
51
- <im-long-press-menu v-else-if="msgInfo.type == MESSAGE_TYPE.AUDIO" :items="menuItems"
51
+ <im-context-menu v-else-if="msgInfo.type == MESSAGE_TYPE.AUDIO" :items="menuItems"
52
52
  @select="onSelectMenu">
53
53
  <view class="message-audio message-text" @click="onPlayAudio()">
54
54
  <text class="iconfont icon-voice-play"></text>
@@ -56,8 +56,8 @@
56
56
  <text v-if="audioPlayState == 'PAUSE'" class="iconfont icon-play"></text>
57
57
  <text v-if="audioPlayState == 'PLAYING'" class="iconfont icon-pause"></text>
58
58
  </view>
59
- </im-long-press-menu>
60
- <im-long-press-menu v-if="isAction" :items="menuItems" @select="onSelectMenu">
59
+ </im-context-menu>
60
+ <im-context-menu v-if="isAction" :items="menuItems" @select="onSelectMenu">
61
61
  <view class="chat-realtime message-text" @click="$emit('call')">
62
62
  <text v-if="msgInfo.type == MESSAGE_TYPE.ACT_RT_VOICE"
63
63
  class="iconfont icon-chat-voice"></text>
@@ -65,7 +65,7 @@
65
65
  class="iconfont icon-chat-video"></text>
66
66
  <text>{{ msgInfo.content }}</text>
67
67
  </view>
68
- </im-long-press-menu>
68
+ </im-context-menu>
69
69
  <view v-if="sending && isTextMessage" class="sending">
70
70
  <im-loading :size="40" icon-color="#656adf" :mask="false"></im-loading>
71
71
  </view>
@@ -83,24 +83,22 @@
83
83
  </view>
84
84
  </view>
85
85
  </view>
86
- <im-chat-group-readed ref="chatGroupReaded" :groupMembers="groupMembers as any[]" :msgInfo="msgInfo" />
86
+ <im-read-receipt ref="chatGroupReaded" :groupMembers="groupMembers as any[]" :msgInfo="msgInfo" />
87
87
  </view>
88
88
  </template>
89
89
 
90
90
  <script setup lang="ts">
91
91
  import { ref, computed } from 'vue'
92
- import ImHeadImage from '../im-head-image/im-head-image.vue'
93
- import ImChatGroupReaded from '../im-chat-group-readed/im-chat-group-readed.vue'
94
- import ImLongPressMenu from '../im-long-press-menu/im-long-press-menu.vue'
95
- import { MESSAGE_TYPE, MESSAGE_STATUS } from '../../index'
96
- import { datetime, dom, url, messageType } from '../../index'
92
+ import ImAvatar from '../im-avatar/im-avatar.vue'
93
+ import ImReadReceipt from '../im-read-receipt/im-read-receipt.vue'
94
+ import ImContextMenu from '../im-context-menu/im-context-menu.vue'
95
+ import { MESSAGE_TYPE, MESSAGE_STATUS, datetime, dom, url, messageType, emoji } from '../../index'
97
96
 
98
97
  interface Props {
99
98
  avatar?: string;
100
99
  showName: string;
101
100
  msgInfo: any;
102
101
  groupMembers?: any[];
103
- emoji: any;
104
102
  }
105
103
 
106
104
  interface Emits {
@@ -261,7 +259,7 @@ const nodesText = computed(() => {
261
259
  const color = props.msgInfo.selfSend ? 'white' : '';
262
260
  let text = dom.html2Escape(props.msgInfo.content);
263
261
  text = url.replaceURLWithHTMLLinks(text, color);
264
- return props.emoji.transform(text, 'emoji-normal');
262
+ return emoji.transform(text, 'emoji-normal');
265
263
  });
266
264
 
267
265
  const imageStyle = computed(() => {
@@ -284,7 +282,7 @@ const imageStyle = computed(() => {
284
282
  </script>
285
283
 
286
284
  <style scoped lang="scss">
287
- .chat-message-item {
285
+ .message-item {
288
286
  padding: 2rpx 20rpx;
289
287
 
290
288
  .message-tip {
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <u-popup ref="popup" mode="bottom">
3
- <view class="chat-group-readed">
3
+ <view class="read-receipt">
4
4
  <view class="uni-padding-wrap uni-common-mt">
5
5
  <u-tabs :current="current" :list="items" :show-bar="false" @change="onClickItem"></u-tabs>
6
6
  </view>
@@ -9,7 +9,7 @@
9
9
  <im-virtual-scroller :items="readedMembers">
10
10
  <template v-slot="{ item }">
11
11
  <view class="member-item">
12
- <im-head-image :name="item.showNickName" :online="item.online" :url="item.headImage"
12
+ <im-avatar :name="item.showNickName" :online="item.online" :url="item.headImage"
13
13
  :size="90" />
14
14
  <view class="member-name">{{ item.showNickName }}</view>
15
15
  </view>
@@ -20,7 +20,7 @@
20
20
  <im-virtual-scroller :items="unreadMembers">
21
21
  <template v-slot="{ item }">
22
22
  <view class="member-item">
23
- <im-head-image :name="item.showNickName" :online="item.online" :url="item.headImage"
23
+ <im-avatar :name="item.showNickName" :online="item.online" :url="item.headImage"
24
24
  :size="90" />
25
25
  <view class="member-name">{{ item.showNickName }}</view>
26
26
  </view>
@@ -34,7 +34,7 @@
34
34
 
35
35
  <script setup lang="ts">
36
36
  import { ref } from 'vue'
37
- import ImHeadImage from '../im-head-image/im-head-image.vue'
37
+ import ImAvatar from '../im-avatar/im-avatar.vue'
38
38
  import ImVirtualScroller from '../im-virtual-scroller/im-virtual-scroller.vue'
39
39
  import { Chat, Message } from '../../libs';
40
40
 
@@ -143,7 +143,7 @@ defineExpose({
143
143
  </script>
144
144
 
145
145
  <style lang="scss" scoped>
146
- .chat-group-readed {
146
+ .read-receipt {
147
147
  position: relative;
148
148
  display: flex;
149
149
  flex-direction: column;