Implement getting and dismissing server announcements (#4)
to be fair, I didn't test it on a real mastodon server. I just hope it works. I also don't think it matters much anyway as this is a fork for calckey? idk please let me know if I need to test it on mastodon too. It's a bit silly implementation as mfm is just escaped to plaintext and the announcement title is glued to `content`, but overall I think it works fine :) Reviewed-on: https://codeberg.org/calckey/megalodon/pulls/4 Co-authored-by: fruye <fruye@unix.dog> Co-committed-by: fruye <fruye@unix.dog>
This commit is contained in:
parent
ee8d042bb8
commit
3e9e1635e2
34
megalodon/src/entities/announcement.ts
Normal file
34
megalodon/src/entities/announcement.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
/// <reference path="tag.ts" />
|
||||
/// <reference path="emoji.ts" />
|
||||
/// <reference path="reaction.ts" />
|
||||
|
||||
namespace Entity {
|
||||
export type Announcement = {
|
||||
id: string
|
||||
content: string
|
||||
starts_at: string | null
|
||||
ends_at: string | null
|
||||
published: boolean
|
||||
all_day: boolean
|
||||
published_at: string
|
||||
updated_at: string
|
||||
read?: boolean
|
||||
mentions: Array<AnnouncementAccount>
|
||||
statuses: Array<AnnouncementStatus>
|
||||
tags: Array<Tag>
|
||||
emojis: Array<Emoji>
|
||||
reactions: Array<Reaction>
|
||||
}
|
||||
|
||||
export type AnnouncementAccount = {
|
||||
id: string
|
||||
username: string
|
||||
url: string
|
||||
acct: string
|
||||
}
|
||||
|
||||
export type AnnouncementStatus = {
|
||||
id: string
|
||||
url: string
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
/// <reference path="./entities/account.ts" />
|
||||
/// <reference path="./entities/activity.ts" />
|
||||
/// <reference path="./entities/announcement.ts" />
|
||||
/// <reference path="./entities/application.ts" />
|
||||
/// <reference path="./entities/async_attachment.ts" />
|
||||
/// <reference path="./entities/attachment.ts" />
|
||||
|
|
|
@ -2221,6 +2221,26 @@ export default class Mastodon implements MegalodonInterface {
|
|||
})
|
||||
}
|
||||
|
||||
// ======================================
|
||||
// instance/announcements
|
||||
// ======================================
|
||||
public async getInstanceAnnouncements(with_dismissed?: boolean | null): Promise<Response<Array<Entity.Announcement>>> {
|
||||
let params = {}
|
||||
if (with_dismissed) {
|
||||
params = Object.assign(params, {
|
||||
with_dismissed
|
||||
})
|
||||
}
|
||||
return this.client.get<Array<MastodonAPI.Entity.Announcement>>('/api/v1/announcements', params).then(res => ({
|
||||
...res,
|
||||
data: res.data.map(t => MastodonAPI.Converter.announcement(t))
|
||||
}))
|
||||
}
|
||||
|
||||
public async dismissInstanceAnnouncement(id: string): Promise<Response<{}>> {
|
||||
return this.client.post<{}>(`/api/v1/announcements/${id}/dismiss`)
|
||||
}
|
||||
|
||||
// ======================================
|
||||
// Emoji reactions
|
||||
// ======================================
|
||||
|
|
|
@ -444,6 +444,7 @@ namespace MastodonAPI {
|
|||
export namespace Entity {
|
||||
export type Account = MastodonEntity.Account
|
||||
export type Activity = MastodonEntity.Activity
|
||||
export type Announcement = MastodonEntity.Announcement
|
||||
export type Application = MastodonEntity.Application
|
||||
export type AsyncAttachment = MegalodonEntity.AsyncAttachment
|
||||
export type Attachment = MastodonEntity.Attachment
|
||||
|
@ -466,6 +467,7 @@ namespace MastodonAPI {
|
|||
export type Preferences = MastodonEntity.Preferences
|
||||
export type PushSubscription = MastodonEntity.PushSubscription
|
||||
export type Relationship = MastodonEntity.Relationship
|
||||
export type Reaction = MastodonEntity.Reaction
|
||||
export type Report = MastodonEntity.Report
|
||||
export type Results = MastodonEntity.Results
|
||||
export type ScheduledStatus = MastodonEntity.ScheduledStatus
|
||||
|
@ -523,6 +525,10 @@ namespace MastodonAPI {
|
|||
|
||||
export const account = (a: Entity.Account): MegalodonEntity.Account => a
|
||||
export const activity = (a: Entity.Activity): MegalodonEntity.Activity => a
|
||||
export const announcement = (a: Entity.Announcement): MegalodonEntity.Announcement => ({
|
||||
...a,
|
||||
reactions: a.reactions.map(r => reaction(r))
|
||||
})
|
||||
export const application = (a: Entity.Application): MegalodonEntity.Application => a
|
||||
export const attachment = (a: Entity.Attachment): MegalodonEntity.Attachment => a
|
||||
export const async_attachment = (a: Entity.AsyncAttachment) => {
|
||||
|
@ -586,6 +592,12 @@ namespace MastodonAPI {
|
|||
export const preferences = (p: Entity.Preferences): MegalodonEntity.Preferences => p
|
||||
export const push_subscription = (p: Entity.PushSubscription): MegalodonEntity.PushSubscription => p
|
||||
export const relationship = (r: Entity.Relationship): MegalodonEntity.Relationship => r
|
||||
export const reaction = (r: Entity.Reaction): MegalodonEntity.Reaction => ({
|
||||
count: r.count,
|
||||
me: r.me ?? false,
|
||||
name: r.name,
|
||||
url: r.url,
|
||||
})
|
||||
export const report = (r: Entity.Report): MegalodonEntity.Report => r
|
||||
export const results = (r: Entity.Results): MegalodonEntity.Results => ({
|
||||
accounts: r.accounts.map(a => account(a)),
|
||||
|
|
41
megalodon/src/mastodon/entities/announcement.ts
Normal file
41
megalodon/src/mastodon/entities/announcement.ts
Normal file
|
@ -0,0 +1,41 @@
|
|||
/// <reference path="tag.ts" />
|
||||
/// <reference path="emoji.ts" />
|
||||
|
||||
namespace MastodonEntity {
|
||||
export type Announcement = {
|
||||
id: string
|
||||
content: string
|
||||
starts_at: string | null
|
||||
ends_at: string | null
|
||||
published: boolean
|
||||
all_day: boolean
|
||||
published_at: string
|
||||
updated_at: string
|
||||
read?: boolean
|
||||
mentions: Array<AnnouncementAccount>
|
||||
statuses: Array<AnnouncementStatus>
|
||||
tags: Array<Tag>
|
||||
emojis: Array<Emoji>
|
||||
reactions: Array<Reaction>
|
||||
}
|
||||
|
||||
export type AnnouncementAccount = {
|
||||
id: string
|
||||
username: string
|
||||
url: string
|
||||
acct: string
|
||||
}
|
||||
|
||||
export type AnnouncementStatus = {
|
||||
id: string
|
||||
url: string
|
||||
}
|
||||
|
||||
export type Reaction = {
|
||||
name: string
|
||||
count: number
|
||||
me?: boolean
|
||||
url?: string
|
||||
static_url?: string
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
/// <reference path="./entities/account.ts" />
|
||||
/// <reference path="./entities/activity.ts" />
|
||||
/// <reference path="./entities/announcement.ts" />
|
||||
/// <reference path="./entities/application.ts" />
|
||||
/// <reference path="./entities/async_attachment.ts" />
|
||||
/// <reference path="./entities/attachment.ts" />
|
||||
|
|
|
@ -1256,6 +1256,22 @@ export interface MegalodonInterface {
|
|||
*/
|
||||
getInstanceCustomEmojis(): Promise<Response<Array<Entity.Emoji>>>
|
||||
|
||||
// ======================================
|
||||
// instance/announcements
|
||||
// ======================================
|
||||
/**
|
||||
* GET /api/v1/announcements
|
||||
*
|
||||
* @param with_dismissed Include announcements dismissed by the user. Defaults to false.
|
||||
* @return Array of announcements.
|
||||
*/
|
||||
getInstanceAnnouncements(with_dismissed?: boolean | null): Promise<Response<Array<Entity.Announcement>>>
|
||||
|
||||
/**
|
||||
* POST /api/v1/announcements/:id/dismiss
|
||||
*/
|
||||
dismissInstanceAnnouncement(id: string): Promise<Response<{}>>
|
||||
|
||||
// ======================================
|
||||
// Emoji reactions
|
||||
// ======================================
|
||||
|
|
|
@ -2107,6 +2107,26 @@ export default class Misskey implements MegalodonInterface {
|
|||
.then(res => ({ ...res, data: res.data.emojis.map(e => MisskeyAPI.Converter.emoji(e)) }))
|
||||
}
|
||||
|
||||
// ======================================
|
||||
// instance/announcements
|
||||
// ======================================
|
||||
public async getInstanceAnnouncements(with_dismissed?: boolean | null): Promise<Response<Array<Entity.Announcement>>> {
|
||||
let params = {}
|
||||
if (with_dismissed) {
|
||||
params = Object.assign(params, {
|
||||
withUnreads: with_dismissed
|
||||
})
|
||||
}
|
||||
return this.client.post<Array<MisskeyAPI.Entity.Announcement>>('/api/announcements', params).then(res => ({
|
||||
...res,
|
||||
data: res.data.map(t => MisskeyAPI.Converter.announcement(t))
|
||||
}))
|
||||
}
|
||||
|
||||
public async dismissInstanceAnnouncement(id: string): Promise<Response<{}>> {
|
||||
return this.client.post<{}>('/api/i/read-announcement', { announcementId: id })
|
||||
}
|
||||
|
||||
// ======================================
|
||||
// Emoji reactions
|
||||
// ======================================
|
||||
|
|
|
@ -14,6 +14,7 @@ import NotificationType from '../notification'
|
|||
namespace MisskeyAPI {
|
||||
export namespace Entity {
|
||||
export type App = MisskeyEntity.App
|
||||
export type Announcement = MisskeyEntity.Announcement
|
||||
export type Blocking = MisskeyEntity.Blocking
|
||||
export type Choice = MisskeyEntity.Choice
|
||||
export type CreatedNote = MisskeyEntity.CreatedNote
|
||||
|
@ -384,6 +385,34 @@ namespace MisskeyAPI {
|
|||
moved: null
|
||||
}
|
||||
|
||||
export const announcement = (a: Entity.Announcement): MegalodonEntity.Announcement => {
|
||||
// Reused from Note converter.
|
||||
const escapeHTML = (text: string) => text
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''')
|
||||
.replace(/`/g, '`')
|
||||
.replace(/\r?\n/g, '<br>');
|
||||
return {
|
||||
id: a.id,
|
||||
content: `<h1>${escapeHTML(a.title)}</h1>${escapeHTML(a.text)}`,
|
||||
starts_at: null,
|
||||
ends_at: null,
|
||||
published: true,
|
||||
all_day: false,
|
||||
published_at: a.createdAt,
|
||||
updated_at: a.updatedAt,
|
||||
read: a.isRead,
|
||||
mentions: [],
|
||||
statuses: [],
|
||||
tags: [],
|
||||
emojis: [],
|
||||
reactions: [],
|
||||
};
|
||||
}
|
||||
|
||||
export const notification = (n: Entity.Notification, host: string): MegalodonEntity.Notification => {
|
||||
let notification = {
|
||||
id: n.id,
|
||||
|
|
10
megalodon/src/misskey/entities/announcement.ts
Normal file
10
megalodon/src/misskey/entities/announcement.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace MisskeyEntity {
|
||||
export type Announcement = {
|
||||
id: string
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
text: string
|
||||
title: string
|
||||
isRead?: boolean
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
/// <reference path="entities/app.ts" />
|
||||
/// <reference path="entities/announcement.ts" />
|
||||
/// <reference path="entities/blocking.ts" />
|
||||
/// <reference path="entities/createdNote.ts" />
|
||||
/// <reference path="entities/emoji.ts" />
|
||||
|
|
|
@ -2229,6 +2229,26 @@ export default class Pleroma implements MegalodonInterface {
|
|||
})
|
||||
}
|
||||
|
||||
// ======================================
|
||||
// instance/announcements
|
||||
// ======================================
|
||||
public async getInstanceAnnouncements(with_dismissed?: boolean | null): Promise<Response<Array<Entity.Announcement>>> {
|
||||
let params = {}
|
||||
if (with_dismissed) {
|
||||
params = Object.assign(params, {
|
||||
with_dismissed
|
||||
})
|
||||
}
|
||||
return this.client.get<Array<PleromaAPI.Entity.Announcement>>('/api/v1/announcements', params).then(res => ({
|
||||
...res,
|
||||
data: res.data.map(t => PleromaAPI.Converter.announcement(t))
|
||||
}))
|
||||
}
|
||||
|
||||
public async dismissInstanceAnnouncement(id: string): Promise<Response<{}>> {
|
||||
return this.client.post<{}>(`/api/v1/announcements/${id}/dismiss`)
|
||||
}
|
||||
|
||||
// ======================================
|
||||
// Emoji reactions
|
||||
// ======================================
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace PleromaAPI {
|
|||
export namespace Entity {
|
||||
export type Account = PleromaEntity.Account
|
||||
export type Activity = PleromaEntity.Activity
|
||||
export type Announcement = PleromaEntity.Announcement
|
||||
export type Application = PleromaEntity.Application
|
||||
export type AsyncAttachment = PleromaEntity.AsyncAttachment
|
||||
export type Attachment = PleromaEntity.Attachment
|
||||
|
@ -94,6 +95,7 @@ namespace PleromaAPI {
|
|||
|
||||
export const account = (a: Entity.Account): MegalodonEntity.Account => a
|
||||
export const activity = (a: Entity.Activity): MegalodonEntity.Activity => a
|
||||
export const announcement = (a: Entity.Announcement): MegalodonEntity.Announcement => a
|
||||
export const application = (a: Entity.Application): MegalodonEntity.Application => a
|
||||
export const attachment = (a: Entity.Attachment): MegalodonEntity.Attachment => a
|
||||
export const async_attachment = (a: Entity.AsyncAttachment) => {
|
||||
|
|
34
megalodon/src/pleroma/entities/announcement.ts
Normal file
34
megalodon/src/pleroma/entities/announcement.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
/// <reference path="tag.ts" />
|
||||
/// <reference path="emoji.ts" />
|
||||
/// <reference path="reaction.ts" />
|
||||
|
||||
namespace PleromaEntity {
|
||||
export type Announcement = {
|
||||
id: string
|
||||
content: string
|
||||
starts_at: string | null
|
||||
ends_at: string | null
|
||||
published: boolean
|
||||
all_day: boolean
|
||||
published_at: string
|
||||
updated_at: string
|
||||
read?: boolean
|
||||
mentions: Array<AnnouncementAccount>
|
||||
statuses: Array<AnnouncementStatus>
|
||||
tags: Array<Tag>
|
||||
emojis: Array<Emoji>
|
||||
reactions: Array<Reaction>
|
||||
}
|
||||
|
||||
export type AnnouncementAccount = {
|
||||
id: string
|
||||
username: string
|
||||
url: string
|
||||
acct: string
|
||||
}
|
||||
|
||||
export type AnnouncementStatus = {
|
||||
id: string
|
||||
url: string
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
/// <reference path="./entities/account.ts" />
|
||||
/// <reference path="./entities/activity.ts" />
|
||||
/// <reference path="./entities/announcement.ts" />
|
||||
/// <reference path="./entities/application.ts" />
|
||||
/// <reference path="./entities/async_attachment.ts" />
|
||||
/// <reference path="./entities/attachment.ts" />
|
||||
|
|
Loading…
Reference in a new issue