Merge remote-tracking branch 'misskey-original/develop' into develop

# Conflicts:
#	package.json
#	packages/backend/src/core/QueueService.ts
#	packages/frontend/src/components/global/MkPageHeader.vue
#	packages/frontend/src/pages/admin/index.vue
#	packages/frontend/src/pages/clicker.vue
#	packages/frontend/src/pages/my-lists/index.vue
#	packages/frontend/src/pages/notifications.vue
#	packages/frontend/src/pages/settings/emoji-picker.vue
#	packages/frontend/src/pages/settings/mute-block.vue
#	packages/frontend/src/pages/timeline.vue
#	packages/frontend/src/ui/universal.vue
#	pnpm-lock.yaml
This commit is contained in:
mattyatea 2024-02-16 19:40:51 +09:00
commit 2b52a215e5
238 changed files with 3369 additions and 3002 deletions

View file

@ -6,6 +6,10 @@
import { deepClone } from './clone.js';
import type { Cloneable } from './clone.js';
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends Record<string | number | symbol, unknown> ? DeepPartial<T[P]> : T[P];
};
function isPureObject(value: unknown): value is Record<string | number | symbol, unknown> {
return typeof value === 'object' && value !== null && !Array.isArray(value);
}
@ -14,18 +18,18 @@ function isPureObject(value: unknown): value is Record<string | number | symbol,
* valueにないキーをdefからもらう\
* nullはそのままundefinedはdefの値
**/
export function deepMerge<X extends Record<string | number | symbol, unknown>>(value: X, def: X): X {
export function deepMerge<X extends Record<string | number | symbol, unknown>>(value: DeepPartial<X>, def: X): X {
if (isPureObject(value) && isPureObject(def)) {
const result = deepClone(value as Cloneable) as X;
for (const [k, v] of Object.entries(def) as [keyof X, X[keyof X]][]) {
if (!Object.prototype.hasOwnProperty.call(value, k) || value[k] === undefined) {
result[k] = v;
} else if (isPureObject(v) && isPureObject(result[k])) {
const child = deepClone(result[k] as Cloneable) as X[keyof X] & Record<string | number | symbol, unknown>;
const child = deepClone(result[k] as Cloneable) as DeepPartial<X[keyof X] & Record<string | number | symbol, unknown>>;
result[k] = deepMerge<typeof v>(child, v);
}
}
return result;
}
return value;
throw new Error('deepMerge: value and def must be pure objects');
}

View file

@ -4,10 +4,7 @@
*/
import * as Misskey from 'misskey-js';
import { ComputedRef, inject, isRef, onActivated, onMounted, provide, ref, Ref } from 'vue';
export const setPageMetadata = Symbol('setPageMetadata');
export const pageMetadataProvider = Symbol('pageMetadataProvider');
import { MaybeRefOrGetter, Ref, inject, isRef, onActivated, onBeforeUnmount, provide, ref, toValue, watch } from 'vue';
export type PageMetadata = {
title: string;
@ -18,29 +15,56 @@ export type PageMetadata = {
needWideArea?: boolean;
};
export function definePageMetadata(metadata: PageMetadata | null | Ref<PageMetadata | null> | ComputedRef<PageMetadata | null>): void {
const _metadata = isRef(metadata) ? metadata : ref(metadata);
type PageMetadataGetter = () => PageMetadata;
type PageMetadataReceiver = (getter: PageMetadataGetter) => void;
provide(pageMetadataProvider, _metadata);
const RECEIVER_KEY = Symbol('ReceiverKey');
const setReceiver = (v: PageMetadataReceiver): void => {
provide<PageMetadataReceiver>(RECEIVER_KEY, v);
};
const getReceiver = (): PageMetadataReceiver | undefined => {
return inject<PageMetadataReceiver>(RECEIVER_KEY);
};
const set = inject(setPageMetadata) as any;
if (set) {
set(_metadata);
const METADATA_KEY = Symbol('MetadataKey');
const setMetadata = (v: Ref<PageMetadata | null>): void => {
provide<Ref<PageMetadata | null>>(METADATA_KEY, v);
};
const getMetadata = (): Ref<PageMetadata | null> | undefined => {
return inject<Ref<PageMetadata | null>>(METADATA_KEY);
};
onMounted(() => {
set(_metadata);
});
export const definePageMetadata = (maybeRefOrGetterMetadata: MaybeRefOrGetter<PageMetadata>): void => {
const metadataRef = ref(toValue(maybeRefOrGetterMetadata));
const metadataGetter = () => metadataRef.value;
const receiver = getReceiver();
onActivated(() => {
set(_metadata);
});
}
}
// setup handler
receiver?.(metadataGetter);
export function provideMetadataReceiver(callback: (info: ComputedRef<PageMetadata>) => void): void {
provide(setPageMetadata, callback);
}
// update handler
onBeforeUnmount(watch(
() => toValue(maybeRefOrGetterMetadata),
(metadata) => {
metadataRef.value = metadata;
receiver?.(metadataGetter);
},
{ deep: true },
));
onActivated(() => {
receiver?.(metadataGetter);
});
};
export function injectPageMetadata(): PageMetadata | undefined {
return inject(pageMetadataProvider);
}
export const provideMetadataReceiver = (receiver: PageMetadataReceiver): void => {
setReceiver(receiver);
};
export const provideReactiveMetadata = (metadataRef: Ref<PageMetadata | null>): void => {
setMetadata(metadataRef);
};
export const injectReactiveMetadata = (): Ref<PageMetadata | null> => {
const metadataRef = getMetadata();
return isRef(metadataRef) ? metadataRef : ref(null);
};