Procházet zdrojové kódy

Merge branch 'master' of http://svn.ouj.com:3000/eos_sicbo/chat

dmy před 5 roky
rodič
revize
836108d2f8
100 změnil soubory, kde provedl 644 přidání a 586 odebrání
  1. 17 14
      _src/api/modules/person.js
  2. 1 1
      _src/api/modules/session.js
  3. 9 1
      _src/components/chatAt/atme.vue
  4. 1 1
      _src/components/chatGroudMgr/index.vue
  5. 1 0
      _src/components/chatMini/chatMini.scss
  6. 18 10
      _src/components/chatMini/chatMini.vue
  7. 1 1
      _src/components/chatRoom/chatRoom.vue
  8. 1 1
      _src/components/chatSet/index.vue
  9. 3 0
      _src/components/emoji/index.vue
  10. 25 10
      _src/components/msgItem/index.vue
  11. 1 0
      _src/components/msgItem/style.scss
  12. 1 0
      _src/components/panel/panel.scss
  13. 1 3
      _src/components/panel/panel.vue
  14. 1 1
      _src/components/panel/sessionItem.vue
  15. 15 5
      _src/components/popup/invite/index.vue
  16. 14 4
      _src/components/popup/otherInfo/index.vue
  17. 1 0
      _src/components/popup/userInfo/index.js
  18. 1 1
      _src/components/popup/userInfo/index.vue
  19. 1 2
      _src/mixins/chat.js
  20. 1 0
      _src/mixins/index.js
  21. 1 0
      _src/pages/index/App.vue
  22. 41 38
      _src/pages/index/main.js
  23. 6 0
      _src/pages/mini/main.js
  24. 21 2
      _src/store/db/Message.js
  25. 2 0
      _src/store/db/Session.js
  26. 2 0
      _src/store/db/User.js
  27. 8 2
      _src/store/db/lib/DB.js
  28. 4 0
      _src/store/db/lib/TableHelper.js
  29. 10 0
      _src/store/index.js
  30. 15 3
      _src/store/module/chat.js
  31. 29 11
      _src/store/module/group/actions.js
  32. 4 1
      _src/store/module/group/mutations.js
  33. 135 0
      _src/style/mini.scss
  34. 5 5
      _src/util/emoji.js
  35. 9 1
      _src/util/util.js
  36. 0 0
      dist/css/chunk-059c8c86.10b04e6a.css
  37. 0 0
      dist/css/chunk-0d1dfdc4.18863327.css
  38. 0 0
      dist/css/chunk-0ee422d0.1cd40ba4.css
  39. 0 0
      dist/css/chunk-21e00cbc.eed9b4ef.css
  40. 0 0
      dist/css/chunk-2d2f7d98.03d9f0bc.css
  41. 0 0
      dist/css/chunk-2d2f7d98.11f748be.css
  42. 0 0
      dist/css/chunk-4ad29ea1.da62d525.css
  43. 0 0
      dist/css/chunk-common.8be1955b.css
  44. 0 0
      dist/css/chunk-common.ca1cadb3.css
  45. 0 0
      dist/css/chunk-d8ac0884.5734681f.css
  46. 0 0
      dist/css/chunk-vendors.2fc48d69.css
  47. 0 0
      dist/css/chunk-vendors.a7200cfa.css
  48. 0 0
      dist/css/chunk-vendors.e9c8b283.css
  49. 0 0
      dist/css/index.03af8c10.css
  50. 0 0
      dist/css/index.24b1d028.css
  51. 0 0
      dist/css/index.ab4a2586.css
  52. 0 0
      dist/css/index.f2e8d51c.css
  53. 0 0
      dist/css/mini.49b29b54.css
  54. 0 0
      dist/css/mini.5c40c6d3.css
  55. 0 0
      dist/css/mini.6beedc15.css
  56. 0 0
      dist/js/chunk-059c8c86.db0e726b.js
  57. 0 0
      dist/js/chunk-0d1dfdc4.a39b3f9c.js
  58. 0 0
      dist/js/chunk-0ee422d0.1c400eec.js
  59. 0 0
      dist/js/chunk-0ee422d0.23fcc03b.js
  60. 0 0
      dist/js/chunk-14b7d1c9.0b969439.js
  61. 0 0
      dist/js/chunk-21e00cbc.12f9bf78.js
  62. 0 0
      dist/js/chunk-2c06dfd2.42bf31dd.js
  63. 0 0
      dist/js/chunk-2d2f7d98.1497b473.js
  64. 0 0
      dist/js/chunk-2d2f7d98.321c90a6.js
  65. 0 0
      dist/js/chunk-2d2f7d98.64a521c7.js
  66. 0 0
      dist/js/chunk-411abfe3.98a6fbd4.js
  67. 0 0
      dist/js/chunk-4ad29ea1.0175d519.js
  68. 0 0
      dist/js/chunk-4ae53135.d7b7a22d.js
  69. 0 0
      dist/js/chunk-6d98040b.61247f20.js
  70. 0 0
      dist/js/chunk-6d98040b.b5e27c57.js
  71. 0 0
      dist/js/chunk-common.01a67a4a.js
  72. 0 0
      dist/js/chunk-common.2e02adf3.js
  73. 0 0
      dist/js/chunk-common.31950b99.js
  74. 0 0
      dist/js/chunk-common.3fbfe6b6.js
  75. 0 0
      dist/js/chunk-d8ac0884.6feb146d.js
  76. 0 0
      dist/js/chunk-vendors.e082776c.js
  77. 0 0
      dist/js/chunk-vendors.f2f92cd6.js
  78. 0 0
      dist/js/h5.35dd4f02.js
  79. 0 0
      dist/js/h5.487c3ee2.js
  80. 0 0
      dist/js/h5.896cd3a0.js
  81. 0 0
      dist/js/h5.f47e8109.js
  82. 0 0
      dist/js/index.0f1e1ca2.js
  83. 0 0
      dist/js/index.0f40e1d0.js
  84. 0 0
      dist/js/index.62cedca3.js
  85. 0 0
      dist/js/index.678fe8c4.js
  86. 0 0
      dist/js/mini.61722891.js
  87. 0 0
      dist/js/mini.af882c22.js
  88. 0 0
      dist/js/mini.ca2ac66b.js
  89. 0 146
      dist/precache-manifest.183449aebb9584f63fb0b00ff8c8c8d4.js
  90. 0 146
      dist/precache-manifest.27fe4966b146ff97450b10c649ad6e97.js
  91. 0 146
      dist/precache-manifest.877feee0d916f2c57faa670055e68a03.js
  92. 146 0
      dist/precache-manifest.d48a5fbfeb55aa8e8d2a19d2650a7202.js
  93. 1 1
      dist/sw.js
  94. 28 0
      protected/bin/once/fixGroupMemberNum.php
  95. 1 1
      protected/conf/config.dev.inc.php
  96. 1 0
      protected/conf/config.form.inc.php
  97. 2 0
      protected/conf/config.inc.php
  98. 1 0
      protected/conf/config.new.inc.php
  99. 43 25
      protected/controllers/DefaultController.php
  100. 15 3
      protected/controllers/GroupController.php

+ 17 - 14
_src/api/modules/person.js

@@ -9,25 +9,28 @@ export default {
    * @param {String} data.group_id
    * @param {String} data.client_hash // 客户端最新消息hash
    */
-  getNewMsg (params) {
-    return axios.request({
+  async getNewMsg (params) {
+    let res = await axios.request({
       url: 'person/newMsg',
       method: 'get',
       needLogin: true,
       params
-    }).then(res => {
-      const objMessage = new Message()
-      objMessage.saveMsg(params['session_id'], res.data.data)
-      // 解密数据
-      res.data.data.list.forEach(item => {
-        if (item.msg_type == 4) {
-          item.msg = JSON.parse(decryptoMsg(item.msg))
-        } else {
-          item.msg = decryptoMsg(item.msg)
-        }
-      })
-      return Promise.resolve(res)
     })
+
+    const objMessage = new Message()
+    // 如果不同步执行,第一次初始化数据库会出现很奇怪的问题...
+    await objMessage.saveMsg(params['session_id'], res.data.data)
+
+    // 解密数据
+    res.data.data.list.forEach(item => {
+      if (item.msg_type == 4) {
+        item.msg = JSON.parse(decryptoMsg(item.msg))
+      } else {
+        item.msg = decryptoMsg(item.msg)
+      }
+    })
+
+    return res
   },
   /**
    * 用户历史消息

+ 1 - 1
_src/api/modules/session.js

@@ -10,7 +10,7 @@ export default {
       url: 'session/list',
       method: 'get',
       needLogin: true,
-      // cache: true,
+      cache: true,
       callback
     })
   },

+ 9 - 1
_src/components/chatAt/atme.vue

@@ -6,7 +6,7 @@
       </div>
       <div class="at-me-item" v-else-if="atNum && itemVisible" @click="scrollToMsg">
           <div class="at-content">{{atList[0].name}}提到了你</div>
-        <i class="icon-close" title="关闭" @click.stop="itemVisible = false"></i>
+        <i class="icon-close" title="关闭" @click.stop="closeAtme"></i>
       </div>
 
   </div>
@@ -14,6 +14,7 @@
 
 <script>
 import _ from 'lodash'
+import { mapMutations } from 'vuex'
 
 export default {
   name: 'atMe',
@@ -32,8 +33,15 @@ export default {
     }
   },
   methods: {
+    ...mapMutations([
+      'clearAtList'
+    ]),
     scrollToMsg () {
       this.$emit('scrollToMsg', this.atList.length - 1)
+    },
+    closeAtme () {
+      this.itemVisible = false
+      this.clearAtList()
     }
   }
 }

+ 1 - 1
_src/components/chatGroudMgr/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="r-view-mgr">
+  <div class="r-view-mgr" @click.stop>
     <template v-if="!adminShow">
       <div class="groudMgr-top">
         <i class="el-icon-arrow-left" @click="handleGroudMgr"></i>

+ 1 - 0
_src/components/chatMini/chatMini.scss

@@ -133,6 +133,7 @@ $offsetRight: 5px;
     font-size: 0;
     text-align: right;
     overflow: hidden;
+    cursor: pointer;
     &:before{
       margin-right: 3px;
     }

+ 18 - 10
_src/components/chatMini/chatMini.vue

@@ -5,9 +5,9 @@
         <div class="box-hd">
           <div class="btn-menu" @click.stop="showMenuExtra = !showMenuExtra"></div>
           <div class="btn-close" @click="handleToggleChat(false)"></div>
-          <div class="box-title">{{group.groupName}}</div>
-          <div class="user-tips">
-            <em>{{group.membersNum}}</em>
+          <div class="box-title">{{group.groupName}}({{group.membersNum}})</div>
+          <div class="user-tips" @click="chatToCreator">
+            <em>群主</em>
           </div>
 
           <ul class="menu-extra" v-show="showMenuExtra">
@@ -38,7 +38,7 @@
               <div class="msg-top-load" v-if="lockMore && !lockEnd">
                 <i class="msg-loading-icon"></i>
               </div>
-              <template v-if="group.chatList.length">
+              <template v-if="chatList.length">
                 <msg-item v-for="(item ,key) in group.pinList"
                 :key="'pin' + key"
                 v-bind="item"
@@ -47,7 +47,7 @@
                 >
                 </msg-item>
               </template>
-              <msg-item v-for="item in group.chatList"
+              <msg-item v-for="item in chatList"
                 :key="item.hash"
                 v-bind="item"
                 :msgItem="item"
@@ -163,7 +163,7 @@ import atMe from '@/components/chatAt/atme'
 import chatPin from '@/components/chatPin'
 import { mapActions, mapState, mapMutations } from 'vuex'
 import { getMiniWsUrl } from '@/util/contract.js'
-import { isMobile, scrollMsgIntoView } from '@/util/util.js'
+import { isMobile, scrollMsgIntoView, openPcPage } from '@/util/util.js'
 import WsManager from '@/util/wsManager.js'
 import PostMessager from '@/util/postMessager.js'
 import ScatterJS from 'scatter-js/dist/scatter.esm'
@@ -210,6 +210,7 @@ export default {
       pinMsg: state => state.group.pinMsg,
       pinList: state => state.group.pinList,
       atList: state => state.group.atList,
+      chatList: state => state.group.chatList,
       unreadNums: state => state.group.unreadNums
     }),
     emojiMap () {
@@ -254,9 +255,11 @@ export default {
         this.inputHeight = Math.max(18, Math.min(ele.scrollHeight, 75)) + 'px'
       })
     },
-    unreadNums (val, newval) {
-      if (val > 0 && this.isBottom) {
-        setTimeout(this.resizeToBottom.bind(this), 150)
+    chatList (val) {
+      let lastVal = val[val.length - 1]
+      if ((lastVal && lastVal.msg_type == 4) || this.isBottom) {
+        // 自己发的红包自动滚动到底部
+        this.$nextTick(this.resizeToBottom)
       }
     },
     chatInputFocus (val, newval) {
@@ -360,6 +363,11 @@ export default {
       'doSendFile',
       'doContractLogin'
     ]),
+    chatToCreator () {
+      let { creator, userId } = this.group
+      let sessionId = creator > userId ? `${creator}-${userId}` : `${creator}-${userId}`
+      openPcPage(`/pm/${sessionId}`)
+    },
     handleMoreClick () {
       this.showEmoji = false
       this.toolShow = !this.toolShow
@@ -668,7 +676,7 @@ export default {
       }
       // 替换emoji字符串
       let _inputMsg = this.inputMsg
-      let parts = _inputMsg.match(/\["[a-z_]+"\]/g)
+      let parts = _inputMsg.match(/\["[a-z0-9A-Z_]+"\]/g)
       for (let k in parts) {
         let emoji = this.emojiMap[parts[k]]
         if (emoji) {

+ 1 - 1
_src/components/chatRoom/chatRoom.vue

@@ -56,7 +56,7 @@
           </em>
         </div>
       </div>
-      <input-area ref="inputArea" @toBottom="resizeToBottom" v-show="isJoinGroup==1"></input-area>
+      <input-area ref="inputArea" @toBottom="resizeToBottom" v-show="isJoinGroup==1" @handleFocus="showCharSet(0)"></input-area>
       <div @click="joinGroup()" class="btn-join" v-show="isJoinGroup==0">加入群聊</div>
     </div>
     <chat-set

+ 1 - 1
_src/components/chatSet/index.vue

@@ -123,7 +123,7 @@
     <div class="setting-item ext-group-admin" v-if="isCreator" @click="handleGroudMgr">
       <div class="title">群管理<i class="el-icon-arrow-right team-arrow-icon"></i></div>
     </div>
-    <div class="setting-bottom">
+    <div class="setting-bottom" v-show="group.isJoin">
       <button class="delete-btn" @click="leaveGroup">退出群组</button>
     </div>
     <!-- 群公告 -->

+ 3 - 0
_src/components/emoji/index.vue

@@ -88,6 +88,9 @@ export default {
     },
     handleScroll () {
       let emojiList = document.getElementById('emojiList')
+
+      if (!emojiList) return
+
       let imageArr = emojiList.querySelectorAll('img')
 
       imageArr.forEach(item => {

+ 25 - 10
_src/components/msgItem/index.vue

@@ -179,6 +179,7 @@ export default {
   },
   computed: {
     ...mapState({
+      curSession: state => state.curSession,
       myId: state => state.userId,
       userInfo: state => state.group.userInfo,
       blockList: state => state.group.blockList,
@@ -194,15 +195,13 @@ export default {
         if (this.from == this.userId) {
           return `${this.type == 'me' ? '你' : this.name}撤回了一条消息`
         } else {
-          if (this.userId == this.myId) {
+          if (this.from != this.userId) {
             let admin = this.members[this.from]
-            let adminName = '管理员'
-            if (admin) {
-              adminName = admin.nick_name
-            }
+            let adminName = admin ? admin.nick_name : '管理员'
+
             return `${adminName}撤回了${this.name}的一条消息`
           } else {
-            return ''
+            return `${this.name}撤回了的一条消息`
           }
         }
       } else {
@@ -228,7 +227,7 @@ export default {
   },
   created () {},
   methods: {
-    ...mapMutations(['updateChatInputFocus', 'reSendChatItem']),
+    ...mapMutations(['updateChatInputFocus', 'reSendChatItem', 'setSessionRepeal']),
     ...mapActions([
       'doRepealPersonMsg',
       'doRepealGroupMsg',
@@ -326,7 +325,15 @@ export default {
     },
     handleQuote () {
       let { name, content } = this
-      let quoteStr = `「${name}:${content}」\n- - - - - - - - - - - - - - -\n`
+      let emojiReg = /<img class="emoji" .+?\/>/gi
+      let newCont = content.replace(emojiReg, function (match) {
+        let emoji = match.match(/alt=.+?&*"/g)
+        let emojiCont = emoji && emoji[0].replace(/"|alt=|/g, '')
+
+        return emojiCont
+      })
+
+      let quoteStr = `「${name}:${newCont}」\n- - - - - - - - - - - - - - -\n`
       this.$emit('quoteMsg', quoteStr)
       this.$nextTick(() => {
         this.updateChatInputFocus(true)
@@ -364,8 +371,16 @@ export default {
     },
     handleRevoke () {
       if (this.isPrivate) {
-        console.log('撤回')
-        this.doRepealPersonMsg({ hash: this.hash })
+        this.doRepealPersonMsg({ hash: this.hash }).then(() => {
+          this.$store.commit('setSessionRepeal', {
+            me: true,
+            sessionId: this.curSession
+          })
+          this.$store.commit('repealChatItem', {
+            hash: this.hash,
+            from: this.from
+          })
+        })
       } else {
         this.doRepealGroupMsg({ hash: this.hash })
       }

+ 1 - 0
_src/components/msgItem/style.scss

@@ -3,6 +3,7 @@
     text-align: center;
     font-size: 12px;
     line-height: 20px;
+    color: #b2b2b2;
 }
 .msg-item {
   padding: 0 7px;

+ 1 - 0
_src/components/panel/panel.scss

@@ -73,6 +73,7 @@
   z-index: 1;
   margin-left: 66px;
   height: 100%;
+  width: 284px;
   @include webkitbox(2);
 }
 

+ 1 - 3
_src/components/panel/panel.vue

@@ -105,9 +105,7 @@ export default {
       this.isShowSetting = false
     },
     handleFeedback () {
-      API.base.feedback({
-        group_id: this.curGroupId
-      }).then(({ data }) => {
+      API.base.feedback().then(({ data }) => {
         let serverId = data.data.serverId
         let sessionId = this.userId > serverId
           ? `${serverId}-${this.userId}`

+ 1 - 1
_src/components/panel/sessionItem.vue

@@ -23,7 +23,7 @@
         <span>{{item.name}}</span>
         <i class="icon-mute" v-if="item.is_mute==1"></i>
       </h3>
-      <p>{{item.cont}}</p>
+      <p><span v-if="item.unread>0 && item.is_mute==1">[{{item.unread}}条]</span>{{item.cont}}</p>
       <span class="time">{{item.update_time_int | handleUpdate}}</span>
     </div>
     <ul

+ 15 - 5
_src/components/popup/invite/index.vue

@@ -1,8 +1,12 @@
 <template>
   <transition name="msgbox-fade">
-    <div class="pub-wrapper" v-if="visible">
-      <div class="pub-mask"></div>
-      <div class="pub-modal invite-modal">
+    <div class="pub-wrapper" v-if="visible" @click.stop>
+      <div class="pub-mask" @click="visible = false"></div>
+      <div class="pub-modal invite-modal"
+        v-loading="isLoading"
+        element-loading-text="加载中"
+        element-loading-spinner="el-icon-loading"
+        element-loading-background="rgba(0, 0, 0, 0.2)">
         <div class="modal-hd">
           <!-- <div class="title">
             <i class="el-icon-close" @click="visible = false"></i>
@@ -95,7 +99,7 @@
               </template>
             </div>
             <div class="send-btn">
-              <el-button @click="optSubmit" type="primary" :disabled="checkedNum<=0">确认</el-button>
+              <el-button @click="optSubmit" type="primary" :disabled="this.popInviteType!=1 && checkedNum<=0">确认</el-button>
               <el-button @click="visible = false">取消</el-button>
             </div>
           </div>
@@ -122,7 +126,8 @@ export default {
     return {
       curItemIndex: 0,
       checkList: [],
-      groupName: ''
+      groupName: '',
+      isLoading: false
     }
   },
   computed: {
@@ -270,6 +275,7 @@ export default {
     // 建群
     createGroup () {
       if (this.groupName) {
+        this.isLoading = true
         API.group
           .createGroup({
             group_title: this.groupName,
@@ -289,6 +295,7 @@ export default {
     },
     // 邀请成员加入
     invitesMember () {
+      this.isLoading = true
       API.group
         .invites({
           user_ids: this.inviteList,
@@ -301,6 +308,7 @@ export default {
     },
     // 删除成员
     removesMember () {
+      this.isLoading = true
       API.group
         .removes({
           user_ids: this.inviteList,
@@ -313,6 +321,7 @@ export default {
     },
     // 添加群管理
     addAdmin () {
+      this.isLoading = true
       API.group
         .addAdmin({
           user_ids: this.inviteList,
@@ -332,6 +341,7 @@ export default {
       let username = curMember.nick_name || curMember.user_name
       MessageBox.confirm(`确定要把群主转让给${username}`)
         .then(() => {
+          this.isLoading = true
           API.group
             .changeCreator({
               new_creator: this.inviteList,

+ 14 - 4
_src/components/popup/otherInfo/index.vue

@@ -9,7 +9,7 @@
         <div class="modal-bd" v-if="userInfo">
           <div class="user-top">
             <div class="user-avatar">
-              <img v-if="userInfo.cover_photo" :src="userInfo.cover_photo" alt="">
+              <img v-if="userInfo.cover_photo" :src="userInfo.cover_photo" @click="$showImgPreview(userInfo.cover_photo)" alt="">
               <div v-else class="user-avatar"
               :class="'avatar_bg' + userInfo.user_id % 9"
               :data-name="userInfo.nick_name.slice(0,2).toUpperCase()"
@@ -43,6 +43,7 @@
 import { Button, Message, Switch } from 'element-ui'
 import Vue from 'vue'
 import { mapState } from 'vuex'
+import { openPcPage } from '@/util/util'
 import API from '@/api'
 
 Vue.component(Button.name, Button)
@@ -64,15 +65,26 @@ export default {
       sessionList: state => state.chat.sessionList,
       meId: state => state.userId,
       meInfo: state => state.userInfo
-    })
+    }),
+    meechatType () {
+      return this.$store.getters.meechatType
+    }
   },
   methods: {
     sendMsg () {
+      this.visible = false
+
       let youId = this.userInfo.user_id
       let sessionId = Number(youId) < Number(this.meId)
         ? `${youId}-${this.meId}`
         : `${this.meId}-${youId}`
 
+      // mini版跳转完成版
+      if (this.meechatType === 'mini') {
+        openPcPage(`/pm/${sessionId}`)
+        return
+      }
+
       let repeatFlag = this.sessionList.some(e => {
         return e.session_id == sessionId
       })
@@ -109,8 +121,6 @@ export default {
         data: this.userInfo.nick_name
       })
       this.$router.push({ path: `/pm/${sessionId}` })
-
-      this.visible = false
     }
   },
   created () {

+ 1 - 0
_src/components/popup/userInfo/index.js

@@ -5,6 +5,7 @@ Info.install = function (Vue, store) {
   let instance
 
   Vue.prototype.$showUserInfo = () => {
+    console.log('showUserInfo')
     if (instance) {
       document.body.removeChild(instance.$el)
       instance = null

+ 1 - 1
_src/components/popup/userInfo/index.vue

@@ -36,7 +36,7 @@
                 <strong>{{item.type.toUpperCase()}}</strong>
                 <span class="open-tips" v-if="item.type == 'eth' || item.type == 'tron'">即将开放</span>
                 <div class="fr" v-if="item.account">
-                  <span>{{item.is_visible === 0?'已隐藏':'已公开'}}</span>
+                  <span>{{item.is_visible === 0?'未公开':'已公开'}}</span>
                   <el-switch
                     v-model="item.is_visible"
                     :active-value="0"

+ 1 - 2
_src/mixins/chat.js

@@ -195,7 +195,6 @@ export const chatMixin = {
      * @des 聊天窗体滚动到底部
      */
     resizeToBottom () {
-      console.log('resizeToBottom')
       this.$refs.scrollWrap.scrollTop = this.$refs.msgWrap.offsetHeight
       this.resetUnreadNums()
       this.isBottom = true
@@ -335,7 +334,7 @@ export const inputMixin = {
 
       // 替换emoji字符串
       let _inputMsg = this.inputMsg
-      let parts = _inputMsg.match(/\["[a-z_]+"\]/g)
+      let parts = _inputMsg.match(/\["[a-z0-9A-Z_]+"\]/g)
       for (let k in parts) {
         let emoji = this.emojiMap[parts[k]]
         if (emoji) {

+ 1 - 0
_src/mixins/index.js

@@ -262,6 +262,7 @@ export const chatInputMixin = {
     },
     handleFocus () {
       this.fixIOS()
+      this.$emit('handleFocus') // 针对完整版
       document.addEventListener('selectionchange', this.handleSelectionChange)
     },
     handleBlur () {

+ 1 - 0
_src/pages/index/App.vue

@@ -53,6 +53,7 @@ export default {
   async created () {
     // 连接scatter
     ScatterJS.scatter.connect('MEE_CHAT').then(async connected => {
+      console.log('ScatterJS.scatter', connected)
       if (connected) {
         // 设置scatter
         this.setScatter(ScatterJS.scatter)

+ 41 - 38
_src/pages/index/main.js

@@ -2,6 +2,7 @@ import Vue from 'vue'
 import App from './App.vue'
 import store from '@/store'
 import { pcRouter } from '@/router'
+import { Loading } from 'element-ui'
 
 import Invite from '@/components/popup/invite'
 import Avatar from '@/components/popup/avatar'
@@ -14,7 +15,7 @@ import Toast from '@/components/popup/toast'
 import VueClipboard from 'vue-clipboard2'
 import directive from '@/plugins/directive'
 import TWEEN from '@tweenjs/tween.js'
-// import { register } from 'register-service-worker'
+import { register } from 'register-service-worker'
 // import { MessageBox } from 'element-ui'
 
 Vue.use(Invite, store)
@@ -28,6 +29,8 @@ Vue.use(VueClipboard)
 Vue.use(directive)
 Vue.use(imgPreview)
 
+Vue.use(Loading)
+
 Vue.config.productionTip = false
 
 new Vue({
@@ -43,40 +46,40 @@ function animate (time) {
 }
 requestAnimationFrame(animate)
 
-// if (process.env.NODE_ENV === 'production') {
-//   let updatefound = false
-//   register('/sw.js', {
-//     ready () {
-//       console.log(
-//         'App is being served from cache by a service worker.\n' +
-//         'For more details, visit https://goo.gl/AFskqB'
-//       )
-//     },
-//     registered () {
-//       console.log('Service worker has been registered.')
-//     },
-//     cached () {
-//       console.log('Content has been cached for offline use.')
-//     },
-//     updatefound () {
-//       updatefound = true
-//       console.log('New content is downloading.')
-//     },
-//     updated () {
-//       if (updatefound) {
-//         MessageBox.confirm('新的内容已更新完毕,立即刷新页面?', '提示', {
-//           confirmButtonText: '确定',
-//           cancelButtonText: '取消'
-//         }).then(() => {
-//           location.reload() && window.location.reload()
-//         }).catch(() => {})
-//       }
-//     },
-//     offline () {
-//       console.log('No internet connection found. App is running in offline mode.')
-//     },
-//     error (error) {
-//       console.error('Error during service worker registration:', error)
-//     }
-//   })
-// }
+if (process.env.NODE_ENV === 'production') {
+  let updatefound = false
+  register('/sw.js', {
+    ready () {
+      console.log(
+        'App is being served from cache by a service worker.\n' +
+        'For more details, visit https://goo.gl/AFskqB'
+      )
+    },
+    registered () {
+      console.log('Service worker has been registered.')
+    },
+    cached () {
+      console.log('Content has been cached for offline use.')
+    },
+    updatefound () {
+      updatefound = true
+      console.log('New content is downloading.')
+    },
+    updated () {
+      if (updatefound) {
+        // MessageBox.confirm('新的内容已更新完毕,立即刷新页面?', '提示', {
+        //   confirmButtonText: '确定',
+        //   cancelButtonText: '取消'
+        // }).then(() => {
+        //   location.reload() && window.location.reload()
+        // }).catch(() => {})
+      }
+    },
+    offline () {
+      console.log('No internet connection found. App is running in offline mode.')
+    },
+    error (error) {
+      console.error('Error during service worker registration:', error)
+    }
+  })
+}

+ 6 - 0
_src/pages/mini/main.js

@@ -2,20 +2,26 @@ import Vue from 'vue'
 import App from './App.vue'
 import store from '@/store'
 import VueClipboard from 'vue-clipboard2'
+import Avatar from '@/components/popup/avatar'
 import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
 import VueVirtualScroller from 'vue-virtual-scroller'
 import imgPreview from '@/components/popup/imgPreview'
 import packetGet from '@/components/popup/packetGet'
 import packetSend from '@/components/popup/packetSend'
 import otherInfo from '@/components/popup/otherInfo'
+import Info from '@/components/popup/userInfo'
 import TWEEN from '@tweenjs/tween.js'
+import directive from '@/plugins/directive'
 
+Vue.use(Avatar, store)
 Vue.use(VueClipboard)
 Vue.use(VueVirtualScroller)
 Vue.use(imgPreview)
+Vue.use(Info, store)
 Vue.use(otherInfo, store)
 Vue.use(packetGet, store)
 Vue.use(packetSend, store)
+Vue.use(directive, store)
 
 Vue.config.productionTip = false
 

+ 21 - 2
_src/store/db/Message.js

@@ -10,6 +10,8 @@ class Message extends TableHelper {
   async getMsg (sessionId, limit = 100) {
     if (!sessionId) return null
     let objTable = await this.getObjTable()
+    if (!objTable) return
+
     var lowerBound = [sessionId, 0]
     var upperBound = [sessionId, 999999999999999]
     let keyRangeValue = IDBKeyRange.bound(lowerBound, upperBound)
@@ -53,15 +55,23 @@ class Message extends TableHelper {
 
   async updatePackInfo (hash, type, value) {
     let objTable = await this.getObjTable()
+    if (!objTable) return
+
     let obj = await objTable.get(hash)
-    obj.ext[type] = value
-    objTable.put(obj)
+    if (obj) {
+      obj.ext[type] = value
+      objTable.put(obj)
+    } else {
+      console.log('can not find redpack:' + hash)
+    }
   }
 
   async saveMsg (sessionId, data) {
     const objMessage = new Message()
     // 数据保存到indexDB
     let objTable = await objMessage.getObjTable()
+    if (!objTable) return
+
     for (let key in data.list) {
       let value = Object.assign({ 'session_id': sessionId }, data.list[key])
       await objTable.put(value)
@@ -70,6 +80,15 @@ class Message extends TableHelper {
     let objUser = new User()
     objUser.replaceObjects(data.userMap)
   }
+
+  async removeMsg (sessionId, hash) {
+    const objMessage = new Message()
+    // 数据保存到indexDB
+    let objTable = await objMessage.getObjTable()
+    if (!objTable) return
+
+    objTable.delete(hash)
+  }
 }
 
 export default Message

+ 2 - 0
_src/store/db/Session.js

@@ -6,6 +6,8 @@ class Session extends TableHelper {
   }
   async getSortList () {
     let objTable = await this.getObjTable()
+    if (!objTable) return []
+
     let cursor = await objTable.index('pin_time_int').openCursor(null, 'prev')
     let list = []
     // let list2 = []

+ 2 - 0
_src/store/db/User.js

@@ -8,6 +8,8 @@ class User extends TableHelper {
   async getUserMap (userIds) {
     let objTable = await this.getObjTable()
     let map = {}
+    if (!objTable) return map
+
     for (let k in userIds) {
       let userId = userIds[k]
       map[userId] = await objTable.get(userId)

+ 8 - 2
_src/store/db/lib/DB.js

@@ -6,14 +6,17 @@ class DB {
   static async initDb (tableName) {
     if (!objDb) {
       objDb = await initDb()
-      console.log('finish', objDb)
     }
 
     return objDb
   }
   static async init (tableName) {
     await DB.initDb()
-    return objDb.transaction(tableName, 'readwrite').objectStore(tableName)
+    if (objDb) {
+      return objDb.transaction(tableName, 'readwrite').objectStore(tableName)
+    } else {
+      return null
+    }
   }
 }
 
@@ -50,6 +53,9 @@ async function initDb () {
         objMessage.deleteIndex('group_id')
         objMessage.createIndex('session_id', ['session_id', 'create_time_int'], { unique: false })
     }
+  }).catch(function (ex) {
+    console.error('initDb error:' + ex.message)
+    // alert('initDb error:' + ex.message)
   })
 
   return objDb

+ 4 - 0
_src/store/db/lib/TableHelper.js

@@ -9,10 +9,12 @@ class TableHelper {
   }
   async replaceObject (obj) {
     let objTable = await this.getObjTable()
+    if (!objTable) return
     objTable.put(obj)
   }
   async replaceObjects (list) {
     let objTable = await this.getObjTable()
+    if (!objTable) return
     // 解密数据
     for (let key in list) {
       objTable.put(list[key])
@@ -20,6 +22,8 @@ class TableHelper {
   }
   async updateObject (newObject, where) {
     let objTable = await this.getObjTable()
+    if (!objTable) return
+
     for (let key in where) {
       let obj = null
       if (key == objTable.keyPath) {

+ 10 - 0
_src/store/index.js

@@ -30,11 +30,21 @@ const getters = {
   },
   // 私聊时候对方的userId
   otherUserId: state => {
+    if (!state.curSession) return
     if (state.curSession.indexOf('-') > -1) {
       return state.curSession.replace('-', '').replace(state.userId, '')
     } else {
       return ''
     }
+  },
+  meechatType: state => {
+    if (location.pathname.indexOf('mini') > -1) {
+      return 'mini'
+    } else if (location.pathname.indexOf('h5') > -1) {
+      return 'h5'
+    } else {
+      return 'pc'
+    }
   }
 }
 

+ 15 - 3
_src/store/module/chat.js

@@ -39,6 +39,7 @@ const mutations = {
   addSessionItem (state, data) {
     state.sessionList.unshift(data)
   },
+  // 会话列表未读消息设置
   setSessionItemUnread (state, data) {
     state.sessionList.forEach((item) => {
       if (item.session_id == `${data.session_id}`) {
@@ -59,6 +60,15 @@ const mutations = {
   setFriendList (state, data) {
     state.friendList = data
   },
+  // 左侧会话撤回-用于私聊主动撤回
+  setSessionRepeal (state, data) {
+    state.sessionList.forEach((item) => {
+      if (item.session_id == data.sessionId) {
+        Vue.set(item, 'cont', `${data.me ? '你' : '对方'}撤回一条消息`)
+        Vue.set(item, 'update_time_int', data.timestamp)
+      }
+    })
+  },
   setSessionItem (state, data) {
     state.sessionList.forEach(item => {
       if (item.session_id == data.session_id) {
@@ -156,9 +166,11 @@ const actions = {
     }
 
     API.session.sessionList(function ({ data }) {
-      commit('setSessionList', data.data)
-      // 存储到indexDB
-      objSession.replaceObjects(data.data)
+      if (data && data.data) {
+        commit('setSessionList', data.data)
+        // 存储到indexDB
+        objSession.replaceObjects(data.data)
+      }
     })
   },
   async getUserInfo ({ commit, state, rootState }) {

+ 29 - 11
_src/store/module/group/actions.js

@@ -1,3 +1,4 @@
+import Vue from 'vue'
 import API from '@/api'
 import { getWsUrl } from '@/util/contract.js'
 import WsManager from '@/util/wsManager.js'
@@ -29,7 +30,9 @@ const actions = {
         let membersNum = info.data.data.group.member_num
         let userInfo = info.data.data.userInfo
         let sessionInfo = info.data.data.sessionInfo
-        let isJoin = !!info.data.data.sessionInfo
+        let isJoin = info.data.data.members.some((item) => {
+          return state.userId == item.user_id
+        })
         let eosInfo = info.data.data.eosInfo
         pinMsg && (pinMsg.visible = true)
         let _members = {}
@@ -68,7 +71,7 @@ const actions = {
     let { state } = store
     const objMessage = new Message()
     let data = await objMessage.getMsg(state.groupId)
-    if (data.list.length > 0) {
+    if (data && data.list.length > 0) {
       actions._renderGroupMsg(store, data, params)
     }
 
@@ -127,7 +130,7 @@ const actions = {
     let { state, rootState } = store
     const objMessage = new Message()
     let data = await objMessage.getMsg(rootState.curSession)
-    if (data.list.length > 0) {
+    if (data && data.list.length > 0) {
       actions._renderPrivateMsg(store, data, params)
     }
 
@@ -199,12 +202,10 @@ const actions = {
       dList = JSON.parse(his)
     } else {
       // 本地缓存中没有记录,从接口获取
-      let msg = await API.group
-        .getHistoryMsg({
-          group_id: state.groupId,
-          client_hash: state.startHash
-        })
-        .catch(() => {})
+      let msg = await API.group.getHistoryMsg({
+        group_id: state.groupId,
+        client_hash: state.startHash
+      }).catch(() => {})
 
       if (msg && msg.data.code === 0 && msg.data.data.list.length > 0) {
         // 重新格式数据
@@ -563,6 +564,13 @@ const actions = {
         }
         if (data.type === 'repeal') {
           commit('repealChatItem', data)
+          // 左侧会话
+          rootState.chat.sessionList.forEach((item) => {
+            if (item.session_id == `${data.group_id}`) {
+              Vue.set(item, 'cont', `有人撤回一条消息`)
+              Vue.set(item, 'update_time_int', data.timestamp)
+            }
+          })
         }
         if (data.type === 'block') {
           commit('updateGroupBlockList', {
@@ -622,7 +630,16 @@ const actions = {
           }
         }
         if (data.type === 'repeal') {
-          commit('repealChatItem', data.data)
+          commit('repealChatItem', data)
+          let sessionId = data.from > data.to ? `${data.to}-${data.from}` : `${data.from}-${data.to}`
+
+          // 左侧会话
+          rootState.chat.sessionList.forEach((item) => {
+            if (item.session_id == sessionId) {
+              Vue.set(item, 'cont', `对方撤回一条消息`)
+              Vue.set(item, 'update_time_int', data.timestamp)
+            }
+          })
         }
         // if (data.type === 'new_redpack' && rootGetters.otherUserId == data.from) {
         if (data.type === 'new_redpack') {
@@ -675,7 +692,8 @@ const actions = {
               let obj = {
                 cover_photo: group.cover_photo,
                 is_group: '1',
-                name: group.group_name
+                is_auth: group.is_auth,
+                name: group.group_title
               }
               commit('addSessionItem', Object.assign(obj, baseObj))
             })

+ 4 - 1
_src/store/module/group/mutations.js

@@ -10,6 +10,7 @@ import {
 import _ from 'lodash'
 import Vue from 'vue'
 import Message from '@/store/db/Message.js'
+const objMessage = new Message()
 
 const mutations = {
   initGroup (state, data) {
@@ -184,7 +185,6 @@ const mutations = {
     item.ext[type] = data
     Vue.set(state.chatList, ind, item)
 
-    const objMessage = new Message()
     objMessage.updatePackInfo(item.hash, type, data)
   },
   reSendChatItem (state, data) {
@@ -221,11 +221,14 @@ const mutations = {
     if (pinList.length) {
       removeItemIfEixt(pinList, [data], item => item.hash)
     }
+
+    objMessage.removeMsg(data['session_id'], data.hash)
   },
 
   deleteChatItem (state, hash) {
     let index = state.chatList.findIndex(item => item.hash === hash)
     state.chatList.splice(index, index)
+    // objMessage.removeMsg(data['session_id'], data.hash)
   },
 
   addUnreadNums (state) {

+ 135 - 0
_src/style/mini.scss

@@ -64,6 +64,47 @@ body, html{
     text-decoration: underline;
   }
 }
+
+.pub-pop-toolbar {
+    position: absolute;
+    background: #ffffff;
+    border-radius: 5px;
+    overflow: hidden;
+    box-shadow: 1px 1px 50px rgba(212, 180, 180, 0.3);
+    z-index: 11;
+    width: 60px;
+    user-select: none;
+    text-align: center;
+    &.ext-session{
+      width: 100px;
+      text-align: left;
+      li{
+        padding: 0 10px;
+      }
+    }
+    li {
+      line-height: 36px;
+      font-size: 14px;
+      color: #333333;
+      position: relative;
+      cursor: pointer;
+      &.split-line{
+        &:after {
+        content: "";
+        height: 1px;
+        left: 5px;
+        right: 5px;
+        bottom: 0;
+        position: absolute;
+        background: #dfdfdf;
+      }
+      }
+      &:hover {
+        background: #dfdfdf;
+      }
+    }
+  }
+	
 .avatar_bg0{background:#f5882b}
 .avatar_bg1{background:#cc90e2}
 .avatar_bg2{background:#80d066}
@@ -107,6 +148,100 @@ body, html{
   }
 }
 
+.pub-wrapper{
+  position: fixed;
+  left: 0;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  z-index: 888;
+  text-align: center;
+  &:after{
+    content: "";
+    display: inline-block;
+    height: 100%;
+    width: 0;
+    vertical-align: middle;
+  }
+  .pub-mask{
+    position: fixed;
+    left: 0;
+    top: 0;
+    width: 100%;
+    height: 100%;
+    opacity: .5;
+    background: #000;
+    z-index: 1014;
+  }
+}
+.pub-modal{
+  display: inline-block;
+  vertical-align: middle;
+  background-color: #ffffff;
+  min-width: 330px;
+  position: relative;
+  z-index: 1015;
+  padding: 0 18px 18px;
+  box-sizing: border-box;
+  .modal-hd{
+    .title{
+      font-size: 14px;
+      color: #333333;
+      text-align: center;
+      height: 30px;
+      line-height: 30px;
+      padding-top: 10px;
+    }
+    i{
+      position: absolute;
+      right: 6px;
+      top: 6px;
+      font-size: 20px;
+      cursor: pointer;
+    }
+  }
+}
+
+.pub-pop-toolbar {
+    position: absolute;
+    background: #ffffff;
+    border-radius: 5px;
+    overflow: hidden;
+    box-shadow: 1px 1px 50px rgba(212, 180, 180, 0.3);
+    z-index: 11;
+    width: 60px;
+    user-select: none;
+    text-align: center;
+    &.ext-session{
+      width: 100px;
+      text-align: left;
+      li{
+        padding: 0 10px;
+      }
+    }
+    li {
+      line-height: 36px;
+      font-size: 14px;
+      color: #333333;
+      position: relative;
+      cursor: pointer;
+      &.split-line{
+        &:after {
+        content: "";
+        height: 1px;
+        left: 5px;
+        right: 5px;
+        bottom: 0;
+        position: absolute;
+        background: #dfdfdf;
+      }
+      }
+      &:hover {
+        background: #dfdfdf;
+      }
+    }
+  }
+
 // element-ui
 .el-message {
   min-width: 200px;

+ 5 - 5
_src/util/emoji.js

@@ -314,11 +314,11 @@ const emojiList = {
     { 'names': ['8ball'], 'surrogates': '🎱' },
     { 'names': ['golf'], 'surrogates': '⛳' },
     { 'names': ['golfer'], 'surrogates': '🏌', 'hasDiversity': true },
-    { 'names': ['ping_pong', 'table_tennis'], 'surrogates': '🏓' },
+    { 'names': ['ping_pong'], 'surrogates': '🏓' },
     { 'names': ['badminton'], 'surrogates': '🏸' },
     { 'names': ['hockey'], 'surrogates': '🏒' },
     { 'names': ['field_hockey'], 'surrogates': '🏑' },
-    { 'names': ['cricket', 'cricket_bat_ball'], 'surrogates': '🏏' },
+    { 'names': ['cricket'], 'surrogates': '🏏' },
     { 'names': ['ski'], 'surrogates': '🎿' },
     { 'names': ['skier'], 'surrogates': '⛷', 'hasDiversity': true },
     { 'names': ['snowboarder'], 'surrogates': '🏂', 'hasDiversity': true },
@@ -342,7 +342,7 @@ const emojiList = {
     { 'names': ['reminder_ribbon'], 'surrogates': '🎗' },
     { 'names': ['rosette'], 'surrogates': '🏵' },
     { 'names': ['ticket'], 'surrogates': '🎫' },
-    { 'names': ['tickets', 'admission_tickets'], 'surrogates': '🎟' },
+    { 'names': ['tickets'], 'surrogates': '🎟' },
     { 'names': ['performing_arts'], 'surrogates': '🎭' },
     { 'names': ['art'], 'surrogates': '🎨' },
     { 'names': ['circus_tent'], 'surrogates': '🎪' },
@@ -381,7 +381,7 @@ const emojiList = {
     { 'names': ['blue_car'], 'surrogates': '🚙' },
     { 'names': ['bus'], 'surrogates': '🚌' },
     { 'names': ['trolleybus'], 'surrogates': '🚎' },
-    { 'names': ['race_car', 'racing_car'], 'surrogates': '🏎' },
+    { 'names': ['race_car'], 'surrogates': '🏎' },
     { 'names': ['police_car'], 'surrogates': '🚓' },
     { 'names': ['ambulance'], 'surrogates': '🚑' },
     { 'names': ['fire_engine'], 'surrogates': '🚒' },
@@ -486,7 +486,7 @@ const emojiList = {
     { 'names': ['hearts'], 'surrogates': '♥' },
     { 'names': ['diamonds'], 'surrogates': '♦' },
     { 'names': ['black_heart'], 'surrogates': '🖤' },
-    { 'names': ['octagonal_sign', 'stop_sign'], 'surrogates': '🛑' }
+    { 'names': ['stop_sign'], 'surrogates': '🛑' }
   ]
 }
 

+ 9 - 1
_src/util/util.js

@@ -296,6 +296,8 @@ export function formatLastMsg (lastMsg, isGroup) {
       cont = '[音频]'
     } else if (lastMsg.msg_type == 4) {
       cont = '[红包]'
+    } else {
+      cont = '有人撤回一条消息'
     }
 
     if (isGroup) {
@@ -413,7 +415,7 @@ export var noticeManager = {
     this.askPermission().then(() => {
       let notification = new Notification(data.name, {
         body: '你收到了一条消息',
-        icon: `/dist/icons/meechat.png`
+        icon: `/dist/img/icons/meechat.png`
       })
 
       // 打开页面
@@ -502,3 +504,9 @@ export function formatMsgTime (timeStamp, type = 1) {
       }
   }
 }
+
+export function openPcPage (path) {
+  if (!path) return
+  let pcUrl = [`${location.origin}/`, path].join('#')
+  window.open(pcUrl, 'meechatpc')
+}

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/css/chunk-059c8c86.10b04e6a.css


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/css/chunk-0d1dfdc4.18863327.css


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/css/chunk-0ee422d0.1cd40ba4.css


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/css/chunk-21e00cbc.eed9b4ef.css


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/css/chunk-2d2f7d98.03d9f0bc.css


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/css/chunk-2d2f7d98.11f748be.css


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/css/chunk-4ad29ea1.da62d525.css


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/css/chunk-common.8be1955b.css


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/css/chunk-common.ca1cadb3.css


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/css/chunk-d8ac0884.5734681f.css


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/css/chunk-vendors.2fc48d69.css


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/css/chunk-vendors.a7200cfa.css


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/css/chunk-vendors.e9c8b283.css


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/css/index.03af8c10.css


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/css/index.24b1d028.css


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/css/index.ab4a2586.css


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/css/index.f2e8d51c.css


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/css/mini.49b29b54.css


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/css/mini.5c40c6d3.css


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/css/mini.6beedc15.css


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/chunk-059c8c86.db0e726b.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/chunk-0d1dfdc4.a39b3f9c.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/chunk-0ee422d0.1c400eec.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/chunk-0ee422d0.23fcc03b.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/chunk-14b7d1c9.0b969439.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/chunk-21e00cbc.12f9bf78.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/chunk-2c06dfd2.42bf31dd.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/chunk-2d2f7d98.1497b473.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/chunk-2d2f7d98.321c90a6.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/chunk-2d2f7d98.64a521c7.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/chunk-411abfe3.98a6fbd4.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/chunk-4ad29ea1.0175d519.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/chunk-4ae53135.d7b7a22d.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/chunk-6d98040b.61247f20.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/chunk-6d98040b.b5e27c57.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/chunk-common.01a67a4a.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/chunk-common.2e02adf3.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/chunk-common.31950b99.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/chunk-common.3fbfe6b6.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/chunk-d8ac0884.6feb146d.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/chunk-vendors.e082776c.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/chunk-vendors.f2f92cd6.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/h5.35dd4f02.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/h5.487c3ee2.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/h5.896cd3a0.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/h5.f47e8109.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/index.0f1e1ca2.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/index.0f40e1d0.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/index.62cedca3.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/index.678fe8c4.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/mini.61722891.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/mini.af882c22.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/mini.ca2ac66b.js


+ 0 - 146
dist/precache-manifest.183449aebb9584f63fb0b00ff8c8c8d4.js

@@ -1,146 +0,0 @@
-self.__precacheManifest = [
-  {
-    "revision": "26f05f2621e6d30f145f",
-    "url": "/dist/css/chunk-0d1dfdc4.18863327.css"
-  },
-  {
-    "revision": "26f05f2621e6d30f145f",
-    "url": "/dist/js/chunk-0d1dfdc4.a39b3f9c.js"
-  },
-  {
-    "revision": "ea23d8e511c5ddd8e4b8",
-    "url": "/dist/css/chunk-0ee422d0.0d139ddf.css"
-  },
-  {
-    "revision": "ea23d8e511c5ddd8e4b8",
-    "url": "/dist/js/chunk-0ee422d0.23fcc03b.js"
-  },
-  {
-    "revision": "53f77aa108ebf6fed1d2",
-    "url": "/dist/css/chunk-14b7d1c9.d3bb9736.css"
-  },
-  {
-    "revision": "53f77aa108ebf6fed1d2",
-    "url": "/dist/js/chunk-14b7d1c9.0b969439.js"
-  },
-  {
-    "revision": "8116ae1b1ef4a549effb",
-    "url": "/dist/css/chunk-2c06dfd2.d4c88e50.css"
-  },
-  {
-    "revision": "8116ae1b1ef4a549effb",
-    "url": "/dist/js/chunk-2c06dfd2.2f24cda4.js"
-  },
-  {
-    "revision": "caf6eefcb8e40acde551",
-    "url": "/dist/css/chunk-2d2f7d98.11f748be.css"
-  },
-  {
-    "revision": "caf6eefcb8e40acde551",
-    "url": "/dist/js/chunk-2d2f7d98.321c90a6.js"
-  },
-  {
-    "revision": "6dd0037a4c9e3b411cc4",
-    "url": "/dist/css/chunk-369c7fde.384c55e4.css"
-  },
-  {
-    "revision": "6dd0037a4c9e3b411cc4",
-    "url": "/dist/js/chunk-369c7fde.6979e4fa.js"
-  },
-  {
-    "revision": "a7df56d4f599c1b531f9",
-    "url": "/dist/css/chunk-4ae53135.0dc1cd14.css"
-  },
-  {
-    "revision": "a7df56d4f599c1b531f9",
-    "url": "/dist/js/chunk-4ae53135.cb56044f.js"
-  },
-  {
-    "revision": "14c2c57bebfb472d5149",
-    "url": "/dist/css/chunk-common.8be1955b.css"
-  },
-  {
-    "revision": "14c2c57bebfb472d5149",
-    "url": "/dist/js/chunk-common.2e02adf3.js"
-  },
-  {
-    "revision": "ae7dd4686211972be40d",
-    "url": "/dist/css/chunk-vendors.e9c8b283.css"
-  },
-  {
-    "revision": "ae7dd4686211972be40d",
-    "url": "/dist/js/chunk-vendors.3e86b43c.js"
-  },
-  {
-    "revision": "94fd03fe8b4c0f27d0eb",
-    "url": "/dist/css/h5.b36a6392.css"
-  },
-  {
-    "revision": "94fd03fe8b4c0f27d0eb",
-    "url": "/dist/js/h5.35dd4f02.js"
-  },
-  {
-    "revision": "a90ce782e0c1d20f3732",
-    "url": "/dist/css/index.ab4a2586.css"
-  },
-  {
-    "revision": "a90ce782e0c1d20f3732",
-    "url": "/dist/js/index.0f1e1ca2.js"
-  },
-  {
-    "revision": "ccef2fc4847651fa1ad5",
-    "url": "/dist/css/mini.5c40c6d3.css"
-  },
-  {
-    "revision": "ccef2fc4847651fa1ad5",
-    "url": "/dist/js/mini.ca2ac66b.js"
-  },
-  {
-    "revision": "eb029f3afb0aa1294ffa0cf0ade29412",
-    "url": "/dist/img/bg.eb029f3a.png"
-  },
-  {
-    "revision": "0b28333db188e069d1ff4907da0148c6",
-    "url": "/dist/img/bg2.0b28333d.png"
-  },
-  {
-    "revision": "2fad952a20fbbcfd1bf2ebb210dccf7a",
-    "url": "/dist/fonts/element-icons.2fad952a.woff"
-  },
-  {
-    "revision": "6f0a76321d30f3c8120915e57f7bd77e",
-    "url": "/dist/fonts/element-icons.6f0a7632.ttf"
-  },
-  {
-    "revision": "71de928a26b3ba1fe61c933166c7e5ec",
-    "url": "/dist/img/bg.71de928a.jpg"
-  },
-  {
-    "revision": "c32be0c8ca35b820d913d487747c050f",
-    "url": "/dist/../protected/views/index.html"
-  },
-  {
-    "revision": "6ab519db1373a90dc0d9a5270d059958",
-    "url": "/dist/../protected/views/mini.html"
-  },
-  {
-    "revision": "0e5b272662d0387a30d7e9623b154896",
-    "url": "/dist/../protected/views/h5.html"
-  },
-  {
-    "revision": "4af8e5e7525bc1a78ca5378ec568a0eb",
-    "url": "/dist/h5.html"
-  },
-  {
-    "revision": "6dc2cb834b811f7d3de4fddd33d61ec9",
-    "url": "/dist/mini.html"
-  },
-  {
-    "revision": "b6216d61c03e6ce0c9aea6ca7808f7ca",
-    "url": "/dist/robots.txt"
-  },
-  {
-    "revision": "a060f53ea02ecdd52835d8b5495a1d48",
-    "url": "/dist/sw.js"
-  }
-];

+ 0 - 146
dist/precache-manifest.27fe4966b146ff97450b10c649ad6e97.js

@@ -1,146 +0,0 @@
-self.__precacheManifest = [
-  {
-    "revision": "89ee9bd5e841da5f3ece",
-    "url": "/dist/css/h5.b36a6392.css"
-  },
-  {
-    "revision": "b6216d61c03e6ce0c9aea6ca7808f7ca",
-    "url": "/dist/robots.txt"
-  },
-  {
-    "revision": "a060f53ea02ecdd52835d8b5495a1d48",
-    "url": "/dist/sw.js"
-  },
-  {
-    "revision": "89ee9bd5e841da5f3ece",
-    "url": "/dist/js/h5.487c3ee2.js"
-  },
-  {
-    "revision": "7f8c088eaeedd24eac3f",
-    "url": "/dist/js/chunk-2c06dfd2.42bf31dd.js"
-  },
-  {
-    "revision": "6e637c14c1bb5698e871",
-    "url": "/dist/js/chunk-2d2f7d98.64a521c7.js"
-  },
-  {
-    "revision": "6dc2cb834b811f7d3de4fddd33d61ec9",
-    "url": "/dist/mini.html"
-  },
-  {
-    "revision": "6dd0037a4c9e3b411cc4",
-    "url": "/dist/js/chunk-369c7fde.6979e4fa.js"
-  },
-  {
-    "revision": "84e88db0ef57024a65f6",
-    "url": "/dist/js/mini.61722891.js"
-  },
-  {
-    "revision": "135eec6c040e2cce29e0",
-    "url": "/dist/js/chunk-411abfe3.98a6fbd4.js"
-  },
-  {
-    "revision": "f9449ea07ca86aa97aba",
-    "url": "/dist/js/index.62cedca3.js"
-  },
-  {
-    "revision": "6ef0e07ac4ed0ed7c829",
-    "url": "/dist/js/chunk-4ae53135.d7b7a22d.js"
-  },
-  {
-    "revision": "690a819e868a2e3fc455",
-    "url": "/dist/js/chunk-vendors.f2f92cd6.js"
-  },
-  {
-    "revision": "19e30bd9420250c2a82b",
-    "url": "/dist/js/chunk-6d98040b.b5e27c57.js"
-  },
-  {
-    "revision": "ce0d2e0e8d455c7dd863",
-    "url": "/dist/js/chunk-common.01a67a4a.js"
-  },
-  {
-    "revision": "0b28333db188e069d1ff4907da0148c6",
-    "url": "/dist/img/bg2.0b28333d.png"
-  },
-  {
-    "revision": "ce0d2e0e8d455c7dd863",
-    "url": "/dist/css/chunk-common.52c032e7.css"
-  },
-  {
-    "revision": "4af8e5e7525bc1a78ca5378ec568a0eb",
-    "url": "/dist/h5.html"
-  },
-  {
-    "revision": "a1f0ad70eecfcbd58f9a",
-    "url": "/dist/js/chunk-0ee422d0.1c400eec.js"
-  },
-  {
-    "revision": "71de928a26b3ba1fe61c933166c7e5ec",
-    "url": "/dist/img/bg.71de928a.jpg"
-  },
-  {
-    "revision": "f9449ea07ca86aa97aba",
-    "url": "/dist/css/index.03af8c10.css"
-  },
-  {
-    "revision": "6f0a76321d30f3c8120915e57f7bd77e",
-    "url": "/dist/fonts/element-icons.6f0a7632.ttf"
-  },
-  {
-    "revision": "84e88db0ef57024a65f6",
-    "url": "/dist/css/mini.6beedc15.css"
-  },
-  {
-    "revision": "2fad952a20fbbcfd1bf2ebb210dccf7a",
-    "url": "/dist/fonts/element-icons.2fad952a.woff"
-  },
-  {
-    "revision": "eb029f3afb0aa1294ffa0cf0ade29412",
-    "url": "/dist/img/bg.eb029f3a.png"
-  },
-  {
-    "revision": "690a819e868a2e3fc455",
-    "url": "/dist/css/chunk-vendors.2fc48d69.css"
-  },
-  {
-    "revision": "19e30bd9420250c2a82b",
-    "url": "/dist/css/chunk-6d98040b.f3f84f3d.css"
-  },
-  {
-    "revision": "6ef0e07ac4ed0ed7c829",
-    "url": "/dist/css/chunk-4ae53135.0dc1cd14.css"
-  },
-  {
-    "revision": "135eec6c040e2cce29e0",
-    "url": "/dist/css/chunk-411abfe3.8bd5766c.css"
-  },
-  {
-    "revision": "6dd0037a4c9e3b411cc4",
-    "url": "/dist/css/chunk-369c7fde.384c55e4.css"
-  },
-  {
-    "revision": "6e637c14c1bb5698e871",
-    "url": "/dist/css/chunk-2d2f7d98.03d9f0bc.css"
-  },
-  {
-    "revision": "7f8c088eaeedd24eac3f",
-    "url": "/dist/css/chunk-2c06dfd2.d4c88e50.css"
-  },
-  {
-    "revision": "a1f0ad70eecfcbd58f9a",
-    "url": "/dist/css/chunk-0ee422d0.1cd40ba4.css"
-  },
-  {
-    "revision": "02836413fd8e2b24e15fe53d24ddcdba",
-    "url": "/dist/../protected/views/mini.html"
-  },
-  {
-    "revision": "66c038fd6c1f716260b0c9ed9f87c76a",
-    "url": "/dist/../protected/views/index.html"
-  },
-  {
-    "revision": "7dd2f13de4083a66aa651ff7cd022753",
-    "url": "/dist/../protected/views/h5.html"
-  }
-];

+ 0 - 146
dist/precache-manifest.877feee0d916f2c57faa670055e68a03.js

@@ -1,146 +0,0 @@
-self.__precacheManifest = [
-  {
-    "revision": "084153b8dc73eb5098d9",
-    "url": "/dist/css/h5.b36a6392.css"
-  },
-  {
-    "revision": "a060f53ea02ecdd52835d8b5495a1d48",
-    "url": "/dist/sw.js"
-  },
-  {
-    "revision": "084153b8dc73eb5098d9",
-    "url": "/dist/js/h5.f47e8109.js"
-  },
-  {
-    "revision": "7f8c088eaeedd24eac3f",
-    "url": "/dist/css/chunk-2c06dfd2.d4c88e50.css"
-  },
-  {
-    "revision": "9bffc826b8a8226c537e",
-    "url": "/dist/css/chunk-2d2f7d98.03d9f0bc.css"
-  },
-  {
-    "revision": "9bffc826b8a8226c537e",
-    "url": "/dist/js/chunk-2d2f7d98.1497b473.js"
-  },
-  {
-    "revision": "6dd0037a4c9e3b411cc4",
-    "url": "/dist/css/chunk-369c7fde.384c55e4.css"
-  },
-  {
-    "revision": "6dd0037a4c9e3b411cc4",
-    "url": "/dist/js/chunk-369c7fde.6979e4fa.js"
-  },
-  {
-    "revision": "6ef0e07ac4ed0ed7c829",
-    "url": "/dist/css/chunk-4ae53135.0dc1cd14.css"
-  },
-  {
-    "revision": "6ef0e07ac4ed0ed7c829",
-    "url": "/dist/js/chunk-4ae53135.d7b7a22d.js"
-  },
-  {
-    "revision": "19e30bd9420250c2a82b",
-    "url": "/dist/css/chunk-6d98040b.f3f84f3d.css"
-  },
-  {
-    "revision": "19e30bd9420250c2a82b",
-    "url": "/dist/js/chunk-6d98040b.b5e27c57.js"
-  },
-  {
-    "revision": "8e57fdae7d5895cb5460",
-    "url": "/dist/css/chunk-7e7394b2.5e600808.css"
-  },
-  {
-    "revision": "8e57fdae7d5895cb5460",
-    "url": "/dist/js/chunk-7e7394b2.fb8b2bd8.js"
-  },
-  {
-    "revision": "1993f1dbee5123efd407",
-    "url": "/dist/css/chunk-common.52c032e7.css"
-  },
-  {
-    "revision": "1993f1dbee5123efd407",
-    "url": "/dist/js/chunk-common.31950b99.js"
-  },
-  {
-    "revision": "690a819e868a2e3fc455",
-    "url": "/dist/css/chunk-vendors.2fc48d69.css"
-  },
-  {
-    "revision": "690a819e868a2e3fc455",
-    "url": "/dist/js/chunk-vendors.f2f92cd6.js"
-  },
-  {
-    "revision": "7e58fc4e801db8aaaf0e",
-    "url": "/dist/js/chunk-059c8c86.db0e726b.js"
-  },
-  {
-    "revision": "7f8c088eaeedd24eac3f",
-    "url": "/dist/js/chunk-2c06dfd2.42bf31dd.js"
-  },
-  {
-    "revision": "e4070feff7d1db425b39",
-    "url": "/dist/css/index.f2e8d51c.css"
-  },
-  {
-    "revision": "e4070feff7d1db425b39",
-    "url": "/dist/js/index.0f40e1d0.js"
-  },
-  {
-    "revision": "84e88db0ef57024a65f6",
-    "url": "/dist/css/mini.6beedc15.css"
-  },
-  {
-    "revision": "84e88db0ef57024a65f6",
-    "url": "/dist/js/mini.61722891.js"
-  },
-  {
-    "revision": "eb029f3afb0aa1294ffa0cf0ade29412",
-    "url": "/dist/img/bg.eb029f3a.png"
-  },
-  {
-    "revision": "0b28333db188e069d1ff4907da0148c6",
-    "url": "/dist/img/bg2.0b28333d.png"
-  },
-  {
-    "revision": "2fad952a20fbbcfd1bf2ebb210dccf7a",
-    "url": "/dist/fonts/element-icons.2fad952a.woff"
-  },
-  {
-    "revision": "6f0a76321d30f3c8120915e57f7bd77e",
-    "url": "/dist/fonts/element-icons.6f0a7632.ttf"
-  },
-  {
-    "revision": "71de928a26b3ba1fe61c933166c7e5ec",
-    "url": "/dist/img/bg.71de928a.jpg"
-  },
-  {
-    "revision": "b6216d61c03e6ce0c9aea6ca7808f7ca",
-    "url": "/dist/robots.txt"
-  },
-  {
-    "revision": "6dc2cb834b811f7d3de4fddd33d61ec9",
-    "url": "/dist/mini.html"
-  },
-  {
-    "revision": "4af8e5e7525bc1a78ca5378ec568a0eb",
-    "url": "/dist/h5.html"
-  },
-  {
-    "revision": "7e58fc4e801db8aaaf0e",
-    "url": "/dist/css/chunk-059c8c86.10b04e6a.css"
-  },
-  {
-    "revision": "ed25b7e502cda0f996c1d72d3524f510",
-    "url": "/dist/../protected/views/mini.html"
-  },
-  {
-    "revision": "ed33a3c7d3afdb8103595eb3617c24ab",
-    "url": "/dist/../protected/views/index.html"
-  },
-  {
-    "revision": "9ea77207c15f9f767dcfb93d661c966a",
-    "url": "/dist/../protected/views/h5.html"
-  }
-];

+ 146 - 0
dist/precache-manifest.d48a5fbfeb55aa8e8d2a19d2650a7202.js

@@ -0,0 +1,146 @@
+self.__precacheManifest = [
+  {
+    "revision": "9059e7d98564b878353a",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/css/chunk-21e00cbc.eed9b4ef.css"
+  },
+  {
+    "revision": "9059e7d98564b878353a",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/js/chunk-21e00cbc.12f9bf78.js"
+  },
+  {
+    "revision": "8116ae1b1ef4a549effb",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/css/chunk-2c06dfd2.d4c88e50.css"
+  },
+  {
+    "revision": "8116ae1b1ef4a549effb",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/js/chunk-2c06dfd2.2f24cda4.js"
+  },
+  {
+    "revision": "6dd0037a4c9e3b411cc4",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/css/chunk-369c7fde.384c55e4.css"
+  },
+  {
+    "revision": "6dd0037a4c9e3b411cc4",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/js/chunk-369c7fde.6979e4fa.js"
+  },
+  {
+    "revision": "cf81aab30483caa1baa9",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/css/chunk-4ad29ea1.da62d525.css"
+  },
+  {
+    "revision": "cf81aab30483caa1baa9",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/js/chunk-4ad29ea1.0175d519.js"
+  },
+  {
+    "revision": "a7df56d4f599c1b531f9",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/css/chunk-4ae53135.0dc1cd14.css"
+  },
+  {
+    "revision": "a7df56d4f599c1b531f9",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/js/chunk-4ae53135.cb56044f.js"
+  },
+  {
+    "revision": "0f13c095b4c9c2df7ecc",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/css/chunk-6d98040b.f3f84f3d.css"
+  },
+  {
+    "revision": "0f13c095b4c9c2df7ecc",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/js/chunk-6d98040b.61247f20.js"
+  },
+  {
+    "revision": "abab088309a64d9ae13c",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/css/chunk-common.ca1cadb3.css"
+  },
+  {
+    "revision": "abab088309a64d9ae13c",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/js/chunk-common.3fbfe6b6.js"
+  },
+  {
+    "revision": "b9920eb626f113600a13",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/css/chunk-d8ac0884.5734681f.css"
+  },
+  {
+    "revision": "b9920eb626f113600a13",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/js/chunk-d8ac0884.6feb146d.js"
+  },
+  {
+    "revision": "c16342ded396715666ea",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/css/chunk-vendors.a7200cfa.css"
+  },
+  {
+    "revision": "c16342ded396715666ea",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/js/chunk-vendors.e082776c.js"
+  },
+  {
+    "revision": "ccba56418dfaac194a26",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/css/h5.b36a6392.css"
+  },
+  {
+    "revision": "ccba56418dfaac194a26",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/js/h5.896cd3a0.js"
+  },
+  {
+    "revision": "57ceda2754865a0b8949",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/css/index.24b1d028.css"
+  },
+  {
+    "revision": "57ceda2754865a0b8949",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/js/index.678fe8c4.js"
+  },
+  {
+    "revision": "749b3babdfe4f3525684",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/css/mini.49b29b54.css"
+  },
+  {
+    "revision": "749b3babdfe4f3525684",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/js/mini.af882c22.js"
+  },
+  {
+    "revision": "eb029f3afb0aa1294ffa0cf0ade29412",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/img/bg.eb029f3a.png"
+  },
+  {
+    "revision": "0b28333db188e069d1ff4907da0148c6",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/img/bg2.0b28333d.png"
+  },
+  {
+    "revision": "2fad952a20fbbcfd1bf2ebb210dccf7a",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/fonts/element-icons.2fad952a.woff"
+  },
+  {
+    "revision": "6f0a76321d30f3c8120915e57f7bd77e",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/fonts/element-icons.6f0a7632.ttf"
+  },
+  {
+    "revision": "71de928a26b3ba1fe61c933166c7e5ec",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/img/bg.71de928a.jpg"
+  },
+  {
+    "revision": "151a0f52d46a6dccaa30e1069bbbe077",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/../protected/views/index.html"
+  },
+  {
+    "revision": "a94154309b016c5465ced84f77529c11",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/../protected/views/mini.html"
+  },
+  {
+    "revision": "16b65bf1203d4139de0e620885e40f11",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/../protected/views/h5.html"
+  },
+  {
+    "revision": "4af8e5e7525bc1a78ca5378ec568a0eb",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/h5.html"
+  },
+  {
+    "revision": "6dc2cb834b811f7d3de4fddd33d61ec9",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/mini.html"
+  },
+  {
+    "revision": "b6216d61c03e6ce0c9aea6ca7808f7ca",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/robots.txt"
+  },
+  {
+    "revision": "a060f53ea02ecdd52835d8b5495a1d48",
+    "url": "//static.meechat.me/cdn/new.mee.chat/dist/sw.js"
+  }
+];

+ 1 - 1
dist/sw.js

@@ -1,4 +1,4 @@
-importScripts("/dist/precache-manifest.27fe4966b146ff97450b10c649ad6e97.js");
+importScripts("//static.meechat.me/cdn/new.mee.chat/dist/precache-manifest.d48a5fbfeb55aa8e8d2a19d2650a7202.js");
 
 
 var workbox=function(){"use strict";try{self.workbox.v["workbox:sw:3.6.3"]=1}catch(t){}const t="https://storage.googleapis.com/workbox-cdn/releases/3.6.3",e={backgroundSync:"background-sync",broadcastUpdate:"broadcast-cache-update",cacheableResponse:"cacheable-response",core:"core",expiration:"cache-expiration",googleAnalytics:"google-analytics",navigationPreload:"navigation-preload",precaching:"precaching",rangeRequests:"range-requests",routing:"routing",strategies:"strategies",streams:"streams"};return new class{constructor(){return this.v={},this.t={debug:"localhost"===self.location.hostname,modulePathPrefix:null,modulePathCb:null},this.e=this.t.debug?"dev":"prod",this.s=!1,new Proxy(this,{get(t,s){if(t[s])return t[s];const o=e[s];return o&&t.loadModule(`workbox-${o}`),t[s]}})}setConfig(t={}){if(this.s)throw new Error("Config must be set before accessing workbox.* modules");Object.assign(this.t,t),this.e=this.t.debug?"dev":"prod"}skipWaiting(){self.addEventListener("install",()=>self.skipWaiting())}clientsClaim(){self.addEventListener("activate",()=>self.clients.claim())}loadModule(t){const e=this.o(t);try{importScripts(e),this.s=!0}catch(s){throw console.error(`Unable to import module '${t}' from '${e}'.`),s}}o(e){if(this.t.modulePathCb)return this.t.modulePathCb(e,this.t.debug);let s=[t];const o=`${e}.${this.e}.js`,r=this.t.modulePathPrefix;return r&&""===(s=r.split("/"))[s.length-1]&&s.splice(s.length-1,1),s.push(o),s.join("/")}}}();

+ 28 - 0
protected/bin/once/fixGroupMemberNum.php

@@ -0,0 +1,28 @@
+<?php
+/**
+ * 修复群人数
+ * User: solu
+ * Date: 2019/2/27
+ */
+
+ini_set("display_errors", "On");
+set_time_limit(0);
+error_reporting(E_ALL & ~E_NOTICE);
+require_once realpath(dirname(__FILE__)) . '/../common.php';
+
+$st = microtime(true);
+$objGroup = new GroupInfo();
+$objUserGroup = new UserGroup();
+
+$groups = $objUserGroup->objTable->getAll([
+    '_field' => 'group_id, count(user_id) as c',
+    '_groupby' => 'group_id',
+]);
+
+foreach ($groups as $g) {
+    $objGroup->objTable->updateObject(['member_num' => $g['c']], ['group_id' => $g['group_id']]);
+}
+
+$c = count($groups);
+$t = microtime(true) - $st;
+var_dump("处理{$c},耗时{$t}");

+ 1 - 1
protected/conf/config.dev.inc.php

@@ -37,5 +37,5 @@ define('MESSAGING_PRIVATE_KEY', 'u6CKkk1-8dnejuOs7twd65KDCgVTz2BQt1pDIsW-Rjc');
 define('MESSAGING_PUBLIC_KEY', 'BAEJLGwWlflC8M1aN2Xj2GEwNp5_2Lv_-yjm29XVT93nbgdZkSH4pqDYKx60wjt0oyUg1Fw_LlEfs3i3-Lgi2yw');
 
 define('URL_SELF', '//test.mee.chat');
-
+define('CHAT_SERVER_ID', 1);
 //end of script

+ 1 - 0
protected/conf/config.form.inc.php

@@ -33,5 +33,6 @@ define('MESSAGING_PRIVATE_KEY', 'VaWG-r7hYLlWApB3vwGj0Pp4KhzVx5NibCVWSiOjm8A');
 define('MESSAGING_PUBLIC_KEY', 'BNan2ZkZRV6skCmS9rAJx5jb0eZgjo1-hmil3ZkhJs20yDOpBpEFaV9p1mag6KfBItZdzCT9-8pt15GSIIGV5DE');
 
 define('URL_SELF', '//mee.chat');
+define('CHAT_SERVER_ID', 10000);
 //end of script
 

+ 2 - 0
protected/conf/config.inc.php

@@ -29,6 +29,8 @@ $GLOBALS['rewrite'] = array(
     'robots.txt' => 'default/robots',
     'sw.js' => 'default/sw',
     'mini.html' => 'default/mini',
+    'h5.html' => 'default/h5',
+    'manifest_<type>.json' => 'default/manifest',
     's/<group_name>' => 'default/share',
 );
 

+ 1 - 0
protected/conf/config.new.inc.php

@@ -33,4 +33,5 @@ define('MESSAGING_PRIVATE_KEY', 'VaWG-r7hYLlWApB3vwGj0Pp4KhzVx5NibCVWSiOjm8A');
 define('MESSAGING_PUBLIC_KEY', 'BNan2ZkZRV6skCmS9rAJx5jb0eZgjo1-hmil3ZkhJs20yDOpBpEFaV9p1mag6KfBItZdzCT9-8pt15GSIIGV5DE');
 
 define('URL_SELF', '//new.mee.chat');
+define('CHAT_SERVER_ID', 10000);
 //end of script

+ 43 - 25
protected/controllers/DefaultController.php

@@ -10,34 +10,49 @@ class DefaultController extends BaseController {
         parent::__construct(true);
     }
 
-    const SERVER_ID = 1; // 客服id
 
     /**
      * 判断ip,输出首页
      */
     public function actionIndex() {
-//        if (ENV != ENV_DEV) {
-//            header('Location: https://dice.eosget.io/#/box');
-//            Response::exitMsg('');
-//        } else {
-//            // 清除无效的cookie
-//            Account::checkToken();
-//
-//            if (ENV != ENV_DEV) {
-//                $GLOBALS['eosProtocol'] = "https";
-//                $GLOBALS['eosHost'] = "api.eosbeijing.one";
-//                $GLOBALS['eosPort'] = 443;
-//            }
-
-            $this->tpl->display('index');
-//        }
+        $html = $this->tpl->fetch('index');
+        $html = str_replace('/dist/manifest.json', URL_SELF . '/manifest_pc.json', $html);
+
+        Response::exitMsg($html, CODE_SUCCESS, '', true);
     }
 
     /**
      * 判断ip,输出首页
      */
     public function actionMini() {
-        $this->tpl->display('mini');
+        $html = $this->tpl->fetch('mini');
+        $html = str_replace('<link rel=manifest ', '<link ', $html);
+
+        Response::exitMsg($html, CODE_SUCCESS, '', true);
+    }
+
+    public function actionH5() {
+        $html = $this->tpl->fetch('h5');
+        $html = str_replace('/dist/manifest.json', URL_SELF . '/manifest_h5.json', $html);
+
+        Response::exitMsg($html, CODE_SUCCESS, '', true);
+    }
+
+    public function actionManifest($args) {
+        if ($args['type'] == 'pc') {
+            $startUrl = '/?pwa=1';
+        } else {
+            $startUrl = '/h5.html?pwa=1';
+        }
+
+        $this->tpl->assign(compact('startUrl'));
+        $this->tpl->postfix = '.json';
+
+        // 不需要默认头部信息
+        $GLOBALS['FORBID_ORIGIN'] = true;
+        header("Content-Type: application/json; charset=utf-8");
+
+        $this->tpl->display('manifest', CODE_SUCCESS, '', true);
     }
 
     /**
@@ -108,16 +123,19 @@ class DefaultController extends BaseController {
             Response::error(CODE_NO_PERMITION);
         }
 
-        $serverId = self::SERVER_ID; // 客服id
+        $serverId = CHAT_SERVER_ID; // 客服id
         $msg =<<<MSG
 欢迎申请群组认证,您需要提供如下信息:
-1. 项目地址(如:https://dice.eosget.io)
-2. 代币合约名(如:eosio.token)
-3. 代币名(如:EOS)
-4. Vip合约名(如:eosgetadmin1)
-5. Vip表名(如:vip)
+1. 项目地址(如:https://vsbet.io/)
+2. 代币合约名(如:vsvscontract)
+3. 代币名(如:VS)
+-------以下内容为可选提供----------
+4. Vip合约名(如:vsvsvsvipvip)
+5. Vip表名(如:t.player)
 6. 等级字段名(如:vip_level)
-7. 投注额字段名(如:total_bet_amount)
+7. 投注额字段名(如:total_energy)
+
+4~7选项,用于后续在聊天内显示用户vip等功能。
 MSG;
 
         $msg = Utils::encodeRC4($msg);
@@ -141,7 +159,7 @@ MSG;
         Param::checkParam2($rules, $args);
 
         $userId = User::getUserId();
-        $serverId = self::SERVER_ID; // 客服id
+        $serverId = CHAT_SERVER_ID; // 客服id
         $msg =<<<MSG
 Hi,请问您遇到了什么问题?
 MSG;

+ 15 - 3
protected/controllers/GroupController.php

@@ -42,6 +42,8 @@ class GroupController extends BaseController {
         ];
         Param::checkParam2($rules, $args);
 
+        $user_id = User::getUserId();
+
         $objGroupInfo = new GroupInfo();
         $_field = 'group_id, group_name, group_title, group_notice, cover_photo, member_num, creator';
         $group = $objGroupInfo->objTable->getRow($args, compact('_field'));
@@ -56,6 +58,15 @@ class GroupController extends BaseController {
         $blockList = [];
         $adminList = [];
 
+        // 把自己加进去
+        if (!in_array($user_id, array_keys($joinMap))) {
+            $_row = $objUserGroup->objTable->getRow(['user_id' => $user_id, 'group_id' => $args['group_id'], 'state' => 1], ['_field' => $_field]);
+            if ($_row) {
+                $groupUsers[] = $_row;
+                $joinMap[$user_id] = $_row['join_time'];
+            }
+        }
+
         foreach ($groupUsers as $_u) {
             $_uid = intval($_u['user_id']);
             $user_ids[] = $_uid;
@@ -120,7 +131,6 @@ class GroupController extends BaseController {
             $members = array_values($members);
         }
 
-        $user_id = User::getUserId();
         $sessionInfo = null;
         if ($user_id) {
             $objSession = new Session();
@@ -450,7 +460,8 @@ class GroupController extends BaseController {
         }
 
         $args['creator'] = User::getUserId();
-        $args['member_num'] = 0;
+        $memberNum = 0;
+        $args['member_num'] = $memberNum;
         $args['create_time'] = $args['update_time'] = NOW;
         $objGroupInfo->objTable->addObject($args);
         $group_id = $objGroupInfo->objTable->getInsertId();
@@ -460,6 +471,7 @@ class GroupController extends BaseController {
 
         // 默认加群
         $this->actionJoin(compact('group_id'));
+        $memberNum++;
 
         // 设置为管理员
         $objUserGroup = new UserGroup();
@@ -471,7 +483,7 @@ class GroupController extends BaseController {
 
         $friend_ids = $this->_getFriendList($creator, $user_id_list);
         if ($friend_ids) {
-            $objGroupInfo->appendToGroup($friend_ids, $group_id);
+            $objGroupInfo->appendToGroup($friend_ids, $group_id, $memberNum);
         }
 
         $objSession = new Session();

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů