PickUserPage.vue 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. <template>
  2. <div class="pick-contact-container">
  3. <section class="contact-list-container" v-if="users">
  4. <div class="input-container">
  5. <input type="text" :placeholder="$t('common.search')" v-model="filterQuery">
  6. <i class="icon-ion-ios-search"></i>
  7. </div>
  8. <div class="friend-list-container">
  9. <CheckableUserListView :enable-pick="true"
  10. :users="filterUsers"
  11. :initial-checked-users="initialCheckedUsers"
  12. :uncheckable-users="uncheckableUsers"
  13. :show-category-label="showCategoryLabel && !filterQuery"
  14. :padding-left="'20px'"
  15. enable-category-label-sticky/>
  16. </div>
  17. </section>
  18. <section class="checked-contact-list-container">
  19. <header>
  20. <span v-if="checkedUsers.length === 0">{{ $t('pick.picked_contact') }}</span>
  21. <span v-else>{{ $t('pick.picked_contact') + this.checkedUsers.length }}</span>
  22. <button size="mini" @click="confirm"> {{ confirmTitle }}</button>
  23. </header>
  24. <div class="content" ref="pickedUserContainer">
  25. <div class="picked-user" v-for="(user, index) in checkedUsers" :key="index" @click="unpick(user)">
  26. <div class="avatar-container">
  27. <img class="avatar" :src="user.portrait" alt="">
  28. </div>
  29. <span class="name single-line">{{ user.displayName }}</span>
  30. </div>
  31. </div>
  32. <!-- <footer>-->
  33. <!-- <button @click="cancel" class="cancel">{{ $t('common.cancel') }}</button>-->
  34. <!-- <button @click="confirm" class="confirm" v-bind:class="{disable:checkedUsers.length === 0}">-->
  35. <!-- {{ confirmTitle }}-->
  36. <!-- </button>-->
  37. <!-- </footer>-->
  38. </section>
  39. </div>
  40. </template>
  41. <script>
  42. import store from "@/store";
  43. import CheckableUserListView from "@/pages/user/CheckableUserListView";
  44. export default {
  45. name: "PickUserPage",
  46. props: {
  47. users: {
  48. type: Array,
  49. required: false,
  50. },
  51. initialCheckedUsers: {
  52. type: Array,
  53. required: false,
  54. default: null,
  55. },
  56. uncheckableUsers: {
  57. type: Array,
  58. required: false,
  59. default: null,
  60. },
  61. title: {
  62. type: String,
  63. required: false,
  64. default: '',
  65. },
  66. confirmTitle: {
  67. type: String,
  68. required: false,
  69. default: 'confirm',
  70. },
  71. showCategoryLabel: {
  72. type: Boolean,
  73. required: false,
  74. default: true,
  75. }
  76. },
  77. data() {
  78. return {
  79. sharedPickState: store.state.pick,
  80. filterQuery: '',
  81. scrollLeft:0,
  82. }
  83. },
  84. onLoad(option) {
  85. console.log('PickUserPage onLoad')
  86. // #ifdef APP-NVUE
  87. const eventChannel = this.$scope.eventChannel; // 兼容APP-NVUE
  88. // #endif
  89. // #ifndef APP-NVUE
  90. const eventChannel = this.getOpenerEventChannel();
  91. // #endif
  92. // 监听openerUsers事件,获取上一页面通过eventChannel传送到当前页面的数据
  93. eventChannel.on('pickOptions', (options) => {
  94. this.users = options.users;
  95. this.initialCheckedUsers = options.initialCheckedUsers;
  96. this.uncheckableUsers = options.uncheckableUsers;
  97. this.showCategoryLabel = options.showCategoryLabel;
  98. this.confirmTitle = options.confirmTitle;
  99. })
  100. },
  101. onUnload() {
  102. this.sharedPickState.users.length = 0
  103. },
  104. methods: {
  105. unpick(user) {
  106. if (this.isUserUncheckable(user)) {
  107. return;
  108. }
  109. store.pickOrUnpickUser(user);
  110. },
  111. isUserUncheckable(user) {
  112. return this.uncheckableUsers && this.uncheckableUsers.findIndex(u => u.uid === user.uid) >= 0;
  113. },
  114. /**
  115. * 不包含默认选中的用户
  116. */
  117. confirm() {
  118. let pickedUsers = this.sharedPickState.users;
  119. if (this.initialCheckedUsers) {
  120. pickedUsers = this.sharedPickState.users.filter(u => this.initialCheckedUsers.findIndex(iu => iu.uid === u.uid) === -1);
  121. } else {
  122. pickedUsers = this.sharedPickState.users;
  123. }
  124. let users = [...pickedUsers];
  125. this.sharedPickState.users.length = 0
  126. // #ifdef APP-NVUE
  127. const eventChannel = this.$scope.eventChannel; // 兼容APP-NVUE
  128. // #endif
  129. // #ifndef APP-NVUE
  130. const eventChannel = this.getOpenerEventChannel();
  131. // #endif
  132. eventChannel.emit('pickedUsers', users);
  133. uni.navigateBack();
  134. },
  135. },
  136. computed: {
  137. checkedUsers() {
  138. let users = this.sharedPickState.users;
  139. if (!this.initialCheckedUsers || this.initialCheckedUsers.length === 0) {
  140. return users;
  141. }
  142. return users.filter(u => {
  143. return this.initialCheckedUsers.findIndex(iu => iu.uid === u.uid) === -1
  144. })
  145. },
  146. filterUsers() {
  147. console.log('filterUsers', this.filterQuery)
  148. if (this.filterQuery) {
  149. return store.filterUsers(this.users, this.filterQuery);
  150. } else {
  151. return this.users;
  152. }
  153. }
  154. },
  155. watch:{
  156. checkedUsers(){
  157. // uniapp 里面无效,不知道为啥
  158. this.$nextTick(() => {
  159. this.$refs.pickedUserContainer.scrollLeft = this.$refs.pickedUserContainer.scrollWidth;
  160. this.scrollLeft = this.$refs.pickedUserContainer.scrollWidth;
  161. });
  162. }
  163. },
  164. components: {CheckableUserListView},
  165. }
  166. </script>
  167. <style lang="css" scoped>
  168. .pick-contact-container {
  169. display: flex;
  170. flex-direction: column;
  171. position: relative;
  172. height: 100vh;
  173. width: 100%;
  174. overflow: hidden;
  175. }
  176. .contact-list-container {
  177. flex: 1;
  178. display: flex;
  179. flex-direction: column;
  180. justify-content: flex-start;
  181. background-color: #f7f7f7;
  182. margin-bottom: 150px;
  183. overflow: auto;
  184. }
  185. .contact-list-container .input-container {
  186. position: relative;
  187. display: flex;
  188. align-items: center;
  189. width: 100%;
  190. }
  191. .input-container input {
  192. height: 35px;
  193. flex: 1;
  194. border-radius: 3px;
  195. border: 1px solid #ededed;
  196. background-color: white;
  197. margin: 0 15px;
  198. padding-left: 20px;
  199. text-align: left;
  200. outline: none;
  201. }
  202. /*.input-container input:active {*/
  203. /* border: 1px solid #4168e0;*/
  204. /*}*/
  205. /*.input-container input:focus {*/
  206. /* border: 1px solid #4168e0;*/
  207. /*}*/
  208. .input-container i {
  209. position: absolute;
  210. left: 20px;
  211. }
  212. .contact-list-container .friend-list-container {
  213. height: 100%;
  214. overflow: auto;
  215. }
  216. .checked-contact-list-container {
  217. height: 150px;
  218. width: 100%;
  219. display: flex;
  220. background: white;
  221. flex-direction: column;
  222. position: fixed;
  223. bottom: 0;
  224. left: 0;
  225. }
  226. .checked-contact-list-container header {
  227. height: 55px;
  228. display: flex;
  229. justify-content: space-between;
  230. align-items: center;
  231. }
  232. .checked-contact-list-container header span {
  233. font-size: 14px;
  234. margin-left: 20px;
  235. }
  236. .checked-contact-list-container header button {
  237. border-style: none;
  238. margin-right: 20px;
  239. color: #4168e0;
  240. }
  241. .checked-contact-list-container .content {
  242. height: 100%;
  243. flex: 1;
  244. display: flex;
  245. padding: 0 10px;
  246. flex-wrap: nowrap;
  247. justify-content: flex-start;
  248. align-items: flex-start;
  249. align-content: flex-start;
  250. overflow: scroll;
  251. }
  252. .checked-contact-list-container .content .picked-user{
  253. display: flex;
  254. flex-direction: column;
  255. column-count: 1;
  256. justify-content: center;
  257. align-items: center;
  258. padding: 5px 5px;
  259. }
  260. .checked-contact-list-container .content .picked-user .name {
  261. font-size: 12px;
  262. }
  263. .checked-contact-list-container .content .picked-user .avatar-container{
  264. position: relative;
  265. height: 65px;
  266. width: 65px;
  267. }
  268. .checked-contact-list-container .content .avatar {
  269. width: 45px;
  270. height: 45px;
  271. margin: 10px 10px;
  272. border-radius: 3px;
  273. }
  274. </style>