index.js 7.1 KB
Newer Older
DCloud_JSON's avatar
DCloud_JSON 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
import $state from '@/uni_modules/uni-im/sdk/state/index.js';
import $methods from '@/uni_modules/uni-im/sdk/methods/index.js';
import appEvent from './appEvent';
import createObservable from './createObservable';
import toFriendlyTime from './toFriendlyTime';
import shortcutKey from './shortcut-key.js';
import parseHtml from './html-parser.js';
import markdownIt from './markdown-it.min.js';
import md5 from './md5.min.js'

export default {
  appEvent,
  createObservable,
  toFriendlyTime,
  shortcutKey,
  parseHtml,
  markdownIt,
  /**
   *深度合并多个对象的方法
   */
  deepAssign() {
    let len = arguments.length,
      target = arguments[0]
    if (!this.isPlainObject(target)) {
      target = {}
    }
    for (let i = 1; i < len; i++) {
      let source = arguments[i]
      if (this.isPlainObject(source)) {
        for (let s in source) {
          if (s === '__proto__' || target === source[s]) {
            continue
          }
          if (this.isPlainObject(source[s])) {
            target[s] = this.deepAssign(target[s], source[s])
          } else {
            target[s] = source[s]
          }
        }
      }
    }
    return target
  },
  /**
   * 替换文本中的url为套了html的a标签的方式
   */
  replaceUrlToLink(str) {
    // 找网址
    let urlPattern = /(https?:\/\/|www\.)[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]/g;
    return str.replace(urlPattern, function(match) {
      var href = match;
      if (match.indexOf("http") == -1) {
        //如果不带http://开头就带上
        href = "http://" + match;
      }
      return `<a class="link" target="_blank" href="${href}">${match}</a> `;
    });
  },
  /**
   *判断对象是否是一个纯粹的对象
   */
  isPlainObject(obj) {
    return typeof obj === 'object' && Object.prototype.toString.call(obj) === '[object Object]'
  },
  getScreenMetrics() {
    let metrics = {
      pageLeft: 0,
      pageTop: 0,
      pageWidth: $state.systemInfo.screenWidth,
      pageHeight: $state.systemInfo.screenHeight,
    };
    [
      'screenWidth',
      'screenHeight',
      'windowWidth',
      'windowHeight',
      'windowTop',
      'windowBottom',
      'statusBarHeight',
      'safeArea',
      'safeAreaInsets',
    ].forEach(name => { metrics[name] = $state.systemInfo[name] })
    try {
      uni.createSelectorQuery()
        .select('uni-page-body > #page, uni-page-body > .page')
        .boundingClientRect(data => {
          if (data) {
            metrics['pageLeft'] = data.left
            metrics['pageTop'] = data.top
            metrics['pageWidth'] = data.width
            metrics['pageHeight'] = data.height
          }
        })
        .exec()
    } catch (e) {
      console.error('调用 uni.createSelectorQuery 时机过早:', e)
    }
    return metrics
  },
  isMuteMsg(msg){
    return (
      // TODO:静默消息
      msg.is_mute === true
      ||
      // 加群消息
      msg.action === "join-group" 
      || 
      // 禁言通知
      msg.action === 'update-group-info-mute_all_members' 
    )
  },
  isReadableMsg(msg) {
    // 如果是扩展的消息类型,则由扩展程序决定结果
    let result = $methods.msgTypes.get(msg.type)?.isReadable()
    if (typeof result !== 'undefined') return result
    return msg.type !== 'revoke_msg' &&
      msg.action !== 'update-group-info-avatar_file' && 
      msg.type !== 'clear-conversation-unreadCount'
  },
  filterMsgList(msgList) {
    return msgList.filter(msg => this.isReadableMsg(msg))
  },
  getMsgNote(_msg) {
    const msg = JSON.parse(JSON.stringify(_msg))
    const type = msg.type;
    let note = '[多媒体]'
    if (msg.is_revoke) {
      note = "消息已被撤回"
    } else if (msg.is_delete) {
      note = "消息已被删除"
    } else if (type === 'text') {
      note = msg.body.toString()
    } else if (type === 'userinfo-card') {
      note = `[${msg.body.name} 的名片]`
    } else {
      note = {
        "image": "[图片]",
        "sound": "[语音]",
        "video": "[视频]",
        "file": "[文件]",
        "location": "[位置]",
        "system": "[系统通知]",
        "code": "[代码]",
144 145
        "rich-text": "[富文本消息]",
        "revoke_msg": "[消息已被撤回]",
DCloud_JSON's avatar
DCloud_JSON 已提交
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
      } [type] || `[${type}]`
        
      if (type == "system") {
        note = {
          "join-group": "[新用户加入群聊]",
          "group-exit": "[退出群聊]",
          "group-expel": "[被踢出群聊]",
          "group-dissolved": "[此群聊已被解散]"
        } [msg.action] || '[系统消息]'
      } else if (type == "rich-text") {
        note = getRichTextText(msg.body)
        function getRichTextText(nodesList) {
          return getTextNode(nodesList)
          function getTextNode(nodesList) {
            let text = '';
            nodesList.forEach(item => {
              if (item.type == "text") {
                text += item.text.replace(/(\r\n|\n|\r)/gm, "")
              } else{
                text += ({
                  'image': '[图片]',
                  'link': '[链接]',
                })[item.type] || ''
              }
              if(item.name === 'img'){
                text += ' [图片] '
              }
              if (item.attrs && item.attrs.class === 'nickname' && item.attrs.user_id) {
                let userInfo = $state.users[item.attrs.user_id]
                delete item.children
                if(userInfo){
                  text += ` @${userInfo.nickname} `
                }else{
                  text += '@[昵称加载中...]'
                  $state.users.get(item.attrs.user_id)
                }
              }
              if (Array.isArray(item.children)) {
                text += getTextNode(item.children)
              }
            })
            // 替换换行为空格
            return text || '';
          }
        }
      }
    }
193 194 195 196 197 198
    // 去掉换行符
    note = note.replace(/(\r\n|\n|\r)/gm, "");
    // 改 &nbsp; &emsp; &ensp;等空格为普通空格
    note = note.replace(/&nbsp;|&emsp;|&ensp;/g, ' ')
    // 截取80个字符
    note = note.slice(0, 80).trim()
DCloud_JSON's avatar
DCloud_JSON 已提交
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
    return note
  },
  // 节流执行函数,用于控制频繁触发的事件。
  throttle(fn, delay) {
    fn.timer && clearTimeout(fn.timer);
    fn.timer = setTimeout(fn, delay);
  },
  async sleep(time) {
    return await new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve()
      }, time)
    })
  },
  getConversationId(id, type = 'single') { //single,group
    if (type == 'single') {
      let current_uid = uniCloud.getCurrentUserInfo().uid
      if (!current_uid) {
        console.error('错误current_uid不能为空', current_uid);
      }
      let param = [id, current_uid]
      return 'single_' + md5(param.sort().toString())
    } else {
      return 'group_' + id
    }
  },
  async getTempFileURL(fileid) {
    // console.log('getTempFileURL', fileid)
    // 如果不是fileid就直接返回。
    if (!fileid || fileid.indexOf('blob:') === 0 || fileid.indexOf('data:image/png;base64,') === 0 || fileid.substring(0, 8) != "cloud://") {
      return fileid
    }
    let res = await uniCloud.getTempFileURL({
      fileList: [fileid]
    })
    return res.fileList[0].tempFileURL
  }
}