Merge branch 'develop' of https://codeberg.org/calckey/calckey into keyboard-accessability
This commit is contained in:
commit
9e7bd91f88
76 changed files with 875 additions and 219 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -42,6 +42,8 @@ api-docs.json
|
|||
files
|
||||
ormconfig.json
|
||||
packages/backend/assets/instance.css
|
||||
packages/backend/assets/sounds/None.mp3
|
||||
|
||||
|
||||
# blender backups
|
||||
*.blend1
|
||||
|
|
|
@ -124,6 +124,8 @@ psql postgres -c "create database calckey with encoding = 'UTF8';"
|
|||
- To add custom CSS for all users, edit `./custom/assets/instance.css`.
|
||||
- To add static assets (such as images for the splash screen), place them in the `./custom/assets/` directory. They'll then be available on `https://yourinstance.tld/static-assets/filename.ext`.
|
||||
- To add custom locales, place them in the `./custom/locales/` directory. If you name your custom locale the same as an existing locale, it will overwrite it. If you give it a unique name, it will be added to the list. Also make sure that the first part of the filename matches the locale you're basing it on. (Example: `en-FOO.yml`)
|
||||
- To add custom error images, place them in the `./custom/assets/badges` directory, replacing the files already there.
|
||||
- To add custom sounds, place only mp3 files in the `./custom/assets/sounds` directory.
|
||||
- To update custom assets without rebuilding, just run `pnpm run gulp`.
|
||||
|
||||
## 🧑🔬 Configuring a new instance
|
||||
|
|
BIN
custom/assets/badges/error.png
Normal file
BIN
custom/assets/badges/error.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 57 KiB |
BIN
custom/assets/badges/info.png
Normal file
BIN
custom/assets/badges/info.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 55 KiB |
BIN
custom/assets/badges/not-found.png
Normal file
BIN
custom/assets/badges/not-found.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 56 KiB |
|
@ -15,8 +15,9 @@ gulp.task('copy:backend:views', () =>
|
|||
gulp.src('./packages/backend/src/server/web/views/**/*').pipe(gulp.dest('./packages/backend/built/server/web/views'))
|
||||
);
|
||||
|
||||
|
||||
gulp.task('copy:backend:custom', () =>
|
||||
gulp.src('./custom/assets/*').pipe(gulp.dest('./packages/backend/assets/'))
|
||||
gulp.src('./custom/assets/**/*').pipe(gulp.dest('./packages/backend/assets/'))
|
||||
);
|
||||
|
||||
gulp.task('copy:client:fonts', () =>
|
||||
|
|
|
@ -32,6 +32,7 @@ uploading: "Uploading..."
|
|||
save: "Save"
|
||||
users: "Users"
|
||||
addUser: "Add a user"
|
||||
addInstance: "Add an instance"
|
||||
favorite: "Add to bookmarks"
|
||||
favorites: "Bookmarks"
|
||||
unfavorite: "Remove from bookmarks"
|
||||
|
@ -160,6 +161,7 @@ proxyAccount: "Proxy account"
|
|||
proxyAccountDescription: "A proxy account is an account that acts as a remote follower for users under certain conditions. For example, when a user adds a remote user to the list, the remote user's activity will not be delivered to the instance if no local user is following that user, so the proxy account will follow instead."
|
||||
host: "Host"
|
||||
selectUser: "Select a user"
|
||||
selectInstance: "Select an instance"
|
||||
recipient: "Recipient(s)"
|
||||
annotation: "Comments"
|
||||
federation: "Federation"
|
||||
|
@ -197,6 +199,7 @@ muteAndBlock: "Mutes and Blocks"
|
|||
mutedUsers: "Muted users"
|
||||
blockedUsers: "Blocked users"
|
||||
noUsers: "There are no users"
|
||||
noInstances: "There are no instances"
|
||||
editProfile: "Edit profile"
|
||||
noteDeleteConfirm: "Are you sure you want to delete this post?"
|
||||
pinLimitExceeded: "You cannot pin any more posts"
|
||||
|
@ -363,6 +366,7 @@ notifyAntenna: "Notify about new posts"
|
|||
withFileAntenna: "Only posts with files"
|
||||
enableServiceworker: "Enable Push-Notifications for your Browser"
|
||||
antennaUsersDescription: "List one username per line"
|
||||
antennaInstancesDescription: "List one instance host per line"
|
||||
caseSensitive: "Case sensitive"
|
||||
withReplies: "Include replies"
|
||||
connectedTo: "Following account(s) are connected"
|
||||
|
@ -1294,12 +1298,14 @@ _auth:
|
|||
pleaseGoBack: "Please go back to the application"
|
||||
callback: "Returning to the application"
|
||||
denied: "Access denied"
|
||||
copyAsk: "Please paste the following authorization code to the application"
|
||||
_antennaSources:
|
||||
all: "All posts"
|
||||
homeTimeline: "Posts from followed users"
|
||||
users: "Posts from specific users"
|
||||
userList: "Posts from a specified list of users"
|
||||
userGroup: "Posts from users in a specified group"
|
||||
instances: "Posts from all users on an instance"
|
||||
_weekday:
|
||||
sunday: "Sunday"
|
||||
monday: "Monday"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "calckey",
|
||||
"version": "13.2.0-dev",
|
||||
"version": "13.2.0-dev4",
|
||||
"codename": "aqua",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -39,7 +39,7 @@
|
|||
"@bull-board/api": "^4.10.2",
|
||||
"@bull-board/ui": "^4.10.2",
|
||||
"@tensorflow/tfjs": "^3.21.0",
|
||||
"calckey-js": "^0.0.20",
|
||||
"calckey-js": "^0.0.22",
|
||||
"js-yaml": "4.1.0",
|
||||
"phosphor-icons": "^1.4.2",
|
||||
"seedrandom": "^3.0.5"
|
||||
|
|
17
packages/backend/migration/1676093997212-AntennaInstances.js
Normal file
17
packages/backend/migration/1676093997212-AntennaInstances.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
export class AntennaInstances1676093997212 {
|
||||
name = 'AntennaInstances1676093997212'
|
||||
|
||||
async up(queryRunner) {
|
||||
await queryRunner.query(`ALTER TYPE "antenna_src_enum" ADD VALUE 'instances'`);
|
||||
await queryRunner.query(`ALTER TABLE "antenna" ADD "instances" jsonb NOT NULL DEFAULT '[]'`);
|
||||
}
|
||||
|
||||
async down(queryRunner) {
|
||||
await queryRunner.query(`DELETE FROM "antenna" WHERE "src" = 'instances'`);
|
||||
await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "instances"`);
|
||||
await queryRunner.query(`CREATE TYPE "public"."antenna_src_enum_old" AS ENUM('home', 'all', 'users', 'list', 'group')`);
|
||||
await queryRunner.query(`ALTER TABLE "antenna" ALTER COLUMN "src" TYPE "public"."antenna_src_enum_old" USING "src"::"text"::"public"."antenna_src_enum_old"`);
|
||||
await queryRunner.query(`DROP TYPE "public"."antenna_src_enum"`);
|
||||
await queryRunner.query(`ALTER TYPE "public"."antenna_src_enum_old" RENAME TO "antenna_src_enum"`);
|
||||
}
|
||||
}
|
|
@ -47,7 +47,7 @@
|
|||
"blurhash": "1.1.5",
|
||||
"bull": "4.10.2",
|
||||
"cacheable-lookup": "7.0.0",
|
||||
"calckey-js": "^0.0.20",
|
||||
"calckey-js": "^0.0.22",
|
||||
"cbor": "8.1.0",
|
||||
"chalk": "5.2.0",
|
||||
"chalk-template": "0.4.0",
|
||||
|
@ -79,7 +79,7 @@
|
|||
"koa-send": "5.0.1",
|
||||
"koa-slow": "2.1.0",
|
||||
"koa-views": "7.0.2",
|
||||
"@cutls/megalodon": "5.1.15",
|
||||
"@calckey/megalodon": "5.1.2",
|
||||
"mfm-js": "0.23.2",
|
||||
"mime-types": "2.1.35",
|
||||
"multer": "1.4.4-lts.1",
|
||||
|
|
|
@ -80,6 +80,13 @@ export async function checkHitAntenna(
|
|||
)
|
||||
)
|
||||
return false;
|
||||
} else if (antenna.src === "instances") {
|
||||
const instances = antenna.instances
|
||||
.filter((x) => x !== "")
|
||||
.map((host) => {
|
||||
return host.toLowerCase();
|
||||
});
|
||||
if (!instances.includes(noteUser.host?.toLowerCase() ?? "")) return false;
|
||||
}
|
||||
|
||||
const keywords = antenna.keywords
|
||||
|
|
|
@ -40,8 +40,8 @@ export class Antenna {
|
|||
})
|
||||
public name: string;
|
||||
|
||||
@Column('enum', { enum: ['home', 'all', 'users', 'list', 'group'] })
|
||||
public src: "home" | "all" | "users" | "list" | "group";
|
||||
@Column('enum', { enum: ['home', 'all', 'users', 'list', 'group', 'instances'] })
|
||||
public src: "home" | "all" | "users" | "list" | "group" | "instances";
|
||||
|
||||
@Column({
|
||||
...id(),
|
||||
|
@ -73,6 +73,11 @@ export class Antenna {
|
|||
})
|
||||
public users: string[];
|
||||
|
||||
@Column('jsonb', {
|
||||
default: [],
|
||||
})
|
||||
public instances: string[];
|
||||
|
||||
@Column('jsonb', {
|
||||
default: [],
|
||||
})
|
||||
|
|
|
@ -25,6 +25,7 @@ export const AntennaRepository = db.getRepository(Antenna).extend({
|
|||
userListId: antenna.userListId,
|
||||
userGroupId: userGroupJoining ? userGroupJoining.userGroupId : null,
|
||||
users: antenna.users,
|
||||
instances: antenna.instances,
|
||||
caseSensitive: antenna.caseSensitive,
|
||||
notify: antenna.notify,
|
||||
withReplies: antenna.withReplies,
|
||||
|
|
|
@ -52,7 +52,7 @@ export const packedAntennaSchema = {
|
|||
type: "string",
|
||||
optional: false,
|
||||
nullable: false,
|
||||
enum: ["home", "all", "users", "list", "group"],
|
||||
enum: ["home", "all", "users", "list", "group", "instances"],
|
||||
},
|
||||
userListId: {
|
||||
type: "string",
|
||||
|
@ -76,6 +76,16 @@ export const packedAntennaSchema = {
|
|||
nullable: false,
|
||||
},
|
||||
},
|
||||
instances: {
|
||||
type: "array",
|
||||
optional: false,
|
||||
nullable: false,
|
||||
items: {
|
||||
type: "string",
|
||||
optional: false,
|
||||
nullable: false,
|
||||
},
|
||||
},
|
||||
caseSensitive: {
|
||||
type: "boolean",
|
||||
optional: false,
|
||||
|
|
|
@ -125,6 +125,24 @@ export async function createNote(
|
|||
|
||||
logger.info(`Creating the Note: ${note.id}`);
|
||||
|
||||
// Skip if note is made before 2007 (1yr before Fedi was created)
|
||||
// OR skip if note is made 3 days in advance
|
||||
if (note.published) {
|
||||
const DateChecker = new Date(note.published);
|
||||
const FutureCheck = new Date();
|
||||
FutureCheck.setDate(FutureCheck.getDate() + 3); // Allow some wiggle room for misconfigured hosts
|
||||
if (DateChecker.getFullYear() < 2007) {
|
||||
logger.warn(
|
||||
"Note somehow made before Activitypub was created; discarding",
|
||||
);
|
||||
return null;
|
||||
}
|
||||
if (DateChecker > FutureCheck) {
|
||||
logger.warn("Note somehow made after today; discarding");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch author
|
||||
const actor = (await resolvePerson(
|
||||
getOneApId(note.attributedTo),
|
||||
|
|
|
@ -222,6 +222,7 @@ import * as ep___messaging_messages_create from "./endpoints/messaging/messages/
|
|||
import * as ep___messaging_messages_delete from "./endpoints/messaging/messages/delete.js";
|
||||
import * as ep___messaging_messages_read from "./endpoints/messaging/messages/read.js";
|
||||
import * as ep___meta from "./endpoints/meta.js";
|
||||
import * as ep___sounds from "./endpoints/get-sounds.js";
|
||||
import * as ep___miauth_genToken from "./endpoints/miauth/gen-token.js";
|
||||
import * as ep___mute_create from "./endpoints/mute/create.js";
|
||||
import * as ep___mute_delete from "./endpoints/mute/delete.js";
|
||||
|
@ -668,6 +669,7 @@ const eps = [
|
|||
["users/stats", ep___users_stats],
|
||||
["admin/drive-capacity-override", ep___admin_driveCapOverride],
|
||||
["fetch-rss", ep___fetchRss],
|
||||
["get-sounds", ep___sounds],
|
||||
];
|
||||
|
||||
export interface IEndpointMeta {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import define from "../../define.js";
|
||||
import { Users } from "@/models/index.js";
|
||||
import { User } from "@/models/entities/user.js";
|
||||
import { insertModerationLog } from "@/services/insert-moderation-log.js";
|
||||
import { publishInternalEvent } from "@/services/stream.js";
|
||||
export const meta = {
|
||||
tags: ["admin"],
|
||||
|
||||
|
@ -29,17 +29,14 @@ export default define(meta, paramDef, async (ps, me) => {
|
|||
throw new Error("user is not local user");
|
||||
}
|
||||
|
||||
/*if (user.isAdmin) {
|
||||
throw new Error('cannot suspend admin');
|
||||
}
|
||||
if (user.isModerator) {
|
||||
throw new Error('cannot suspend moderator');
|
||||
}*/
|
||||
|
||||
await Users.update(user.id, {
|
||||
driveCapacityOverrideMb: ps.overrideMb,
|
||||
});
|
||||
|
||||
publishInternalEvent("localUserUpdated", {
|
||||
id: user.id,
|
||||
});
|
||||
|
||||
insertModerationLog(me, "change-drive-capacity-override", {
|
||||
targetId: user.id,
|
||||
});
|
||||
|
|
|
@ -37,7 +37,10 @@ export const paramDef = {
|
|||
type: "object",
|
||||
properties: {
|
||||
name: { type: "string", minLength: 1, maxLength: 100 },
|
||||
src: { type: "string", enum: ["home", "all", "users", "list", "group"] },
|
||||
src: {
|
||||
type: "string",
|
||||
enum: ["home", "all", "users", "list", "group", "instances"],
|
||||
},
|
||||
userListId: { type: "string", format: "misskey:id", nullable: true },
|
||||
userGroupId: { type: "string", format: "misskey:id", nullable: true },
|
||||
keywords: {
|
||||
|
@ -64,6 +67,12 @@ export const paramDef = {
|
|||
type: "string",
|
||||
},
|
||||
},
|
||||
instances: {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
caseSensitive: { type: "boolean" },
|
||||
withReplies: { type: "boolean" },
|
||||
withFile: { type: "boolean" },
|
||||
|
@ -75,6 +84,7 @@ export const paramDef = {
|
|||
"keywords",
|
||||
"excludeKeywords",
|
||||
"users",
|
||||
"instances",
|
||||
"caseSensitive",
|
||||
"withReplies",
|
||||
"withFile",
|
||||
|
@ -118,6 +128,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
keywords: ps.keywords,
|
||||
excludeKeywords: ps.excludeKeywords,
|
||||
users: ps.users,
|
||||
instances: ps.instances,
|
||||
caseSensitive: ps.caseSensitive,
|
||||
withReplies: ps.withReplies,
|
||||
withFile: ps.withFile,
|
||||
|
|
|
@ -43,7 +43,10 @@ export const paramDef = {
|
|||
properties: {
|
||||
antennaId: { type: "string", format: "misskey:id" },
|
||||
name: { type: "string", minLength: 1, maxLength: 100 },
|
||||
src: { type: "string", enum: ["home", "all", "users", "list", "group"] },
|
||||
src: {
|
||||
type: "string",
|
||||
enum: ["home", "all", "users", "list", "group", "instances"],
|
||||
},
|
||||
userListId: { type: "string", format: "misskey:id", nullable: true },
|
||||
userGroupId: { type: "string", format: "misskey:id", nullable: true },
|
||||
keywords: {
|
||||
|
@ -70,6 +73,12 @@ export const paramDef = {
|
|||
type: "string",
|
||||
},
|
||||
},
|
||||
instances: {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
caseSensitive: { type: "boolean" },
|
||||
withReplies: { type: "boolean" },
|
||||
withFile: { type: "boolean" },
|
||||
|
@ -82,6 +91,7 @@ export const paramDef = {
|
|||
"keywords",
|
||||
"excludeKeywords",
|
||||
"users",
|
||||
"instances",
|
||||
"caseSensitive",
|
||||
"withReplies",
|
||||
"withFile",
|
||||
|
@ -131,6 +141,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
keywords: ps.keywords,
|
||||
excludeKeywords: ps.excludeKeywords,
|
||||
users: ps.users,
|
||||
instances: ps.instances,
|
||||
caseSensitive: ps.caseSensitive,
|
||||
withReplies: ps.withReplies,
|
||||
withFile: ps.withFile,
|
||||
|
|
|
@ -102,10 +102,13 @@ export default define(meta, paramDef, async (ps, me) => {
|
|||
if (typeof ps.blocked === "boolean") {
|
||||
const meta = await fetchMeta(true);
|
||||
if (ps.blocked) {
|
||||
if (meta.blockedHosts.length === 0) {
|
||||
return [];
|
||||
}
|
||||
query.andWhere("instance.host IN (:...blocks)", {
|
||||
blocks: meta.blockedHosts,
|
||||
});
|
||||
} else {
|
||||
} else if (meta.blockedHosts.length > 0) {
|
||||
query.andWhere("instance.host NOT IN (:...blocks)", {
|
||||
blocks: meta.blockedHosts,
|
||||
});
|
||||
|
|
30
packages/backend/src/server/api/endpoints/get-sounds.ts
Normal file
30
packages/backend/src/server/api/endpoints/get-sounds.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
import { readdir } from "fs/promises";
|
||||
import define from "../define.js";
|
||||
|
||||
export const meta = {
|
||||
tags: ["meta"],
|
||||
requireCredential: false,
|
||||
requireCredentialPrivateMode: false,
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: "object",
|
||||
properties: {},
|
||||
required: [],
|
||||
} as const;
|
||||
|
||||
export default define(meta, paramDef, async () => {
|
||||
const music_files: (string | null)[] = [null];
|
||||
const directory = (
|
||||
await readdir("./assets/sounds", { withFileTypes: true })
|
||||
).filter((potentialFolder) => potentialFolder.isDirectory());
|
||||
for await (const folder of directory) {
|
||||
const files = (await readdir(`./assets/sounds/${folder.name}`)).filter(
|
||||
(potentialSong) => potentialSong.endsWith(".mp3"),
|
||||
);
|
||||
for await (const file of files) {
|
||||
music_files.push(`${folder.name}/${file.replace(".mp3", "")}`);
|
||||
}
|
||||
}
|
||||
return music_files;
|
||||
});
|
|
@ -27,6 +27,11 @@ export const paramDef = {
|
|||
properties: {
|
||||
limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
|
||||
offset: { type: "integer", default: 0 },
|
||||
origin: {
|
||||
type: "string",
|
||||
enum: ["combined", "local", "remote"],
|
||||
default: "local",
|
||||
},
|
||||
},
|
||||
required: [],
|
||||
} as const;
|
||||
|
@ -37,7 +42,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
|
||||
const query = Notes.createQueryBuilder("note")
|
||||
.addSelect("note.score")
|
||||
.where("note.userHost IS NULL")
|
||||
// .where("note.userHost IS NULL")
|
||||
.andWhere("note.score > 0")
|
||||
.andWhere("note.createdAt > :date", { date: new Date(Date.now() - day) })
|
||||
.andWhere("note.visibility = 'public'")
|
||||
|
@ -53,6 +58,15 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
|
||||
.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
|
||||
|
||||
switch (ps.origin) {
|
||||
case "local":
|
||||
query.andWhere("note.userHost IS NULL");
|
||||
break;
|
||||
case "remote":
|
||||
query.andWhere("note.userHost IS NOT NULL");
|
||||
break;
|
||||
}
|
||||
|
||||
if (user) generateMutedUserQuery(query, user);
|
||||
if (user) generateBlockedUserQuery(query, user);
|
||||
|
||||
|
|
|
@ -61,10 +61,12 @@ router.use(
|
|||
}),
|
||||
);
|
||||
|
||||
mastoRouter.use(koaBody({
|
||||
multipart: true,
|
||||
urlencoded: true
|
||||
}));
|
||||
mastoRouter.use(
|
||||
koaBody({
|
||||
multipart: true,
|
||||
urlencoded: true,
|
||||
}),
|
||||
);
|
||||
|
||||
apiMastodonCompatible(mastoRouter);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import Router from "@koa/router";
|
||||
import megalodon, { MegalodonInterface } from "@cutls/megalodon";
|
||||
import megalodon, { MegalodonInterface } from "@calckey/megalodon";
|
||||
import { apiAuthMastodon } from "./endpoints/auth.js";
|
||||
import { apiAccountMastodon } from "./endpoints/account.js";
|
||||
import { apiStatusMastodon } from "./endpoints/status.js";
|
||||
|
|
|
@ -1,11 +1,26 @@
|
|||
import megalodon, { MegalodonInterface } from "@cutls/megalodon";
|
||||
import Router from "@koa/router";
|
||||
import { koaBody } from "koa-body";
|
||||
import { getClient } from "../ApiMastodonCompatibleService.js";
|
||||
import { toLimitToInt } from "./timeline.js";
|
||||
|
||||
const relationshopModel = {
|
||||
id: "",
|
||||
following: false,
|
||||
followed_by: false,
|
||||
delivery_following: false,
|
||||
blocking: false,
|
||||
blocked_by: false,
|
||||
muting: false,
|
||||
muting_notifications: false,
|
||||
requested: false,
|
||||
domain_blocking: false,
|
||||
showing_reblogs: false,
|
||||
endorsed: false,
|
||||
notifying: false,
|
||||
note: "",
|
||||
};
|
||||
|
||||
export function apiAccountMastodon(router: Router): void {
|
||||
router.get("/v1/accounts/verify_credentials", async (ctx, next) => {
|
||||
router.get("/v1/accounts/verify_credentials", async (ctx) => {
|
||||
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
|
||||
const accessTokens = ctx.headers.authorization;
|
||||
const client = getClient(BASE_URL, accessTokens);
|
||||
|
@ -48,26 +63,39 @@ export function apiAccountMastodon(router: Router): void {
|
|||
ctx.body = e.response.data;
|
||||
}
|
||||
});
|
||||
router.get<{ Params: { id: string } }>(
|
||||
"/v1/accounts/:id",
|
||||
async (ctx, next) => {
|
||||
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
|
||||
const accessTokens = ctx.headers.authorization;
|
||||
const client = getClient(BASE_URL, accessTokens);
|
||||
try {
|
||||
const data = await client.getAccount(ctx.params.id);
|
||||
ctx.body = data.data;
|
||||
} catch (e: any) {
|
||||
console.error(e);
|
||||
console.error(e.response.data);
|
||||
ctx.status = 401;
|
||||
ctx.body = e.response.data;
|
||||
}
|
||||
},
|
||||
);
|
||||
router.get("/v1/accounts/lookup", async (ctx) => {
|
||||
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
|
||||
const accessTokens = ctx.headers.authorization;
|
||||
const client = getClient(BASE_URL, accessTokens);
|
||||
try {
|
||||
const data = await client.getAccount(
|
||||
`@${(ctx.query.acct || "").toString()}`,
|
||||
);
|
||||
ctx.body = data.data;
|
||||
} catch (e: any) {
|
||||
console.error(e);
|
||||
console.error(e.response.data);
|
||||
ctx.status = 401;
|
||||
ctx.body = e.response.data;
|
||||
}
|
||||
});
|
||||
router.get<{ Params: { id: string } }>("/v1/accounts/:id", async (ctx) => {
|
||||
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
|
||||
const accessTokens = ctx.headers.authorization;
|
||||
const client = getClient(BASE_URL, accessTokens);
|
||||
try {
|
||||
const data = await client.getAccount(ctx.params.id);
|
||||
ctx.body = data.data;
|
||||
} catch (e: any) {
|
||||
console.error(e);
|
||||
console.error(e.response.data);
|
||||
ctx.status = 401;
|
||||
ctx.body = e.response.data;
|
||||
}
|
||||
});
|
||||
router.get<{ Params: { id: string } }>(
|
||||
"/v1/accounts/:id/statuses",
|
||||
async (ctx, next) => {
|
||||
async (ctx) => {
|
||||
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
|
||||
const accessTokens = ctx.headers.authorization;
|
||||
const client = getClient(BASE_URL, accessTokens);
|
||||
|
@ -87,7 +115,7 @@ export function apiAccountMastodon(router: Router): void {
|
|||
);
|
||||
router.get<{ Params: { id: string } }>(
|
||||
"/v1/accounts/:id/followers",
|
||||
async (ctx, next) => {
|
||||
async (ctx) => {
|
||||
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
|
||||
const accessTokens = ctx.headers.authorization;
|
||||
const client = getClient(BASE_URL, accessTokens);
|
||||
|
@ -107,7 +135,7 @@ export function apiAccountMastodon(router: Router): void {
|
|||
);
|
||||
router.get<{ Params: { id: string } }>(
|
||||
"/v1/accounts/:id/following",
|
||||
async (ctx, next) => {
|
||||
async (ctx) => {
|
||||
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
|
||||
const accessTokens = ctx.headers.authorization;
|
||||
const client = getClient(BASE_URL, accessTokens);
|
||||
|
@ -127,7 +155,7 @@ export function apiAccountMastodon(router: Router): void {
|
|||
);
|
||||
router.get<{ Params: { id: string } }>(
|
||||
"/v1/accounts/:id/lists",
|
||||
async (ctx, next) => {
|
||||
async (ctx) => {
|
||||
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
|
||||
const accessTokens = ctx.headers.authorization;
|
||||
const client = getClient(BASE_URL, accessTokens);
|
||||
|
@ -144,7 +172,7 @@ export function apiAccountMastodon(router: Router): void {
|
|||
);
|
||||
router.post<{ Params: { id: string } }>(
|
||||
"/v1/accounts/:id/follow",
|
||||
async (ctx, next) => {
|
||||
async (ctx) => {
|
||||
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
|
||||
const accessTokens = ctx.headers.authorization;
|
||||
const client = getClient(BASE_URL, accessTokens);
|
||||
|
@ -163,7 +191,7 @@ export function apiAccountMastodon(router: Router): void {
|
|||
);
|
||||
router.post<{ Params: { id: string } }>(
|
||||
"/v1/accounts/:id/unfollow",
|
||||
async (ctx, next) => {
|
||||
async (ctx) => {
|
||||
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
|
||||
const accessTokens = ctx.headers.authorization;
|
||||
const client = getClient(BASE_URL, accessTokens);
|
||||
|
@ -182,7 +210,7 @@ export function apiAccountMastodon(router: Router): void {
|
|||
);
|
||||
router.post<{ Params: { id: string } }>(
|
||||
"/v1/accounts/:id/block",
|
||||
async (ctx, next) => {
|
||||
async (ctx) => {
|
||||
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
|
||||
const accessTokens = ctx.headers.authorization;
|
||||
const client = getClient(BASE_URL, accessTokens);
|
||||
|
@ -199,7 +227,7 @@ export function apiAccountMastodon(router: Router): void {
|
|||
);
|
||||
router.post<{ Params: { id: string } }>(
|
||||
"/v1/accounts/:id/unblock",
|
||||
async (ctx, next) => {
|
||||
async (ctx) => {
|
||||
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
|
||||
const accessTokens = ctx.headers.authorization;
|
||||
const client = getClient(BASE_URL, accessTokens);
|
||||
|
@ -236,7 +264,7 @@ export function apiAccountMastodon(router: Router): void {
|
|||
);
|
||||
router.post<{ Params: { id: string } }>(
|
||||
"/v1/accounts/:id/unmute",
|
||||
async (ctx, next) => {
|
||||
async (ctx) => {
|
||||
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
|
||||
const accessTokens = ctx.headers.authorization;
|
||||
const client = getClient(BASE_URL, accessTokens);
|
||||
|
@ -251,13 +279,15 @@ export function apiAccountMastodon(router: Router): void {
|
|||
}
|
||||
},
|
||||
);
|
||||
router.get("/v1/accounts/relationships", async (ctx, next) => {
|
||||
router.get("/v1/accounts/relationships", async (ctx) => {
|
||||
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
|
||||
const accessTokens = ctx.headers.authorization;
|
||||
const client = getClient(BASE_URL, accessTokens);
|
||||
try {
|
||||
const idsRaw = (ctx.query as any)["id[]"];
|
||||
const ids = typeof idsRaw === "string" ? [idsRaw] : idsRaw;
|
||||
relationshopModel.id = idsRaw || "1";
|
||||
if (!idsRaw) return [relationshopModel];
|
||||
const data = (await client.getRelationships(ids)) as any;
|
||||
ctx.body = data.data;
|
||||
} catch (e: any) {
|
||||
|
@ -267,7 +297,7 @@ export function apiAccountMastodon(router: Router): void {
|
|||
ctx.body = e.response.data;
|
||||
}
|
||||
});
|
||||
router.get("/v1/bookmarks", async (ctx, next) => {
|
||||
router.get("/v1/bookmarks", async (ctx) => {
|
||||
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
|
||||
const accessTokens = ctx.headers.authorization;
|
||||
const client = getClient(BASE_URL, accessTokens);
|
||||
|
@ -281,7 +311,7 @@ export function apiAccountMastodon(router: Router): void {
|
|||
ctx.body = e.response.data;
|
||||
}
|
||||
});
|
||||
router.get("/v1/favourites", async (ctx, next) => {
|
||||
router.get("/v1/favourites", async (ctx) => {
|
||||
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
|
||||
const accessTokens = ctx.headers.authorization;
|
||||
const client = getClient(BASE_URL, accessTokens);
|
||||
|
@ -295,7 +325,7 @@ export function apiAccountMastodon(router: Router): void {
|
|||
ctx.body = e.response.data;
|
||||
}
|
||||
});
|
||||
router.get("/v1/mutes", async (ctx, next) => {
|
||||
router.get("/v1/mutes", async (ctx) => {
|
||||
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
|
||||
const accessTokens = ctx.headers.authorization;
|
||||
const client = getClient(BASE_URL, accessTokens);
|
||||
|
@ -309,7 +339,7 @@ export function apiAccountMastodon(router: Router): void {
|
|||
ctx.body = e.response.data;
|
||||
}
|
||||
});
|
||||
router.get("/v1/blocks", async (ctx, next) => {
|
||||
router.get("/v1/blocks", async (ctx) => {
|
||||
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
|
||||
const accessTokens = ctx.headers.authorization;
|
||||
const client = getClient(BASE_URL, accessTokens);
|
||||
|
@ -323,7 +353,7 @@ export function apiAccountMastodon(router: Router): void {
|
|||
ctx.body = e.response.data;
|
||||
}
|
||||
});
|
||||
router.get("/v1/follow_ctxs", async (ctx, next) => {
|
||||
router.get("/v1/follow_ctxs", async (ctx) => {
|
||||
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
|
||||
const accessTokens = ctx.headers.authorization;
|
||||
const client = getClient(BASE_URL, accessTokens);
|
||||
|
@ -341,7 +371,7 @@ export function apiAccountMastodon(router: Router): void {
|
|||
});
|
||||
router.post<{ Params: { id: string } }>(
|
||||
"/v1/follow_ctxs/:id/authorize",
|
||||
async (ctx, next) => {
|
||||
async (ctx) => {
|
||||
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
|
||||
const accessTokens = ctx.headers.authorization;
|
||||
const client = getClient(BASE_URL, accessTokens);
|
||||
|
@ -358,7 +388,7 @@ export function apiAccountMastodon(router: Router): void {
|
|||
);
|
||||
router.post<{ Params: { id: string } }>(
|
||||
"/v1/follow_ctxs/:id/reject",
|
||||
async (ctx, next) => {
|
||||
async (ctx) => {
|
||||
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
|
||||
const accessTokens = ctx.headers.authorization;
|
||||
const client = getClient(BASE_URL, accessTokens);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import megalodon, { MegalodonInterface } from "@cutls/megalodon";
|
||||
import megalodon, { MegalodonInterface } from "@calckey/megalodon";
|
||||
import Router from "@koa/router";
|
||||
import { koaBody } from "koa-body";
|
||||
import { getClient } from "../ApiMastodonCompatibleService.js";
|
||||
|
@ -58,10 +58,7 @@ export function apiAuthMastodon(router: Router): void {
|
|||
}
|
||||
const scopeArr = Array.from(pushScope);
|
||||
|
||||
let red = body.redirect_uris;
|
||||
if (red === "urn:ietf:wg:oauth:2.0:oob") {
|
||||
red = "https://thedesk.top/hello.html";
|
||||
}
|
||||
const red = body.redirect_uris;
|
||||
const appData = await client.registerApp(body.client_name, {
|
||||
scopes: scopeArr,
|
||||
redirect_uris: red,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import megalodon, { MegalodonInterface } from "@cutls/megalodon";
|
||||
import megalodon, { MegalodonInterface } from "@calckey/megalodon";
|
||||
import Router from "@koa/router";
|
||||
import { getClient } from "../ApiMastodonCompatibleService.js";
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Entity } from "@cutls/megalodon";
|
||||
import { Entity } from "@calckey/megalodon";
|
||||
// TODO: add calckey features
|
||||
export function getInstance(response: Entity.Instance) {
|
||||
return {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import megalodon, { MegalodonInterface } from "@cutls/megalodon";
|
||||
import megalodon, { MegalodonInterface } from "@calckey/megalodon";
|
||||
import Router from "@koa/router";
|
||||
import { koaBody } from "koa-body";
|
||||
import { getClient } from "../ApiMastodonCompatibleService.js";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import megalodon, { MegalodonInterface } from "@cutls/megalodon";
|
||||
import megalodon, { MegalodonInterface } from "@calckey/megalodon";
|
||||
import Router from "@koa/router";
|
||||
import { getClient } from "../ApiMastodonCompatibleService.js";
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import Router from "@koa/router";
|
||||
import megalodon, { MegalodonInterface } from "@cutls/megalodon";
|
||||
import megalodon, { MegalodonInterface } from "@calckey/megalodon";
|
||||
import { getClient } from "../ApiMastodonCompatibleService.js";
|
||||
import fs from "fs";
|
||||
import { pipeline } from "node:stream";
|
||||
|
@ -435,7 +435,7 @@ export function statusModel(
|
|||
id: "9arzuvv0sw",
|
||||
username: "ReactionBot",
|
||||
acct: "ReactionBot",
|
||||
display_name: "ReactionOfThisPost",
|
||||
display_name: "ReactionsToThisPost",
|
||||
locked: false,
|
||||
created_at: now,
|
||||
followers_count: 0,
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
import Router from "@koa/router";
|
||||
import megalodon, { Entity, MegalodonInterface } from "@cutls/megalodon";
|
||||
import megalodon, { Entity, MegalodonInterface } from "@calckey/megalodon";
|
||||
import { getClient } from "../ApiMastodonCompatibleService.js";
|
||||
import { statusModel } from "./status.js";
|
||||
import Autolinker from "autolinker";
|
||||
import { ParsedUrlQuery } from "querystring";
|
||||
|
||||
export function toLimitToInt(q: ParsedUrlQuery) {
|
||||
let object: any = q;
|
||||
if (q.limit)
|
||||
if (typeof q.limit === "string") q.limit = parseInt(q.limit, 10).toString();
|
||||
if (typeof q.limit === "string") object.limit = parseInt(q.limit, 10);
|
||||
return q;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ import { readNotification } from "../common/read-notification.js";
|
|||
import channels from "./channels/index.js";
|
||||
import type Channel from "./channel.js";
|
||||
import type { StreamEventEmitter, StreamMessages } from "./types.js";
|
||||
import { Converter } from "@cutls/megalodon";
|
||||
import { Converter } from "@calckey/megalodon";
|
||||
import { getClient } from "../mastodon/ApiMastodonCompatibleService.js";
|
||||
import { toTextWithReaction } from "../mastodon/endpoints/timeline.js";
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ import type { Note } from "@/models/entities/note.js";
|
|||
import type { Antenna } from "@/models/entities/antenna.js";
|
||||
import type { DriveFile } from "@/models/entities/drive-file.js";
|
||||
import type { DriveFolder } from "@/models/entities/drive-folder.js";
|
||||
import { Emoji } from "@/models/entities/emoji.js";
|
||||
import type { UserList } from "@/models/entities/user-list.js";
|
||||
import type { MessagingMessage } from "@/models/entities/messaging-message.js";
|
||||
import type { UserGroup } from "@/models/entities/user-group.js";
|
||||
|
@ -23,7 +22,10 @@ export interface InternalStreamTypes {
|
|||
id: User["id"];
|
||||
isSuspended: User["isSuspended"];
|
||||
};
|
||||
userChangeSilencedState: { id: User["id"]; isSilenced: User["isSilenced"] };
|
||||
userChangeSilencedState: {
|
||||
id: User["id"];
|
||||
isSilenced: User["isSilenced"];
|
||||
};
|
||||
userChangeModeratorState: {
|
||||
id: User["id"];
|
||||
isModerator: User["isModerator"];
|
||||
|
@ -33,7 +35,12 @@ export interface InternalStreamTypes {
|
|||
oldToken: User["token"];
|
||||
newToken: User["token"];
|
||||
};
|
||||
remoteUserUpdated: { id: User["id"] };
|
||||
localUserUpdated: {
|
||||
id: User["id"];
|
||||
};
|
||||
remoteUserUpdated: {
|
||||
id: User["id"];
|
||||
};
|
||||
webhookCreated: Webhook;
|
||||
webhookDeleted: Webhook;
|
||||
webhookUpdated: Webhook;
|
||||
|
@ -135,6 +142,9 @@ export interface NoteStreamTypes {
|
|||
reaction: string;
|
||||
userId: User["id"];
|
||||
};
|
||||
replied: {
|
||||
id: Note["id"];
|
||||
};
|
||||
}
|
||||
type NoteStreamEventTypes = {
|
||||
[key in keyof NoteStreamTypes]: {
|
||||
|
|
|
@ -20,7 +20,7 @@ import { createTemp } from "@/misc/create-temp.js";
|
|||
import { publishMainStream } from "@/services/stream.js";
|
||||
import * as Acct from "@/misc/acct.js";
|
||||
import { envOption } from "@/env.js";
|
||||
import megalodon, { MegalodonInterface } from "@cutls/megalodon";
|
||||
import megalodon, { MegalodonInterface } from "@calckey/megalodon";
|
||||
import activityPub from "./activitypub.js";
|
||||
import nodeinfo from "./nodeinfo.js";
|
||||
import wellKnown from "./well-known.js";
|
||||
|
@ -72,9 +72,11 @@ app.use(mount("/proxy", proxyServer));
|
|||
const router = new Router();
|
||||
const mastoRouter = new Router();
|
||||
|
||||
mastoRouter.use(koaBody({
|
||||
urlencoded: true
|
||||
}));
|
||||
mastoRouter.use(
|
||||
koaBody({
|
||||
urlencoded: true,
|
||||
}),
|
||||
);
|
||||
|
||||
// Routing
|
||||
router.use(activityPub.routes());
|
||||
|
@ -159,9 +161,9 @@ mastoRouter.post("/oauth/token", async (ctx) => {
|
|||
ctx.body = { error: "Invalid code" };
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (client_id instanceof Array) {
|
||||
client_id = client_id.toString();;
|
||||
client_id = client_id.toString();
|
||||
} else if (!client_id) {
|
||||
client_id = null;
|
||||
}
|
||||
|
@ -169,7 +171,7 @@ mastoRouter.post("/oauth/token", async (ctx) => {
|
|||
const atData = await client.fetchAccessToken(
|
||||
client_id,
|
||||
body.client_secret,
|
||||
m ? m[0] : '',
|
||||
m ? m[0] : "",
|
||||
);
|
||||
ctx.body = {
|
||||
access_token: atData.accessToken,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
html {
|
||||
html, body {
|
||||
background-color: var(--bg);
|
||||
color: var(--fg);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
import * as mfm from "mfm-js";
|
||||
import es from "../../db/elasticsearch.js";
|
||||
import { publishMainStream, publishNotesStream } from "@/services/stream.js";
|
||||
import {
|
||||
publishMainStream,
|
||||
publishNotesStream,
|
||||
publishNoteStream,
|
||||
} from "@/services/stream.js";
|
||||
import DeliverManager from "@/remote/activitypub/deliver-manager.js";
|
||||
import renderNote from "@/remote/activitypub/renderer/note.js";
|
||||
import renderCreate from "@/remote/activitypub/renderer/create.js";
|
||||
|
@ -430,6 +434,12 @@ export default async (
|
|||
}
|
||||
|
||||
publishNotesStream(note);
|
||||
if (note.replyId != null) {
|
||||
// Only provide the reply note id here as the recipient may not be authorized to see the note.
|
||||
publishNoteStream(note.replyId, "replied", {
|
||||
id: note.id,
|
||||
});
|
||||
}
|
||||
|
||||
const webhooks = await getActiveWebhooks().then((webhooks) =>
|
||||
webhooks.filter((x) => x.userId === user.id && x.on.includes("note")),
|
||||
|
|
|
@ -21,6 +21,16 @@ subscriber.on("message", async (_, data) => {
|
|||
if (obj.channel === "internal") {
|
||||
const { type, body } = obj.message;
|
||||
switch (type) {
|
||||
case "localUserUpdated": {
|
||||
userByIdCache.delete(body.id);
|
||||
localUserByIdCache.delete(body.id);
|
||||
localUserByNativeTokenCache.cache.forEach((v, k) => {
|
||||
if (v.value?.id === body.id) {
|
||||
localUserByNativeTokenCache.delete(k);
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "userChangeSuspendedState":
|
||||
case "userChangeSilencedState":
|
||||
case "userChangeModeratorState":
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
"blurhash": "1.1.5",
|
||||
"broadcast-channel": "4.19.1",
|
||||
"browser-image-resizer": "https://github.com/misskey-dev/browser-image-resizer.git",
|
||||
"calckey-js": "^0.0.20",
|
||||
"calckey-js": "^0.0.22",
|
||||
"chart.js": "4.1.1",
|
||||
"chartjs-adapter-date-fns": "2.0.1",
|
||||
"chartjs-plugin-gradient": "0.5.1",
|
||||
|
|
157
packages/client/src/components/MkInstanceSelectDialog.vue
Normal file
157
packages/client/src/components/MkInstanceSelectDialog.vue
Normal file
|
@ -0,0 +1,157 @@
|
|||
<template>
|
||||
<XModalWindow
|
||||
ref="dialogEl"
|
||||
:with-ok-button="true"
|
||||
:ok-button-disabled="selected == null"
|
||||
@click="cancel()"
|
||||
@close="cancel()"
|
||||
@ok="ok()"
|
||||
@closed="$emit('closed')"
|
||||
>
|
||||
<template #header>{{ i18n.ts.selectInstance }}</template>
|
||||
<div class="mehkoush">
|
||||
<div class="form">
|
||||
<MkInput v-model="hostname" :autofocus="true" @update:modelValue="search">
|
||||
<template #label>{{ i18n.ts.instance }}</template>
|
||||
</MkInput>
|
||||
</div>
|
||||
<div v-if="hostname != ''" class="result" :class="{ hit: instances.length > 0 }">
|
||||
<div v-if="instances.length > 0" class="instances">
|
||||
<div v-for="item in instances" :key="item.id" class="instance" :class="{ selected: selected && selected.id === item.id }" @click="selected = item" @dblclick="ok()">
|
||||
<div class="body">
|
||||
<img class="icon" :src="item.iconUrl ?? '/client-assets/dummy.png'" aria-hidden="true"/>
|
||||
<span class="name">{{ item.host }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="empty">
|
||||
<span>{{ i18n.ts.noInstances }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</XModalWindow>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import MkInput from '@/components/form/input.vue';
|
||||
import XModalWindow from '@/components/MkModalWindow.vue';
|
||||
import * as os from '@/os';
|
||||
import { i18n } from '@/i18n';
|
||||
import { Instance } from 'calckey-js/built/entities';
|
||||
|
||||
const emit = defineEmits<{
|
||||
(ev: 'ok', selected: Instance): void;
|
||||
(ev: 'cancel'): void;
|
||||
(ev: 'closed'): void;
|
||||
}>();
|
||||
|
||||
let hostname = $ref('');
|
||||
let instances: Instance[] = $ref([]);
|
||||
let selected: Instance | null = $ref(null);
|
||||
let dialogEl = $ref<InstanceType<typeof XModalWindow>>();
|
||||
|
||||
let searchOrderLatch = 0;
|
||||
const search = () => {
|
||||
if (hostname === '') {
|
||||
instances = [];
|
||||
return;
|
||||
}
|
||||
|
||||
const searchId = ++searchOrderLatch;
|
||||
os.api('federation/instances', {
|
||||
host: hostname,
|
||||
limit: 10,
|
||||
blocked: false,
|
||||
suspended: false,
|
||||
sort: '+pubSub',
|
||||
}).then(_instances => {
|
||||
if (searchId !== searchOrderLatch) return;
|
||||
instances = _instances.map(x => ({
|
||||
id: x.id,
|
||||
host: x.host,
|
||||
iconUrl: x.iconUrl,
|
||||
} as Instance));
|
||||
});
|
||||
};
|
||||
|
||||
const ok = () => {
|
||||
if (selected == null) return;
|
||||
emit('ok', selected);
|
||||
dialogEl?.close();
|
||||
};
|
||||
|
||||
const cancel = () => {
|
||||
emit('cancel');
|
||||
dialogEl?.close();
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mehkoush {
|
||||
margin: var(--marginFull) 0;
|
||||
|
||||
> .form {
|
||||
padding: 0 var(--root-margin);
|
||||
}
|
||||
|
||||
> .result {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: auto;
|
||||
height: 100%;
|
||||
|
||||
&.result.hit {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
> .instances {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
padding: 8px 0;
|
||||
|
||||
> .instance {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px var(--root-margin);
|
||||
font-size: 14px;
|
||||
|
||||
&:hover {
|
||||
background: var(--X7);
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background: var(--accent);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
> * {
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
> .body {
|
||||
padding: 0 8px;
|
||||
width: 100%;
|
||||
|
||||
> .name {
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
> .icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-right: 8px;
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> .empty {
|
||||
opacity: 0.7;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -142,6 +142,8 @@ import { i18n } from '@/i18n';
|
|||
import { getNoteMenu } from '@/scripts/get-note-menu';
|
||||
import { useNoteCapture } from '@/scripts/use-note-capture';
|
||||
import { deepClone } from '@/scripts/clone';
|
||||
import { stream } from '@/stream';
|
||||
import { NoteUpdatedEvent } from 'calckey-js/built/streaming.types';
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
|
@ -302,6 +304,31 @@ if (appearNote.replyId) {
|
|||
conversation.value = res.reverse();
|
||||
});
|
||||
}
|
||||
|
||||
function onNoteReplied(noteData: NoteUpdatedEvent): void {
|
||||
const { type, id, body } = noteData;
|
||||
if (type === 'replied' && id === appearNote.id) {
|
||||
const { id: createdId } = body;
|
||||
|
||||
os.api('notes/show', {
|
||||
noteId: createdId,
|
||||
}).then(note => {
|
||||
if (note.replyId === appearNote.id) {
|
||||
replies.value.unshift(note);
|
||||
directReplies.value.unshift(note);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
stream.on("noteUpdated", onNoteReplied);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
stream.off("noteUpdated", onNoteReplied);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
<template>
|
||||
<div v-if="show" ref="el" class="fdidabkb" :class="{ slim: narrow, thin: thin_ }" :style="{ background: bg }" @click="onClick">
|
||||
<div v-if="narrow" class="buttons left" @click="openAccountMenu">
|
||||
<div v-if="show" ref="el" class="fdidabkb" :class="{ slim: narrow, thin: thin_ }" :style="{ background: bg }" @click="onClick">
|
||||
<div v-if="narrow" class="buttons left" @click="openAccountMenu">
|
||||
<MkAvatar v-if="props.displayMyAvatar && $i" class="avatar" :user="$i" :disable-preview="true"/>
|
||||
</div>
|
||||
<template v-if="metadata">
|
||||
<div v-if="!hideTitle" class="titleContainer" @click="showTabsPopup">
|
||||
<MkAvatar v-if="metadata.avatar" class="avatar" :user="metadata.avatar" :disable-preview="true" :show-indicator="true"/>
|
||||
<i v-else-if="metadata.icon && !narrow" class="icon" :class="metadata.icon"></i>
|
||||
<i v-else-if="metadata.icon && !narrow" class="icon" :class="metadata.icon"></i>
|
||||
|
||||
<div class="title">
|
||||
<MkUserName v-if="metadata.userName" :user="metadata.userName" :nowrap="true" class="title"/>
|
||||
<div v-else-if="metadata.title && !(tabs != null && tabs.length > 0 && narrow)" class="title">{{ metadata.title }}</div>
|
||||
<div v-if="!narrow && metadata.subtitle" class="subtitle">
|
||||
{{ metadata.subtitle }}
|
||||
<div class="title">
|
||||
<MkUserName v-if="metadata.userName" :user="metadata.userName" :nowrap="true" class="title"/>
|
||||
<div v-else-if="metadata.title && !(tabs != null && tabs.length > 0 && narrow)" class="title">{{ metadata.title }}</div>
|
||||
<div v-if="!narrow && metadata.subtitle" class="subtitle">
|
||||
{{ metadata.subtitle }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ref="tabsEl" v-if="hasTabs" class="tabs">
|
||||
<button v-for="tab in tabs" :ref="(el) => tabRefs[tab.key] = el" v-tooltip.noDelay="tab.title" class="tab _button" :class="{ active: tab.key != null && tab.key === props.tab }" @mousedown="(ev) => onTabMousedown(tab, ev)" @click="(ev) => onTabClick(tab, ev)">
|
||||
<i v-if="tab.icon" class="icon" :class="tab.icon"></i>
|
||||
<span v-if="deviceKind !== 'desktop' || isTouchUsing || (!tab.iconOnly && !narrow)" class="title">{{ tab.title }}</span>
|
||||
</button>
|
||||
<div ref="tabHighlightEl" class="highlight"></div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="buttons right">
|
||||
<template v-for="action in actions">
|
||||
<button v-tooltip.noDelay="action.text" class="_button button" :class="{ highlighted: action.highlighted }" @click.stop="action.handler" @touchstart="preventDrag"><i :class="action.icon"></i></button>
|
||||
<div ref="tabsEl" v-if="hasTabs" class="tabs">
|
||||
<button v-for="tab in tabs" :ref="(el) => tabRefs[tab.key] = el" v-tooltip.noDelay="tab.title" class="tab _button" :class="{ active: tab.key != null && tab.key === props.tab }" @mousedown="(ev) => onTabMousedown(tab, ev)" @click="(ev) => onTabClick(tab, ev)">
|
||||
<i v-if="tab.icon" class="icon" :class="tab.icon"></i>
|
||||
<span class="title">{{ tab.title }}</span>
|
||||
</button>
|
||||
<div ref="tabHighlightEl" class="highlight"></div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="buttons right">
|
||||
<template v-for="action in actions">
|
||||
<button v-tooltip.noDelay="action.text" class="_button button" :class="{ highlighted: action.highlighted }" @click.stop="action.handler" @touchstart="preventDrag"><i :class="action.icon"></i></button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@ -37,10 +37,7 @@ import { computed, onMounted, onUnmounted, ref, inject, watch, shallowReactive,
|
|||
import tinycolor from 'tinycolor2';
|
||||
import { popupMenu } from '@/os';
|
||||
import { scrollToTop } from '@/scripts/scroll';
|
||||
import { i18n } from '@/i18n';
|
||||
import { globalEvents } from '@/events';
|
||||
import { deviceKind } from '@/scripts/device-kind';
|
||||
import { isTouchUsing } from '@/scripts/touch';
|
||||
import { injectPageMetadata } from '@/scripts/page-metadata';
|
||||
import { $i, openAccountMenu as openAccountMenu_ } from '@/account';
|
||||
|
||||
|
@ -146,19 +143,21 @@ let ro: ResizeObserver | null;
|
|||
onMounted(() => {
|
||||
calcBg();
|
||||
globalEvents.on('themeChanged', calcBg);
|
||||
|
||||
|
||||
watch(() => [props.tab, props.tabs], () => {
|
||||
nextTick(() => {
|
||||
const tabEl = tabRefs[props.tab];
|
||||
if (tabEl && tabHighlightEl) {
|
||||
// offsetWidth や offsetLeft は少数を丸めてしまうため getBoundingClientRect を使う必要がある
|
||||
// https://developer.mozilla.org/ja/docs/Web/API/HTMLElement/offsetWidth#%E5%80%A4
|
||||
const parentRect = tabsEl.getBoundingClientRect();
|
||||
const rect = tabEl.getBoundingClientRect();
|
||||
const left = (rect.left - parentRect.left + tabsEl?.scrollLeft);
|
||||
tabHighlightEl.style.width = rect.width + 'px';
|
||||
tabHighlightEl.style.left = left + 'px';
|
||||
tabsEl.scrollTo({left: left - 80, behavior: "smooth"});
|
||||
setTimeout(() => {
|
||||
const parentRect = tabsEl.getBoundingClientRect();
|
||||
const rect = tabEl.getBoundingClientRect();
|
||||
const left = (rect.left - parentRect.left + tabsEl?.scrollLeft);
|
||||
tabHighlightEl.style.width = rect.width + 'px';
|
||||
tabHighlightEl.style.left = left + 'px';
|
||||
tabsEl?.scrollTo({left: left - 60, behavior: "smooth"});
|
||||
}, 200);
|
||||
}
|
||||
});
|
||||
}, {
|
||||
|
@ -235,7 +234,7 @@ onUnmounted(() => {
|
|||
> .buttons {
|
||||
--margin: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-items: center;
|
||||
height: var(--height);
|
||||
margin: 0 var(--margin);
|
||||
|
||||
|
@ -373,6 +372,15 @@ onUnmounted(() => {
|
|||
> .icon + .title {
|
||||
margin-left: 8px;
|
||||
}
|
||||
> .title {
|
||||
transition: font-size .2s, opacity .2s .15s;
|
||||
}
|
||||
&:not(.active) > .title {
|
||||
font-size: 0;
|
||||
opacity: 0;
|
||||
margin-inline: 0;
|
||||
transition: font-size .2s, opacity .1s;
|
||||
}
|
||||
}
|
||||
|
||||
> .highlight {
|
||||
|
@ -381,7 +389,8 @@ onUnmounted(() => {
|
|||
height: 3px;
|
||||
background: var(--accent);
|
||||
border-radius: 999px;
|
||||
transition: all 0.2s ease;
|
||||
transition: width .2s, left .2s;
|
||||
transition-timing-function: cubic-bezier(0,0,0,1.2);
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -545,6 +545,23 @@ export async function selectUser() {
|
|||
});
|
||||
}
|
||||
|
||||
export async function selectInstance(): Promise<Misskey.entities.Instance> {
|
||||
return new Promise((resolve, reject) => {
|
||||
popup(
|
||||
defineAsyncComponent(
|
||||
() => import("@/components/MkInstanceSelectDialog.vue"),
|
||||
),
|
||||
{},
|
||||
{
|
||||
ok: (instance) => {
|
||||
resolve(instance);
|
||||
},
|
||||
},
|
||||
"closed",
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export async function selectDriveFile(multiple: boolean) {
|
||||
return new Promise((resolve, reject) => {
|
||||
popup(
|
||||
|
|
|
@ -16,7 +16,11 @@
|
|||
</div>
|
||||
<div v-if="state == 'accepted'" class="accepted">
|
||||
<h1>{{ session.app.isAuthorized ? i18n.t('already-authorized') : i18n.ts.allowed }}</h1>
|
||||
<p v-if="session.app.callbackUrl">{{ i18n.ts._auth.callback }}<MkEllipsis/></p>
|
||||
<p v-if="session.app.callbackUrl && !auth_code">{{ i18n.ts._auth.callback }}<MkEllipsis/></p>
|
||||
<MkKeyValue v-if="session.app.callbackUrl && auth_code" :copy="auth_code">
|
||||
<template #key>{{ i18n.ts._auth.copyAsk }}</template>
|
||||
<template #value>{{ auth_code }}</template>
|
||||
</MkKeyValue>
|
||||
<p v-if="!session.app.callbackUrl">{{ i18n.ts._auth.pleaseGoBack }}</p>
|
||||
</div>
|
||||
<div v-if="state == 'fetch-session-error'" class="error">
|
||||
|
@ -32,6 +36,7 @@
|
|||
import { defineComponent } from 'vue';
|
||||
import XForm from './auth.form.vue';
|
||||
import MkSignin from '@/components/MkSignin.vue';
|
||||
import MkKeyValue from '@/components/MkKeyValue.vue';
|
||||
import * as os from '@/os';
|
||||
import { login } from '@/account';
|
||||
import { i18n } from '@/i18n';
|
||||
|
@ -40,6 +45,7 @@ export default defineComponent({
|
|||
components: {
|
||||
XForm,
|
||||
MkSignin,
|
||||
MkKeyValue
|
||||
},
|
||||
props: ['token'],
|
||||
data() {
|
||||
|
@ -48,6 +54,7 @@ export default defineComponent({
|
|||
session: null,
|
||||
fetching: true,
|
||||
i18n,
|
||||
auth_code: null
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
|
@ -82,7 +89,11 @@ export default defineComponent({
|
|||
if (this.session.app.callbackUrl) {
|
||||
const url = new URL(this.session.app.callbackUrl);
|
||||
if (['javascript:', 'file:', 'data:', 'mailto:', 'tel:'].includes(url.protocol)) throw new Error('invalid url');
|
||||
location.href = `${this.session.app.callbackUrl}?token=${this.session.token}&code=${this.session.token}&state=${getUrlParams().state || ''}`;
|
||||
if (this.session.app.callbackUrl === "urn:ietf:wg:oauth:2.0:oob") {
|
||||
this.auth_code = this.session.token;
|
||||
} else {
|
||||
location.href = `${this.session.app.callbackUrl}?token=${this.session.token}&code=${this.session.token}&state=${getUrlParams().state || ''}`;
|
||||
}
|
||||
}
|
||||
}, onLogin(res) {
|
||||
login(res.i);
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<template>
|
||||
<MkSpacer :content-max="800">
|
||||
<MkTab v-model="tab" style="margin-bottom: var(--margin);">
|
||||
<option value="notes">{{ i18n.ts.notes }}</option>
|
||||
<option value="polls">{{ i18n.ts.poll }}</option>
|
||||
<option value="local">{{ i18n.ts.local }}</option>
|
||||
<option value="remote">{{ i18n.ts.remote }}</option>
|
||||
</MkTab>
|
||||
<XNotes v-if="tab === 'notes'" :pagination="paginationForNotes"/>
|
||||
<XNotes v-else-if="tab === 'polls'" :pagination="paginationForPolls"/>
|
||||
<XNotes v-if="tab === 'local'" :pagination="paginationForLocal"/>
|
||||
<XNotes v-else-if="tab === 'remote'" :pagination="paginationForRemote"/>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
|
@ -14,17 +14,27 @@ import XNotes from '@/components/MkNotes.vue';
|
|||
import MkTab from '@/components/MkTab.vue';
|
||||
import { i18n } from '@/i18n';
|
||||
|
||||
const paginationForNotes = {
|
||||
const paginationForLocal = {
|
||||
endpoint: 'notes/featured' as const,
|
||||
limit: 10,
|
||||
origin: 'local',
|
||||
offsetMode: true,
|
||||
};
|
||||
|
||||
const paginationForPolls = {
|
||||
endpoint: 'notes/polls/recommendation' as const,
|
||||
limit: 10,
|
||||
const paginationForRemote = {
|
||||
endpoint: 'notes/featured' as const,
|
||||
limit: 20,
|
||||
offsetMode: true,
|
||||
};
|
||||
params: {
|
||||
origin: 'remote',
|
||||
}
|
||||
}
|
||||
|
||||
let tab = $ref('notes');
|
||||
// const paginationForRemote = {
|
||||
// endpoint: 'notes/polls/recommendation' as const,
|
||||
// limit: 10,
|
||||
// offsetMode: true,
|
||||
// };
|
||||
|
||||
let tab = $ref('local');
|
||||
</script>
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { inject } from 'vue';
|
||||
import XAntenna from './editor.vue';
|
||||
import { i18n } from '@/i18n';
|
||||
import { definePageMetadata } from '@/scripts/page-metadata';
|
||||
|
@ -19,6 +18,7 @@ let draft = $ref({
|
|||
userListId: null,
|
||||
userGroupId: null,
|
||||
users: [],
|
||||
instances: [],
|
||||
keywords: [],
|
||||
excludeKeywords: [],
|
||||
withReplies: false,
|
||||
|
@ -31,10 +31,6 @@ function onAntennaCreated() {
|
|||
router.push('/my/antennas');
|
||||
}
|
||||
|
||||
const headerActions = $computed(() => []);
|
||||
|
||||
const headerTabs = $computed(() => []);
|
||||
|
||||
definePageMetadata({
|
||||
title: i18n.ts.manageAntennas,
|
||||
icon: 'ph-flying-saucer-bold ph-lg',
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
<option value="users">{{ i18n.ts._antennaSources.users }}</option>
|
||||
<!--<option value="list">{{ i18n.ts._antennaSources.userList }}</option>-->
|
||||
<!--<option value="group">{{ i18n.ts._antennaSources.userGroup }}</option>-->
|
||||
<option value="instances">{{ i18n.ts._antennaSources.instances }}</option>
|
||||
</MkSelect>
|
||||
<MkSelect v-if="src === 'list'" v-model="userListId" class="_formBlock">
|
||||
<template #label>{{ i18n.ts.userList }}</template>
|
||||
|
@ -24,6 +25,10 @@
|
|||
<template #label>{{ i18n.ts.users }}</template>
|
||||
<template #caption>{{ i18n.ts.antennaUsersDescription }} <button class="_textButton" @click="addUser">{{ i18n.ts.addUser }}</button></template>
|
||||
</MkTextarea>
|
||||
<MkTextarea v-else-if="src === 'instances'" v-model="instances" class="_formBlock">
|
||||
<template #label>{{ i18n.ts.instances }}</template>
|
||||
<template #caption>{{ i18n.ts.antennaInstancesDescription }} <button class="_textButton" @click="addInstance">{{ i18n.ts.addInstance }}</button></template>
|
||||
</MkTextarea>
|
||||
<MkSwitch v-model="withReplies" class="_formBlock">{{ i18n.ts.withReplies }}</MkSwitch>
|
||||
<MkTextarea v-model="keywords" class="_formBlock">
|
||||
<template #label>{{ i18n.ts.antennaKeywords }}</template>
|
||||
|
@ -70,6 +75,7 @@ let src: string = $ref(props.antenna.src);
|
|||
let userListId: any = $ref(props.antenna.userListId);
|
||||
let userGroupId: any = $ref(props.antenna.userGroupId);
|
||||
let users: string = $ref(props.antenna.users.join('\n'));
|
||||
let instances: string = $ref(props.antenna.instances.join('\n'));
|
||||
let keywords: string = $ref(props.antenna.keywords.map(x => x.join(' ')).join('\n'));
|
||||
let excludeKeywords: string = $ref(props.antenna.excludeKeywords.map(x => x.join(' ')).join('\n'));
|
||||
let caseSensitive: boolean = $ref(props.antenna.caseSensitive);
|
||||
|
@ -103,6 +109,7 @@ async function saveAntenna() {
|
|||
notify,
|
||||
caseSensitive,
|
||||
users: users.trim().split('\n').map(x => x.trim()),
|
||||
instances: instances.trim().split('\n').map(x => x.trim()),
|
||||
keywords: keywords.trim().split('\n').map(x => x.trim().split(' ')),
|
||||
excludeKeywords: excludeKeywords.trim().split('\n').map(x => x.trim().split(' ')),
|
||||
};
|
||||
|
@ -135,10 +142,18 @@ async function deleteAntenna() {
|
|||
function addUser() {
|
||||
os.selectUser().then(user => {
|
||||
users = users.trim();
|
||||
users += '\n@' + Acct.toString(user as any);
|
||||
users += `\n@${Acct.toString(user as any)}`;
|
||||
users = users.trim();
|
||||
});
|
||||
}
|
||||
|
||||
function addInstance() {
|
||||
os.selectInstance().then(instance => {
|
||||
instances = instances.trim();
|
||||
instances += '\n' + instance.host;
|
||||
instances = instances.trim();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -50,32 +50,8 @@ const sounds = ref({
|
|||
channel: ColdDeviceStorage.get('sound_channel'),
|
||||
});
|
||||
|
||||
const soundsTypes = [
|
||||
null,
|
||||
'syuilo/up',
|
||||
'syuilo/down',
|
||||
'syuilo/pope1',
|
||||
'syuilo/pope2',
|
||||
'syuilo/waon',
|
||||
'syuilo/popo',
|
||||
'syuilo/triple',
|
||||
'syuilo/poi1',
|
||||
'syuilo/poi2',
|
||||
'syuilo/pirori',
|
||||
'syuilo/pirori-wet',
|
||||
'syuilo/pirori-square-wet',
|
||||
'syuilo/square-pico',
|
||||
'syuilo/reverved',
|
||||
'syuilo/ryukyu',
|
||||
'syuilo/kick',
|
||||
'syuilo/snare',
|
||||
'syuilo/queue-jammed',
|
||||
'aisha/1',
|
||||
'aisha/2',
|
||||
'aisha/3',
|
||||
'noizenecio/kick_gaba',
|
||||
'noizenecio/kick_gaba2',
|
||||
];
|
||||
const soundsTypes = await os.api('get-sounds')
|
||||
|
||||
|
||||
async function edit(type) {
|
||||
const { canceled, result } = await os.form(i18n.t('_sfx.' + type), {
|
||||
|
|
|
@ -7,7 +7,7 @@ export function getAudio(file: string, useCache = true): HTMLAudioElement {
|
|||
if (useCache && cache.has(file)) {
|
||||
audio = cache.get(file);
|
||||
} else {
|
||||
audio = new Audio(`/client-assets/sounds/${file}.mp3`);
|
||||
audio = new Audio(`/static-assets/sounds/${file}.mp3`);
|
||||
if (useCache) cache.set(file, audio);
|
||||
}
|
||||
return audio;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"name": "sw",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "pnpm swc src -d built -D",
|
||||
"build": "webpack",
|
||||
"watch": "pnpm swc src -d built -D -w",
|
||||
"lint": "pnpm rome check \"src/**/*.ts\""
|
||||
},
|
||||
|
@ -13,9 +13,10 @@
|
|||
"@swc/cli": "^0.1.59",
|
||||
"@swc/core": "^1.3.26",
|
||||
"@swc/core-android-arm64": "1.3.11",
|
||||
"calckey-js": "^0.0.20",
|
||||
"calckey-js": "^0.0.22",
|
||||
"idb-keyval": "^6.2.0",
|
||||
"swc-loader": "^0.2.3",
|
||||
"webpack": "^5.75.0"
|
||||
"webpack": "^5.75.0",
|
||||
"webpack-cli": "^5.0.1"
|
||||
}
|
||||
}
|
||||
|
|
48
packages/sw/webpack.config.js
Normal file
48
packages/sw/webpack.config.js
Normal file
|
@ -0,0 +1,48 @@
|
|||
const webpack = require("webpack");
|
||||
const path = require('path');
|
||||
const locales = require('../../locales');
|
||||
const meta = require('../../package.json');
|
||||
|
||||
const isProduction = process.env.NODE_ENV === "production";
|
||||
|
||||
module.exports = {
|
||||
mode: isProduction ? "production" : "development",
|
||||
stats: "errors-only",
|
||||
entry: "./src/sw.ts",
|
||||
output: {
|
||||
path: path.resolve(__dirname, "../../built/_sw_dist_"),
|
||||
filename: "sw.js"
|
||||
},
|
||||
resolve: {
|
||||
extensions: [".js", ".ts"],
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
exclude: /(node_modules|bower_components)/,
|
||||
use: {
|
||||
loader: "swc-loader",
|
||||
options: {
|
||||
// This makes swc-loader invoke swc synchronously.
|
||||
sync: true,
|
||||
jsc: {
|
||||
parser: {
|
||||
syntax: "typescript"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
_VERSION_: JSON.stringify(meta.version),
|
||||
_LANGS_: JSON.stringify(Object.entries(locales).map(([k, v]) => [k, v._lang_])),
|
||||
_ENV_: JSON.stringify(process.env.NODE_ENV),
|
||||
_DEV_: !isProduction,
|
||||
_PERF_PREFIX_: JSON.stringify('Calckey:'),
|
||||
})
|
||||
]
|
||||
}
|
288
pnpm-lock.yaml
288
pnpm-lock.yaml
|
@ -12,7 +12,7 @@ importers:
|
|||
'@tensorflow/tfjs': ^3.21.0
|
||||
'@types/gulp': 4.0.10
|
||||
'@types/gulp-rename': 2.0.1
|
||||
calckey-js: ^0.0.20
|
||||
calckey-js: ^0.0.22
|
||||
cross-env: 7.0.3
|
||||
cypress: 10.11.0
|
||||
execa: 5.1.1
|
||||
|
@ -32,7 +32,7 @@ importers:
|
|||
'@bull-board/api': 4.10.2
|
||||
'@bull-board/ui': 4.10.2
|
||||
'@tensorflow/tfjs': 3.21.0_seedrandom@3.0.5
|
||||
calckey-js: 0.0.20
|
||||
calckey-js: 0.0.22
|
||||
js-yaml: 4.1.0
|
||||
phosphor-icons: 1.4.2
|
||||
seedrandom: 3.0.5
|
||||
|
@ -57,7 +57,7 @@ importers:
|
|||
'@bull-board/api': ^4.6.4
|
||||
'@bull-board/koa': ^4.6.4
|
||||
'@bull-board/ui': ^4.6.4
|
||||
'@cutls/megalodon': 5.1.15
|
||||
'@calckey/megalodon': 5.1.2
|
||||
'@discordapp/twemoji': 14.0.2
|
||||
'@elastic/elasticsearch': 7.17.0
|
||||
'@koa/cors': 3.4.3
|
||||
|
@ -126,7 +126,7 @@ importers:
|
|||
blurhash: 1.1.5
|
||||
bull: 4.10.2
|
||||
cacheable-lookup: 7.0.0
|
||||
calckey-js: ^0.0.20
|
||||
calckey-js: ^0.0.22
|
||||
cbor: 8.1.0
|
||||
chalk: 5.2.0
|
||||
chalk-template: 0.4.0
|
||||
|
@ -223,7 +223,7 @@ importers:
|
|||
'@bull-board/api': 4.10.2
|
||||
'@bull-board/koa': 4.10.2_6tybghmia4wsnt33xeid7y4rby
|
||||
'@bull-board/ui': 4.10.2
|
||||
'@cutls/megalodon': 5.1.15
|
||||
'@calckey/megalodon': 5.1.2
|
||||
'@discordapp/twemoji': 14.0.2
|
||||
'@elastic/elasticsearch': 7.17.0
|
||||
'@koa/cors': 3.4.3
|
||||
|
@ -245,7 +245,7 @@ importers:
|
|||
blurhash: 1.1.5
|
||||
bull: 4.10.2
|
||||
cacheable-lookup: 7.0.0
|
||||
calckey-js: 0.0.20
|
||||
calckey-js: 0.0.22
|
||||
cbor: 8.1.0
|
||||
chalk: 5.2.0
|
||||
chalk-template: 0.4.0
|
||||
|
@ -414,7 +414,7 @@ importers:
|
|||
blurhash: 1.1.5
|
||||
broadcast-channel: 4.19.1
|
||||
browser-image-resizer: https://github.com/misskey-dev/browser-image-resizer.git
|
||||
calckey-js: ^0.0.20
|
||||
calckey-js: ^0.0.22
|
||||
chart.js: 4.1.1
|
||||
chartjs-adapter-date-fns: 2.0.1
|
||||
chartjs-plugin-gradient: 0.5.1
|
||||
|
@ -488,7 +488,7 @@ importers:
|
|||
blurhash: 1.1.5
|
||||
broadcast-channel: 4.19.1
|
||||
browser-image-resizer: github.com/misskey-dev/browser-image-resizer/0380d12c8e736788ea7f4e6e985175521ea7b23c
|
||||
calckey-js: 0.0.20
|
||||
calckey-js: 0.0.22
|
||||
chart.js: 4.1.1
|
||||
chartjs-adapter-date-fns: 2.0.1_chart.js@4.1.1
|
||||
chartjs-plugin-gradient: 0.5.1_chart.js@4.1.1
|
||||
|
@ -542,18 +542,20 @@ importers:
|
|||
'@swc/cli': ^0.1.59
|
||||
'@swc/core': ^1.3.26
|
||||
'@swc/core-android-arm64': 1.3.11
|
||||
calckey-js: ^0.0.20
|
||||
calckey-js: ^0.0.22
|
||||
idb-keyval: ^6.2.0
|
||||
swc-loader: ^0.2.3
|
||||
webpack: ^5.75.0
|
||||
webpack-cli: ^5.0.1
|
||||
devDependencies:
|
||||
'@swc/cli': 0.1.59_@swc+core@1.3.26
|
||||
'@swc/core': 1.3.26
|
||||
'@swc/core-android-arm64': 1.3.11
|
||||
calckey-js: 0.0.20
|
||||
calckey-js: 0.0.22
|
||||
idb-keyval: 6.2.0
|
||||
swc-loader: 0.2.3_v4imsvpumnwpgduroyqmpcfjiy
|
||||
webpack: 5.75.0_@swc+core@1.3.26
|
||||
webpack: 5.75.0_bix6ghzcb3jjkfxenpixt6qrpa
|
||||
webpack-cli: 5.0.1_webpack@5.75.0
|
||||
|
||||
packages:
|
||||
|
||||
|
@ -746,6 +748,30 @@ packages:
|
|||
'@bull-board/api': 4.10.2
|
||||
dev: false
|
||||
|
||||
/@calckey/megalodon/5.1.2:
|
||||
resolution: {integrity: sha512-bUjPOfASy8X2NxdBvYDOWN9Rw/KdkfbTxy5vMQBcrGXepFbT4M+00blEYNc00Uu/epwH9YoNqpQC8PKQr/WU4w==}
|
||||
engines: {node: '>=15.0.0'}
|
||||
dependencies:
|
||||
'@types/oauth': 0.9.1
|
||||
'@types/ws': 8.5.4
|
||||
axios: 1.2.2
|
||||
dayjs: 1.11.7
|
||||
form-data: 4.0.0
|
||||
https-proxy-agent: 5.0.1
|
||||
oauth: 0.10.0
|
||||
object-assign-deep: 0.4.0
|
||||
parse-link-header: 2.0.0
|
||||
socks-proxy-agent: 7.0.0
|
||||
typescript: 4.9.4
|
||||
uuid: 9.0.0
|
||||
ws: 8.12.0
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- debug
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
dev: false
|
||||
|
||||
/@colors/colors/1.5.0:
|
||||
resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==}
|
||||
engines: {node: '>=0.1.90'}
|
||||
|
@ -847,30 +873,6 @@ packages:
|
|||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.9
|
||||
|
||||
/@cutls/megalodon/5.1.15:
|
||||
resolution: {integrity: sha512-4+mIKUYYr2CLY3idSxXk56WSTG9ww3opeenmsPRxftTwcjQTYxGntNkWmJWEbzeJ4rPslnvpwD7cFR62bPf41g==}
|
||||
engines: {node: '>=15.0.0'}
|
||||
dependencies:
|
||||
'@types/oauth': 0.9.1
|
||||
'@types/ws': 8.5.4
|
||||
axios: 1.2.2
|
||||
dayjs: 1.11.7
|
||||
form-data: 4.0.0
|
||||
https-proxy-agent: 5.0.1
|
||||
oauth: 0.10.0
|
||||
object-assign-deep: 0.4.0
|
||||
parse-link-header: 2.0.0
|
||||
socks-proxy-agent: 7.0.0
|
||||
typescript: 4.9.4
|
||||
uuid: 9.0.0
|
||||
ws: 8.12.0
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- debug
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
dev: false
|
||||
|
||||
/@cypress/request/2.88.11:
|
||||
resolution: {integrity: sha512-M83/wfQ1EkspjkE2lNWNV5ui2Cv7UCv1swW1DqljahbzLVWltcsexQh8jYtuS/vzFXP+HySntGM83ZXA9fn17w==}
|
||||
engines: {node: '>= 6'}
|
||||
|
@ -923,6 +925,11 @@ packages:
|
|||
twemoji-parser: 14.0.0
|
||||
universalify: 0.1.2
|
||||
|
||||
/@discoveryjs/json-ext/0.5.7:
|
||||
resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
dev: true
|
||||
|
||||
/@elastic/elasticsearch/7.17.0:
|
||||
resolution: {integrity: sha512-5QLPCjd0uLmLj1lSuKSThjNpq39f6NmlTy9ROLFwG5gjyTgpwSqufDeYG/Fm43Xs05uF7WcscoO7eguI3HuuYA==}
|
||||
engines: {node: '>=12'}
|
||||
|
@ -2819,6 +2826,43 @@ packages:
|
|||
resolution: {integrity: sha512-pUrWq3V5PiSGFLeLxoGqReTZmiiXwY3jRkIG5sLLKjyqNxrwm/04b4nw7LSmGWJcKk59XOM/YRTUwOzo4MMlow==}
|
||||
dev: false
|
||||
|
||||
/@webpack-cli/configtest/2.0.1_rjsyjcrmk25kqsjzwkvj3a2evq:
|
||||
resolution: {integrity: sha512-njsdJXJSiS2iNbQVS0eT8A/KPnmyH4pv1APj2K0d1wrZcBLw+yppxOy4CGqa0OxDJkzfL/XELDhD8rocnIwB5A==}
|
||||
engines: {node: '>=14.15.0'}
|
||||
peerDependencies:
|
||||
webpack: 5.x.x
|
||||
webpack-cli: 5.x.x
|
||||
dependencies:
|
||||
webpack: 5.75.0_bix6ghzcb3jjkfxenpixt6qrpa
|
||||
webpack-cli: 5.0.1_webpack@5.75.0
|
||||
dev: true
|
||||
|
||||
/@webpack-cli/info/2.0.1_rjsyjcrmk25kqsjzwkvj3a2evq:
|
||||
resolution: {integrity: sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA==}
|
||||
engines: {node: '>=14.15.0'}
|
||||
peerDependencies:
|
||||
webpack: 5.x.x
|
||||
webpack-cli: 5.x.x
|
||||
dependencies:
|
||||
webpack: 5.75.0_bix6ghzcb3jjkfxenpixt6qrpa
|
||||
webpack-cli: 5.0.1_webpack@5.75.0
|
||||
dev: true
|
||||
|
||||
/@webpack-cli/serve/2.0.1_rjsyjcrmk25kqsjzwkvj3a2evq:
|
||||
resolution: {integrity: sha512-0G7tNyS+yW8TdgHwZKlDWYXFA6OJQnoLCQvYKkQP0Q2X205PSQ6RNUj0M+1OB/9gRQaUZ/ccYfaxd0nhaWKfjw==}
|
||||
engines: {node: '>=14.15.0'}
|
||||
peerDependencies:
|
||||
webpack: 5.x.x
|
||||
webpack-cli: 5.x.x
|
||||
webpack-dev-server: '*'
|
||||
peerDependenciesMeta:
|
||||
webpack-dev-server:
|
||||
optional: true
|
||||
dependencies:
|
||||
webpack: 5.75.0_bix6ghzcb3jjkfxenpixt6qrpa
|
||||
webpack-cli: 5.0.1_webpack@5.75.0
|
||||
dev: true
|
||||
|
||||
/@xtuc/ieee754/1.2.0:
|
||||
resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==}
|
||||
dev: true
|
||||
|
@ -3335,7 +3379,7 @@ packages:
|
|||
/axios/0.24.0:
|
||||
resolution: {integrity: sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==}
|
||||
dependencies:
|
||||
follow-redirects: 1.15.2_debug@4.3.4
|
||||
follow-redirects: 1.15.2
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
dev: false
|
||||
|
@ -3343,7 +3387,7 @@ packages:
|
|||
/axios/0.25.0_debug@4.3.4:
|
||||
resolution: {integrity: sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==}
|
||||
dependencies:
|
||||
follow-redirects: 1.15.2_debug@4.3.4
|
||||
follow-redirects: 1.15.2
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
dev: true
|
||||
|
@ -3351,7 +3395,7 @@ packages:
|
|||
/axios/1.2.2:
|
||||
resolution: {integrity: sha512-bz/J4gS2S3I7mpN/YZfGFTqhXTYzRho8Ay38w2otuuDR322KzFIWm/4W2K6gIwvWaws5n+mnb7D1lN9uD+QH6Q==}
|
||||
dependencies:
|
||||
follow-redirects: 1.15.2_debug@4.3.4
|
||||
follow-redirects: 1.15.2
|
||||
form-data: 4.0.0
|
||||
proxy-from-env: 1.1.0
|
||||
transitivePeerDependencies:
|
||||
|
@ -3361,7 +3405,7 @@ packages:
|
|||
/axios/1.3.2:
|
||||
resolution: {integrity: sha512-1M3O703bYqYuPhbHeya5bnhpYVsDDRyQSabNja04mZtboLNSuZ4YrltestrLXfHgmzua4TpUqRiVKbiQuo2epw==}
|
||||
dependencies:
|
||||
follow-redirects: 1.15.2_debug@4.3.4
|
||||
follow-redirects: 1.15.2
|
||||
form-data: 4.0.0
|
||||
proxy-from-env: 1.1.0
|
||||
transitivePeerDependencies:
|
||||
|
@ -3820,8 +3864,8 @@ packages:
|
|||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/calckey-js/0.0.20:
|
||||
resolution: {integrity: sha512-KqydxFuMKAEmi+NPOpNZfnq5Ik7w2eApY7hc2MxrqIkcuy/lgUv8io4rnNx512fHppEHtV7AVxovU2//buvgZA==}
|
||||
/calckey-js/0.0.22:
|
||||
resolution: {integrity: sha512-So4Jc3w5QiwNO+8yLomjgNvHR9luKZ5bGLqjIEzAMsD/bIvUqWvriQAyWHN4EweyQUJ8UZCXBG9iyVX8VjtiXw==}
|
||||
dependencies:
|
||||
autobind-decorator: 2.4.0
|
||||
eventemitter3: 4.0.7
|
||||
|
@ -4145,6 +4189,15 @@ packages:
|
|||
engines: {node: '>= 0.10'}
|
||||
dev: true
|
||||
|
||||
/clone-deep/4.0.1:
|
||||
resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==}
|
||||
engines: {node: '>=6'}
|
||||
dependencies:
|
||||
is-plain-object: 2.0.4
|
||||
kind-of: 6.0.3
|
||||
shallow-clone: 3.0.1
|
||||
dev: true
|
||||
|
||||
/clone-response/1.0.2:
|
||||
resolution: {integrity: sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==}
|
||||
dependencies:
|
||||
|
@ -5570,6 +5623,12 @@ packages:
|
|||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/envinfo/7.8.1:
|
||||
resolution: {integrity: sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==}
|
||||
engines: {node: '>=4'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/err-code/2.0.3:
|
||||
resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==}
|
||||
dev: false
|
||||
|
@ -6083,6 +6142,11 @@ packages:
|
|||
strnum: 1.0.5
|
||||
dev: false
|
||||
|
||||
/fastest-levenshtein/1.0.16:
|
||||
resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==}
|
||||
engines: {node: '>= 4.9.1'}
|
||||
dev: true
|
||||
|
||||
/fastq/1.15.0:
|
||||
resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==}
|
||||
dependencies:
|
||||
|
@ -6210,7 +6274,6 @@ packages:
|
|||
dependencies:
|
||||
locate-path: 5.0.0
|
||||
path-exists: 4.0.0
|
||||
dev: false
|
||||
|
||||
/find-up/5.0.0:
|
||||
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
|
||||
|
@ -6301,7 +6364,7 @@ packages:
|
|||
readable-stream: 2.3.7
|
||||
dev: true
|
||||
|
||||
/follow-redirects/1.15.2_debug@4.3.4:
|
||||
/follow-redirects/1.15.2:
|
||||
resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
|
||||
engines: {node: '>=4.0'}
|
||||
peerDependencies:
|
||||
|
@ -6309,8 +6372,6 @@ packages:
|
|||
peerDependenciesMeta:
|
||||
debug:
|
||||
optional: true
|
||||
dependencies:
|
||||
debug: 4.3.4
|
||||
|
||||
/for-each/0.3.3:
|
||||
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
|
||||
|
@ -7280,6 +7341,15 @@ packages:
|
|||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/import-local/3.1.0:
|
||||
resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==}
|
||||
engines: {node: '>=8'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
pkg-dir: 4.2.0
|
||||
resolve-cwd: 3.0.0
|
||||
dev: true
|
||||
|
||||
/imurmurhash/0.1.4:
|
||||
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
|
||||
engines: {node: '>=0.8.19'}
|
||||
|
@ -7342,6 +7412,11 @@ packages:
|
|||
engines: {node: '>= 0.10'}
|
||||
dev: true
|
||||
|
||||
/interpret/3.1.1:
|
||||
resolution: {integrity: sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
dev: true
|
||||
|
||||
/into-stream/3.1.0:
|
||||
resolution: {integrity: sha512-TcdjPibTksa1NQximqep2r17ISRiNE9fwlfbg3F8ANdvP5/yrFTew86VcO//jk4QTaMlbjypPBq76HN2zaKfZQ==}
|
||||
engines: {node: '>=4'}
|
||||
|
@ -8544,7 +8619,6 @@ packages:
|
|||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
p-locate: 4.1.0
|
||||
dev: false
|
||||
|
||||
/locate-path/6.0.0:
|
||||
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
|
||||
|
@ -9678,7 +9752,6 @@ packages:
|
|||
engines: {node: '>=6'}
|
||||
dependencies:
|
||||
p-try: 2.2.0
|
||||
dev: false
|
||||
|
||||
/p-limit/3.1.0:
|
||||
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
|
||||
|
@ -9691,7 +9764,6 @@ packages:
|
|||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
p-limit: 2.3.0
|
||||
dev: false
|
||||
|
||||
/p-locate/5.0.0:
|
||||
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
|
||||
|
@ -9729,7 +9801,6 @@ packages:
|
|||
/p-try/2.2.0:
|
||||
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/packet-reader/1.0.0:
|
||||
resolution: {integrity: sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==}
|
||||
|
@ -9998,6 +10069,13 @@ packages:
|
|||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/pkg-dir/4.2.0:
|
||||
resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
find-up: 4.1.0
|
||||
dev: true
|
||||
|
||||
/plimit-lit/1.5.0:
|
||||
resolution: {integrity: sha512-Eb/MqCb1Iv/ok4m1FqIXqvUKPISufcjZ605hl3KM/n8GaX8zfhtgdLwZU3vKjuHGh2O9Rjog/bHTq8ofIShdng==}
|
||||
dependencies:
|
||||
|
@ -10769,6 +10847,13 @@ packages:
|
|||
resolve: 1.22.1
|
||||
dev: true
|
||||
|
||||
/rechoir/0.8.0:
|
||||
resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==}
|
||||
engines: {node: '>= 10.13.0'}
|
||||
dependencies:
|
||||
resolve: 1.22.1
|
||||
dev: true
|
||||
|
||||
/reconnecting-websocket/4.4.0:
|
||||
resolution: {integrity: sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng==}
|
||||
|
||||
|
@ -10961,6 +11046,13 @@ packages:
|
|||
resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==}
|
||||
dev: false
|
||||
|
||||
/resolve-cwd/3.0.0:
|
||||
resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
resolve-from: 5.0.0
|
||||
dev: true
|
||||
|
||||
/resolve-dir/1.0.1:
|
||||
resolution: {integrity: sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
@ -10973,6 +11065,11 @@ packages:
|
|||
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
/resolve-from/5.0.0:
|
||||
resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/resolve-options/1.1.0:
|
||||
resolution: {integrity: sha512-NYDgziiroVeDC29xq7bp/CacZERYsA9bXYd1ZmcJlF3BcrZv5pTb4NG7SjdyKDnXZ84aC4vo2u6sNKIA1LCu/A==}
|
||||
engines: {node: '>= 0.10'}
|
||||
|
@ -11275,6 +11372,13 @@ packages:
|
|||
crypt: 0.0.2
|
||||
dev: true
|
||||
|
||||
/shallow-clone/3.0.1:
|
||||
resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
kind-of: 6.0.3
|
||||
dev: true
|
||||
|
||||
/sharp/0.31.3:
|
||||
resolution: {integrity: sha512-XcR4+FCLBFKw1bdB+GEhnUNXNXvnt0tDo4WsBsraKymuo/IAuPuCBVAL2wIkUw2r/dwFW5Q5+g66Kwl2dgDFVg==}
|
||||
engines: {node: '>=14.15.0'}
|
||||
|
@ -12908,6 +13012,47 @@ packages:
|
|||
engines: {node: '>=12'}
|
||||
dev: false
|
||||
|
||||
/webpack-cli/5.0.1_webpack@5.75.0:
|
||||
resolution: {integrity: sha512-S3KVAyfwUqr0Mo/ur3NzIp6jnerNpo7GUO6so51mxLi1spqsA17YcMXy0WOIJtBSnj748lthxC6XLbNKh/ZC+A==}
|
||||
engines: {node: '>=14.15.0'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@webpack-cli/generators': '*'
|
||||
webpack: 5.x.x
|
||||
webpack-bundle-analyzer: '*'
|
||||
webpack-dev-server: '*'
|
||||
peerDependenciesMeta:
|
||||
'@webpack-cli/generators':
|
||||
optional: true
|
||||
webpack-bundle-analyzer:
|
||||
optional: true
|
||||
webpack-dev-server:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@discoveryjs/json-ext': 0.5.7
|
||||
'@webpack-cli/configtest': 2.0.1_rjsyjcrmk25kqsjzwkvj3a2evq
|
||||
'@webpack-cli/info': 2.0.1_rjsyjcrmk25kqsjzwkvj3a2evq
|
||||
'@webpack-cli/serve': 2.0.1_rjsyjcrmk25kqsjzwkvj3a2evq
|
||||
colorette: 2.0.19
|
||||
commander: 9.5.0
|
||||
cross-spawn: 7.0.3
|
||||
envinfo: 7.8.1
|
||||
fastest-levenshtein: 1.0.16
|
||||
import-local: 3.1.0
|
||||
interpret: 3.1.1
|
||||
rechoir: 0.8.0
|
||||
webpack: 5.75.0_bix6ghzcb3jjkfxenpixt6qrpa
|
||||
webpack-merge: 5.8.0
|
||||
dev: true
|
||||
|
||||
/webpack-merge/5.8.0:
|
||||
resolution: {integrity: sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
dependencies:
|
||||
clone-deep: 4.0.1
|
||||
wildcard: 2.0.0
|
||||
dev: true
|
||||
|
||||
/webpack-sources/3.2.3:
|
||||
resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
|
@ -12953,6 +13098,47 @@ packages:
|
|||
- uglify-js
|
||||
dev: true
|
||||
|
||||
/webpack/5.75.0_bix6ghzcb3jjkfxenpixt6qrpa:
|
||||
resolution: {integrity: sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
webpack-cli: '*'
|
||||
peerDependenciesMeta:
|
||||
webpack-cli:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/eslint-scope': 3.7.4
|
||||
'@types/estree': 0.0.51
|
||||
'@webassemblyjs/ast': 1.11.1
|
||||
'@webassemblyjs/wasm-edit': 1.11.1
|
||||
'@webassemblyjs/wasm-parser': 1.11.1
|
||||
acorn: 8.8.1
|
||||
acorn-import-assertions: 1.8.0_acorn@8.8.1
|
||||
browserslist: 4.21.4
|
||||
chrome-trace-event: 1.0.3
|
||||
enhanced-resolve: 5.12.0
|
||||
es-module-lexer: 0.9.3
|
||||
eslint-scope: 5.1.1
|
||||
events: 3.3.0
|
||||
glob-to-regexp: 0.4.1
|
||||
graceful-fs: 4.2.10
|
||||
json-parse-even-better-errors: 2.3.1
|
||||
loader-runner: 4.3.0
|
||||
mime-types: 2.1.35
|
||||
neo-async: 2.6.2
|
||||
schema-utils: 3.1.1
|
||||
tapable: 2.2.1
|
||||
terser-webpack-plugin: 5.3.6_v4imsvpumnwpgduroyqmpcfjiy
|
||||
watchpack: 2.4.0
|
||||
webpack-cli: 5.0.1_webpack@5.75.0
|
||||
webpack-sources: 3.2.3
|
||||
transitivePeerDependencies:
|
||||
- '@swc/core'
|
||||
- esbuild
|
||||
- uglify-js
|
||||
dev: true
|
||||
|
||||
/websocket/1.0.34:
|
||||
resolution: {integrity: sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==}
|
||||
engines: {node: '>=4.0.0'}
|
||||
|
@ -13038,6 +13224,10 @@ packages:
|
|||
string-width: 4.2.3
|
||||
dev: false
|
||||
|
||||
/wildcard/2.0.0:
|
||||
resolution: {integrity: sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==}
|
||||
dev: true
|
||||
|
||||
/with/7.0.2:
|
||||
resolution: {integrity: sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
|
|
Loading…
Reference in a new issue