GroupConversationInfoPage.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. <template>
  2. <div class="conversation-info" v-if="conversationInfo">
  3. <header>
  4. <label>
  5. {{ $t('conversation.group_name') }}
  6. <input type="text"
  7. ref="groupNameInput"
  8. :disabled="!enableEditGroupNameOrAnnouncement"
  9. v-model="newGroupName"
  10. @confirm="updateGroupName"
  11. :placeholder="conversationInfo.conversation._target._displayName">
  12. </label>
  13. <label>
  14. {{ $t('conversation.group_announcement') }}
  15. <input type="text"
  16. ref="groupAnnouncementInput"
  17. :disabled="!enableEditGroupNameOrAnnouncement"
  18. @confirm='updateGroupAnnouncement'
  19. v-model="newGroupAnnouncement"
  20. :placeholder="groupAnnouncement">
  21. </label>
  22. <label class="switch">
  23. 保存到通讯录
  24. <checkbox-group @change="setFavGroup(conversationInfo.conversation.target, $event.target.value.length === 1)">
  25. <checkbox
  26. value="fav"
  27. :checked="conversationInfo.conversation._target._isFav"
  28. />
  29. </checkbox-group>
  30. <span class="slider"></span>
  31. </label>
  32. </header>
  33. <div class="search-item">
  34. <input type="text" v-model="filterQuery" :placeholder="$t('common.search')">
  35. <i class="icon-ion-ios-search"></i>
  36. </div>
  37. <div class="member-container">
  38. <div v-if="enableAddGroupMember && !filterQuery" @click="showCreateConversationModal" class="action-item">
  39. <div class="icon">+</div>
  40. <p>{{ $t('conversation.add_member') }}</p>
  41. </div>
  42. <div v-if="enableRemoveGroupMember && !filterQuery" @click="showRemoveGroupMemberModal" class="action-item">
  43. <div class="icon">-</div>
  44. <p>{{ $t('conversation.remove_member') }}</p>
  45. </div>
  46. <UserListVue :users="users"
  47. :show-category-label="false"
  48. :padding-left="'20px'"
  49. />
  50. </div>
  51. <div @click="quitGroup" class="quit-group-item">
  52. {{ $t('conversation.quit_group') }}
  53. </div>
  54. </div>
  55. </template>
  56. <script>
  57. import UserListVue from "@/pages/user/UserListVue";
  58. import ConversationInfo from "@/wfc/model/conversationInfo";
  59. import store from "@/store";
  60. import wfc from "@/wfc/client/wfc";
  61. // import axios from "axios";
  62. import GroupMemberType from "@/wfc/model/groupMemberType";
  63. import GroupType from "@/wfc/model/groupType";
  64. import ModifyGroupInfoType from "@/wfc/model/modifyGroupInfoType";
  65. import Config from "../../config";
  66. import EventType from "../../wfc/client/wfcEvent";
  67. import appServerApi from "../../api/appServerApi";
  68. export default {
  69. name: "GroupConversationInfoPage",
  70. props: {
  71. conversationInfo: {
  72. type: ConversationInfo,
  73. required: false,
  74. }
  75. },
  76. data() {
  77. return {
  78. groupMemberUserInfos: null,
  79. filterQuery: '',
  80. sharedContactState: store.state.contact,
  81. groupAnnouncement: '',
  82. newGroupName: '',
  83. newGroupAnnouncement: '',
  84. }
  85. },
  86. onLoad(option) {
  87. console.log('GroupConversationInfoPage onLoad')
  88. // #ifdef APP-NVUE
  89. const eventChannel = this.$scope.eventChannel; // 兼容APP-NVUE
  90. // #endif
  91. // #ifndef APP-NVUE
  92. const eventChannel = this.getOpenerEventChannel();
  93. // #endif
  94. eventChannel.on('conversationInfo', (options) => {
  95. this.conversationInfo = options.conversationInfo;
  96. this.groupMemberUserInfos = store.getConversationMemberUsrInfos(this.conversationInfo.conversation);
  97. uni.setNavigationBarTitle({
  98. title: this.conversationInfo.conversation._target._displayName,
  99. });
  100. this.getGroupAnnouncement();
  101. })
  102. },
  103. mounted() {
  104. wfc.eventEmitter.on(EventType.UserInfosUpdate, this.onConversationMembersUpdate)
  105. wfc.eventEmitter.on(EventType.GroupMembersUpdate, this.onConversationMembersUpdate)
  106. },
  107. beforeDestroy() {
  108. wfc.eventEmitter.removeListener(EventType.UserInfosUpdate, this.onConversationMembersUpdate)
  109. wfc.eventEmitter.removeListener(EventType.GroupMembersUpdate, this.onConversationMembersUpdate)
  110. },
  111. methods: {
  112. onConversationMembersUpdate() {
  113. this.groupMemberUserInfos = store.getConversationMemberUsrInfos(this.conversationInfo.conversation);
  114. },
  115. showCreateConversationModal() {
  116. let beforeClose = (users) => {
  117. let ids = users.map(u => u.uid);
  118. wfc.addGroupMembers(this.conversationInfo.conversation.target, ids, null, [0], null, () => {
  119. this.groupMemberUserInfos = store.getConversationMemberUsrInfos(this.conversationInfo.conversation);
  120. }, err => {
  121. uni.showToast({
  122. title: '邀请新成员失败 ' + err,
  123. });
  124. })
  125. };
  126. let groupMemberUserInfos = store.getGroupMemberUserInfos(this.conversationInfo.conversation.target, false);
  127. this.$pickUser(
  128. {
  129. users: this.sharedContactState.favContactList.concat(this.sharedContactState.friendList),
  130. initialCheckedUsers: groupMemberUserInfos,
  131. uncheckableUsers: groupMemberUserInfos,
  132. confirmTitle: this.$t('common.add'),
  133. successCB: beforeClose,
  134. })
  135. },
  136. showRemoveGroupMemberModal() {
  137. let beforeClose = (users) => {
  138. let ids = users.map(u => u.uid);
  139. wfc.kickoffGroupMembers(this.conversationInfo.conversation.target, ids, [0], null, () => {
  140. this.groupMemberUserInfos = store.getConversationMemberUsrInfos(this.conversationInfo.conversation);
  141. }, err => {
  142. uni.showToast({
  143. title: '踢除群成员失败' + err,
  144. });
  145. })
  146. }
  147. let groupMemberUserInfos = store.getGroupMemberUserInfos(this.conversationInfo.conversation.target, false, false);
  148. this.$pickUser(
  149. {
  150. users: groupMemberUserInfos,
  151. confirmTitle: this.$t('common.remove'),
  152. showCategoryLabel: false,
  153. successCB: beforeClose,
  154. })
  155. },
  156. showUserInfo(user) {
  157. console.log('todo show userInfo', user);
  158. },
  159. async getGroupAnnouncement() {
  160. let url = Config.APP_SERVER + '/get_group_announcement';
  161. console.log('to getGroupAnnouncement', url, this.conversationInfo.conversation.target)
  162. appServerApi.getGroupAnnouncement(this.conversationInfo.conversation.target)
  163. .then(result => {
  164. if (result.text) {
  165. this.groupAnnouncement = result.text;
  166. } else {
  167. if (this.enableEditGroupNameOrAnnouncement) {
  168. this.groupAnnouncement = this.$t('conversation.click_to_edit_group_announcement');
  169. }
  170. }
  171. })
  172. },
  173. updateGroupName() {
  174. let groupId = this.conversationInfo.conversation.target;
  175. if (!this.newGroupName || this.newGroupName === this.conversationInfo.conversation._target._displayName) {
  176. return;
  177. }
  178. wfc.modifyGroupInfo(groupId, ModifyGroupInfoType.Modify_Group_Name, this.newGroupName, [0], null, () => {
  179. this.conversationInfo.conversation._target._displayName = this.newGroupName;
  180. uni.setNavigationBarTitle({
  181. title: this.conversationInfo.conversation._target._displayName,
  182. });
  183. }, (err) => {
  184. // do nothing
  185. console.log('err', err)
  186. })
  187. },
  188. async updateGroupAnnouncement() {
  189. if (!this.newGroupAnnouncement || this.newGroupAnnouncement === this.groupAnnouncement) {
  190. return;
  191. }
  192. console.log('updateGroupAnnouncement')
  193. appServerApi.updateGroupAnnouncement(wfc.getUserId(), this.conversationInfo.conversation.target, this.newGroupAnnouncement)
  194. .then(result => {
  195. this.groupAnnouncement = this.newGroupAnnouncement;
  196. })
  197. },
  198. quitGroup() {
  199. let groupInfo = this.conversationInfo.conversation._target;
  200. if (groupInfo.owner === store.state.contact.selfUserInfo.uid) {
  201. store.quitGroup(this.conversationInfo.conversation.target)
  202. } else {
  203. store.quitGroup(this.conversationInfo.conversation.target)
  204. }
  205. uni.switchTab({
  206. url: '/pages/conversationList/ConversationListPage',
  207. success: () => {
  208. console.log('to conversation list success');
  209. },
  210. fail: e => {
  211. console.log('to conversation list error', e);
  212. },
  213. complete: () => {
  214. console.log('switch tab complete')
  215. }
  216. });
  217. },
  218. setFavGroup(groupId, fav) {
  219. console.log('setFavGroup', groupId, fav)
  220. wfc.setFavGroup(groupId, fav, () => {
  221. this.conversationInfo.conversation._target._isFav = fav;
  222. store.reloadFavGroupList();
  223. }, (err) => {
  224. console.log('setFavGroup error', err);
  225. })
  226. }
  227. },
  228. components: {UserListVue},
  229. created() {
  230. // 这个时候,this.conversationInfo 还没数据
  231. // this.getGroupAnnouncement();
  232. },
  233. computed: {
  234. enableAddGroupMember() {
  235. let selfUid = wfc.getUserId();
  236. let groupInfo = this.conversationInfo.conversation._target;
  237. //在group type为Restricted时,0 开放加入权限(群成员可以拉人,用户也可以主动加入);1 只能群成员拉人入群;2 只能群管理拉人入群
  238. if (groupInfo.type === GroupType.Restricted) {
  239. if (groupInfo.joinType === 0 || groupInfo.joinType === 1) {
  240. return true;
  241. } else if (groupInfo.joinType === 2) {
  242. let groupMember = wfc.getGroupMember(this.conversationInfo.conversation.target, selfUid);
  243. return [GroupMemberType.Manager, GroupMemberType.Owner].indexOf(groupMember.type) >= 0;
  244. }
  245. }
  246. return true;
  247. },
  248. enableRemoveGroupMember() {
  249. let selfUid = wfc.getUserId();
  250. let groupMember = wfc.getGroupMember(this.conversationInfo.conversation.target, selfUid);
  251. let t = false;
  252. if (groupMember) {
  253. t = [GroupMemberType.Manager, GroupMemberType.Owner].indexOf(groupMember.type) >= 0;
  254. }
  255. return t;
  256. },
  257. enableEditGroupNameOrAnnouncement() {
  258. let selfUid = wfc.getUserId();
  259. let groupMember = wfc.getGroupMember(this.conversationInfo.conversation.target, selfUid);
  260. if (groupMember) {
  261. return [GroupMemberType.Manager, GroupMemberType.Owner].indexOf(groupMember.type) >= 0;
  262. }
  263. return false;
  264. },
  265. users() {
  266. if (this.filterQuery) {
  267. return store.filterUsers(this.groupMemberUserInfos, this.filterQuery)
  268. } else {
  269. return this.groupMemberUserInfos;
  270. }
  271. }
  272. },
  273. };
  274. </script>
  275. <style lang="css" scoped>
  276. .conversation-info {
  277. display: flex;
  278. flex-direction: column;
  279. position: relative;
  280. justify-content: flex-start;
  281. height: 100%;
  282. overflow: hidden;
  283. }
  284. header {
  285. padding-left: 20px;
  286. padding-right: 20px;
  287. display: flex;
  288. flex-direction: column;
  289. justify-content: center;
  290. align-items: center;
  291. }
  292. header label {
  293. width: 100%;
  294. display: flex;
  295. margin-top: 15px;
  296. flex-direction: column;
  297. justify-content: center;
  298. align-items: flex-start;
  299. font-size: 14px;
  300. color: #999999;
  301. }
  302. header label:last-of-type {
  303. padding-bottom: 15px;
  304. border-bottom: 1px solid #ececec;
  305. }
  306. header label input {
  307. flex: 1;
  308. margin-top: 5px;
  309. border: none;
  310. outline: none;
  311. width: 100%;
  312. font-size: 13px;
  313. background-color: transparent;
  314. }
  315. .member-container {
  316. flex: 1;
  317. overflow: auto;
  318. }
  319. .search-item {
  320. position: relative;
  321. padding: 10px 20px;
  322. }
  323. .search-item input {
  324. width: 100%;
  325. padding: 0 10px 0 20px;
  326. height: 25px;
  327. border-radius: 3px;
  328. border: 1px solid #ededed;
  329. background-color: white;
  330. text-align: left;
  331. outline: none;
  332. }
  333. .search-item input:active {
  334. border: 1px solid #4168e0;
  335. }
  336. .search-item input:focus {
  337. border: 1px solid #4168e0;
  338. }
  339. .search-item i {
  340. position: absolute;
  341. left: 25px;
  342. top: 15px;
  343. }
  344. .action-item {
  345. height: 50px;
  346. display: flex;
  347. padding-left: 20px;
  348. align-items: center;
  349. }
  350. .action-item .icon {
  351. width: 40px;
  352. height: 40px;
  353. display: flex;
  354. justify-content: center;
  355. align-items: center;
  356. border-radius: 3px;
  357. border: 1px dashed #d6d6d6;
  358. }
  359. .action-item img {
  360. width: 40px;
  361. height: 40px;
  362. }
  363. .action-item p {
  364. margin-left: 10px;
  365. font-size: 13px;
  366. }
  367. .action-item:active {
  368. background-color: #d6d6d6;
  369. }
  370. .quit-group-item {
  371. display: flex;
  372. color: red;
  373. align-items: center;
  374. justify-content: center;
  375. height: 50px;
  376. max-height: 50px;
  377. border-top: 1px solid #ececec;
  378. }
  379. .quit-group-item:active {
  380. background: #d6d6d6;
  381. }
  382. .switch {
  383. display: flex;
  384. flex-direction: row;
  385. justify-content: flex-start;
  386. }
  387. .switch checkbox {
  388. margin-left: 20px;
  389. }
  390. </style>