Various Fixes
This commit is contained in:
parent
17f57c3ed1
commit
554e02dd31
|
@ -1005,6 +1005,14 @@ export default class Mastodon implements MegalodonInterface {
|
|||
})
|
||||
}
|
||||
|
||||
public async getAccountFeaturedTags(id :string): Promise<Response<Array<Entity.FeaturedTag>>> {
|
||||
return this.client.get<Array<MastodonAPI.Entity.FeaturedTag>>(`/api/v1/accounts/${id}/featured_tags`).then(res => {
|
||||
return Object.assign(res, {
|
||||
data: res.data.map(f => MastodonAPI.Converter.featured_tag(f))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
public async createFeaturedTag(name: string): Promise<Response<Entity.FeaturedTag>> {
|
||||
return this.client
|
||||
.post<MastodonAPI.Entity.FeaturedTag>('/api/v1/featured_tags', {
|
||||
|
|
|
@ -229,6 +229,17 @@ export interface MegalodonInterface {
|
|||
sleep_ms?: number
|
||||
}
|
||||
): Promise<Response<Array<Entity.Account>>>
|
||||
|
||||
/**
|
||||
* GET /api/v1/accounts/:id/featured_tags
|
||||
*
|
||||
* @param id The account ID.
|
||||
* @return The array of accounts.
|
||||
*/
|
||||
getAccountFeaturedTags(
|
||||
id: string
|
||||
): Promise<Response<Array<Entity.FeaturedTag>>>
|
||||
|
||||
/**
|
||||
* GET /api/v1/accounts/:id/following
|
||||
*
|
||||
|
|
|
@ -948,10 +948,19 @@ export default class Misskey implements MegalodonInterface {
|
|||
// accounts/featured_tags
|
||||
// ======================================
|
||||
public async getFeaturedTags(): Promise<Response<Array<Entity.FeaturedTag>>> {
|
||||
return new Promise((_, reject) => {
|
||||
const err = new NoImplementedError('misskey does not support')
|
||||
reject(err)
|
||||
})
|
||||
return this.getAccountFeaturedTags();
|
||||
}
|
||||
|
||||
public async getAccountFeaturedTags(): Promise<Response<Array<Entity.FeaturedTag>>> {
|
||||
console.log("getting featured tags");
|
||||
const tags : Entity.FeaturedTag[] = [];
|
||||
const res : Response = {
|
||||
headers: undefined,
|
||||
statusText: "",
|
||||
status: 200,
|
||||
data: tags
|
||||
};
|
||||
return new Promise(resolve => resolve(res))
|
||||
}
|
||||
|
||||
public async createFeaturedTag(_name: string): Promise<Response<Entity.FeaturedTag>> {
|
||||
|
@ -979,10 +988,23 @@ export default class Misskey implements MegalodonInterface {
|
|||
// accounts/preferences
|
||||
// ======================================
|
||||
public async getPreferences(): Promise<Response<Entity.Preferences>> {
|
||||
return new Promise((_, reject) => {
|
||||
const err = new NoImplementedError('misskey does not support')
|
||||
reject(err)
|
||||
})
|
||||
return this.client.post<MisskeyAPI.Entity.UserDetailMe>('/api/i').then(res => {
|
||||
/*
|
||||
return this.client.post<MisskeyAPI.Entity.GetAll>('/api/i/registry/get-all', {
|
||||
scope: ['client', 'base'],
|
||||
}).then(ga => {
|
||||
return Object.assign(res, {
|
||||
data: MisskeyAPI.Converter.userPreferences(res.data, ga.data)
|
||||
})
|
||||
})
|
||||
*/
|
||||
|
||||
// TODO:
|
||||
// FIXME: get this from api
|
||||
return Object.assign(res, {
|
||||
data: MisskeyAPI.Converter.userPreferences(res.data, {defaultNoteVisibility: "followers", tutorial: -1})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// ======================================
|
||||
|
@ -1148,7 +1170,14 @@ export default class Misskey implements MegalodonInterface {
|
|||
if (options) {
|
||||
if (options.limit) {
|
||||
params = Object.assign(params, {
|
||||
limit: options.limit
|
||||
limit: options.limit,
|
||||
depth: 12
|
||||
})
|
||||
}
|
||||
else {
|
||||
params = Object.assign(params, {
|
||||
limit: 30,
|
||||
depth: 12
|
||||
})
|
||||
}
|
||||
if (options.max_id) {
|
||||
|
@ -1162,10 +1191,31 @@ export default class Misskey implements MegalodonInterface {
|
|||
})
|
||||
}
|
||||
}
|
||||
else {
|
||||
params = Object.assign(params, {
|
||||
limit: 30,
|
||||
depth: 12
|
||||
})
|
||||
}
|
||||
return this.client.post<Array<MisskeyAPI.Entity.Note>>('/api/notes/children', params).then(res => {
|
||||
console.log(JSON.stringify(res, null, 2));
|
||||
|
||||
const parent : Entity.Status[] = [];
|
||||
|
||||
this.getStatus(params.noteId).then(res => {
|
||||
console.log("getting status");
|
||||
if (res.data.in_reply_to_id != null){
|
||||
console.log("replyid not null");
|
||||
this.getStatus(res.data.in_reply_to_id).then(res => {
|
||||
console.log("setting parent to " + res.data.id);
|
||||
parent.push(res.data);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const context: Entity.Context = {
|
||||
ancestors: [],
|
||||
descendants: res.data.map(n => MisskeyAPI.Converter.note(n, this.baseUrlToHost(this.baseUrl)))
|
||||
ancestors: parent,
|
||||
descendants: this.dfs(res.data.map(n => MisskeyAPI.Converter.note(n, this.baseUrlToHost(this.baseUrl))))
|
||||
}
|
||||
return {
|
||||
...res,
|
||||
|
@ -1174,6 +1224,46 @@ export default class Misskey implements MegalodonInterface {
|
|||
})
|
||||
}
|
||||
|
||||
private dfs(graph: Entity.Status[]) {
|
||||
// we don't need to run dfs if we have zero or one elements
|
||||
if (graph.length <= 1) {
|
||||
return graph;
|
||||
}
|
||||
|
||||
// sort the graph first, so we can grab the correct starting point
|
||||
graph = graph.sort((a, b) => {
|
||||
if (a.id < b.id) return -1;
|
||||
if (a.id > b.id) return 1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
const initialPostId = graph[0].in_reply_to_id;
|
||||
|
||||
// populate stack with all top level replies
|
||||
const stack = graph.filter(reply => reply.in_reply_to_id === initialPostId).reverse();
|
||||
const visited = new Set();
|
||||
const result = [];
|
||||
|
||||
while (stack.length) {
|
||||
const currentPost = stack.pop();
|
||||
|
||||
if (currentPost === undefined)
|
||||
return result;
|
||||
|
||||
if (!visited.has(currentPost)) {
|
||||
visited.add(currentPost);
|
||||
result.push(currentPost);
|
||||
|
||||
for (const reply of graph.filter(reply => reply.in_reply_to_id === currentPost.id).reverse()) {
|
||||
stack.push(reply);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* POST /api/notes/renotes
|
||||
*/
|
||||
|
@ -1196,16 +1286,20 @@ export default class Misskey implements MegalodonInterface {
|
|||
}
|
||||
|
||||
public async favouriteStatus(id: string): Promise<Response<Entity.Status>> {
|
||||
return this.createEmojiReaction(id, await this.getDefaultFavoriteEmoji());
|
||||
}
|
||||
|
||||
private async getDefaultFavoriteEmoji(): Promise<string> {
|
||||
// NOTE: get-unsecure is calckey's extension.
|
||||
// Misskey doesn't have this endpoint and regular `/i/registry/get` won't work
|
||||
// unless you have a 'nativeToken', which is reserved for the frontend webapp.
|
||||
const reaction = await this.client
|
||||
.post<Array<string>>('/api/i/registry/get-unsecure', {
|
||||
key: 'reactions',
|
||||
scope: ['client', 'base'],
|
||||
})
|
||||
.then(res => res.data[0] ?? '⭐');
|
||||
return this.createEmojiReaction(id, reaction);
|
||||
|
||||
return await this.client
|
||||
.post<Array<string>>('/api/i/registry/get-unsecure', {
|
||||
key: 'reactions',
|
||||
scope: ['client', 'base'],
|
||||
})
|
||||
.then(res => res.data[0] ?? '⭐');
|
||||
}
|
||||
|
||||
public async unfavouriteStatus(id: string): Promise<Response<Entity.Status>> {
|
||||
|
|
|
@ -36,6 +36,8 @@ namespace MisskeyAPI {
|
|||
export type Relation = MisskeyEntity.Relation
|
||||
export type User = MisskeyEntity.User
|
||||
export type UserDetail = MisskeyEntity.UserDetail
|
||||
export type UserDetailMe = MisskeyEntity.UserDetailMe
|
||||
export type GetAll = MisskeyEntity.GetAll
|
||||
export type UserKey = MisskeyEntity.UserKey
|
||||
export type Session = MisskeyEntity.Session
|
||||
export type Stats = MisskeyEntity.Stats
|
||||
|
@ -90,8 +92,8 @@ namespace MisskeyAPI {
|
|||
url: acctUrl,
|
||||
avatar: u.avatarUrl,
|
||||
avatar_static: u.avatarColor,
|
||||
header: '',
|
||||
header_static: '',
|
||||
header: 'https://http.cat/404', // FIXME
|
||||
header_static: 'https://http.cat/404', // FIXME
|
||||
emojis: u.emojis.map(e => emoji(e)),
|
||||
moved: null,
|
||||
fields: [],
|
||||
|
@ -130,6 +132,16 @@ namespace MisskeyAPI {
|
|||
}
|
||||
}
|
||||
|
||||
export const userPreferences = (u: MisskeyAPI.Entity.UserDetailMe, g: MisskeyAPI.Entity.GetAll): MegalodonEntity.Preferences => {
|
||||
return {
|
||||
"reading:expand:media": "default",
|
||||
"reading:expand:spoilers": false,
|
||||
"posting:default:language": u.lang,
|
||||
"posting:default:sensitive": u.alwaysMarkNsfw,
|
||||
"posting:default:visibility": visibility(g.defaultNoteVisibility)
|
||||
}
|
||||
}
|
||||
|
||||
export const visibility = (v: 'public' | 'home' | 'followers' | 'specified'): 'public' | 'unlisted' | 'private' | 'direct' => {
|
||||
switch (v) {
|
||||
case 'public':
|
||||
|
@ -252,7 +264,7 @@ namespace MisskeyAPI {
|
|||
emojis: n.emojis.map(e => emoji(e)),
|
||||
replies_count: n.repliesCount,
|
||||
reblogs_count: n.renoteCount,
|
||||
favourites_count: 0,
|
||||
favourites_count: getTotalReactions(n.reactions), // FIXME: instead get # of default reaction emoji reactions
|
||||
reblogged: false,
|
||||
favourited: !!n.myReaction,
|
||||
muted: false,
|
||||
|
@ -290,6 +302,10 @@ namespace MisskeyAPI {
|
|||
})
|
||||
}
|
||||
|
||||
export const getTotalReactions = (r: { [key: string]: number }): number => {
|
||||
return Object.values(r).length > 0 ? Object.values(r).reduce((previousValue, currentValue) => previousValue + currentValue) : 0
|
||||
}
|
||||
|
||||
export const reactions = (r: Array<Entity.Reaction>): Array<MegalodonEntity.Reaction> => {
|
||||
const result: Array<MegalodonEntity.Reaction> = []
|
||||
for (const e of r) {
|
||||
|
@ -553,6 +569,9 @@ namespace MisskeyAPI {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
console.log(JSON.stringify(bodyParams, null, 2));
|
||||
|
||||
return axios.post<T>(this.baseUrl + path, bodyParams, options).then((resp: AxiosResponse<T>) => {
|
||||
const res: Response<T> = {
|
||||
data: resp.data,
|
||||
|
|
6
megalodon/src/misskey/entities/GetAll.ts
Normal file
6
megalodon/src/misskey/entities/GetAll.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
namespace MisskeyEntity {
|
||||
export type GetAll = {
|
||||
tutorial: number
|
||||
defaultNoteVisibility: 'public' | 'home' | 'followers' | 'specified'
|
||||
}
|
||||
}
|
36
megalodon/src/misskey/entities/userDetailMe.ts
Normal file
36
megalodon/src/misskey/entities/userDetailMe.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
/// <reference path="emoji.ts" />
|
||||
/// <reference path="field.ts" />
|
||||
/// <reference path="note.ts" />
|
||||
|
||||
namespace MisskeyEntity {
|
||||
export type UserDetailMe = {
|
||||
id: string
|
||||
name: string
|
||||
username: string
|
||||
host: string | null
|
||||
avatarUrl: string
|
||||
avatarColor: string
|
||||
isAdmin: boolean
|
||||
isModerator: boolean
|
||||
isBot: boolean
|
||||
isCat: boolean
|
||||
emojis: Array<Emoji>
|
||||
createdAt: string
|
||||
bannerUrl: string
|
||||
bannerColor: string
|
||||
isLocked: boolean
|
||||
isSilenced: boolean
|
||||
isSuspended: boolean
|
||||
description: string
|
||||
followersCount: number
|
||||
followingCount: number
|
||||
notesCount: number
|
||||
avatarId: string
|
||||
bannerId: string
|
||||
pinnedNoteIds?: Array<string>
|
||||
pinnedNotes?: Array<Note>
|
||||
fields: Array<Field>
|
||||
alwaysMarkNsfw: boolean
|
||||
lang: string | null
|
||||
}
|
||||
}
|
|
@ -20,6 +20,7 @@
|
|||
/// <reference path="entities/relation.ts" />
|
||||
/// <reference path="entities/user.ts" />
|
||||
/// <reference path="entities/userDetail.ts" />
|
||||
/// <reference path="entities/userDetailMe.ts" />
|
||||
/// <reference path="entities/userkey.ts" />
|
||||
/// <reference path="entities/session.ts" />
|
||||
/// <reference path="entities/stats.ts" />
|
||||
|
|
|
@ -997,6 +997,14 @@ export default class Pleroma implements MegalodonInterface {
|
|||
})
|
||||
}
|
||||
|
||||
public async getAccountFeaturedTags(id: string): Promise<Response<Array<Entity.FeaturedTag>>> {
|
||||
return this.client.get<Array<PleromaAPI.Entity.FeaturedTag>>(`/api/v1/accounts/${id}/featured_tags`).then(res => {
|
||||
return Object.assign(res, {
|
||||
data: res.data.map(f => PleromaAPI.Converter.featured_tag(f))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
public async createFeaturedTag(name: string): Promise<Response<Entity.FeaturedTag>> {
|
||||
return this.client
|
||||
.post<PleromaAPI.Entity.FeaturedTag>('/api/v1/featured_tags', {
|
||||
|
|
Loading…
Reference in a new issue