Skip to content

Commit

Permalink
feat: 拖拽改变元素大小的hook,一些样式fix
Browse files Browse the repository at this point in the history
  • Loading branch information
xgChange committed Aug 15, 2023
1 parent 8109d88 commit c3a0af7
Show file tree
Hide file tree
Showing 10 changed files with 215 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const props = defineProps<{
</script>

<template>
<div class="flex flex-col justify-end overflow-y-auto">
<div class="flex flex-col justify-end overflow-y-auto overflow-x-hidden">
<ChatMessage
v-for="(item, index) in props.msgList"
:key="index"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ type ChatMessageProps = Partial<
defineOptions({
name: 'ChatMessage',
inheritAttrs: true,
});
const props = withDefaults(defineProps<ChatMessageProps>(), {
Expand All @@ -30,7 +29,7 @@ const props = withDefaults(defineProps<ChatMessageProps>(), {
:class="[reverse ? 'justify-end' : 'justify-start']"
>
<div
class="whitespace-pre-wrap rounded-lg px-4 py-2 leading-6 text-black"
class="max-w-[260px] whitespace-pre-wrap break-words rounded-lg px-4 py-2 leading-6 text-black lg:max-w-[500px]"
:class="[background ? background : 'bg-slate-200']"
>
{{ props.message }}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts" setup>
import { Member } from '@/hooks';
import { Member, useDragChangeSize } from '@/hooks';
import UserCard from './user-card.vue';
import { computed } from 'vue';
import { computed, ref } from 'vue';
import { PropType } from 'vue';
defineOptions({
Expand All @@ -21,15 +21,45 @@ const props = defineProps({
type: Object as PropType<Partial<Member>>,
default: () => ({}),
},
width: {
type: String as PropType<string>,
default: '220px',
},
});
const memberwithoutOwner = computed(() =>
props.members.filter((item) => !item.owner)
);
const chatRoomUserRef = ref<any>();
const { style, canDragged } = useDragChangeSize(chatRoomUserRef, {
initialSize: {
width: props.width,
},
position: 'left',
persistentSize: {
height: '100%',
},
});
const reSizeClass = computed(() => {
if (canDragged.value.draggable) {
if (canDragged.value.position === 'left') {
return ['cursor-w-resize'];
}
}
return [];
});
</script>

<template>
<div class="px-2 pt-2 text-sm">
<div
ref="chatRoomUserRef"
:class="[...reSizeClass]"
class="h-full overflow-auto px-2 py-2 text-sm"
:style="style"
>
<div class="mb-1 text-gray-400">房主</div>
<UserCard
class="mb-4"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { UserCardProps } from './props';
defineOptions({
name: 'UserCard',
inheritAttrs: false,
});
withDefaults(defineProps<UserCardProps>(), {
Expand Down
2 changes: 1 addition & 1 deletion client/packages/rtc-web/src/components/menu/menu-side.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ defineOptions({
</script>

<template>
<div class="menu h-full w-80 p-4">
<div class="menu h-full w-80 min-w-[320px] p-4">
<MenuList />
</div>
</template>
Expand Down
1 change: 1 addition & 0 deletions client/packages/rtc-web/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './useRoom';
export * from './useInitData';
export * from './socket-utils';
export * from './useRouterReactive';
export * from './useDragChangeSize';
123 changes: 123 additions & 0 deletions client/packages/rtc-web/src/hooks/useDragChangeSize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import { isItBetween } from '@/utils';
import {
MaybeElementRef,
useMouseInElement,
useMousePressed,
} from '@vueuse/core';
import { computed, ref, watch } from 'vue';

type ResizeOption = {
initialSize?: {
width?: string;
height?: string;
};
position?: 'left' | 'right' | 'top' | 'bottom';
persistentSize?: {
width?: string;
height?: string;
}; // 用来控制在拖拽时不会变的数据
};

export const useDragChangeSize = (
target: MaybeElementRef,
options?: ResizeOption
) => {
const offset = 5;
const { elementX, elementY, elementWidth, elementHeight } =
useMouseInElement(target);

const style = computed(() => {
return Object.assign(
{},
{
width: `${
elementWidth.value
? elementWidth.value + 'px'
: options?.initialSize?.width ?? '100%'
}`,
height: `${
elementHeight.value
? elementHeight.value + 'px'
: options?.initialSize?.height ?? '100%'
}`,
},
options?.persistentSize || ({} as any)
);
});

const { pressed } = useMousePressed({ target, touch: false });

const draggablePos = computed(() => ({
left: {
x: [-offset, offset],
y: [0, elementHeight.value],
},
top: {
x: [0, elementWidth.value],
y: [-offset, offset],
},
}));

const judgeEnterPos = () => {
const findV = Object.keys(draggablePos.value).find((key) => {
const posKey = key as keyof typeof draggablePos.value;

return (
isItBetween(elementX.value, draggablePos.value[posKey].x) &&
isItBetween(elementY.value, draggablePos.value[posKey].y)
);
});
const draggable = options?.position ? options.position === findV : !!findV;
return {
draggable,
position: findV || '',
};
};

// 判断点击时候是否在拖拽范围内
const draggableByClick = ref({
draggable: false,
position: '',
});

// 供外部用的判断 是否可以拖拽
const canDragged = computed(judgeEnterPos);

const doResize = ([posX, posY]: number[], type: string) => {
const movX = posX - offset;
const movY = posY - offset;
if (type === 'left') {
const differenceX = -movX;
elementWidth.value = elementWidth.value + differenceX;
}

if (type === 'top') {
const differenceY = -movY;
elementHeight.value = elementHeight.value + differenceY;
}
};

watch([elementX, elementY], (v) => {
if (pressed.value) {
if (draggableByClick.value.draggable) {
doResize(v, draggableByClick.value.position);
}
}
});

watch(pressed, (v) => {
if (v) {
draggableByClick.value = judgeEnterPos();
} else {
draggableByClick.value = {
draggable: false,
position: '',
};
}
});

return {
canDragged,
style,
};
};
4 changes: 4 additions & 0 deletions client/packages/rtc-web/src/utils/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,7 @@ export function unescapeStr(str: string) {
}
);
}

export const isItBetween = (num: number, arr: number[]) => {
return num >= arr[0] && num <= arr[1];
};
58 changes: 49 additions & 9 deletions client/packages/rtc-web/src/views/chat/chat-room.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import { useGetRoomInfo } from '@/hooks/useRoom';
import { useChat } from './hooks/useChat';
import { escapeStr } from '@/utils';
import dayjs from 'dayjs';
import { computed, ref } from 'vue';
import { computed, ref, nextTick } from 'vue';
import { useDragChangeSize } from '@/hooks';
defineOptions({
name: 'ChatRoomCom',
Expand All @@ -21,6 +22,26 @@ const { sendMessage, msgList } = useChat();
const inputMsg = ref('');
const chatMsgBoxRef = ref<any>(null);
const chatMsgContentRef = ref<Element | null>(null);
const { canDragged, style } = useDragChangeSize(chatMsgBoxRef, {
initialSize: { height: '260px' },
position: 'top',
persistentSize: {
width: '100%',
},
});
const reSizeClass = computed(() => {
if (canDragged.value.draggable) {
if (canDragged.value.position === 'top') {
return ['cursor-ns-resize'];
}
}
return [];
});
const handleSendmsg = (msg: string) => {
if (self.value) {
const { roomInfo, nickName = '' } = self.value;
Expand All @@ -32,6 +53,14 @@ const handleSendmsg = (msg: string) => {
recoderId: roomInfo?.recoderId,
time: dayjs().format('YYYY-MM-DD HH:mm:ss'),
});
nextTick(() => {
chatMsgContentRef?.value?.scroll({
top: chatMsgContentRef.value.scrollHeight,
left: 0,
behavior: 'smooth',
});
});
}
};
Expand All @@ -53,9 +82,18 @@ const handleEmojiChange = (data: any) => {
<template>
<div class="flex h-full">
<div class="flex flex-1 flex-col">
<ChatContent class="flex-1 px-4 py-4" :msg-list="msgContent" />
<!-- 这里得多加一个 div 才能 scroll -->
<div
ref="chatMsgContentRef"
class="ces min-h-0 flex-1 overflow-y-auto overflow-x-hidden px-4 py-4"
>
<ChatContent :msg-list="msgContent" />
</div>
<div
class="flex h-[260px] flex-col border-t pb-1.5 dark:border-neutral-600"
ref="chatMsgBoxRef"
:style="style"
:class="[...reSizeClass]"
class="flex h-[260px] max-h-[610px] flex-col border-t pb-1.5 dark:border-neutral-600"
>
<MenuAction
:menu-action="ChatInputAction"
Expand All @@ -69,11 +107,13 @@ const handleEmojiChange = (data: any) => {
/>
</div>
</div>
<div
v-if="open"
class="hidden w-[220px] border-l dark:border-neutral-600 lg:block"
>
<ChatRoomUser :members="members" :room-owner="roomOwner" :self="self" />
</div>
<ChatRoomUser
v-show="open"
class="hidden max-w-[400px] border-l dark:border-neutral-600 lg:block"
width="220px"
:members="members"
:room-owner="roomOwner"
:self="self"
/>
</div>
</template>
1 change: 1 addition & 0 deletions client/packages/rtc-web/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export default defineConfig({
],
},
server: {
host: '0.0.0.0',
proxy: {
'/api': {
target: 'http://localhost:9092/api',
Expand Down

0 comments on commit c3a0af7

Please sign in to comment.