fix types
This commit is contained in:
parent
9a42745926
commit
5994a1d615
11 changed files with 133 additions and 51 deletions
|
@ -1,6 +1,8 @@
|
|||
export function collectPageVars(content) {
|
||||
const pageVars = [];
|
||||
const collect = (xs: any[]) => {
|
||||
import type { PageContent, PageVar } from "@/types/page";
|
||||
|
||||
export function collectPageVars(content: PageContent[]) {
|
||||
const pageVars: PageVar[] = [];
|
||||
const collect = (xs: PageContent[]) => {
|
||||
for (const x of xs) {
|
||||
if (x.type === "textInput") {
|
||||
pageVars.push({
|
||||
|
@ -24,7 +26,7 @@ export function collectPageVars(content) {
|
|||
pageVars.push({
|
||||
name: x.name,
|
||||
type: "boolean",
|
||||
value: x.default,
|
||||
value: x.default!,
|
||||
});
|
||||
} else if (x.type === "counter") {
|
||||
pageVars.push({
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Clipboardに値をコピー(TODO: 文字列以外も対応)
|
||||
*/
|
||||
export default (val) => {
|
||||
function obsoleteCopyToClipboard(val: string) {
|
||||
// 空div 生成
|
||||
const tmp = document.createElement("div");
|
||||
// 選択用のタグ生成
|
||||
|
@ -21,7 +21,7 @@ export default (val) => {
|
|||
// body に追加
|
||||
document.body.appendChild(tmp);
|
||||
// 要素を選択
|
||||
document.getSelection().selectAllChildren(tmp);
|
||||
document.getSelection()?.selectAllChildren(tmp);
|
||||
|
||||
// クリップボードにコピー
|
||||
const result = document.execCommand("copy");
|
||||
|
@ -30,4 +30,20 @@ export default (val) => {
|
|||
document.body.removeChild(tmp);
|
||||
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
export default async function (val?: string | null) {
|
||||
if (val == null) return true;
|
||||
const clipboardObj = window.navigator?.clipboard;
|
||||
if (clipboardObj == null) {
|
||||
// not supported
|
||||
return obsoleteCopyToClipboard(val);
|
||||
} else {
|
||||
return new Promise<boolean>((res) => {
|
||||
clipboardObj
|
||||
.writeText(val)
|
||||
.then(() => res(true))
|
||||
.catch(() => res(obsoleteCopyToClipboard(val)));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ export function extractMentions(
|
|||
nodes: mfm.MfmNode[],
|
||||
): mfm.MfmMention["props"][] {
|
||||
// TODO: 重複を削除
|
||||
const mentionNodes = mfm.extract(nodes, (node) => node.type === "mention");
|
||||
const mentionNodes = mfm.extract(nodes, (node) => node.type === "mention") as mfm.MfmMention[];
|
||||
const mentions = mentionNodes.map((x) => x.props);
|
||||
|
||||
return mentions;
|
||||
|
|
|
@ -15,7 +15,8 @@ const animatedMfm = [
|
|||
export function extractMfmWithAnimation(nodes: mfm.MfmNode[]): string[] {
|
||||
const mfmNodes = mfm.extract(nodes, (node) => {
|
||||
return node.type === "fn" && animatedMfm.includes(node.props.name);
|
||||
});
|
||||
}) as mfm.MfmFn[];
|
||||
// FIXME: mfm type error
|
||||
const mfms = mfmNodes.map((x) => x.props.fn);
|
||||
|
||||
return mfms;
|
||||
|
|
|
@ -14,7 +14,7 @@ export function extractUrlFromMfm(
|
|||
node.type === "url" ||
|
||||
(node.type === "link" && !(respectSilentFlag && node.props.silent))
|
||||
);
|
||||
});
|
||||
}) as (mfm.MfmLink | mfm.MfmUrl)[];
|
||||
const urls: string[] = unique(urlNodes.map((x) => x.props.url));
|
||||
|
||||
return urls.reduce((array, url) => {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
export function focusPrev(el: Element | null, self = false, scroll = true) {
|
||||
if (el == null) return;
|
||||
// biome-ignore lint/style/noParameterAssign: assign it intentionally
|
||||
if (!self) el = el.previousElementSibling;
|
||||
if (el) {
|
||||
if (el.hasAttribute("tabindex")) {
|
||||
|
@ -14,6 +15,7 @@ export function focusPrev(el: Element | null, self = false, scroll = true) {
|
|||
|
||||
export function focusNext(el: Element | null, self = false, scroll = true) {
|
||||
if (el == null) return;
|
||||
// biome-ignore lint/style/noParameterAssign: assign it intentionally
|
||||
if (!self) el = el.nextElementSibling;
|
||||
if (el) {
|
||||
if (el.hasAttribute("tabindex")) {
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
import { acct } from "firefish-js";
|
||||
import { host as localHost } from "@/config";
|
||||
|
||||
export async function genSearchQuery(v: any, q: string) {
|
||||
let host: string;
|
||||
let userId: string;
|
||||
if (q.split(" ").some((x) => x.startsWith("@"))) {
|
||||
for (const at of q
|
||||
.split(" ")
|
||||
.filter((x) => x.startsWith("@"))
|
||||
.map((x) => x.slice(1))) {
|
||||
if (at.includes(".")) {
|
||||
if (at === localHost || at === ".") {
|
||||
host = null;
|
||||
} else {
|
||||
host = at;
|
||||
}
|
||||
} else {
|
||||
const user = await v.os
|
||||
.api("users/show", acct.parse(at))
|
||||
.catch((x) => null);
|
||||
if (user) {
|
||||
userId = user.id;
|
||||
} else {
|
||||
// todo: show error
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
query: q
|
||||
.split(" ")
|
||||
.filter((x) => !(x.startsWith("/") || x.startsWith("@")))
|
||||
.join(" "),
|
||||
host,
|
||||
userId,
|
||||
};
|
||||
}
|
|
@ -15,6 +15,7 @@ import { useRouter } from "@/router";
|
|||
import { notePage } from "@/filters/note";
|
||||
import type { NoteTranslation } from "@/types/note";
|
||||
import type { MenuItem } from "@/types/menu";
|
||||
import type { NoteDraft } from "@/types/post-form";
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
|
@ -61,7 +62,7 @@ export function getNoteMenu(props: {
|
|||
});
|
||||
|
||||
os.post({
|
||||
initialNote: appearNote,
|
||||
initialNote: appearNote as NoteDraft,
|
||||
renote: appearNote.renote,
|
||||
reply: appearNote.reply,
|
||||
channel: appearNote.channel,
|
||||
|
@ -71,7 +72,7 @@ export function getNoteMenu(props: {
|
|||
|
||||
function edit(): void {
|
||||
os.post({
|
||||
initialNote: appearNote,
|
||||
initialNote: appearNote as NoteDraft,
|
||||
renote: appearNote.renote,
|
||||
reply: appearNote.reply,
|
||||
channel: appearNote.channel,
|
||||
|
|
78
packages/client/src/types/page.ts
Normal file
78
packages/client/src/types/page.ts
Normal file
|
@ -0,0 +1,78 @@
|
|||
import type { TypeUtils } from "firefish-js";
|
||||
|
||||
export type BasePageContent = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
export type PageContentTextInput = BasePageContent & {
|
||||
type: "textInput";
|
||||
default: string;
|
||||
};
|
||||
|
||||
export type PageContentTextareaInput = BasePageContent & {
|
||||
type: "textareaInput";
|
||||
default?: string;
|
||||
};
|
||||
|
||||
export type PageContentNumberInput = BasePageContent & {
|
||||
type: "numberInput";
|
||||
default?: number;
|
||||
};
|
||||
|
||||
export type PageContentSwitch = BasePageContent & {
|
||||
type: "switch";
|
||||
default?: boolean;
|
||||
};
|
||||
export type PageContentCounter = BasePageContent & {
|
||||
type: "counter";
|
||||
default?: number;
|
||||
};
|
||||
|
||||
export type PageContentRadioButton = BasePageContent & {
|
||||
type: "radioButton";
|
||||
default?: string;
|
||||
};
|
||||
|
||||
export type PageContentChildren =
|
||||
| PageContentTextInput
|
||||
| PageContentTextareaInput
|
||||
| PageContentNumberInput
|
||||
| PageContentSwitch
|
||||
| PageContentCounter
|
||||
| PageContentRadioButton;
|
||||
|
||||
export type PageContentParent = {
|
||||
type: "parent";
|
||||
children: PageContentChildren[];
|
||||
};
|
||||
|
||||
export type PageContent = PageContentParent | PageContentChildren;
|
||||
|
||||
export type GetPageVar<T extends PageContentChildren> = {
|
||||
name: string;
|
||||
type: TypeUtils.NonUndefinedAble<T["default"]> extends string
|
||||
? "string"
|
||||
: TypeUtils.NonUndefinedAble<T["default"]> extends boolean
|
||||
? "boolean"
|
||||
: TypeUtils.NonUndefinedAble<T["default"]> extends number
|
||||
? "number"
|
||||
: never;
|
||||
value: TypeUtils.NonUndefinedAble<T["default"]>;
|
||||
};
|
||||
|
||||
export type PageVar =
|
||||
| {
|
||||
name: string;
|
||||
type: "string";
|
||||
value: string;
|
||||
}
|
||||
| {
|
||||
name: string;
|
||||
type: "boolean";
|
||||
value: boolean;
|
||||
}
|
||||
| {
|
||||
name: string;
|
||||
type: "number";
|
||||
value: number;
|
||||
};
|
|
@ -263,7 +263,7 @@ export type Endpoints = {
|
|||
|
||||
// clips
|
||||
"clips/add-note": { req: TODO; res: TODO };
|
||||
"clips/create": { req: TODO; res: TODO };
|
||||
"clips/create": { req: TODO; res: Clip };
|
||||
"clips/delete": { req: { clipId: Clip["id"] }; res: null };
|
||||
"clips/list": { req: TODO; res: TODO };
|
||||
"clips/notes": { req: TODO; res: TODO };
|
||||
|
@ -748,6 +748,18 @@ export type Endpoints = {
|
|||
};
|
||||
res: Note[];
|
||||
};
|
||||
"notes/thread-muting/create": {
|
||||
req: {
|
||||
noteId: Note["id"];
|
||||
};
|
||||
res: null;
|
||||
};
|
||||
"notes/thread-muting/delete": {
|
||||
req: {
|
||||
noteId: Note["id"];
|
||||
};
|
||||
res: null;
|
||||
};
|
||||
"notes/hybrid-timeline": {
|
||||
req: {
|
||||
limit?: number;
|
||||
|
@ -768,6 +780,12 @@ export type Endpoints = {
|
|||
};
|
||||
res: Note[];
|
||||
};
|
||||
"notes/make-private": {
|
||||
req: {
|
||||
noteId: Note["id"];
|
||||
};
|
||||
res: null;
|
||||
}
|
||||
"notes/mentions": {
|
||||
req: {
|
||||
following?: boolean;
|
||||
|
|
|
@ -5,3 +5,5 @@ export type PropertyOfType<Type, U> = {
|
|||
}[keyof Type];
|
||||
|
||||
export type EndpointsOf<T> = PropertyOfType<Endpoints, { res: T }>;
|
||||
|
||||
export type NonUndefinedAble<T> = T extends undefined ? never : T;
|
||||
|
|
Loading…
Reference in a new issue