manage-name.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. <template>
  2. <div class="name">
  3. <label>{{ $t(`TUIChat.manage.群名称`) }}</label>
  4. <div v-if="isEdit" :class="[isH5 ? 'edit-h5' : '']" ref="dialog">
  5. <main>
  6. <header class="edit-h5-header" v-if="isH5">
  7. <aside class="left">
  8. <h1>{{ $t(`TUIChat.manage.修改群聊名称`) }}</h1>
  9. <span>
  10. {{ $t(`TUIChat.manage.修改群聊名称后,将在群内通知其他成员`) }}
  11. </span>
  12. </aside>
  13. <span class="close" @click="toggleEdit">{{ $t(`关闭`) }}</span>
  14. </header>
  15. <div class="input-box">
  16. <input
  17. class="input"
  18. v-if="isEdit"
  19. v-model="input"
  20. type="text"
  21. @keyup.enter="updateProfile"
  22. />
  23. <span v-if="isH5">
  24. {{ $t(`TUIChat.manage.仅限中文、字母、数字和下划线,2-20个字`) }}
  25. </span>
  26. </div>
  27. <footer class="edit-h5-footer" v-if="isH5">
  28. <button class="btn" :disabled="!input" @click="updateProfile">
  29. {{ $t(`确认`) }}
  30. </button>
  31. </footer>
  32. </main>
  33. </div>
  34. <p v-if="!isEdit || isH5" @click="toggleEdit">
  35. <span>{{ groupProfile.name }}</span>
  36. <i class="icon icon-edit" v-if="isAuth"></i>
  37. </p>
  38. </div>
  39. </template>
  40. <script lang="ts">
  41. import { defineComponent, watchEffect, reactive, toRefs, ref } from 'vue';
  42. import { onClickOutside } from '@vueuse/core';
  43. const manageName = defineComponent({
  44. props: {
  45. data: {
  46. type: Object,
  47. default: () => ({})
  48. },
  49. isAuth: {
  50. type: Boolean,
  51. default: false
  52. },
  53. isH5: {
  54. type: Boolean,
  55. default: false
  56. }
  57. },
  58. setup(props: any, ctx: any) {
  59. const data: any = reactive({
  60. groupProfile: {},
  61. input: '',
  62. isEdit: false
  63. });
  64. watchEffect(() => {
  65. data.groupProfile = props.data;
  66. });
  67. const dialog: any = ref();
  68. onClickOutside(dialog, () => {
  69. data.isEdit = false;
  70. });
  71. const updateProfile = async () => {
  72. if (data.input && data.input !== data.groupProfile.name) {
  73. ctx.emit('update', { key: 'name', value: data.input });
  74. data.groupProfile.name = data.input;
  75. data.input = '';
  76. }
  77. toggleEdit();
  78. };
  79. const toggleEdit = async () => {
  80. if (props.isAuth) {
  81. data.isEdit = !data.isEdit;
  82. }
  83. if (data.isEdit) {
  84. data.input = data.groupProfile.name;
  85. }
  86. };
  87. return {
  88. ...toRefs(data),
  89. updateProfile,
  90. toggleEdit,
  91. dialog
  92. };
  93. }
  94. });
  95. export default manageName;
  96. </script>
  97. <style lang="scss" scoped>
  98. @import url('../../../styles/common.scss');
  99. @import url('../../../styles/icon.scss');
  100. .name {
  101. padding: 14Px 20Px;
  102. font-weight: 400;
  103. font-size: 14Px;
  104. color: #000000;
  105. display: flex;
  106. flex-direction: column;
  107. p {
  108. opacity: 0.6;
  109. display: flex;
  110. align-items: center;
  111. .icon {
  112. margin-left: 4Px;
  113. }
  114. }
  115. }
  116. .input-box {
  117. display: flex;
  118. .input {
  119. flex: 1;
  120. border: 1Px solid #e8e8e9;
  121. border-radius: 4Px;
  122. padding: 4Px 16Px;
  123. font-weight: 400;
  124. font-size: 14Px;
  125. color: #000000;
  126. opacity: 0.6;
  127. }
  128. }
  129. .space-top {
  130. border-top: 10Px solid #f4f5f9;
  131. }
  132. .edit-h5 {
  133. position: fixed;
  134. width: 100%;
  135. height: 100%;
  136. top: 0;
  137. left: 0;
  138. background: rgba(0, 0, 0, 0.5);
  139. display: flex;
  140. align-items: flex-end;
  141. z-index: 1;
  142. main {
  143. background: #ffffff;
  144. flex: 1;
  145. padding: 18Px;
  146. border-radius: 12Px 12Px 0 0;
  147. .input-box {
  148. flex-direction: column;
  149. padding: 18Px 0;
  150. .input {
  151. background: #f8f8f8;
  152. padding: 10Px 12Px;
  153. }
  154. span {
  155. font-family: PingFangSC-Regular;
  156. font-weight: 400;
  157. font-size: 12Px;
  158. color: #888888;
  159. letter-spacing: 0;
  160. padding-top: 8Px;
  161. }
  162. }
  163. }
  164. &-header {
  165. display: flex;
  166. align-items: center;
  167. justify-content: space-between;
  168. .close {
  169. font-family: PingFangSC-Regular;
  170. font-weight: 400;
  171. font-size: 18Px;
  172. color: #3370ff;
  173. letter-spacing: 0;
  174. line-height: 27Px;
  175. }
  176. }
  177. &-footer {
  178. display: flex;
  179. .btn {
  180. flex: 1;
  181. border: none;
  182. background: #147aff;
  183. border-radius: 5Px;
  184. font-family: PingFangSC-Regular;
  185. font-weight: 400;
  186. font-size: 16Px;
  187. color: #ffffff;
  188. letter-spacing: 0;
  189. line-height: 27Px;
  190. padding: 8Px 0;
  191. &:disabled {
  192. opacity: 0.3;
  193. }
  194. }
  195. }
  196. }
  197. </style>