Skip to content

Commit

Permalink
Merge pull request #1932 from h3poteto/fix/unwrap
Browse files Browse the repository at this point in the history
Stop using force unwrap for mapReactions
  • Loading branch information
h3poteto authored Sep 24, 2023
2 parents 90461fa + 34bf6b9 commit 559e125
Show file tree
Hide file tree
Showing 2 changed files with 164 additions and 42 deletions.
86 changes: 44 additions & 42 deletions megalodon/src/firefish/api_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,7 @@ namespace FirefishAPI {
plain_content: n.text ? n.text : null,
created_at: n.createdAt,
// Remove reaction emojis with names containing @ from the emojis list.
emojis: Array.isArray(n.emojis) ? n.emojis
.filter((e) => e.name.indexOf("@") === -1)
.map((e) => emoji(e)) : [],
emojis: Array.isArray(n.emojis) ? n.emojis.filter(e => !e.name.includes('@')).map(e => emoji(e)) : [],
replies_count: n.repliesCount,
reblogs_count: n.renoteCount,
favourites_count: 0,
Expand All @@ -288,33 +286,34 @@ namespace FirefishAPI {
language: null,
pinned: null,
// Use emojis list to provide URLs for emoji reactions.
emoji_reactions: mapReactions(n.emojis!, n.reactions, n.myReaction),
emoji_reactions: mapReactions(n.emojis ? n.emojis : [], n.reactions, n.myReaction),
bookmarked: false,
quote: n.renote !== undefined && n.text !== null
}
}

export const mapReactions = (emojis: Array<FirefishEntity.Emoji>, r: { [key: string]: number }, myReaction?: string | null): Array<MegalodonEntity.Reaction> => {
export const mapReactions = (
emojis: Array<FirefishEntity.Emoji>,
r: { [key: string]: number },
myReaction?: string | null
): Array<MegalodonEntity.Reaction> => {
// Map of emoji shortcodes to image URLs.
const emojiUrls = new Map<string, string>(
emojis.map((e) => [e.name, e.url]),
);
const emojiUrls = new Map<string, string>(emojis.map(e => [e.name, e.url]))
return Object.keys(r).map(key => {
// Strip colons from custom emoji reaction names to match emoji shortcodes.
const shortcode = key.replace(/:/g, "");
const shortcode = key.replace(/:/g, '')
// If this is a custom emoji (vs. a Unicode emoji), find its image URL.
const url = emojiUrls.get(shortcode);
const url = emojiUrls.get(shortcode)
// Finally, remove trailing @. from local custom emoji reaction names.
const name = shortcode.replace("@.", "");
const name = shortcode.replace('@.', '')

return {
count: r[key],
me: key === myReaction,
name,
url,
// We don't actually have a static version of the asset, but clients expect one anyway.
static_url: url,

static_url: url
}
})
}
Expand Down Expand Up @@ -419,9 +418,12 @@ namespace FirefishAPI {
})
}
if (n.reaction) {
notification = Object.assign(notification, {
reaction: mapReactions(n.note!.emojis!, { [n.reaction]: 1 })[0],
});
const reactions = mapReactions(n.note?.emojis ?? [], { [n.reaction]: 1 })
if (reactions.length > 0) {
notification = Object.assign(notification, {
reaction: reactions[0]
})
}
}
return notification
}
Expand Down Expand Up @@ -567,8 +569,8 @@ namespace FirefishAPI {
]

/**
* Interface
*/
* Interface
*/
export interface Interface {
get<T = any>(path: string, params?: any, headers?: { [key: string]: string }): Promise<Response<T>>
post<T = any>(path: string, params?: any, headers?: { [key: string]: string }): Promise<Response<T>>
Expand All @@ -577,10 +579,10 @@ namespace FirefishAPI {
}

/**
* Firefish API client.
*
* Usign axios for request, you will handle promises.
*/
* Firefish API client.
*
* Usign axios for request, you will handle promises.
*/
export class Client implements Interface {
private accessToken: string | null
private baseUrl: string
Expand All @@ -589,11 +591,11 @@ namespace FirefishAPI {
private proxyConfig: ProxyConfig | false = false

/**
* @param baseUrl hostname or base URL
* @param accessToken access token from OAuth2 authorization
* @param userAgent UserAgent is specified in header on request.
* @param proxyConfig Proxy setting, or set false if don't use proxy.
*/
* @param baseUrl hostname or base URL
* @param accessToken access token from OAuth2 authorization
* @param userAgent UserAgent is specified in header on request.
* @param proxyConfig Proxy setting, or set false if don't use proxy.
*/
constructor(baseUrl: string, accessToken: string | null, userAgent: string = DEFAULT_UA, proxyConfig: ProxyConfig | false = false) {
this.accessToken = accessToken
this.baseUrl = baseUrl
Expand All @@ -604,8 +606,8 @@ namespace FirefishAPI {
}

/**
* GET request to firefish API.
**/
* GET request to firefish API.
**/
public async get<T>(path: string, params: any = {}, headers: { [key: string]: string } = {}): Promise<Response<T>> {
let options: AxiosRequestConfig = {
params: params,
Expand All @@ -631,11 +633,11 @@ namespace FirefishAPI {
}

/**
* POST request to firefish REST API.
* @param path relative path from baseUrl
* @param params Form data
* @param headers Request header object
*/
* POST request to firefish REST API.
* @param path relative path from baseUrl
* @param params Form data
* @param headers Request header object
*/
public async post<T>(path: string, params: any = {}, headers: { [key: string]: string } = {}): Promise<Response<T>> {
let options: AxiosRequestConfig = {
headers: headers,
Expand Down Expand Up @@ -670,19 +672,19 @@ namespace FirefishAPI {
}

/**
* Cancel all requests in this instance.
* @returns void
*/
* Cancel all requests in this instance.
* @returns void
*/
public cancel(): void {
return this.abortController.abort()
}

/**
* Get connection and receive websocket connection for Firefish API.
*
* @param channel Channel name is user, localTimeline, hybridTimeline, globalTimeline, conversation or list.
* @param listId This parameter is required only list channel.
*/
* Get connection and receive websocket connection for Firefish API.
*
* @param channel Channel name is user, localTimeline, hybridTimeline, globalTimeline, conversation or list.
* @param listId This parameter is required only list channel.
*/
public socket(
channel: 'user' | 'localTimeline' | 'hybridTimeline' | 'globalTimeline' | 'conversation' | 'list',
listId?: string
Expand Down
120 changes: 120 additions & 0 deletions megalodon/test/unit/firefish/api_client.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import FirefishAPI from '@/firefish/api_client'
import MegalodonEntity from '@/entity'

describe('api_client', () => {
describe('mapReactions', () => {
it('should work', () => {
const emojis: Array<FirefishAPI.Entity.Emoji> = [
{
name: 'foxverified',
url: 'https://example.com/files/foxverified',
category: null
},
{
name: 'verificado',
url: 'https://example.com/files/verificado',
category: null
},
{
name: '[email protected]',
url: 'https://example.com/proxy/firefishexample/kawaii',
category: null
},
{
name: 'ablobcatnodfast@.',
url: 'https://example.com/files/ablobcatnodfast',
category: null
}
]
const reactions: { [key: string]: number } = {
':ablobcatnodfast@.:': 2,
':[email protected]:': 1
}

const res = FirefishAPI.Converter.mapReactions(emojis, reactions)
expect(res).toHaveLength(2)
expect(res).toContainEqual({
count: 2,
me: false,
name: 'ablobcatnodfast',
url: 'https://example.com/files/ablobcatnodfast',
static_url: 'https://example.com/files/ablobcatnodfast'
} as MegalodonEntity.Reaction)

expect(res).toContainEqual({
count: 1,
me: false,
name: '[email protected]',
url: 'https://example.com/proxy/firefishexample/kawaii',
static_url: 'https://example.com/proxy/firefishexample/kawaii'
} as MegalodonEntity.Reaction)
})
it('does not have emojis', () => {
const emojis: Array<FirefishAPI.Entity.Emoji> = []
const reactions: { [key: string]: number } = {
':ablobcatnodfast@.:': 2,
':[email protected]:': 1
}

const res = FirefishAPI.Converter.mapReactions(emojis, reactions)
expect(res).toHaveLength(2)
expect(res).toContainEqual({
count: 2,
me: false,
name: 'ablobcatnodfast'
} as MegalodonEntity.Reaction)

expect(res).toContainEqual({
count: 1,
me: false,
name: '[email protected]'
} as MegalodonEntity.Reaction)
})
it('reactions with me', () => {
const emojis: Array<FirefishAPI.Entity.Emoji> = [
{
name: 'foxverified',
url: 'https://example.com/files/foxverified',
category: null
},
{
name: 'verificado',
url: 'https://example.com/files/verificado',
category: null
},
{
name: '[email protected]',
url: 'https://example.com/proxy/firefishexample/kawaii',
category: null
},
{
name: 'ablobcatnodfast@.',
url: 'https://example.com/files/ablobcatnodfast',
category: null
}
]
const reactions: { [key: string]: number } = {
':ablobcatnodfast@.:': 2,
':[email protected]:': 1
}

const res = FirefishAPI.Converter.mapReactions(emojis, reactions, ':ablobcatnodfast@.:')
expect(res).toHaveLength(2)
expect(res).toContainEqual({
count: 2,
me: true,
name: 'ablobcatnodfast',
url: 'https://example.com/files/ablobcatnodfast',
static_url: 'https://example.com/files/ablobcatnodfast'
} as MegalodonEntity.Reaction)

expect(res).toContainEqual({
count: 1,
me: false,
name: '[email protected]',
url: 'https://example.com/proxy/firefishexample/kawaii',
static_url: 'https://example.com/proxy/firefishexample/kawaii'
} as MegalodonEntity.Reaction)
})
})
})

0 comments on commit 559e125

Please sign in to comment.