1
0
mirror of https://github.com/misskey-dev/misskey.git synced 2026-07-25 16:45:00 +02:00
Files
misskey/packages/frontend/src/components/grid/MkHeaderCell.vue
syuilo 8c2ab25e5f Feat: No websocket mode (#15851)
* wip

* wip

* wip

* wip

* Update MkTimeline.vue

* wip

* wip

* wip

* Update MkTimeline.vue

* Update use-pagination.ts

* wip

* wip

* Update MkTimeline.vue

* Update MkTimeline.vue

* wip

* wip

* Update MkTimeline.vue

* Update MkTimeline.vue

* Update MkTimeline.vue

* wip

* Update use-pagination.ts

* wip

* Update use-pagination.ts

* Update MkNotifications.vue

* Update MkNotifications.vue

* wip

* wip

* wip

* Update use-note-capture.ts

* Update use-note-capture.ts

* Update use-note-capture.ts

* wip

* wip

* wip

* wip

* Update MkNoteDetailed.vue

* wip

* wip

* Update MkTimeline.vue

* wip

* fix

* Update MkTimeline.vue

* wip

* test

* Revert "test"

This reverts commit 3375619396.

* Update use-pagination.ts

* test

* Revert "test"

This reverts commit 42c53c830e.

* test

* Revert "test"

This reverts commit c4f8cda4aa.

* Update style.scss

* Update MkTimeline.vue

* Update MkTimeline.vue

* Update MkTimeline.vue

* ✌️

* Update MkTimeline.vue

* wip

* wip

* test

* Update MkPullToRefresh.vue

* Update MkPullToRefresh.vue

* Update MkPullToRefresh.vue

* Update MkPullToRefresh.vue

* Update MkTimeline.vue

* wip

* tweak navbar

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* Update home.vue

* wip

* refactor

* wip

* wip

* Update note.vue

* Update navbar.vue

* Update MkPullToRefresh.vue

* Update MkPullToRefresh.vue

* Update MkPullToRefresh.vue

* wip

* Update MkStreamingNotificationsTimeline.vue

* Update use-pagination.ts

* wip

* improve perf

* wip

* Update MkNotesTimeline.vue

* wip

* megre

* Update use-pagination.ts

* Update use-pagination.ts

* Update MkStreamingNotesTimeline.vue

* Update use-pagination.ts

* Update CHANGELOG.md

* Update CHANGELOG.md

* Update CHANGELOG.md
2025-05-09 17:40:08 +09:00

218 lines
5.0 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!--
SPDX-FileCopyrightText: syuilo and other misskey contributors
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div
ref="rootEl"
class="mk_grid_th"
:class="$style.cell"
:style="[{ maxWidth: column.width, minWidth: column.width, width: column.width }]"
data-grid-cell
:data-grid-cell-row="-1"
:data-grid-cell-col="column.index"
>
<div :class="$style.root">
<div :class="$style.left"></div>
<div :class="$style.wrapper">
<div ref="contentEl" :class="$style.contentArea">
<span v-if="column.setting.icon" class="ti" :class="column.setting.icon" style="line-height: normal"></span>
<span v-else>{{ text }}</span>
</div>
</div>
<div
:class="$style.right"
@mousedown="onHandleMouseDown"
@dblclick="onHandleDoubleClick"
></div>
</div>
</div>
</template>
<script setup lang="ts">
import { computed, nextTick, onMounted, onUnmounted, ref, toRefs, useTemplateRef, watch } from 'vue';
import type { Size } from '@/components/grid/grid.js';
import type { GridColumn } from '@/components/grid/column.js';
import { GridEventEmitter } from '@/components/grid/grid.js';
const emit = defineEmits<{
(ev: 'operation:beginWidthChange', sender: GridColumn): void;
(ev: 'operation:endWidthChange', sender: GridColumn): void;
(ev: 'operation:widthLargest', sender: GridColumn): void;
(ev: 'change:width', sender: GridColumn, width: string): void;
(ev: 'change:contentSize', sender: GridColumn, newSize: Size): void;
}>();
const props = defineProps<{
column: GridColumn,
bus: GridEventEmitter,
}>();
const { column, bus } = toRefs(props);
const rootEl = useTemplateRef('rootEl');
const contentEl = useTemplateRef('contentEl');
const resizing = ref<boolean>(false);
const text = computed(() => {
const result = column.value.setting.title ?? column.value.setting.bindTo;
return result.length > 0 ? result : ' ';
});
watch(column, () => {
// 中身がセットされた直後はサイズが分からないので、次のタイミングで更新する
nextTick(emitContentSizeChanged);
}, { immediate: true });
function onHandleDoubleClick(ev: MouseEvent) {
switch (ev.type) {
case 'dblclick': {
emit('operation:widthLargest', column.value);
break;
}
}
}
function onHandleMouseDown(ev: MouseEvent) {
switch (ev.type) {
case 'mousedown': {
if (!resizing.value) {
registerHandleMouseUp();
registerHandleMouseMove();
resizing.value = true;
emit('operation:beginWidthChange', column.value);
}
break;
}
}
}
function onHandleMouseMove(ev: MouseEvent) {
if (!rootEl.value) {
// 型ガード
return;
}
switch (ev.type) {
case 'mousemove': {
if (resizing.value) {
const bounds = rootEl.value.getBoundingClientRect();
const clientWidth = rootEl.value.clientWidth;
const clientRight = bounds.left + clientWidth;
const nextWidth = clientWidth + (ev.clientX - clientRight);
emit('change:width', column.value, `${nextWidth}px`);
}
break;
}
}
}
function onHandleMouseUp(ev: MouseEvent) {
switch (ev.type) {
case 'mouseup': {
if (resizing.value) {
unregisterHandleMouseUp();
unregisterHandleMouseMove();
resizing.value = false;
emit('operation:endWidthChange', column.value);
}
break;
}
}
}
function onForceRefreshContentSize() {
emitContentSizeChanged();
}
function registerHandleMouseMove() {
unregisterHandleMouseMove();
addEventListener('mousemove', onHandleMouseMove);
}
function unregisterHandleMouseMove() {
removeEventListener('mousemove', onHandleMouseMove);
}
function registerHandleMouseUp() {
unregisterHandleMouseUp();
addEventListener('mouseup', onHandleMouseUp);
}
function unregisterHandleMouseUp() {
removeEventListener('mouseup', onHandleMouseUp);
}
function emitContentSizeChanged() {
const clientWidth = contentEl.value?.clientWidth ?? 0;
const clientHeight = contentEl.value?.clientHeight ?? 0;
emit('change:contentSize', column.value, {
// バーの横幅も考慮したいので、+3px
width: clientWidth + 3 + 3,
height: clientHeight,
});
}
onMounted(() => {
bus.value.on('forceRefreshContentSize', onForceRefreshContentSize);
});
onUnmounted(() => {
bus.value.off('forceRefreshContentSize', onForceRefreshContentSize);
});
</script>
<style module lang="scss">
$handleWidth: 5px;
$cellHeight: 28px;
.cell {
cursor: pointer;
}
.root {
display: flex;
flex-direction: row;
height: $cellHeight;
max-height: $cellHeight;
min-height: $cellHeight;
.wrapper {
flex: 1;
display: flex;
flex-direction: row;
overflow: hidden;
justify-content: center;
}
.contentArea {
display: flex;
padding: 6px 4px;
box-sizing: border-box;
overflow: hidden;
white-space: nowrap;
text-align: center;
}
.left {
// rightのぶんだけズレるのでそれを相殺するためのネガティブマージン
margin-left: -$handleWidth;
margin-right: auto;
width: $handleWidth;
min-width: $handleWidth;
}
.right {
margin-left: auto;
// 判定を罫線の上に重ねたいのでネガティブマージンを使う
margin-right: -$handleWidth;
width: $handleWidth;
min-width: $handleWidth;
cursor: w-resize;
z-index: 1;
}
}
</style>