Skip to content

Commit

Permalink
refactor(frontend): directives
Browse files Browse the repository at this point in the history
  • Loading branch information
taiyme committed Apr 25, 2023
1 parent 94ef700 commit d10cc3a
Show file tree
Hide file tree
Showing 18 changed files with 258 additions and 164 deletions.
2 changes: 1 addition & 1 deletion packages/client/src/components/MkUserCardMini.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div :class="[$style.root, { yellow: user.isSilenced, red: user.isSuspended, gray: false }]">
<div v-adaptive-bg :class="[$style.root, { yellow: user.isSilenced, red: user.isSuspended, gray: false }]">
<MkAvatar class="avatar" :user="user" :disable-link="true" :show-indicator="true"/>
<div class="body">
<span class="name"><MkUserName class="name" :user="user"/></span>
Expand Down
33 changes: 33 additions & 0 deletions packages/client/src/directives/adaptive-bg.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Directive } from 'vue';

// eslint-disable-next-line import/no-default-export
export default {
mounted(src) {
const isTransparent = (color?: string | null): boolean => {
if (!color) return false;
if (color === 'transparent') return true;
const [_r, _g, _b, alpha = null] = [...color.match(/\d+/g) ?? []];
return alpha === '0';
};

const getBgColor = (el: HTMLElement | null): string => {
if (!el) return 'transparent';
const { backgroundColor } = window.getComputedStyle(el);
if (backgroundColor && !isTransparent(backgroundColor)) {
return backgroundColor;
} else {
return getBgColor(el.parentElement);
}
};

const parentBg = getBgColor(src.parentElement);

const { backgroundColor: myBg } = window.getComputedStyle(src);

if (parentBg === myBg) {
src.style.backgroundColor = 'var(--bg)';
} else {
src.style.backgroundColor = myBg;
}
},
} as Directive<HTMLElement>;
25 changes: 17 additions & 8 deletions packages/client/src/directives/adaptive-border.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
import { Directive } from 'vue';

// eslint-disable-next-line import/no-default-export
export default {
mounted(src, binding, vn) {
const getBgColor = (el: HTMLElement) => {
const style = window.getComputedStyle(el);
if (style.backgroundColor && !['rgba(0, 0, 0, 0)', 'rgba(0,0,0,0)', 'transparent'].includes(style.backgroundColor)) {
return style.backgroundColor;
mounted(src) {
const isTransparent = (color?: string | null): boolean => {
if (!color) return false;
if (color === 'transparent') return true;
const [_r, _g, _b, alpha = null] = [...color.match(/\d+/g) ?? []];
return alpha === '0';
};

const getBgColor = (el: HTMLElement | null): string => {
if (!el) return 'transparent';
const { backgroundColor } = window.getComputedStyle(el);
if (backgroundColor && !isTransparent(backgroundColor)) {
return backgroundColor;
} else {
return el.parentElement ? getBgColor(el.parentElement) : 'transparent';
return getBgColor(el.parentElement);
}
};

const parentBg = getBgColor(src.parentElement);

const myBg = window.getComputedStyle(src).backgroundColor;
const { backgroundColor: myBg } = window.getComputedStyle(src);

if (parentBg === myBg) {
src.style.borderColor = 'var(--divider)';
} else {
src.style.borderColor = myBg;
}
},
} as Directive;
} as Directive<HTMLElement>;
7 changes: 4 additions & 3 deletions packages/client/src/directives/anim.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import { Directive } from 'vue';

// eslint-disable-next-line import/no-default-export
export default {
beforeMount(src, binding, vn) {
beforeMount(src) {
src.style.opacity = '0';
src.style.transform = 'scale(0.9)';
// ページネーションと相性が悪いので
//if (typeof binding.value === 'number') src.style.transitionDelay = `${binding.value * 30}ms`;
src.classList.add('_zoom');
},

mounted(src, binding, vn) {
mounted(src) {
window.setTimeout(() => {
src.style.opacity = '1';
src.style.transform = 'none';
}, 1);
},
} as Directive;
} as Directive<HTMLElement, number>;
21 changes: 13 additions & 8 deletions packages/client/src/directives/appear.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { Directive } from 'vue';

const map = new WeakMap<HTMLElement, IntersectionObserver>();

// eslint-disable-next-line import/no-default-export
export default {
mounted(src, binding, vn) {
mounted(src, binding) {
const fn = binding.value;
if (fn == null) return;

Expand All @@ -10,13 +13,15 @@ export default {
fn();
}
});

observer.observe(src);

src._observer_ = observer;
map.set(src, observer);
},

unmounted(src, binding, vn) {
if (src._observer_) src._observer_.disconnect();
}
} as Directive;
unmounted(src) {
const observer = map.get(src);
if (observer) {
observer.disconnect();
map.delete(src);
}
},
} as Directive<HTMLElement, (() => void) | null | undefined>;
14 changes: 8 additions & 6 deletions packages/client/src/directives/click-anime.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { Directive } from 'vue';
import { defaultStore } from '@/store';
import { arrayAt } from '@/scripts/tms/utils';

// eslint-disable-next-line import/no-default-export
export default {
mounted(el: HTMLElement, binding, vn) {
mounted(src) {
if (!defaultStore.state.animation) return;

const target = el.children[0];
const target = arrayAt(src.children, 0);

if (target == null) return;

target.classList.add('_anime_bounce_standBy');

el.addEventListener('mousedown', () => {
src.addEventListener('mousedown', () => {
target.classList.remove('_anime_bounce');

target.classList.add('_anime_bounce_standBy');
Expand All @@ -22,14 +24,14 @@ export default {
});
});

el.addEventListener('click', () => {
src.addEventListener('click', () => {
target.classList.add('_anime_bounce');
target.classList.remove('_anime_bounce_ready');
});

el.addEventListener('animationend', () => {
src.addEventListener('animationend', () => {
target.classList.remove('_anime_bounce');
target.classList.add('_anime_bounce_standBy');
});
},
} as Directive;
} as Directive<HTMLElement>;
6 changes: 3 additions & 3 deletions packages/client/src/directives/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@ const map = new WeakMap<HTMLElement, ResizeObserver>();

// eslint-disable-next-line import/no-default-export
export default {
mounted(el: HTMLElement) {
mounted(el) {
const ro = new ResizeObserver(() => {
el.style.setProperty('--containerHeight', `${el.offsetHeight}px`);
});
ro.observe(el);
map.set(el, ro);
},

unmounted(el: HTMLElement) {
unmounted(el) {
const ro = map.get(el);
if (ro) {
ro.disconnect();
map.delete(el);
}
},
} as Directive;
} as Directive<HTMLElement>;
28 changes: 17 additions & 11 deletions packages/client/src/directives/follow-append.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import { Directive } from 'vue';
import { getScrollContainer, getScrollPosition } from '@/scripts/scroll';

const map = new WeakMap<HTMLElement, ResizeObserver>();

// eslint-disable-next-line import/no-default-export
export default {
mounted(src, binding, vn) {
mounted(src, binding) {
if (binding.value === false) return;

let isBottom = true;

const container = getScrollContainer(src)!;
const container = getScrollContainer(src);
if (!container) return;

container.addEventListener('scroll', () => {
const pos = getScrollPosition(container);
const viewHeight = container.clientHeight;
Expand All @@ -16,20 +21,21 @@ export default {
}, { passive: true });
container.scrollTop = container.scrollHeight;

const ro = new ResizeObserver((entries, observer) => {
const ro = new ResizeObserver(() => {
if (isBottom) {
const height = container.scrollHeight;
container.scrollTop = height;
}
});

ro.observe(src);

// TODO: 新たにプロパティを作るのをやめMapを使う
src._ro_ = ro;
map.set(src, ro);
},

unmounted(src, binding, vn) {
if (src._ro_) src._ro_.unobserve(src);
}
} as Directive;
unmounted(src) {
const ro = map.get(src);
if (ro) {
ro.disconnect();
map.delete(src);
}
},
} as Directive<HTMLElement, boolean>;
19 changes: 10 additions & 9 deletions packages/client/src/directives/get-size.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Directive } from 'vue';

const mountings = new Map<Element, {
const mountings = new Map<HTMLElement, {
resize: ResizeObserver;
intersection?: IntersectionObserver;
fn: (w: number, h: number) => void;
}>();

function calc(src: Element) {
const calc = (src: HTMLElement): void => {
const info = mountings.get(src);
const height = src.clientHeight;
const width = src.clientWidth;
Expand All @@ -30,25 +30,26 @@ function calc(src: Element) {
}

info.fn(width, height);
}
};

// eslint-disable-next-line import/no-default-export
export default {
mounted(src, binding, vn) {
const resize = new ResizeObserver((entries, observer) => {
mounted(src, binding) {
const resize = new ResizeObserver(() => {
calc(src);
});
resize.observe(src);

mountings.set(src, { resize, fn: binding.value, });
mountings.set(src, { resize, fn: binding.value });
calc(src);
},

unmounted(src, binding, vn) {
unmounted(src, binding) {
binding.value(0, 0);
const info = mountings.get(src);
if (!info) return;
info.resize.disconnect();
if (info.intersection) info.intersection.disconnect();
mountings.delete(src);
}
} as Directive<Element, (w: number, h: number) => void>;
},
} as Directive<HTMLElement, (w: number, h: number) => void>;
34 changes: 19 additions & 15 deletions packages/client/src/directives/hotkey.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
import { Directive } from 'vue';
import { makeHotkey } from '../scripts/hotkey';
import { Keymap, makeHotkey } from '../scripts/hotkey';

export default {
mounted(el, binding) {
el._hotkey_global = binding.modifiers.global === true;
const map = new WeakMap<HTMLElement, () => void>();

el._keyHandler = makeHotkey(binding.value);
// eslint-disable-next-line import/no-default-export
export default {
mounted(src, binding) {
const global = binding.modifiers.global === true;
const handler = makeHotkey(binding.value);

if (el._hotkey_global) {
document.addEventListener('keydown', el._keyHandler);
if (global) {
document.addEventListener('keydown', handler);
map.set(src, () => document.removeEventListener('keydown', handler));
} else {
el.addEventListener('keydown', el._keyHandler);
src.addEventListener('keydown', handler);
map.set(src, () => src.removeEventListener('keydown', handler));
}
},

unmounted(el) {
if (el._hotkey_global) {
document.removeEventListener('keydown', el._keyHandler);
} else {
el.removeEventListener('keydown', el._keyHandler);
unmounted(src) {
const stopHandler = map.get(src);
if (stopHandler) {
stopHandler();
map.delete(src);
}
}
} as Directive;
},
} as Directive<HTMLElement, Keymap>;
41 changes: 27 additions & 14 deletions packages/client/src/directives/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,31 @@ import anim from './anim';
import clickAnime from './click-anime';
import panel from './panel';
import adaptiveBorder from './adaptive-border';
import adaptiveBg from './adaptive-bg';
import container from './container';

export default function(app: App) {
app.directive('userPreview', userPreview);
app.directive('user-preview', userPreview);
app.directive('size', size);
app.directive('get-size', getSize);
app.directive('ripple', ripple);
app.directive('tooltip', tooltip);
app.directive('hotkey', hotkey);
app.directive('appear', appear);
app.directive('anim', anim);
app.directive('click-anime', clickAnime);
app.directive('panel', panel);
app.directive('adaptive-border', adaptiveBorder);
}
import { typedEntries } from '@/scripts/tms/utils';

// eslint-disable-next-line import/no-default-export
export default (app: App): void => {
for (const [key, value] of typedEntries(directives)) {
app.directive(key, value);
}
};

export const directives = {
'userPreview': userPreview,
'user-preview': userPreview,
'size': size,
'get-size': getSize,
'ripple': ripple,
'tooltip': tooltip,
'hotkey': hotkey,
'appear': appear,
'anim': anim,
'click-anime': clickAnime,
'panel': panel,
'adaptive-border': adaptiveBorder,
'adaptive-bg': adaptiveBg,
'container': container,
};
Loading

0 comments on commit d10cc3a

Please sign in to comment.