Merge remote-tracking branch 'misskey-dev/develop' into io
This commit is contained in:
@@ -93,9 +93,11 @@ export class Autocomplete {
|
||||
return;
|
||||
}
|
||||
|
||||
const afterLastMfmParam = text.split(/\$\[[a-zA-Z]+/).pop();
|
||||
|
||||
const isMention = mentionIndex !== -1;
|
||||
const isHashtag = hashtagIndex !== -1;
|
||||
const isMfmParam = mfmParamIndex !== -1 && text.split(/\$\[[a-zA-Z]+/).pop()?.includes('.');
|
||||
const isMfmParam = mfmParamIndex !== -1 && afterLastMfmParam?.includes('.') && !afterLastMfmParam?.includes(' ');
|
||||
const isMfmTag = mfmTagIndex !== -1 && !isMfmParam;
|
||||
const isEmoji = emojiIndex !== -1 && text.split(/:[a-z0-9_+\-]+:/).pop()!.includes(':');
|
||||
|
||||
|
@@ -102,10 +102,13 @@ export function getAbuseNoteMenu(note: Misskey.entities.Note, text: string): Men
|
||||
icon: 'ti ti-exclamation-circle',
|
||||
text,
|
||||
action: (): void => {
|
||||
const u = note.url ?? note.uri ?? `${url}/notes/${note.id}`;
|
||||
const localUrl = `${url}/notes/${note.id}`;
|
||||
let noteInfo = '';
|
||||
if (note.url ?? note.uri != null) noteInfo = `Note: ${note.url ?? note.uri}\n`;
|
||||
noteInfo += `Local Note: ${localUrl}\n`;
|
||||
os.popup(defineAsyncComponent(() => import('@/components/MkAbuseReportWindow.vue')), {
|
||||
user: note.user,
|
||||
initialComment: `Note: ${u}\n-----\n`,
|
||||
initialComment: `${noteInfo}-----\n`,
|
||||
}, {}, 'closed');
|
||||
},
|
||||
};
|
||||
|
@@ -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');
|
||||
}
|
||||
|
@@ -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);
|
||||
};
|
||||
|
@@ -188,7 +188,7 @@ export async function loadAudio(url: string, options?: { useCache?: boolean; })
|
||||
*/
|
||||
export function playMisskeySfx(operationType: OperationType) {
|
||||
const sound = defaultStore.state[`sound_${operationType}`];
|
||||
if (sound.type == null || !canPlay) return;
|
||||
if (sound.type == null || !canPlay || !navigator.userActivation.hasBeenActive) return;
|
||||
|
||||
canPlay = false;
|
||||
playMisskeySfxFile(sound).finally(() => {
|
||||
|
Reference in New Issue
Block a user