im相关改造
Showing
14 changed files
with
406 additions
and
182 deletions
... | @@ -7,3 +7,5 @@ VUE_APP_API_SECRET='eb219c4b42bdbbf5dca38f21f5be26ab38f1c157d0ba4277d5acce6507f2 | ... | @@ -7,3 +7,5 @@ VUE_APP_API_SECRET='eb219c4b42bdbbf5dca38f21f5be26ab38f1c157d0ba4277d5acce6507f2 |
7 | #VUE_APP_API_KEY=1400514886 | 7 | #VUE_APP_API_KEY=1400514886 |
8 | #VUE_APP_API_SECRET='9c0cbbb0f08e4087e1b06295cd32fc1f9f368c011539123517f769c59274147a' | 8 | #VUE_APP_API_SECRET='9c0cbbb0f08e4087e1b06295cd32fc1f9f368c011539123517f769c59274147a' |
9 | VUE_APP_API_EXPIRETIME=604800 | 9 | VUE_APP_API_EXPIRETIME=604800 |
10 | |||
11 | VUE_APP_API_UNI_URL='https://spread-dev.hikoon.com/api' | ... | ... |
... | @@ -5,3 +5,4 @@ VUE_APP_API_URL='http://spread_dev.hikoon.com/mapi' | ... | @@ -5,3 +5,4 @@ VUE_APP_API_URL='http://spread_dev.hikoon.com/mapi' |
5 | VUE_APP_API_KEY=1400514950 | 5 | VUE_APP_API_KEY=1400514950 |
6 | VUE_APP_API_SECRET='eb219c4b42bdbbf5dca38f21f5be26ab38f1c157d0ba4277d5acce6507f2d727' | 6 | VUE_APP_API_SECRET='eb219c4b42bdbbf5dca38f21f5be26ab38f1c157d0ba4277d5acce6507f2d727' |
7 | VUE_APP_API_EXPIRETIME=604800 | 7 | VUE_APP_API_EXPIRETIME=604800 |
8 | VUE_APP_API_UNI_URL='https://spread.hikoon.com/api' | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -9,8 +9,8 @@ | ... | @@ -9,8 +9,8 @@ |
9 | ], | 9 | ], |
10 | "rules": { | 10 | "rules": { |
11 | "no-console": 'off', | 11 | "no-console": 'off', |
12 | "quotes": ["error", "single"], | 12 | // "quotes": ["error", "single"], |
13 | "semi": ["error","never"], | 13 | // "semi": ["error","never"], |
14 | "space-before-blocks": "error", | 14 | "space-before-blocks": "error", |
15 | "space-unary-ops": "error" | 15 | "space-unary-ops": "error" |
16 | }, | 16 | }, | ... | ... |
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
1 | <template> | 1 | <template> |
2 | <div class="group-member-list-wrapper"> | 2 | <div class="group-member-list-wrapper"> |
3 | <div class="header"> | 3 | <div class="header"> |
4 | <span class="member-count text-ellipsis">群成员:{{ currentConversation.groupProfile.memberCount }}</span> | 4 | <span class="member-count text-ellipsis" |
5 | <popover v-show="currentUnMemberList.length !== 0" v-model="addGroupMemberVisible"> | 5 | >群成员:{{ currentConversation.groupProfile.memberCount }}</span |
6 | <add-group-member :group="currentConversation.groupProfile.groupID"/> | 6 | > |
7 | <popover | ||
8 | v-show="currentUnMemberList.length !== 0" | ||
9 | v-model="addGroupMemberVisible" | ||
10 | > | ||
11 | <add-group-member :group="currentConversation.groupProfile.groupID" /> | ||
7 | <div slot="reference" class="btn-add-member" title="添加群成员"> | 12 | <div slot="reference" class="btn-add-member" title="添加群成员"> |
8 | <span class="tim-icon-friend-add"></span> | 13 | <span class="tim-icon-friend-add"></span> |
9 | </div> | 14 | </div> |
... | @@ -13,13 +18,24 @@ | ... | @@ -13,13 +18,24 @@ |
13 | <div class="group-member-list"> | 18 | <div class="group-member-list"> |
14 | <div v-for="member in members" :key="member.userID"> | 19 | <div v-for="member in members" :key="member.userID"> |
15 | <popover placement="right" :key="member.userID"> | 20 | <popover placement="right" :key="member.userID"> |
16 | <group-member-info :member="member"/> | 21 | <group-member-info :member="member" /> |
17 | <div slot="reference" class="group-member" @click="currentMemberID = member.userID"> | 22 | <div |
18 | <avatar :title=getGroupMemberAvatarText(member.role) :src="member.avatar"/> | 23 | slot="reference" |
24 | class="group-member" | ||
25 | @click="currentMemberID = member.userID" | ||
26 | > | ||
27 | <avatar | ||
28 | :title="getGroupMemberAvatarText(member.role)" | ||
29 | :src="member.avatar" | ||
30 | /> | ||
19 | <div class="member-name text-ellipsis"> | 31 | <div class="member-name text-ellipsis"> |
20 | <span v-if="member.nameCard" :title=member.nameCard>{{ member.nameCard }}</span> | 32 | <span v-if="member.nameCard" :title="member.nameCard">{{ |
21 | <span v-else-if="member.nick" :title=member.nick>{{ member.nick }}</span> | 33 | member.nameCard |
22 | <span v-else :title=member.userID>{{ member.userID }}</span> | 34 | }}</span> |
35 | <span v-else-if="member.nick" :title="member.nick">{{ | ||
36 | member.nick | ||
37 | }}</span> | ||
38 | <span v-else :title="member.userID">{{ member.userID }}</span> | ||
23 | </div> | 39 | </div> |
24 | </div> | 40 | </div> |
25 | </popover> | 41 | </popover> |
... | @@ -27,66 +43,71 @@ | ... | @@ -27,66 +43,71 @@ |
27 | </div> | 43 | </div> |
28 | </div> | 44 | </div> |
29 | <div class="more"> | 45 | <div class="more"> |
30 | <el-button v-if="showLoadMore" type="text" | 46 | <el-button v-if="showLoadMore" type="text" @click="loadMore" |
31 | @click="loadMore">查看更多 | 47 | >查看更多 |
32 | </el-button> | 48 | </el-button> |
33 | </div> | 49 | </div> |
34 | </div> | 50 | </div> |
35 | </template> | 51 | </template> |
36 | 52 | ||
37 | <script> | 53 | <script> |
38 | import {Popover} from 'element-ui' | 54 | import { Popover } from "element-ui"; |
39 | import {mapState} from 'vuex' | 55 | import { mapState } from "vuex"; |
40 | import AddGroupMember from './add-group-member.vue' | 56 | import AddGroupMember from "./add-group-member.vue"; |
41 | import GroupMemberInfo from './group-member-info.vue' | 57 | import GroupMemberInfo from "./group-member-info.vue"; |
42 | 58 | ||
43 | export default { | 59 | export default { |
44 | data() { | 60 | data() { |
45 | return { | 61 | return { |
46 | addGroupMemberVisible: false, | 62 | addGroupMemberVisible: false, |
47 | addGroupMemberList: [], | 63 | addGroupMemberList: [], |
48 | currentMemberID: '', | 64 | currentMemberID: "", |
49 | count: 30 // 显示的群成员数量 | 65 | count: 30, // 显示的群成员数量 |
50 | } | 66 | }; |
51 | }, | 67 | }, |
52 | props: ['groupProfile'], | 68 | props: ["groupProfile"], |
53 | components: { | 69 | components: { |
54 | Popover, | 70 | Popover, |
55 | AddGroupMember, | 71 | AddGroupMember, |
56 | GroupMemberInfo | 72 | GroupMemberInfo, |
57 | }, | 73 | }, |
58 | computed: { | 74 | computed: { |
59 | ...mapState({ | 75 | ...mapState({ |
60 | currentConversation: state => state.conversation.currentConversation, | 76 | currentConversation: (state) => state.conversation.currentConversation, |
61 | currentMemberList: state => state.group.currentMemberList, | 77 | currentMemberList: (state) => state.group.currentMemberList, |
62 | currentUnMemberList: state => state.group.currentUnMemberList | 78 | currentUnMemberList: (state) => state.group.currentUnMemberList, |
63 | }), | 79 | }), |
64 | showLoadMore() { | 80 | showLoadMore() { |
65 | return this.members.length < this.groupProfile.memberCount | 81 | return this.members.length < this.groupProfile.memberCount; |
66 | }, | 82 | }, |
67 | members() { | 83 | members() { |
68 | return this.currentMemberList.slice(0, this.count) | 84 | console.log( |
69 | } | 85 | "currentMemberList is ", |
86 | this.currentMemberList.slice(0, this.count) | ||
87 | ); | ||
88 | return this.currentMemberList.slice(0, this.count); | ||
89 | }, | ||
70 | }, | 90 | }, |
71 | methods: { | 91 | methods: { |
72 | getGroupMemberAvatarText(role) { | 92 | getGroupMemberAvatarText(role) { |
73 | switch (role) { | 93 | switch (role) { |
74 | case 'Owner': | 94 | case "Owner": |
75 | return '群主' | 95 | return "群主"; |
76 | case 'Admin': | 96 | case "Admin": |
77 | return '管理员' | 97 | return "管理员"; |
78 | default: | 98 | default: |
79 | return '群成员' | 99 | return "群成员"; |
80 | } | 100 | } |
81 | }, | 101 | }, |
82 | loadMore() { | 102 | loadMore() { |
83 | this.$store.dispatch('getGroupMemberList', this.groupProfile.groupID) | 103 | this.$store |
104 | .dispatch("getGroupMemberList", this.groupProfile.groupID) | ||
84 | .then(() => { | 105 | .then(() => { |
85 | this.count += 30 | 106 | this.count += 30; |
86 | }) | 107 | }); |
87 | }, | 108 | }, |
88 | } | 109 | }, |
89 | } | 110 | }; |
90 | </script> | 111 | </script> |
91 | 112 | ||
92 | <style lang="stylus" scoped> | 113 | <style lang="stylus" scoped> |
... | @@ -167,6 +188,4 @@ export default { | ... | @@ -167,6 +188,4 @@ export default { |
167 | // text-align: center; | 188 | // text-align: center; |
168 | // line-height: 30px; | 189 | // line-height: 30px; |
169 | // } | 190 | // } |
170 | |||
171 | |||
172 | </style> | 191 | </style> | ... | ... |
1 | <template> | 1 | <template> |
2 | <div class="chat-bubble" @mousedown.stop @contextmenu.prevent> | 2 | <div class="chat-bubble" @mousedown.stop @contextmenu.prevent> |
3 | <el-dropdown trigger="" ref="dropdown" v-if="!message.isRevoked" @command="handleCommand"> | 3 | <el-dropdown |
4 | trigger="" | ||
5 | ref="dropdown" | ||
6 | v-if="!message.isRevoked" | ||
7 | @command="handleCommand" | ||
8 | > | ||
4 | <div style="display: flex"> | 9 | <div style="display: flex"> |
5 | <div v-if="isMine && messageReadByPeer" class="message-status"> | 10 | <div v-if="isMine && messageReadByPeer" class="message-status"> |
6 | <span>{{messageReadByPeer}}</span> | 11 | <span>{{ messageReadByPeer }}</span> |
7 | </div> | 12 | </div> |
8 | <div class="message-content" :class="bubbleStyle"> | 13 | <div class="message-content" :class="bubbleStyle"> |
9 | <slot></slot> | 14 | <slot></slot> |
... | @@ -15,136 +20,165 @@ | ... | @@ -15,136 +20,165 @@ |
15 | </el-dropdown-menu> | 20 | </el-dropdown-menu> |
16 | </el-dropdown> | 21 | </el-dropdown> |
17 | <div class="group-tip-element-wrapper" v-if="message.isRevoked"> | 22 | <div class="group-tip-element-wrapper" v-if="message.isRevoked"> |
18 | {{text}} | 23 | {{ text }} |
19 | <el-button type="text" size="mini" class="edit-button" v-show="isEdit" @click="reEdit"> 重新编辑</el-button> | 24 | <el-button |
25 | type="text" | ||
26 | size="mini" | ||
27 | class="edit-button" | ||
28 | v-show="isEdit" | ||
29 | @click="reEdit" | ||
30 | > 重新编辑</el-button | ||
31 | > | ||
20 | </div> | 32 | </div> |
21 | </div> | 33 | </div> |
22 | </template> | 34 | </template> |
23 | 35 | ||
24 | <script> | 36 | <script> |
25 | export default { | 37 | export default { |
26 | name: 'MessageBubble', | 38 | name: "MessageBubble", |
27 | data() { | 39 | data() { |
28 | return { | 40 | return { |
29 | isTimeout: false | 41 | isTimeout: false, |
30 | } | 42 | }; |
31 | }, | 43 | }, |
32 | props: { | 44 | props: { |
33 | isMine: { | 45 | isMine: { |
34 | type: Boolean | 46 | type: Boolean, |
35 | }, | 47 | }, |
36 | isNew: { | 48 | isNew: { |
37 | type: Boolean | 49 | type: Boolean, |
38 | }, | 50 | }, |
39 | message: { | 51 | message: { |
40 | type: Object, | 52 | type: Object, |
41 | required: true | 53 | required: true, |
42 | } | 54 | }, |
43 | }, | 55 | }, |
44 | created() { | 56 | created() { |
45 | this.isTimeoutHandler() | 57 | this.isTimeoutHandler(); |
46 | }, | 58 | }, |
47 | mounted() { | 59 | mounted() { |
48 | if (this.$refs.dropdown && this.$refs.dropdown.$el) { | 60 | if (this.$refs.dropdown && this.$refs.dropdown.$el) { |
49 | this.$refs.dropdown.$el.addEventListener('mousedown', this.handleDropDownMousedown) | 61 | this.$refs.dropdown.$el.addEventListener( |
62 | "mousedown", | ||
63 | this.handleDropDownMousedown | ||
64 | ); | ||
50 | } | 65 | } |
51 | }, | 66 | }, |
52 | beforeDestroy() { | 67 | beforeDestroy() { |
53 | if (this.$refs.dropdown && this.$refs.dropdown.$el) { | 68 | if (this.$refs.dropdown && this.$refs.dropdown.$el) { |
54 | this.$refs.dropdown.$el.removeEventListener('mousedown', this.handleDropDownMousedown) | 69 | this.$refs.dropdown.$el.removeEventListener( |
70 | "mousedown", | ||
71 | this.handleDropDownMousedown | ||
72 | ); | ||
55 | } | 73 | } |
56 | }, | 74 | }, |
57 | computed: { | 75 | computed: { |
58 | bubbleStyle() { | 76 | bubbleStyle() { |
59 | let classString = '' | 77 | let classString = ""; |
60 | if (this.isMine) { | 78 | if (this.isMine) { |
61 | classString += 'message-send' | 79 | classString += "message-send"; |
62 | } else { | 80 | } else { |
63 | classString += 'message-received' | 81 | classString += "message-received"; |
64 | } | 82 | } |
65 | if (this.isNew) { | 83 | if (this.isNew) { |
66 | classString += 'new' | 84 | classString += "new"; |
67 | } | 85 | } |
68 | return classString | 86 | return classString; |
69 | }, | 87 | }, |
70 | text() { | 88 | text() { |
71 | if (this.message.conversationType === this.TIM.TYPES.CONV_C2C && !this.isMine) { | 89 | if ( |
72 | return '对方撤回了一条消息' | 90 | this.message.conversationType === this.TIM.TYPES.CONV_C2C && |
91 | !this.isMine | ||
92 | ) { | ||
93 | return "对方撤回了一条消息"; | ||
73 | } | 94 | } |
74 | if (this.message.conversationType === this.TIM.TYPES.CONV_GROUP && !this.isMine) { | 95 | if ( |
75 | return `${this.message.from}撤回了一条消息` | 96 | this.message.conversationType === this.TIM.TYPES.CONV_GROUP && |
97 | !this.isMine | ||
98 | ) { | ||
99 | return `${this.message.nick || this.message.from}撤回了一条消息`; | ||
76 | } | 100 | } |
77 | return '你撤回了一条消息' | 101 | return "你撤回了一条消息"; |
78 | }, | 102 | }, |
79 | messageReadByPeer() { | 103 | messageReadByPeer() { |
80 | if (this.message.status !== 'success') { | 104 | if (this.message.status !== "success") { |
81 | return false | 105 | return false; |
82 | } | 106 | } |
83 | if (this.message.conversationType === this.TIM.TYPES.CONV_C2C && this.message.isPeerRead) { | 107 | if ( |
84 | return '已读' | 108 | this.message.conversationType === this.TIM.TYPES.CONV_C2C && |
109 | this.message.isPeerRead | ||
110 | ) { | ||
111 | return "已读"; | ||
85 | } | 112 | } |
86 | if (this.message.conversationType === this.TIM.TYPES.CONV_C2C && !this.message.isPeerRead) { | 113 | if ( |
87 | return '未读' | 114 | this.message.conversationType === this.TIM.TYPES.CONV_C2C && |
115 | !this.message.isPeerRead | ||
116 | ) { | ||
117 | return "未读"; | ||
88 | } | 118 | } |
89 | return '' | 119 | return ""; |
90 | }, | 120 | }, |
91 | isEdit() { | 121 | isEdit() { |
92 | if (!this.isMine) { | 122 | if (!this.isMine) { |
93 | return false | 123 | return false; |
94 | } | 124 | } |
95 | if (this.message.type !== this.TIM.TYPES.MSG_TEXT) { | 125 | if (this.message.type !== this.TIM.TYPES.MSG_TEXT) { |
96 | return false | 126 | return false; |
97 | } | 127 | } |
98 | if (this.isTimeout) { | 128 | if (this.isTimeout) { |
99 | return false | 129 | return false; |
100 | } | 130 | } |
101 | return true | 131 | return true; |
102 | }, | 132 | }, |
103 | }, | 133 | }, |
104 | methods: { | 134 | methods: { |
105 | handleDropDownMousedown(e) { | 135 | handleDropDownMousedown(e) { |
106 | if (!this.isMine || this.isTimeout) { | 136 | if (!this.isMine || this.isTimeout) { |
107 | return | 137 | return; |
108 | } | 138 | } |
109 | if (e.buttons === 2) { | 139 | if (e.buttons === 2) { |
110 | if (this.$refs.dropdown.visible) { | 140 | if (this.$refs.dropdown.visible) { |
111 | this.$refs.dropdown.hide() | 141 | this.$refs.dropdown.hide(); |
112 | } else { | 142 | } else { |
113 | this.$refs.dropdown.show() | 143 | this.$refs.dropdown.show(); |
114 | } | 144 | } |
115 | } | 145 | } |
116 | }, | 146 | }, |
117 | handleCommand(command) { | 147 | handleCommand(command) { |
118 | switch (command) { | 148 | switch (command) { |
119 | case 'revoke': | 149 | case "revoke": |
120 | this.tim.revokeMessage(this.message).then(() => { | 150 | this.tim |
121 | this.isTimeoutHandler() | 151 | .revokeMessage(this.message) |
122 | }).catch((err) => { | 152 | .then(() => { |
123 | this.$store.commit('showMessage', { | 153 | this.isTimeoutHandler(); |
124 | message: err, | ||
125 | type: 'warning' | ||
126 | }) | ||
127 | }) | 154 | }) |
128 | break | 155 | .catch((err) => { |
129 | case 'delete': | 156 | this.$store.commit("showMessage", { |
130 | break | 157 | message: err, |
158 | type: "warning", | ||
159 | }); | ||
160 | }); | ||
161 | break; | ||
162 | case "delete": | ||
163 | break; | ||
131 | default: | 164 | default: |
132 | break | 165 | break; |
133 | } | 166 | } |
134 | }, | 167 | }, |
135 | isTimeoutHandler() { // 从发送消息时间开始算起,两分钟内可以编辑 | 168 | isTimeoutHandler() { |
136 | let now = new Date() | 169 | // 从发送消息时间开始算起,两分钟内可以编辑 |
170 | let now = new Date(); | ||
137 | if (parseInt(now.getTime() / 1000) - this.message.time > 2 * 60) { | 171 | if (parseInt(now.getTime() / 1000) - this.message.time > 2 * 60) { |
138 | this.isTimeout = true | 172 | this.isTimeout = true; |
139 | return | 173 | return; |
140 | } | 174 | } |
141 | setTimeout(this.isTimeoutHandler, 1000) | 175 | setTimeout(this.isTimeoutHandler, 1000); |
142 | }, | 176 | }, |
143 | reEdit() { | 177 | reEdit() { |
144 | this.$bus.$emit('reEditMessage', this.message.payload.text) | 178 | this.$bus.$emit("reEditMessage", this.message.payload.text); |
145 | } | 179 | }, |
146 | } | 180 | }, |
147 | } | 181 | }; |
148 | </script> | 182 | </script> |
149 | 183 | ||
150 | <style lang="stylus" scoped> | 184 | <style lang="stylus" scoped> | ... | ... |
1 | <template> | ||
2 | <message-bubble :isMine="isMine" :message="message"> | ||
3 | <div class="m-e-content" @click="goAudioDetail"> | ||
4 | <img :src="coverUrl" class="covor" /> | ||
5 | <span class="title" v-if="name">{{ name }}</span> | ||
6 | <span class="title" v-else="name">未命名音乐文件</span> | ||
7 | <!-- <div style="position: absolute; right: 15px"> | ||
8 | <u-icon name="list" color="#fff" size="32"></u-icon> | ||
9 | |||
10 | </div> --> | ||
11 | </div> | ||
12 | </message-bubble> | ||
13 | <!-- <div class="chat-bubble"> | ||
14 | <div class="message-content" :class="isMine ? 'message-send' : 'message-received'"> | ||
15 | <template v-for="(item, index) in contentList"> | ||
16 | <span :key="index" v-if="item.name === 'text'">{{ item.text }}</span> | ||
17 | <img v-else-if="item.name === 'img'" :src="item.src" width="20px" height="20px" :key="index"/> | ||
18 | </template> | ||
19 | </div> | ||
20 | </div> --> | ||
21 | </template> | ||
22 | |||
23 | <script> | ||
24 | import MessageBubble from "../message-bubble"; | ||
25 | |||
26 | export default { | ||
27 | name: "AudioElement", | ||
28 | components: { | ||
29 | MessageBubble, | ||
30 | }, | ||
31 | props: { | ||
32 | payload: { | ||
33 | type: Object, | ||
34 | required: true, | ||
35 | }, | ||
36 | message: { | ||
37 | type: Object, | ||
38 | required: true, | ||
39 | }, | ||
40 | isMine: { | ||
41 | type: Boolean, | ||
42 | }, | ||
43 | }, | ||
44 | methods: { | ||
45 | goAudioDetail() { | ||
46 | console.log("in goAudioDetail"); | ||
47 | // this.$emit("goAudioDetail"); | ||
48 | }, | ||
49 | previewImage() { | ||
50 | uni.previewImage({ | ||
51 | current: 0, | ||
52 | urls: [this.imagePath], | ||
53 | }); | ||
54 | }, | ||
55 | }, | ||
56 | computed: { | ||
57 | audioUrl() { | ||
58 | return this.payload.description; | ||
59 | }, | ||
60 | coverUrl() { | ||
61 | try { | ||
62 | let res = JSON.parse(this.payload.extension); | ||
63 | return res.cover_url; | ||
64 | } catch (e) {} | ||
65 | return ""; | ||
66 | }, | ||
67 | name() { | ||
68 | try { | ||
69 | let res = JSON.parse(this.payload.extension); | ||
70 | return res.name; | ||
71 | } catch (e) {} | ||
72 | return ""; | ||
73 | }, | ||
74 | }, | ||
75 | |||
76 | mounted() { | ||
77 | console.log("this.message is ", this.message); | ||
78 | }, | ||
79 | }; | ||
80 | </script> | ||
81 | |||
82 | <style lang="stylus" scoped> | ||
83 | .covor{ | ||
84 | width: 80px; | ||
85 | height: 80px; | ||
86 | // border-top-left-radius: 10px; | ||
87 | // border-bottom-left-radius: 10px; | ||
88 | border-radius:6px; | ||
89 | } | ||
90 | .m-e-content{ | ||
91 | display: flex; | ||
92 | flex-direction: row; | ||
93 | align-items: center; | ||
94 | width:250px; | ||
95 | height: 80px | ||
96 | // background-color: #2D2F39; | ||
97 | position: relative; | ||
98 | } | ||
99 | |||
100 | .title{ | ||
101 | width: 150px; | ||
102 | // color: #E9E9EA; | ||
103 | font-size: 13px; | ||
104 | overflow: hidden; | ||
105 | |||
106 | text-overflow: ellipsis; | ||
107 | /* #ifndef APP-PLUS-NVUE */ | ||
108 | display: -webkit-box; | ||
109 | word-break: break-all; | ||
110 | -webkit-box-orient: vertical; | ||
111 | -webkit-line-clamp: 2; | ||
112 | /* #endif */ | ||
113 | /* #ifdef APP-PLUS-NVUE */ | ||
114 | lines: 2; | ||
115 | text-overflow:ellipsis; | ||
116 | /* #endif */ | ||
117 | margin-left: 15px | ||
118 | |||
119 | } | ||
120 | </style> |
... | @@ -2,18 +2,36 @@ | ... | @@ -2,18 +2,36 @@ |
2 | <div class="custom-element-wrapper"> | 2 | <div class="custom-element-wrapper"> |
3 | <image-element | 3 | <image-element |
4 | v-if="this.payload.data === 'image'" | 4 | v-if="this.payload.data === 'image'" |
5 | :isMine=isMine | 5 | :isMine="isMine" |
6 | :payload="Object.assign(message.payload,{ imageInfoArray:[ { url: message.payload.description } ] })" | 6 | :payload=" |
7 | :message="message"/> | 7 | Object.assign(message.payload, { |
8 | imageInfoArray: [{ url: message.payload.description }], | ||
9 | }) | ||
10 | " | ||
11 | :message="message" | ||
12 | /> | ||
8 | <video-element | 13 | <video-element |
9 | v-else-if="this.payload.data === 'video'" | 14 | v-else-if="this.payload.data === 'video'" |
10 | :isMine="isMine" | 15 | :isMine="isMine" |
11 | :payload="Object.assign(message.payload,{ videoUrl: message.payload.description })" | 16 | :payload=" |
17 | Object.assign(message.payload, { | ||
18 | videoUrl: message.payload.description, | ||
19 | }) | ||
20 | " | ||
21 | :message="message" | ||
22 | /> | ||
23 | <audio-element | ||
24 | v-else-if="this.payload.data === 'audio'" | ||
25 | :isMine="isMine" | ||
26 | :payload="message.payload" | ||
12 | :message="message" | 27 | :message="message" |
13 | /> | 28 | /> |
14 | <template v-else> | 29 | <template v-else> |
15 | <message-bubble :isMine=isMine :message=message> | 30 | <message-bubble :isMine="isMine" :message="message"> |
16 | <message-group-live-status v-if="text.isFromGroupLive && text.isFromGroupLive === 1" :liveInfo='text'/> | 31 | <message-group-live-status |
32 | v-if="text.isFromGroupLive && text.isFromGroupLive === 1" | ||
33 | :liveInfo="text" | ||
34 | /> | ||
17 | <template v-else>{{ text }}</template> | 35 | <template v-else>{{ text }}</template> |
18 | </message-bubble> | 36 | </message-bubble> |
19 | </template> | 37 | </template> |
... | @@ -21,74 +39,79 @@ | ... | @@ -21,74 +39,79 @@ |
21 | </template> | 39 | </template> |
22 | 40 | ||
23 | <script> | 41 | <script> |
24 | import {mapState} from 'vuex' | 42 | import { mapState } from "vuex"; |
25 | import MessageBubble from '../message-bubble' | 43 | import MessageBubble from "../message-bubble"; |
26 | import MessageGroupLiveStatus from '../message-group-live-status' | 44 | import MessageGroupLiveStatus from "../message-group-live-status"; |
27 | import ImageElement from '../message-elements/image-element.vue' | 45 | import ImageElement from "../message-elements/image-element.vue"; |
28 | import VideoElement from './video-element' | 46 | import VideoElement from "./video-element"; |
29 | 47 | import AudioElement from "./audio-element.vue"; | |
30 | export default { | 48 | export default { |
31 | name: 'CustomElement', | 49 | name: "CustomElement", |
32 | props: { | 50 | props: { |
33 | payload: { | 51 | payload: { |
34 | type: Object, | 52 | type: Object, |
35 | required: true | 53 | required: true, |
36 | }, | 54 | }, |
37 | message: { | 55 | message: { |
38 | type: Object, | 56 | type: Object, |
39 | required: true | 57 | required: true, |
40 | }, | 58 | }, |
41 | isMine: { | 59 | isMine: { |
42 | type: Boolean | 60 | type: Boolean, |
43 | } | 61 | }, |
44 | }, | 62 | }, |
45 | components: { | 63 | components: { |
46 | VideoElement, | 64 | VideoElement, |
47 | MessageBubble, | 65 | MessageBubble, |
48 | MessageGroupLiveStatus, | 66 | MessageGroupLiveStatus, |
49 | ImageElement, | 67 | ImageElement, |
68 | AudioElement, | ||
50 | }, | 69 | }, |
51 | computed: { | 70 | computed: { |
52 | ...mapState({ | 71 | ...mapState({ |
53 | currentUserProfile: state => state.user.currentUserProfile | 72 | currentUserProfile: (state) => state.user.currentUserProfile, |
54 | }), | 73 | }), |
55 | text() { | 74 | text() { |
56 | return this.translateCustomMessage(this.payload) | 75 | return this.translateCustomMessage(this.payload); |
57 | }, | 76 | }, |
58 | rate() { | 77 | rate() { |
59 | return parseInt(this.payload.description) | 78 | return parseInt(this.payload.description); |
60 | } | 79 | }, |
61 | }, | 80 | }, |
62 | methods: { | 81 | methods: { |
63 | guid() { | 82 | guid() { |
64 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { | 83 | return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace( |
65 | let r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8) | 84 | /[xy]/g, |
66 | return v.toString(16) | 85 | function (c) { |
67 | }) | 86 | let r = (Math.random() * 16) | 0, |
87 | v = c == "x" ? r : (r & 0x3) | 0x8; | ||
88 | return v.toString(16); | ||
89 | } | ||
90 | ); | ||
68 | }, | 91 | }, |
69 | translateCustomMessage(payload) { | 92 | translateCustomMessage(payload) { |
70 | let videoPayload = {} | 93 | let videoPayload = {}; |
71 | try { | 94 | try { |
72 | videoPayload = JSON.parse(payload.data) | 95 | videoPayload = JSON.parse(payload.data); |
73 | } catch (e) { | 96 | } catch (e) { |
74 | videoPayload = {} | 97 | videoPayload = {}; |
75 | } | 98 | } |
76 | if (payload.data === 'group_create') { | 99 | if (payload.data === "group_create") { |
77 | return `${payload.extension}` | 100 | return `${payload.extension}`; |
78 | } | 101 | } |
79 | if (videoPayload.roomId) { | 102 | if (videoPayload.roomId) { |
80 | videoPayload.roomId = videoPayload.roomId.toString() | 103 | videoPayload.roomId = videoPayload.roomId.toString(); |
81 | videoPayload.isFromGroupLive = 1 | 104 | videoPayload.isFromGroupLive = 1; |
82 | return videoPayload | 105 | return videoPayload; |
83 | } | 106 | } |
84 | if (payload.text) { | 107 | if (payload.text) { |
85 | return payload.text | 108 | return payload.text; |
86 | } else { | 109 | } else { |
87 | return '[自定义消息]' | 110 | return "[自定义消息]"; |
88 | } | 111 | } |
89 | }, | 112 | }, |
90 | } | 113 | }, |
91 | } | 114 | }; |
92 | </script> | 115 | </script> |
93 | 116 | ||
94 | <style lang="stylus" scoped> | 117 | <style lang="stylus" scoped> | ... | ... |
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
1 | import request from './request' | 1 | import request from "./request"; |
2 | 2 | ||
3 | export default class Helper { | 3 | export default class Helper { |
4 | |||
5 | static getKey() { | 4 | static getKey() { |
6 | return parseInt(process.env.VUE_APP_API_KEY) | 5 | return parseInt(process.env.VUE_APP_API_KEY); |
7 | } | 6 | } |
8 | 7 | ||
9 | static getSecret() { | 8 | static getSecret() { |
10 | return process.env.VUE_APP_API_SECRET | 9 | return process.env.VUE_APP_API_SECRET; |
11 | } | 10 | } |
12 | 11 | ||
13 | static getExpire() { | 12 | static getExpire() { |
14 | return parseInt(process.env.VUE_APP_API_EXPIRETIME) | 13 | return parseInt(process.env.VUE_APP_API_EXPIRETIME); |
15 | } | 14 | } |
16 | 15 | ||
17 | |||
18 | static getUrlKey(name) { | 16 | static getUrlKey(name) { |
19 | return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.href) || [, ''])[1].replace(/\+/g, '%20')) || null | 17 | return ( |
18 | decodeURIComponent( | ||
19 | (new RegExp("[?|&]" + name + "=" + "([^&;]+?)(&|#|;|$)").exec( | ||
20 | location.href | ||
21 | ) || [, ""])[1].replace(/\+/g, "%20") | ||
22 | ) || null | ||
23 | ); | ||
20 | } | 24 | } |
21 | 25 | ||
22 | static getToken() { | 26 | static getToken() { |
23 | return this.getUrlKey('token') | 27 | return this.getUrlKey("token"); |
24 | } | 28 | } |
25 | 29 | ||
26 | static getSignature(userID) { | 30 | static getSignature(userID) { |
27 | const generator = new window.LibGenerateTestUserSig(this.getKey(), this.getSecret(), this.getExpire()) | 31 | const generator = new window.LibGenerateTestUserSig( |
28 | return generator.genTestUserSig(userID) | 32 | this.getKey(), |
33 | this.getSecret(), | ||
34 | this.getExpire() | ||
35 | ); | ||
36 | return generator.genTestUserSig(userID); | ||
29 | } | 37 | } |
30 | 38 | ||
31 | /** | 39 | /** |
... | @@ -33,29 +41,29 @@ export default class Helper { | ... | @@ -33,29 +41,29 @@ export default class Helper { |
33 | * @returns {Promise<never>|Promise<{sign, id}>} | 41 | * @returns {Promise<never>|Promise<{sign, id}>} |
34 | */ | 42 | */ |
35 | static verifyToken() { | 43 | static verifyToken() { |
36 | return request.get('auth').then(res => { | 44 | return request.get("auth").then((res) => { |
37 | const {esm_id} = res.data | 45 | const { esm_id } = res.data; |
38 | return Promise.resolve({id: esm_id, sign: this.getSignature(esm_id)}) | 46 | return Promise.resolve({ id: esm_id, sign: this.getSignature(esm_id) }); |
39 | }) | 47 | }); |
40 | } | 48 | } |
41 | 49 | ||
42 | static contactList(params = {}) { | 50 | static contactList(params = {}) { |
43 | return request.get('im/contacts', {params}) | 51 | return request.get("im/contacts", { params }); |
44 | } | 52 | } |
45 | 53 | ||
46 | static groupList(params = {}) { | 54 | static groupList(params = {}) { |
47 | return request.get('im/groups', {params}) | 55 | return request.get("im/groups", { params }); |
48 | } | 56 | } |
49 | 57 | ||
50 | static groupMemberList(group, params = {}) { | 58 | static groupMemberList(group, params = {}) { |
51 | return request.get(`im/groups/${group}/members`, {params}) | 59 | return request.get(`im/groups/${group}/members`, { params }); |
52 | } | 60 | } |
53 | 61 | ||
54 | static groupMemberDelete(group, member) { | 62 | static groupMemberDelete(group, member) { |
55 | return request.delete(`im/groups/${group}/members/${member}`) | 63 | return request.delete(`im/groups/${group}/members/${member}`); |
56 | } | 64 | } |
57 | 65 | ||
58 | static joinGroup(id, member) { | 66 | static joinGroup(id, member) { |
59 | return request.post(`im/groups/${id}/members`, {member}) | 67 | return request.post(`im/groups/${id}/members`, { member }); |
60 | } | 68 | } |
61 | } | 69 | } | ... | ... |
src/utils/hrequest.js
0 → 100644
1 | import axios from 'axios' | 1 | import axios from "axios"; |
2 | import Helper from './helper' | 2 | import Helper from "./helper"; |
3 | import Store from '../store' | 3 | import Store from "../store"; |
4 | import tim from '../tim' | 4 | import tim from "../tim"; |
5 | |||
6 | 5 | ||
7 | const service = axios.create({ | 6 | const service = axios.create({ |
8 | baseURL: process.env.VUE_APP_API_URL, | 7 | baseURL: process.env.VUE_APP_API_URL, |
9 | // withCredentials: true, // send cookies when cross-domain requests | 8 | // withCredentials: true, // send cookies when cross-domain requests |
10 | timeout: 5000 // request timeout | 9 | timeout: 5000, // request timeout |
11 | }) | 10 | }); |
12 | 11 | ||
13 | service.interceptors.request.use(config => { | 12 | service.interceptors.request.use( |
14 | config.headers['Authorization'] = 'Bearer ' + Helper.getToken() | 13 | (config) => { |
15 | config.headers['Accept'] = 'application/json' | 14 | config.headers["Authorization"] = "Bearer " + Helper.getToken(); |
16 | return config | 15 | config.headers["Accept"] = "application/json"; |
17 | }, error => { | 16 | return config; |
18 | return Promise.reject(error) | 17 | }, |
19 | }) | 18 | (error) => { |
19 | return Promise.reject(error); | ||
20 | } | ||
21 | ); | ||
20 | 22 | ||
21 | service.interceptors.response.use(response => { | 23 | service.interceptors.response.use( |
24 | (response) => { | ||
22 | switch (response.data.code) { | 25 | switch (response.data.code) { |
23 | case 200: | 26 | case 200: |
24 | return response.data | 27 | return response.data; |
25 | case 401: | 28 | case 401: |
26 | Store.commit('showMessage', {type: 'error', message: '身份信息已失效,请重新登录'}) | 29 | Store.commit("showMessage", { |
30 | type: "error", | ||
31 | message: "身份信息已失效,请重新登录", | ||
32 | }); | ||
27 | tim.logout().then(() => { | 33 | tim.logout().then(() => { |
28 | Store.commit('user/toggleIsLogin') | 34 | Store.commit("user/toggleIsLogin"); |
29 | Store.commit('user/stopComputeCurrent') | 35 | Store.commit("user/stopComputeCurrent"); |
30 | Store.commit('user/reset') | 36 | Store.commit("user/reset"); |
31 | }) | 37 | }); |
32 | break | 38 | break; |
33 | default: | 39 | default: |
34 | return Promise.reject(response.data) | 40 | return Promise.reject(response.data); |
41 | } | ||
42 | }, | ||
43 | (error) => { | ||
44 | return Promise.reject(error); | ||
35 | } | 45 | } |
36 | }, error => { | 46 | ); |
37 | return Promise.reject(error) | ||
38 | }) | ||
39 | 47 | ||
40 | export default service | 48 | export default service; | ... | ... |
-
Please register or sign in to post a comment