mirror of
https://iceshrimp.dev/crimekillz/iceshrimp-161sh.git
synced 2024-11-22 20:23:49 +01:00
[mastodon-client] POST /accounts/:id/mute, POST /accounts/:id/unmute; Fix timeline helper function
This commit is contained in:
parent
3c22417a31
commit
f667f2f985
@ -335,15 +335,19 @@ export function apiAccountMastodon(router: Router): void {
|
|||||||
router.post<{ Params: { id: string } }>(
|
router.post<{ Params: { id: string } }>(
|
||||||
"/v1/accounts/:id/mute",
|
"/v1/accounts/:id/mute",
|
||||||
async (ctx) => {
|
async (ctx) => {
|
||||||
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
|
|
||||||
const accessTokens = ctx.headers.authorization;
|
|
||||||
const client = getClient(BASE_URL, accessTokens);
|
|
||||||
try {
|
try {
|
||||||
const data = await client.muteAccount(
|
const auth = await authenticate(ctx.headers.authorization, null);
|
||||||
convertId(ctx.params.id, IdType.IceshrimpId),
|
const user = auth[0] ?? null;
|
||||||
(ctx.request as any).body as any,
|
|
||||||
);
|
if (!user) {
|
||||||
ctx.body = convertRelationship(data.data);
|
ctx.status = 401;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const args = normalizeUrlQuery(argsToBools(limitToInt(ctx.query, ['duration']), ['notifications']));
|
||||||
|
const target = await UserHelpers.getUserCached(convertId(ctx.params.id, IdType.IceshrimpId));
|
||||||
|
const result = await UserHelpers.muteUser(target, user, args.notifications, args.duration);
|
||||||
|
ctx.body = convertRelationship(result)
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
console.error(e.response.data);
|
console.error(e.response.data);
|
||||||
@ -355,14 +359,18 @@ export function apiAccountMastodon(router: Router): void {
|
|||||||
router.post<{ Params: { id: string } }>(
|
router.post<{ Params: { id: string } }>(
|
||||||
"/v1/accounts/:id/unmute",
|
"/v1/accounts/:id/unmute",
|
||||||
async (ctx) => {
|
async (ctx) => {
|
||||||
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
|
|
||||||
const accessTokens = ctx.headers.authorization;
|
|
||||||
const client = getClient(BASE_URL, accessTokens);
|
|
||||||
try {
|
try {
|
||||||
const data = await client.unmuteAccount(
|
const auth = await authenticate(ctx.headers.authorization, null);
|
||||||
convertId(ctx.params.id, IdType.IceshrimpId),
|
const user = auth[0] ?? null;
|
||||||
);
|
|
||||||
ctx.body = convertRelationship(data.data);
|
if (!user) {
|
||||||
|
ctx.status = 401;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const target = await UserHelpers.getUserCached(convertId(ctx.params.id, IdType.IceshrimpId));
|
||||||
|
const result = await UserHelpers.unmuteUser(target, user);
|
||||||
|
ctx.body = convertRelationship(result)
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
console.error(e.response.data);
|
console.error(e.response.data);
|
||||||
|
@ -13,16 +13,18 @@ import { TimelineHelpers } from "@/server/api/mastodon/helpers/timeline.js";
|
|||||||
import { NoteConverter } from "@/server/api/mastodon/converters/note.js";
|
import { NoteConverter } from "@/server/api/mastodon/converters/note.js";
|
||||||
import { UserHelpers } from "@/server/api/mastodon/helpers/user.js";
|
import { UserHelpers } from "@/server/api/mastodon/helpers/user.js";
|
||||||
|
|
||||||
export function limitToInt(q: ParsedUrlQuery) {
|
export function limitToInt(q: ParsedUrlQuery, additional: string[] = []) {
|
||||||
let object: any = q;
|
let object: any = q;
|
||||||
if (q.limit)
|
if (q.limit)
|
||||||
if (typeof q.limit === "string") object.limit = parseInt(q.limit, 10);
|
if (typeof q.limit === "string") object.limit = parseInt(q.limit, 10);
|
||||||
if (q.offset)
|
if (q.offset)
|
||||||
if (typeof q.offset === "string") object.offset = parseInt(q.offset, 10);
|
if (typeof q.offset === "string") object.offset = parseInt(q.offset, 10);
|
||||||
|
for (const key of additional)
|
||||||
|
if (typeof q[key] === "string") object[key] = parseInt(<string>q[key], 10);
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function argsToBools(q: ParsedUrlQuery) {
|
export function argsToBools(q: ParsedUrlQuery, additional: string[] = []) {
|
||||||
// Values taken from https://docs.joinmastodon.org/client/intro/#boolean
|
// Values taken from https://docs.joinmastodon.org/client/intro/#boolean
|
||||||
const toBoolean = (value: string) =>
|
const toBoolean = (value: string) =>
|
||||||
!["0", "f", "F", "false", "FALSE", "off", "OFF"].includes(value);
|
!["0", "f", "F", "false", "FALSE", "off", "OFF"].includes(value);
|
||||||
@ -31,23 +33,14 @@ export function argsToBools(q: ParsedUrlQuery) {
|
|||||||
// - https://docs.joinmastodon.org/methods/accounts/#statuses
|
// - https://docs.joinmastodon.org/methods/accounts/#statuses
|
||||||
// - https://docs.joinmastodon.org/methods/timelines/#public
|
// - https://docs.joinmastodon.org/methods/timelines/#public
|
||||||
// - https://docs.joinmastodon.org/methods/timelines/#tag
|
// - https://docs.joinmastodon.org/methods/timelines/#tag
|
||||||
|
let keys = ['only_media', 'exclude_replies', 'exclude_reblogs', 'pinned', 'local', 'remote']
|
||||||
let object: any = q;
|
let object: any = q;
|
||||||
if (q.only_media)
|
|
||||||
if (typeof q.only_media === "string")
|
for (const key of keys)
|
||||||
object.only_media = toBoolean(q.only_media);
|
if (q[key] && typeof q[key] === "string")
|
||||||
if (q.exclude_replies)
|
object[key] = toBoolean(<string>q[key]);
|
||||||
if (typeof q.exclude_replies === "string")
|
|
||||||
object.exclude_replies = toBoolean(q.exclude_replies);
|
return object;
|
||||||
if (q.exclude_reblogs)
|
|
||||||
if (typeof q.exclude_reblogs === "string")
|
|
||||||
object.exclude_reblogs = toBoolean(q.exclude_reblogs);
|
|
||||||
if (q.pinned)
|
|
||||||
if (typeof q.pinned === "string") object.pinned = toBoolean(q.pinned);
|
|
||||||
if (q.local)
|
|
||||||
if (typeof q.local === "string") object.local = toBoolean(q.local);
|
|
||||||
if (q.remote)
|
|
||||||
if (typeof q.local === "string") object.local = toBoolean(q.local);
|
|
||||||
return q;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function convertTimelinesArgsId(q: ParsedUrlQuery) {
|
export function convertTimelinesArgsId(q: ParsedUrlQuery) {
|
||||||
|
@ -3,10 +3,10 @@ import { ILocalUser, User } from "@/models/entities/user.js";
|
|||||||
import {
|
import {
|
||||||
Blockings,
|
Blockings,
|
||||||
Followings,
|
Followings,
|
||||||
FollowRequests,
|
FollowRequests, Mutings,
|
||||||
NoteFavorites,
|
NoteFavorites,
|
||||||
NoteReactions,
|
NoteReactions,
|
||||||
Notes,
|
Notes, NoteWatchings,
|
||||||
UserProfiles,
|
UserProfiles,
|
||||||
Users
|
Users
|
||||||
} from "@/models/index.js";
|
} from "@/models/index.js";
|
||||||
@ -26,6 +26,9 @@ import deleteFollowing from "@/services/following/delete.js";
|
|||||||
import cancelFollowRequest from "@/services/following/requests/cancel.js";
|
import cancelFollowRequest from "@/services/following/requests/cancel.js";
|
||||||
import createBlocking from "@/services/blocking/create.js";
|
import createBlocking from "@/services/blocking/create.js";
|
||||||
import deleteBlocking from "@/services/blocking/delete.js";
|
import deleteBlocking from "@/services/blocking/delete.js";
|
||||||
|
import { genId } from "@/misc/gen-id.js";
|
||||||
|
import { Muting } from "@/models/entities/muting.js";
|
||||||
|
import { publishUserEvent } from "@/services/stream.js";
|
||||||
|
|
||||||
export type AccountCache = {
|
export type AccountCache = {
|
||||||
locks: AsyncLock;
|
locks: AsyncLock;
|
||||||
@ -79,6 +82,42 @@ export class UserHelpers {
|
|||||||
return this.getUserRelationshipTo(target.id, localUser.id);
|
return this.getUserRelationshipTo(target.id, localUser.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async muteUser(target: User, localUser: ILocalUser, notifications: boolean = true, duration: number = 0) {
|
||||||
|
//FIXME: respect notifications parameter
|
||||||
|
const muted = await Mutings.exist({where: {muterId: localUser.id, muteeId: target.id}});
|
||||||
|
if (!muted) {
|
||||||
|
await Mutings.insert({
|
||||||
|
id: genId(),
|
||||||
|
createdAt: new Date(),
|
||||||
|
expiresAt: duration === 0 ? null : new Date(new Date().getTime() + (duration * 1000)),
|
||||||
|
muterId: localUser.id,
|
||||||
|
muteeId: target.id,
|
||||||
|
} as Muting);
|
||||||
|
|
||||||
|
publishUserEvent(localUser.id, "mute", target);
|
||||||
|
|
||||||
|
NoteWatchings.delete({
|
||||||
|
userId: localUser.id,
|
||||||
|
noteUserId: target.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.getUserRelationshipTo(target.id, localUser.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async unmuteUser(target: User, localUser: ILocalUser) {
|
||||||
|
const muting = await Mutings.findOneBy({muterId: localUser.id, muteeId: target.id});
|
||||||
|
if (muting) {
|
||||||
|
await Mutings.delete({
|
||||||
|
id: muting.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
publishUserEvent(localUser.id, "unmute", target);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.getUserRelationshipTo(target.id, localUser.id);
|
||||||
|
}
|
||||||
|
|
||||||
public static async getUserStatuses(user: User, localUser: ILocalUser | null, maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 20, onlyMedia: boolean = false, excludeReplies: boolean = false, excludeReblogs: boolean = false, pinned: boolean = false, tagged: string | undefined): Promise<Note[]> {
|
public static async getUserStatuses(user: User, localUser: ILocalUser | null, maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 20, onlyMedia: boolean = false, excludeReplies: boolean = false, excludeReblogs: boolean = false, pinned: boolean = false, tagged: string | undefined): Promise<Note[]> {
|
||||||
if (limit > 40) limit = 40;
|
if (limit > 40) limit = 40;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user