Merge branch 'develop' into fix-14783
This commit is contained in:
commit
3fc951eb9b
|
@ -4,6 +4,8 @@
|
||||||
-
|
-
|
||||||
|
|
||||||
### Client
|
### Client
|
||||||
|
- Enhance: Bull DashboardでRelationship Queueの状態も確認できるように
|
||||||
|
(Cherry-picked from https://github.com/MisskeyIO/misskey/pull/751)
|
||||||
- Fix: 通知の範囲指定の設定項目が必要ない通知設定でも範囲指定の設定がでている問題を修正
|
- Fix: 通知の範囲指定の設定項目が必要ない通知設定でも範囲指定の設定がでている問題を修正
|
||||||
|
|
||||||
### Server
|
### Server
|
||||||
|
|
|
@ -30,6 +30,7 @@ import type {
|
||||||
EndedPollNotificationQueue,
|
EndedPollNotificationQueue,
|
||||||
InboxQueue,
|
InboxQueue,
|
||||||
ObjectStorageQueue,
|
ObjectStorageQueue,
|
||||||
|
RelationshipQueue,
|
||||||
SystemQueue,
|
SystemQueue,
|
||||||
UserWebhookDeliverQueue,
|
UserWebhookDeliverQueue,
|
||||||
SystemWebhookDeliverQueue,
|
SystemWebhookDeliverQueue,
|
||||||
|
@ -121,6 +122,7 @@ export class ClientServerService {
|
||||||
@Inject('queue:deliver') public deliverQueue: DeliverQueue,
|
@Inject('queue:deliver') public deliverQueue: DeliverQueue,
|
||||||
@Inject('queue:inbox') public inboxQueue: InboxQueue,
|
@Inject('queue:inbox') public inboxQueue: InboxQueue,
|
||||||
@Inject('queue:db') public dbQueue: DbQueue,
|
@Inject('queue:db') public dbQueue: DbQueue,
|
||||||
|
@Inject('queue:relationship') public relationshipQueue: RelationshipQueue,
|
||||||
@Inject('queue:objectStorage') public objectStorageQueue: ObjectStorageQueue,
|
@Inject('queue:objectStorage') public objectStorageQueue: ObjectStorageQueue,
|
||||||
@Inject('queue:userWebhookDeliver') public userWebhookDeliverQueue: UserWebhookDeliverQueue,
|
@Inject('queue:userWebhookDeliver') public userWebhookDeliverQueue: UserWebhookDeliverQueue,
|
||||||
@Inject('queue:systemWebhookDeliver') public systemWebhookDeliverQueue: SystemWebhookDeliverQueue,
|
@Inject('queue:systemWebhookDeliver') public systemWebhookDeliverQueue: SystemWebhookDeliverQueue,
|
||||||
|
@ -248,6 +250,7 @@ export class ClientServerService {
|
||||||
this.deliverQueue,
|
this.deliverQueue,
|
||||||
this.inboxQueue,
|
this.inboxQueue,
|
||||||
this.dbQueue,
|
this.dbQueue,
|
||||||
|
this.relationshipQueue,
|
||||||
this.objectStorageQueue,
|
this.objectStorageQueue,
|
||||||
this.userWebhookDeliverQueue,
|
this.userWebhookDeliverQueue,
|
||||||
this.systemWebhookDeliverQueue,
|
this.systemWebhookDeliverQueue,
|
||||||
|
|
|
@ -64,26 +64,30 @@ const showBody = ref(props.expanded);
|
||||||
const ignoreOmit = ref(false);
|
const ignoreOmit = ref(false);
|
||||||
const omitted = ref(false);
|
const omitted = ref(false);
|
||||||
|
|
||||||
function enter(el) {
|
function enter(el: Element) {
|
||||||
|
if (!(el instanceof HTMLElement)) return;
|
||||||
const elementHeight = el.getBoundingClientRect().height;
|
const elementHeight = el.getBoundingClientRect().height;
|
||||||
el.style.height = 0;
|
el.style.height = '0';
|
||||||
el.offsetHeight; // reflow
|
el.offsetHeight; // reflow
|
||||||
el.style.height = Math.min(elementHeight, props.maxHeight ?? Infinity) + 'px';
|
el.style.height = `${Math.min(elementHeight, props.maxHeight ?? Infinity)}px`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function afterEnter(el) {
|
function afterEnter(el: Element) {
|
||||||
el.style.height = null;
|
if (!(el instanceof HTMLElement)) return;
|
||||||
|
el.style.height = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
function leave(el) {
|
function leave(el: Element) {
|
||||||
|
if (!(el instanceof HTMLElement)) return;
|
||||||
const elementHeight = el.getBoundingClientRect().height;
|
const elementHeight = el.getBoundingClientRect().height;
|
||||||
el.style.height = elementHeight + 'px';
|
el.style.height = `${elementHeight}px`;
|
||||||
el.offsetHeight; // reflow
|
el.offsetHeight; // reflow
|
||||||
el.style.height = 0;
|
el.style.height = '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
function afterLeave(el) {
|
function afterLeave(el: Element) {
|
||||||
el.style.height = null;
|
if (!(el instanceof HTMLElement)) return;
|
||||||
|
el.style.height = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
const calcOmit = () => {
|
const calcOmit = () => {
|
||||||
|
|
|
@ -128,14 +128,14 @@ export default defineComponent({
|
||||||
return children;
|
return children;
|
||||||
};
|
};
|
||||||
|
|
||||||
function onBeforeLeave(element: Element) {
|
function onBeforeLeave(el: Element) {
|
||||||
const el = element as HTMLElement;
|
if (!(el instanceof HTMLElement)) return;
|
||||||
el.style.top = `${el.offsetTop}px`;
|
el.style.top = `${el.offsetTop}px`;
|
||||||
el.style.left = `${el.offsetLeft}px`;
|
el.style.left = `${el.offsetLeft}px`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onLeaveCancelled(element: Element) {
|
function onLeaveCancelled(el: Element) {
|
||||||
const el = element as HTMLElement;
|
if (!(el instanceof HTMLElement)) return;
|
||||||
el.style.top = '';
|
el.style.top = '';
|
||||||
el.style.left = '';
|
el.style.left = '';
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div ref="rootEl" :class="$style.root">
|
<div ref="rootEl" :class="$style.root">
|
||||||
<header :class="$style.header" class="_button" :style="{ background: bg }" @click="showBody = !showBody">
|
<header :class="$style.header" class="_button" @click="showBody = !showBody">
|
||||||
<div :class="$style.title"><div><slot name="header"></slot></div></div>
|
<div :class="$style.title"><div><slot name="header"></slot></div></div>
|
||||||
<div :class="$style.divider"></div>
|
<div :class="$style.divider"></div>
|
||||||
<button class="_button" :class="$style.button">
|
<button class="_button" :class="$style.button">
|
||||||
|
@ -32,21 +32,23 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref, shallowRef, watch } from 'vue';
|
import { onMounted, ref, shallowRef, watch } from 'vue';
|
||||||
import tinycolor from 'tinycolor2';
|
|
||||||
import { miLocalStorage } from '@/local-storage.js';
|
import { miLocalStorage } from '@/local-storage.js';
|
||||||
import { defaultStore } from '@/store.js';
|
import { defaultStore } from '@/store.js';
|
||||||
|
import { getBgColor } from '@/scripts/get-bg-color.js';
|
||||||
|
|
||||||
const miLocalStoragePrefix = 'ui:folder:' as const;
|
const miLocalStoragePrefix = 'ui:folder:' as const;
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
expanded?: boolean;
|
expanded?: boolean;
|
||||||
persistKey?: string;
|
persistKey?: string | null;
|
||||||
}>(), {
|
}>(), {
|
||||||
expanded: true,
|
expanded: true,
|
||||||
|
persistKey: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
const rootEl = shallowRef<HTMLDivElement>();
|
const rootEl = shallowRef<HTMLElement>();
|
||||||
const bg = ref<string>();
|
const parentBg = ref<string | null>(null);
|
||||||
|
// eslint-disable-next-line vue/no-setup-props-reactivity-loss
|
||||||
const showBody = ref((props.persistKey && miLocalStorage.getItem(`${miLocalStoragePrefix}${props.persistKey}`)) ? (miLocalStorage.getItem(`${miLocalStoragePrefix}${props.persistKey}`) === 't') : props.expanded);
|
const showBody = ref((props.persistKey && miLocalStorage.getItem(`${miLocalStoragePrefix}${props.persistKey}`)) ? (miLocalStorage.getItem(`${miLocalStoragePrefix}${props.persistKey}`) === 't') : props.expanded);
|
||||||
|
|
||||||
watch(showBody, () => {
|
watch(showBody, () => {
|
||||||
|
@ -55,47 +57,34 @@ watch(showBody, () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function enter(element: Element) {
|
function enter(el: Element) {
|
||||||
const el = element as HTMLElement;
|
if (!(el instanceof HTMLElement)) return;
|
||||||
const elementHeight = el.getBoundingClientRect().height;
|
const elementHeight = el.getBoundingClientRect().height;
|
||||||
el.style.height = '0';
|
el.style.height = '0';
|
||||||
el.offsetHeight; // reflow
|
el.offsetHeight; // reflow
|
||||||
el.style.height = elementHeight + 'px';
|
el.style.height = `${elementHeight}px`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function afterEnter(element: Element) {
|
function afterEnter(el: Element) {
|
||||||
const el = element as HTMLElement;
|
if (!(el instanceof HTMLElement)) return;
|
||||||
el.style.height = 'unset';
|
el.style.height = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
function leave(element: Element) {
|
function leave(el: Element) {
|
||||||
const el = element as HTMLElement;
|
if (!(el instanceof HTMLElement)) return;
|
||||||
const elementHeight = el.getBoundingClientRect().height;
|
const elementHeight = el.getBoundingClientRect().height;
|
||||||
el.style.height = elementHeight + 'px';
|
el.style.height = `${elementHeight}px`;
|
||||||
el.offsetHeight; // reflow
|
el.offsetHeight; // reflow
|
||||||
el.style.height = '0';
|
el.style.height = '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
function afterLeave(element: Element) {
|
function afterLeave(el: Element) {
|
||||||
const el = element as HTMLElement;
|
if (!(el instanceof HTMLElement)) return;
|
||||||
el.style.height = 'unset';
|
el.style.height = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
function getParentBg(el?: HTMLElement | null): string {
|
parentBg.value = getBgColor(rootEl.value?.parentElement);
|
||||||
if (el == null || el.tagName === 'BODY') return 'var(--MI_THEME-bg)';
|
|
||||||
const background = el.style.background || el.style.backgroundColor;
|
|
||||||
if (background) {
|
|
||||||
return background;
|
|
||||||
} else {
|
|
||||||
return getParentBg(el.parentElement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const rawBg = getParentBg(rootEl.value);
|
|
||||||
const _bg = tinycolor(rawBg.startsWith('var(') ? getComputedStyle(document.documentElement).getPropertyValue(rawBg.slice(4, -1)) : rawBg);
|
|
||||||
_bg.setAlpha(0.85);
|
|
||||||
bg.value = _bg.toRgbString();
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -121,6 +110,7 @@ onMounted(() => {
|
||||||
top: var(--MI-stickyTop, 0px);
|
top: var(--MI-stickyTop, 0px);
|
||||||
-webkit-backdrop-filter: var(--MI-blur, blur(8px));
|
-webkit-backdrop-filter: var(--MI-blur, blur(8px));
|
||||||
backdrop-filter: var(--MI-blur, blur(20px));
|
backdrop-filter: var(--MI-blur, blur(20px));
|
||||||
|
background-color: color(from v-bind("parentBg ?? 'var(--bg)'") srgb r g b / 0.85);
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
|
|
|
@ -56,8 +56,9 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { nextTick, onMounted, shallowRef, ref } from 'vue';
|
import { nextTick, onMounted, ref, shallowRef } from 'vue';
|
||||||
import { defaultStore } from '@/store.js';
|
import { defaultStore } from '@/store.js';
|
||||||
|
import { getBgColor } from '@/scripts/get-bg-color.js';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
defaultOpen?: boolean;
|
defaultOpen?: boolean;
|
||||||
|
@ -69,40 +70,35 @@ const props = withDefaults(defineProps<{
|
||||||
withSpacer: true,
|
withSpacer: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
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;
|
|
||||||
} else {
|
|
||||||
return el.parentElement ? getBgColor(el.parentElement) : 'transparent';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const rootEl = shallowRef<HTMLElement>();
|
const rootEl = shallowRef<HTMLElement>();
|
||||||
const bgSame = ref(false);
|
const bgSame = ref(false);
|
||||||
const opened = ref(props.defaultOpen);
|
const opened = ref(props.defaultOpen);
|
||||||
const openedAtLeastOnce = ref(props.defaultOpen);
|
const openedAtLeastOnce = ref(props.defaultOpen);
|
||||||
|
|
||||||
function enter(el) {
|
function enter(el: Element) {
|
||||||
|
if (!(el instanceof HTMLElement)) return;
|
||||||
const elementHeight = el.getBoundingClientRect().height;
|
const elementHeight = el.getBoundingClientRect().height;
|
||||||
el.style.height = 0;
|
el.style.height = '0';
|
||||||
el.offsetHeight; // reflow
|
el.offsetHeight; // reflow
|
||||||
el.style.height = Math.min(elementHeight, props.maxHeight ?? Infinity) + 'px';
|
el.style.height = `${Math.min(elementHeight, props.maxHeight ?? Infinity)}px`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function afterEnter(el) {
|
function afterEnter(el: Element) {
|
||||||
el.style.height = null;
|
if (!(el instanceof HTMLElement)) return;
|
||||||
|
el.style.height = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
function leave(el) {
|
function leave(el: Element) {
|
||||||
|
if (!(el instanceof HTMLElement)) return;
|
||||||
const elementHeight = el.getBoundingClientRect().height;
|
const elementHeight = el.getBoundingClientRect().height;
|
||||||
el.style.height = elementHeight + 'px';
|
el.style.height = `${elementHeight}px`;
|
||||||
el.offsetHeight; // reflow
|
el.offsetHeight; // reflow
|
||||||
el.style.height = 0;
|
el.style.height = '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
function afterLeave(el) {
|
function afterLeave(el: Element) {
|
||||||
el.style.height = null;
|
if (!(el instanceof HTMLElement)) return;
|
||||||
|
el.style.height = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggle() {
|
function toggle() {
|
||||||
|
@ -117,7 +113,7 @@ function toggle() {
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const computedStyle = getComputedStyle(document.documentElement);
|
const computedStyle = getComputedStyle(document.documentElement);
|
||||||
const parentBg = getBgColor(rootEl.value!.parentElement!);
|
const parentBg = getBgColor(rootEl.value?.parentElement) ?? 'transparent';
|
||||||
const myBg = computedStyle.getPropertyValue('--MI_THEME-panel');
|
const myBg = computedStyle.getPropertyValue('--MI_THEME-panel');
|
||||||
bgSame.value = parentBg === myBg;
|
bgSame.value = parentBg === myBg;
|
||||||
});
|
});
|
||||||
|
|
|
@ -53,7 +53,7 @@ export type Tab = {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, onUnmounted, watch, nextTick, shallowRef } from 'vue';
|
import { nextTick, onMounted, onUnmounted, shallowRef, watch } from 'vue';
|
||||||
import { defaultStore } from '@/store.js';
|
import { defaultStore } from '@/store.js';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
|
@ -120,14 +120,14 @@ function onTabWheel(ev: WheelEvent) {
|
||||||
|
|
||||||
let entering = false;
|
let entering = false;
|
||||||
|
|
||||||
async function enter(element: Element) {
|
async function enter(el: Element) {
|
||||||
|
if (!(el instanceof HTMLElement)) return;
|
||||||
entering = true;
|
entering = true;
|
||||||
const el = element as HTMLElement;
|
|
||||||
const elementWidth = el.getBoundingClientRect().width;
|
const elementWidth = el.getBoundingClientRect().width;
|
||||||
el.style.width = '0';
|
el.style.width = '0';
|
||||||
el.style.paddingLeft = '0';
|
el.style.paddingLeft = '0';
|
||||||
el.offsetWidth; // force reflow
|
el.offsetWidth; // reflow
|
||||||
el.style.width = elementWidth + 'px';
|
el.style.width = `${elementWidth}px`;
|
||||||
el.style.paddingLeft = '';
|
el.style.paddingLeft = '';
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
entering = false;
|
entering = false;
|
||||||
|
@ -136,22 +136,23 @@ async function enter(element: Element) {
|
||||||
setTimeout(renderTab, 170);
|
setTimeout(renderTab, 170);
|
||||||
}
|
}
|
||||||
|
|
||||||
function afterEnter(element: Element) {
|
function afterEnter(el: Element) {
|
||||||
//el.style.width = '';
|
if (!(el instanceof HTMLElement)) return;
|
||||||
|
// element.style.width = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
async function leave(element: Element) {
|
async function leave(el: Element) {
|
||||||
const el = element as HTMLElement;
|
if (!(el instanceof HTMLElement)) return;
|
||||||
const elementWidth = el.getBoundingClientRect().width;
|
const elementWidth = el.getBoundingClientRect().width;
|
||||||
el.style.width = elementWidth + 'px';
|
el.style.width = `${elementWidth}px`;
|
||||||
el.style.paddingLeft = '';
|
el.style.paddingLeft = '';
|
||||||
el.offsetWidth; // force reflow
|
el.offsetWidth; // reflow
|
||||||
el.style.width = '0';
|
el.style.width = '0';
|
||||||
el.style.paddingLeft = '0';
|
el.style.paddingLeft = '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
function afterLeave(element: Element) {
|
function afterLeave(el: Element) {
|
||||||
const el = element as HTMLElement;
|
if (!(el instanceof HTMLElement)) return;
|
||||||
el.style.width = '';
|
el.style.width = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,19 +4,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Directive } from 'vue';
|
import { Directive } from 'vue';
|
||||||
|
import { getBgColor } from '@/scripts/get-bg-color.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mounted(src, binding, vn) {
|
mounted(src, binding, vn) {
|
||||||
const getBgColor = (el: HTMLElement) => {
|
const parentBg = getBgColor(src.parentElement) ?? 'transparent';
|
||||||
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;
|
|
||||||
} else {
|
|
||||||
return el.parentElement ? getBgColor(el.parentElement) : 'transparent';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const parentBg = getBgColor(src.parentElement);
|
|
||||||
|
|
||||||
const myBg = window.getComputedStyle(src).backgroundColor;
|
const myBg = window.getComputedStyle(src).backgroundColor;
|
||||||
|
|
||||||
|
|
|
@ -4,19 +4,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Directive } from 'vue';
|
import { Directive } from 'vue';
|
||||||
|
import { getBgColor } from '@/scripts/get-bg-color.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mounted(src, binding, vn) {
|
mounted(src, binding, vn) {
|
||||||
const getBgColor = (el: HTMLElement) => {
|
const parentBg = getBgColor(src.parentElement) ?? 'transparent';
|
||||||
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;
|
|
||||||
} else {
|
|
||||||
return el.parentElement ? getBgColor(el.parentElement) : 'transparent';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const parentBg = getBgColor(src.parentElement);
|
|
||||||
|
|
||||||
const myBg = window.getComputedStyle(src).backgroundColor;
|
const myBg = window.getComputedStyle(src).backgroundColor;
|
||||||
|
|
||||||
|
|
|
@ -4,19 +4,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Directive } from 'vue';
|
import { Directive } from 'vue';
|
||||||
|
import { getBgColor } from '@/scripts/get-bg-color.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mounted(src, binding, vn) {
|
mounted(src, binding, vn) {
|
||||||
const getBgColor = (el: HTMLElement) => {
|
const parentBg = getBgColor(src.parentElement) ?? 'transparent';
|
||||||
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;
|
|
||||||
} else {
|
|
||||||
return el.parentElement ? getBgColor(el.parentElement) : 'transparent';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const parentBg = getBgColor(src.parentElement);
|
|
||||||
|
|
||||||
const myBg = getComputedStyle(document.documentElement).getPropertyValue('--MI_THEME-panel');
|
const myBg = getComputedStyle(document.documentElement).getPropertyValue('--MI_THEME-panel');
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MkStickyContainer>
|
<MkStickyContainer>
|
||||||
<template #header>
|
<template #header><MkPageHeader/></template>
|
||||||
<MkPageHeader/>
|
<MkSpacer v-if="!instance.disableRegistration || !($i && ($i.isAdmin || $i.policies.canInvite))" :contentMax="1200">
|
||||||
</template>
|
|
||||||
<MKSpacer v-if="!instance.disableRegistration || !($i && ($i.isAdmin || $i.policies.canInvite))" :contentMax="1200">
|
|
||||||
<div :class="$style.root">
|
<div :class="$style.root">
|
||||||
<img :class="$style.img" :src="serverErrorImageUrl" class="_ghost"/>
|
<img :class="$style.img" :src="serverErrorImageUrl" class="_ghost"/>
|
||||||
<div :class="$style.text">
|
<div :class="$style.text">
|
||||||
|
@ -16,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
{{ i18n.ts.nothing }}
|
{{ i18n.ts.nothing }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</MKSpacer>
|
</MkSpacer>
|
||||||
<MkSpacer v-else :contentMax="800">
|
<MkSpacer v-else :contentMax="800">
|
||||||
<div class="_gaps_m" style="text-align: center;">
|
<div class="_gaps_m" style="text-align: center;">
|
||||||
<div v-if="resetCycle && inviteLimit">{{ i18n.tsx.inviteLimitResetCycle({ time: resetCycle, limit: inviteLimit }) }}</div>
|
<div v-if="resetCycle && inviteLimit">{{ i18n.tsx.inviteLimitResetCycle({ time: resetCycle, limit: inviteLimit }) }}</div>
|
||||||
|
|
|
@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<template>
|
<template>
|
||||||
<MkStickyContainer>
|
<MkStickyContainer>
|
||||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||||
<MKSpacer v-if="!(typeof error === 'undefined')" :contentMax="1200">
|
<MkSpacer v-if="error != null" :contentMax="1200">
|
||||||
<div :class="$style.root">
|
<div :class="$style.root">
|
||||||
<img :class="$style.img" :src="serverErrorImageUrl" class="_ghost"/>
|
<img :class="$style.img" :src="serverErrorImageUrl" class="_ghost"/>
|
||||||
<p :class="$style.text">
|
<p :class="$style.text">
|
||||||
|
@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
{{ i18n.ts.nothing }}
|
{{ i18n.ts.nothing }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</MKSpacer>
|
</MkSpacer>
|
||||||
<MkSpacer v-else-if="list" :contentMax="700" :class="$style.main">
|
<MkSpacer v-else-if="list" :contentMax="700" :class="$style.main">
|
||||||
<div v-if="list" class="members _margin">
|
<div v-if="list" class="members _margin">
|
||||||
<div :class="$style.member_text">{{ i18n.ts.members }}</div>
|
<div :class="$style.member_text">{{ i18n.ts.members }}</div>
|
||||||
|
@ -50,7 +50,7 @@ const props = defineProps<{
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const list = ref<Misskey.entities.UserList | null>(null);
|
const list = ref<Misskey.entities.UserList | null>(null);
|
||||||
const error = ref();
|
const error = ref<unknown | null>(null);
|
||||||
const users = ref<Misskey.entities.UserDetailed[]>([]);
|
const users = ref<Misskey.entities.UserDetailed[]>([]);
|
||||||
|
|
||||||
function fetchList(): void {
|
function fetchList(): void {
|
||||||
|
|
|
@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<template>
|
<template>
|
||||||
<MkStickyContainer>
|
<MkStickyContainer>
|
||||||
<template #header><MkPageHeader v-model:tab="tab" :tabs="headerTabs"/></template>
|
<template #header><MkPageHeader v-model:tab="tab" :tabs="headerTabs"/></template>
|
||||||
<MKSpacer v-if="!(typeof error === 'undefined')" :contentMax="1200">
|
<MkSpacer v-if="error != null" :contentMax="1200">
|
||||||
<div :class="$style.root">
|
<div :class="$style.root">
|
||||||
<img :class="$style.img" :src="serverErrorImageUrl" class="_ghost"/>
|
<img :class="$style.img" :src="serverErrorImageUrl" class="_ghost"/>
|
||||||
<p :class="$style.text">
|
<p :class="$style.text">
|
||||||
|
@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
{{ error }}
|
{{ error }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</MKSpacer>
|
</MkSpacer>
|
||||||
<MkSpacer v-else-if="tab === 'users'" :contentMax="1200">
|
<MkSpacer v-else-if="tab === 'users'" :contentMax="1200">
|
||||||
<div class="_gaps_s">
|
<div class="_gaps_s">
|
||||||
<div v-if="role">{{ role.description }}</div>
|
<div v-if="role">{{ role.description }}</div>
|
||||||
|
@ -26,7 +26,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</div>
|
</div>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
<MkSpacer v-else-if="tab === 'timeline'" :contentMax="700">
|
<MkSpacer v-else-if="tab === 'timeline'" :contentMax="700">
|
||||||
<MkTimeline v-if="visible" ref="timeline" src="role" :role="props.role"/>
|
<MkTimeline v-if="visible" ref="timeline" src="role" :role="props.roleId"/>
|
||||||
<div v-else-if="!visible" class="_fullinfo">
|
<div v-else-if="!visible" class="_fullinfo">
|
||||||
<img :src="infoImageUrl" class="_ghost"/>
|
<img :src="infoImageUrl" class="_ghost"/>
|
||||||
<div>{{ i18n.ts.nothing }}</div>
|
<div>{{ i18n.ts.nothing }}</div>
|
||||||
|
@ -47,23 +47,24 @@ import { instanceName } from '@@/js/config.js';
|
||||||
import { serverErrorImageUrl, infoImageUrl } from '@/instance.js';
|
import { serverErrorImageUrl, infoImageUrl } from '@/instance.js';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
role: string;
|
roleId: string;
|
||||||
initialTab?: string;
|
initialTab?: string;
|
||||||
}>(), {
|
}>(), {
|
||||||
initialTab: 'users',
|
initialTab: 'users',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// eslint-disable-next-line vue/no-setup-props-reactivity-loss
|
||||||
const tab = ref(props.initialTab);
|
const tab = ref(props.initialTab);
|
||||||
const role = ref<Misskey.entities.Role>();
|
const role = ref<Misskey.entities.Role | null>(null);
|
||||||
const error = ref();
|
const error = ref<string | null>(null);
|
||||||
const visible = ref(false);
|
const visible = ref(false);
|
||||||
|
|
||||||
watch(() => props.role, () => {
|
watch(() => props.roleId, () => {
|
||||||
misskeyApi('roles/show', {
|
misskeyApi('roles/show', {
|
||||||
roleId: props.role,
|
roleId: props.roleId,
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
role.value = res;
|
role.value = res;
|
||||||
document.title = `${role.value.name} | ${instanceName}`;
|
error.value = null;
|
||||||
visible.value = res.isExplorable && res.isPublic;
|
visible.value = res.isExplorable && res.isPublic;
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
if (err.code === 'NO_SUCH_ROLE') {
|
if (err.code === 'NO_SUCH_ROLE') {
|
||||||
|
@ -71,7 +72,6 @@ watch(() => props.role, () => {
|
||||||
} else {
|
} else {
|
||||||
error.value = i18n.ts.somethingHappened;
|
error.value = i18n.ts.somethingHappened;
|
||||||
}
|
}
|
||||||
document.title = `${error.value} | ${instanceName}`;
|
|
||||||
});
|
});
|
||||||
}, { immediate: true });
|
}, { immediate: true });
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ const users = computed(() => ({
|
||||||
endpoint: 'roles/users' as const,
|
endpoint: 'roles/users' as const,
|
||||||
limit: 30,
|
limit: 30,
|
||||||
params: {
|
params: {
|
||||||
roleId: props.role,
|
roleId: props.roleId,
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ const headerTabs = computed(() => [{
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
definePageMetadata(() => ({
|
definePageMetadata(() => ({
|
||||||
title: role.value ? role.value.name : i18n.ts.role,
|
title: role.value ? role.value.name : (error.value ?? i18n.ts.role),
|
||||||
icon: 'ti ti-badge',
|
icon: 'ti ti-badge',
|
||||||
}));
|
}));
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -217,7 +217,7 @@ const routes: RouteDef[] = [{
|
||||||
component: page(() => import('@/pages/theme-editor.vue')),
|
component: page(() => import('@/pages/theme-editor.vue')),
|
||||||
loginRequired: true,
|
loginRequired: true,
|
||||||
}, {
|
}, {
|
||||||
path: '/roles/:role',
|
path: '/roles/:roleId',
|
||||||
component: page(() => import('@/pages/role.vue')),
|
component: page(() => import('@/pages/role.vue')),
|
||||||
}, {
|
}, {
|
||||||
path: '/user-tags/:tag',
|
path: '/user-tags/:tag',
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
import tinycolor from 'tinycolor2';
|
||||||
|
|
||||||
|
export const getBgColor = (elem?: Element | null | undefined): string | null => {
|
||||||
|
if (elem == null) return null;
|
||||||
|
|
||||||
|
const { backgroundColor: bg } = window.getComputedStyle(elem);
|
||||||
|
|
||||||
|
if (bg && tinycolor(bg).getAlpha() !== 0) {
|
||||||
|
return bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getBgColor(elem.parentElement);
|
||||||
|
};
|
Loading…
Reference in New Issue