index.js 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. import api from '@/api'
  2. // 搜索mixin
  3. export const searchUserMixin = {
  4. data () {
  5. return {
  6. isSearch: false, // 搜索展示
  7. searchList: null // 搜索结果
  8. }
  9. },
  10. methods: {
  11. searchUser (e, originList) {
  12. let val = e.target.value
  13. if (!val) {
  14. this.isSearch = false
  15. return
  16. }
  17. this.searchList = originList.filter(item => {
  18. let inName, inNick
  19. if (item.name) {
  20. inName = item.name ? item.name.indexOf(val) > -1 : false
  21. } else {
  22. inName = item.user_name ? item.user_name.indexOf(val) > -1 : false
  23. }
  24. inNick = item.nick_name ? item.nick_name.indexOf(val) > -1 : false
  25. return inName || inNick
  26. })
  27. this.isSearch = true
  28. }
  29. }
  30. }
  31. // 群搜索mixin
  32. export const searchGroupUserMixin = {
  33. data () {
  34. return {
  35. isSearchGroup: false, // 搜索展示
  36. searchGroupList: [] // 搜索结果
  37. }
  38. },
  39. methods: {
  40. searchUser (e, originList) {
  41. let val = e.target.value
  42. let inviteType = this.popInviteType
  43. if (!val) {
  44. this.isSearchGroup = false
  45. return
  46. }
  47. if (originList.length >= this.membersNum || inviteType == 1 || inviteType == 2) {
  48. this.searchGroupList = originList.filter(item => {
  49. let inName, inNick
  50. inName = item.user_name ? item.user_name.indexOf(val) > -1 : false
  51. inNick = item.nick_name ? item.nick_name.indexOf(val) > -1 : false
  52. return inName || inNick
  53. })
  54. } else {
  55. api.group.searchMember({
  56. group_id: this.group.groupId,
  57. keyword: this.searchTxt
  58. }).then(({ data }) => {
  59. this.searchGroupList = data.data
  60. })
  61. }
  62. this.isSearchGroup = true
  63. }
  64. }
  65. }
  66. // @人
  67. export const chatAtMixin = {
  68. data () {
  69. return {
  70. atInd: 0 // @人索引
  71. }
  72. },
  73. methods: {
  74. atPerson (name) {
  75. let el = this.$refs.chatInput
  76. let selectionStart = el.selectionStart
  77. let realStart = selectionStart - this.keyAfterAt.length
  78. this.inputMsg = this.inputMsg.slice(0, realStart) + `${name} ` + this.inputMsg.slice(selectionStart)
  79. this.atInd = 0
  80. el.focus()
  81. this.$nextTick(() => {
  82. el.setSelectionRange(realStart + name.length + 1, realStart + name.length + 1)
  83. })
  84. this.$store.commit('updateIsNewAt', {
  85. isNewAt: this.group.isNewAt,
  86. isNewAtFound: true
  87. })
  88. this.$store.commit('updateGroupSearchList', [])
  89. },
  90. handleUp () {
  91. if (this.atInd > 0) {
  92. this.atInd--
  93. }
  94. },
  95. handleDown () {
  96. let membersLen = this.filterMembers.length
  97. this.atInd < membersLen - 1 ? this.atInd++ : this.atInd = 0
  98. }
  99. }
  100. }
  101. // 聊天输入框
  102. export const chatInputMixin = {
  103. data () {
  104. return {
  105. selectionAfterAt: false, // 光标在@后面
  106. keyAfterAt: '', // 光标后的搜索字
  107. lastKeyAfterAt: ''
  108. }
  109. },
  110. mounted () {
  111. document.addEventListener('click', this.handleGlobalClick)
  112. },
  113. computed: {
  114. filterMembers () {
  115. if (!this.group.groupId) return []
  116. let members = this.group.membersArray
  117. let resArr = []
  118. if (this.keyAfterAt !== '') {
  119. resArr = this.group.searchList
  120. } else {
  121. for (let k = 0; k < members.length; k++) {
  122. if (members[k].user_id == this.userId) continue
  123. resArr.push(members[k])
  124. }
  125. }
  126. return resArr.slice(0, 100)
  127. },
  128. atShow () {
  129. this.atInd = 0
  130. return this.selectionAfterAt && this.filterMembers.length
  131. }
  132. },
  133. watch: {
  134. keyAfterAt (val) {
  135. if (!this.group.groupId || val == '') return
  136. if (this.group.isNewAtFound) return
  137. if (this.group.membersArray.length < this.group.membersNum) {
  138. api.group.searchMember({
  139. group_id: this.group.groupId,
  140. keyword: val
  141. }).then(({ data }) => {
  142. this.$store.commit('updateGroupSearchList', data.data)
  143. })
  144. } else {
  145. let searchList = this.group.membersArray.filter(item => {
  146. let inName, inNick
  147. inName = item.user_name ? item.user_name.indexOf(val) > -1 : false
  148. inNick = item.nick_name ? item.nick_name.indexOf(val) > -1 : false
  149. return inName || inNick
  150. })
  151. this.$store.commit('updateGroupSearchList', searchList)
  152. }
  153. },
  154. inputMsg (val, newval) {
  155. this.fixIOS()
  156. this.handleSelectionChange()
  157. }
  158. },
  159. methods: {
  160. getStrBeforeSelection () {
  161. let el = this.$refs.chatInput
  162. if (!el) return ''
  163. let selectionStart = el.selectionStart
  164. let prevStr = this.inputMsg.slice(0, selectionStart)
  165. return prevStr
  166. },
  167. getStrAfterSelection () {
  168. let el = this.$refs.chatInput
  169. if (!el) return ''
  170. let selectionStart = el.selectionStart
  171. let prevStr = this.inputMsg.slice(selectionStart)
  172. return prevStr
  173. },
  174. handleLeft (event) {
  175. let el = this.$refs.chatInput
  176. let selectionStart = el.selectionStart
  177. if (selectionStart === 0) return
  178. let prevStr = this.getStrBeforeSelection()
  179. let members = this.group.members
  180. for (let k in members) {
  181. let name = members[k].user_name
  182. let reg = new RegExp(`@${name} $`)
  183. if (reg.test(prevStr)) {
  184. event.preventDefault()
  185. el.setSelectionRange(selectionStart - name.length - 2, selectionStart - name.length - 2)
  186. return
  187. }
  188. }
  189. },
  190. handleRight (event) {
  191. let el = this.$refs.chatInput
  192. let selectionStart = el.selectionStart
  193. let afterStr = this.getStrAfterSelection()
  194. let members = this.group.members
  195. for (let k in members) {
  196. let name = members[k].user_name
  197. let reg = new RegExp(`^@${name} `)
  198. if (reg.test(afterStr)) {
  199. event.preventDefault()
  200. el.setSelectionRange(selectionStart + name.length + 2, selectionStart + name.length + 2)
  201. return
  202. }
  203. }
  204. },
  205. handleDel (event) {
  206. let el = this.$refs.chatInput
  207. let selectionStart = el.selectionStart
  208. if (selectionStart === 0) return
  209. let prevStr = this.getStrBeforeSelection()
  210. let members = this.group.members
  211. for (let k in members) {
  212. let name = members[k].user_name
  213. let reg = new RegExp(`@${name} $`)
  214. if (reg.test(prevStr)) {
  215. event.preventDefault()
  216. this.inputMsg = this.inputMsg.slice(0, selectionStart - name.length - 2) + this.inputMsg.slice(selectionStart)
  217. this.$nextTick(() => {
  218. el.setSelectionRange(selectionStart - name.length - 2, selectionStart - name.length - 2)
  219. })
  220. return
  221. }
  222. }
  223. },
  224. handleKeyDown (event) {
  225. if (this.atShow) {
  226. event.preventDefault()
  227. let item = this.filterMembers[this.atInd]
  228. this.atPerson(item.user_name)
  229. return
  230. }
  231. if (event.altKey || event.ctrlKey) {
  232. // 单纯换行
  233. this.inputMsg = this.inputMsg + '\n'
  234. } else {
  235. event.returnValue = false
  236. this.handleSend(event)
  237. }
  238. return false
  239. },
  240. handleFocus () {
  241. this.fixIOS()
  242. document.addEventListener('selectionchange', this.handleSelectionChange)
  243. },
  244. handleBlur () {
  245. this.fixIOS(false)
  246. document.removeEventListener('selectionchange', this.handleSelectionChange)
  247. this.updateChatInputFocus(false)
  248. },
  249. handleEsc () {
  250. this.selectionAfterAt = false
  251. },
  252. /**
  253. * 监听全局点击事件
  254. */
  255. handleGlobalClick () {
  256. this.selectionAfterAt = false
  257. },
  258. /**
  259. * 监听光标位置
  260. */
  261. handleSelectionChange () {
  262. let el = this.$refs.chatInput
  263. if (!el) return
  264. let selectionStart = el.selectionStart
  265. let selectionEnd = this.$refs.chatInput.selectionEnd
  266. if (selectionStart !== selectionEnd) return
  267. let prevStr = this.getStrBeforeSelection()
  268. this.selectionAfterAt = /@/.test(prevStr)
  269. if (this.selectionAfterAt) {
  270. this.keyAfterAt = prevStr.slice(prevStr.lastIndexOf('@') + 1)
  271. let isNewAt = this.keyAfterAt.indexOf(this.lastKeyAfterAt) < 0
  272. this.$store.commit('updateIsNewAt', {
  273. isNewAt: isNewAt,
  274. isNewAtFound: isNewAt ? false : this.group.isNewAtFound
  275. })
  276. if (isNewAt) this.$store.commit('updateGroupSearchList', [])
  277. this.lastKeyAfterAt = this.keyAfterAt
  278. }
  279. },
  280. /**
  281. * @des 处理ios系统下窗体闪烁的bug
  282. * @param {boolean} flag {true: 激活修复状态, false: 恢复原始状态}
  283. */
  284. fixIOS (flag = true) {
  285. var u = navigator.userAgent
  286. var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
  287. if (isIOS) {
  288. let el = this.$refs.scrollWrap
  289. if (!el) return
  290. if (flag) {
  291. el.style.overflowY = 'hidden'
  292. } else {
  293. el.style.overflowY = 'scroll'
  294. }
  295. }
  296. }
  297. }
  298. }