manage-name.vue 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. <template>
  2. <div class="group-name">
  3. <label>{{ TUITranslateService.t(`TUIGroup.群名称`) }}</label>
  4. <div
  5. v-if="isEdit"
  6. :class="{
  7. 'edit-h5': isMobile,
  8. }"
  9. >
  10. <main class="edit-h5-main">
  11. <header
  12. v-if="!isPC"
  13. class="edit-h5-header"
  14. >
  15. <aside class="left">
  16. <h1>{{ TUITranslateService.t(`TUIGroup.修改群聊名称`) }}</h1>
  17. <span>{{
  18. TUITranslateService.t(
  19. `TUIGroup.修改群聊名称后,将在群内通知其他成员`
  20. )
  21. }}</span>
  22. </aside>
  23. <span
  24. class="close"
  25. @click="toggleEditStatus"
  26. >{{
  27. TUITranslateService.t(`关闭`)
  28. }}</span>
  29. </header>
  30. <div class="input-box">
  31. <input
  32. v-if="isEdit"
  33. ref="nameInputRef"
  34. v-model="inputGroupName"
  35. class="input"
  36. type="text"
  37. @blur="updateProfile"
  38. >
  39. <span
  40. v-if="!isPC"
  41. class="tip"
  42. >{{
  43. TUITranslateService.t(
  44. `TUIGroup.仅限中文、字母、数字和下划线,2-20个字`
  45. )
  46. }}</span>
  47. </div>
  48. <footer
  49. v-if="!isPC"
  50. class="edit-h5-footer"
  51. >
  52. <button
  53. class="btn"
  54. @click="updateProfile"
  55. >
  56. {{ TUITranslateService.t(`确认`) }}
  57. </button>
  58. </footer>
  59. </main>
  60. </div>
  61. <p
  62. v-if="!isEdit || !isPC"
  63. class="name"
  64. @click="toggleEditStatus"
  65. >
  66. <span>{{ groupProfile.name }}</span>
  67. <Icon
  68. v-if="isAuthor"
  69. class="icon"
  70. :file="editIcon"
  71. width="14px"
  72. height="14px"
  73. />
  74. </p>
  75. </div>
  76. </template>
  77. <script lang="ts" setup>
  78. import { watchEffect, ref, nextTick, watch } from '../../../adapter-vue';
  79. import {
  80. TUITranslateService,
  81. IGroupModel,
  82. } from '@tencentcloud/chat-uikit-engine';
  83. import Icon from '../../common/Icon.vue';
  84. import editIcon from '../../../assets/icon/edit.svg';
  85. import { Toast, TOAST_TYPE } from '../../common/Toast/index';
  86. import { isMobile, isPC } from '../../../utils/env';
  87. const props = defineProps({
  88. data: {
  89. type: Object,
  90. default: () => ({}),
  91. },
  92. isAuthor: {
  93. type: Boolean,
  94. default: false,
  95. },
  96. });
  97. const groupProfile = ref<IGroupModel>({});
  98. const inputGroupName = ref('');
  99. const isEdit = ref(false);
  100. const nameInputRef = ref<HTMLInputElement>(null);
  101. watchEffect(() => {
  102. groupProfile.value = props.data;
  103. });
  104. const emit = defineEmits(['update']);
  105. const updateProfile = () => {
  106. if (!inputGroupName.value) {
  107. Toast({
  108. message: TUITranslateService.t('TUIGroup.群名称不能为空'),
  109. type: TOAST_TYPE.ERROR,
  110. });
  111. } else {
  112. if (inputGroupName.value !== groupProfile.value.name) {
  113. emit('update', { key: 'name', value: inputGroupName.value });
  114. groupProfile.value.name = inputGroupName.value;
  115. inputGroupName.value = '';
  116. Toast({
  117. message: TUITranslateService.t('TUIGroup.群名称修改成功'),
  118. type: TOAST_TYPE.SUCCESS,
  119. });
  120. }
  121. toggleEditStatus();
  122. }
  123. };
  124. const toggleEditStatus = () => {
  125. if (props.isAuthor) {
  126. isEdit.value = !isEdit.value;
  127. }
  128. if (isEdit.value) {
  129. inputGroupName.value = groupProfile.value.name;
  130. }
  131. };
  132. watch(
  133. () => isEdit.value,
  134. (newVal: boolean) => {
  135. if (newVal) {
  136. nextTick(() => {
  137. nameInputRef.value?.focus();
  138. });
  139. }
  140. },
  141. );
  142. </script>
  143. <style lang="scss" scoped>
  144. @import "../../../assets/styles/common";
  145. .group-name {
  146. padding: 14px 20px;
  147. font-weight: 400;
  148. font-size: 14px;
  149. color: #000;
  150. display: flex;
  151. flex-direction: column;
  152. .name {
  153. color: #999;
  154. display: flex;
  155. align-items: center;
  156. .icon {
  157. margin-left: 4px;
  158. }
  159. }
  160. }
  161. .input-box {
  162. display: flex;
  163. .input {
  164. flex: 1;
  165. border: 1px solid #e8e8e9;
  166. border-radius: 4px;
  167. padding: 4px 16px;
  168. font-weight: 400;
  169. font-size: 14px;
  170. color: #000;
  171. opacity: 0.6;
  172. }
  173. }
  174. .space-top {
  175. border-top: 10px solid #f4f5f9;
  176. }
  177. .edit-h5 {
  178. position: fixed;
  179. width: 100%;
  180. height: 100%;
  181. top: 0;
  182. left: 0;
  183. background: rgba(0, 0, 0, 0.5);
  184. display: flex;
  185. align-items: flex-end;
  186. z-index: 1;
  187. .edit-h5-main {
  188. background: #fff;
  189. flex: 1;
  190. padding: 18px;
  191. border-radius: 12px 12px 0 0;
  192. width: 80vw;
  193. .input-box {
  194. flex-direction: column;
  195. padding: 18px 0;
  196. .input {
  197. background: #f8f8f8;
  198. padding: 10px 12px;
  199. }
  200. .tip {
  201. font-size: 12px;
  202. color: #888;
  203. padding-top: 8px;
  204. }
  205. }
  206. }
  207. &-header {
  208. display: flex;
  209. align-items: center;
  210. justify-content: space-between;
  211. .close {
  212. font-family: PingFangSC-Regular;
  213. font-weight: 400;
  214. font-size: 18px;
  215. color: #3370ff;
  216. letter-spacing: 0;
  217. line-height: 27px;
  218. }
  219. }
  220. &-footer {
  221. display: flex;
  222. .btn {
  223. flex: 1;
  224. border: none;
  225. background: #147aff;
  226. border-radius: 5px;
  227. font-family: PingFangSC-Regular;
  228. font-weight: 400;
  229. font-size: 16px;
  230. color: #fff;
  231. letter-spacing: 0;
  232. line-height: 27px;
  233. padding: 8px 0;
  234. &:disabled {
  235. opacity: 0.3;
  236. }
  237. }
  238. }
  239. }
  240. </style>