Support for Flickr album and group pool embeds (#3936)
* Support for Flickr album and group pool embeds * Oops, forgot to add flickr to the persisted externalEmbeds schema * Need a bigint since our id can have more than 52 bits... * Remove unexpected trailing / from test data to match the expected behavior * nits --------- Co-authored-by: Hailey <me@haileyok.com>zio/stable
parent
891b432ead
commit
bd4703ca1e
|
@ -480,6 +480,26 @@ describe('parseEmbedPlayerFromUrl', () => {
|
||||||
'https://media.tenor.com/someID/someName.gif',
|
'https://media.tenor.com/someID/someName.gif',
|
||||||
'https://media.tenor.com/someID',
|
'https://media.tenor.com/someID',
|
||||||
'https://media.tenor.com',
|
'https://media.tenor.com',
|
||||||
|
|
||||||
|
'https://www.flickr.com/photos/username/albums/72177720308493661',
|
||||||
|
'https://flickr.com/photos/username/albums/72177720308493661',
|
||||||
|
'https://flickr.com/photos/username/albums/72177720308493661/',
|
||||||
|
'https://flickr.com/photos/username/albums/72177720308493661//',
|
||||||
|
'https://flic.kr/s/aHBqjAES3i',
|
||||||
|
|
||||||
|
'https://flickr.com/foetoes/username/albums/3903',
|
||||||
|
'https://flickr.com/albums/3903',
|
||||||
|
'https://flic.kr/s/OolI',
|
||||||
|
'https://flic.kr/t/aHBqjAES3i',
|
||||||
|
|
||||||
|
'https://www.flickr.com/groups/898944@N23/pool',
|
||||||
|
'https://flickr.com/groups/898944@N23/pool',
|
||||||
|
'https://flickr.com/groups/898944@N23/pool/',
|
||||||
|
'https://flickr.com/groups/898944@N23/pool//',
|
||||||
|
'https://flic.kr/go/8WJtR',
|
||||||
|
|
||||||
|
'https://www.flickr.com/groups/898944@N23/',
|
||||||
|
'https://www.flickr.com/groups',
|
||||||
]
|
]
|
||||||
|
|
||||||
const outputs = [
|
const outputs = [
|
||||||
|
@ -777,6 +797,66 @@ describe('parseEmbedPlayerFromUrl', () => {
|
||||||
undefined,
|
undefined,
|
||||||
undefined,
|
undefined,
|
||||||
undefined,
|
undefined,
|
||||||
|
|
||||||
|
{
|
||||||
|
type: 'flickr_album',
|
||||||
|
source: 'flickr',
|
||||||
|
playerUri: 'https://embedr.flickr.com/photosets/72177720308493661',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'flickr_album',
|
||||||
|
source: 'flickr',
|
||||||
|
playerUri: 'https://embedr.flickr.com/photosets/72177720308493661',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'flickr_album',
|
||||||
|
source: 'flickr',
|
||||||
|
playerUri: 'https://embedr.flickr.com/photosets/72177720308493661',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'flickr_album',
|
||||||
|
source: 'flickr',
|
||||||
|
playerUri: 'https://embedr.flickr.com/photosets/72177720308493661',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'flickr_album',
|
||||||
|
source: 'flickr',
|
||||||
|
playerUri: 'https://embedr.flickr.com/photosets/72177720308493661',
|
||||||
|
},
|
||||||
|
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
|
||||||
|
{
|
||||||
|
type: 'flickr_album',
|
||||||
|
source: 'flickr',
|
||||||
|
playerUri: 'https://embedr.flickr.com/groups/898944@N23',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'flickr_album',
|
||||||
|
source: 'flickr',
|
||||||
|
playerUri: 'https://embedr.flickr.com/groups/898944@N23',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'flickr_album',
|
||||||
|
source: 'flickr',
|
||||||
|
playerUri: 'https://embedr.flickr.com/groups/898944@N23',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'flickr_album',
|
||||||
|
source: 'flickr',
|
||||||
|
playerUri: 'https://embedr.flickr.com/groups/898944@N23',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'flickr_album',
|
||||||
|
source: 'flickr',
|
||||||
|
playerUri: 'https://embedr.flickr.com/groups/898944@N23',
|
||||||
|
},
|
||||||
|
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
]
|
]
|
||||||
|
|
||||||
it('correctly grabs the correct id from uri', () => {
|
it('correctly grabs the correct id from uri', () => {
|
||||||
|
|
|
@ -23,6 +23,7 @@ export const embedPlayerSources = [
|
||||||
'vimeo',
|
'vimeo',
|
||||||
'giphy',
|
'giphy',
|
||||||
'tenor',
|
'tenor',
|
||||||
|
'flickr',
|
||||||
] as const
|
] as const
|
||||||
|
|
||||||
export type EmbedPlayerSource = (typeof embedPlayerSources)[number]
|
export type EmbedPlayerSource = (typeof embedPlayerSources)[number]
|
||||||
|
@ -42,6 +43,7 @@ export type EmbedPlayerType =
|
||||||
| 'vimeo_video'
|
| 'vimeo_video'
|
||||||
| 'giphy_gif'
|
| 'giphy_gif'
|
||||||
| 'tenor_gif'
|
| 'tenor_gif'
|
||||||
|
| 'flickr_album'
|
||||||
|
|
||||||
export const externalEmbedLabels: Record<EmbedPlayerSource, string> = {
|
export const externalEmbedLabels: Record<EmbedPlayerSource, string> = {
|
||||||
youtube: 'YouTube',
|
youtube: 'YouTube',
|
||||||
|
@ -53,6 +55,7 @@ export const externalEmbedLabels: Record<EmbedPlayerSource, string> = {
|
||||||
spotify: 'Spotify',
|
spotify: 'Spotify',
|
||||||
appleMusic: 'Apple Music',
|
appleMusic: 'Apple Music',
|
||||||
soundcloud: 'SoundCloud',
|
soundcloud: 'SoundCloud',
|
||||||
|
flickr: 'Flickr',
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EmbedPlayerParams {
|
export interface EmbedPlayerParams {
|
||||||
|
@ -375,6 +378,79 @@ export function parseEmbedPlayerFromUrl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this is a standard flickr path! we can use the embedder for albums and groups, so validate the path
|
||||||
|
if (urlp.hostname === 'www.flickr.com' || urlp.hostname === 'flickr.com') {
|
||||||
|
let i = urlp.pathname.length - 1
|
||||||
|
while (i > 0 && urlp.pathname.charAt(i) === '/') {
|
||||||
|
--i
|
||||||
|
}
|
||||||
|
|
||||||
|
const path_components = urlp.pathname.slice(1, i + 1).split('/')
|
||||||
|
if (path_components.length === 4) {
|
||||||
|
// discard username - it's not relevant
|
||||||
|
const [photos, _, albums, id] = path_components
|
||||||
|
if (photos === 'photos' && albums === 'albums') {
|
||||||
|
// this at least has the shape of a valid photo-album URL!
|
||||||
|
return {
|
||||||
|
type: 'flickr_album',
|
||||||
|
source: 'flickr',
|
||||||
|
playerUri: `https://embedr.flickr.com/photosets/${id}`,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path_components.length === 3) {
|
||||||
|
const [groups, id, pool] = path_components
|
||||||
|
if (groups === 'groups' && pool === 'pool') {
|
||||||
|
return {
|
||||||
|
type: 'flickr_album',
|
||||||
|
source: 'flickr',
|
||||||
|
playerUri: `https://embedr.flickr.com/groups/${id}`,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// not an album or a group pool, don't know what to do with this!
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
// link shortened flickr path
|
||||||
|
if (urlp.hostname === 'flic.kr') {
|
||||||
|
const b58alph = '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'
|
||||||
|
let [_, type, idBase58Enc] = urlp.pathname.split('/')
|
||||||
|
let id = 0n
|
||||||
|
for (const char of idBase58Enc) {
|
||||||
|
const nextIdx = b58alph.indexOf(char)
|
||||||
|
if (nextIdx >= 0) {
|
||||||
|
id = id * 58n + BigInt(nextIdx)
|
||||||
|
} else {
|
||||||
|
// not b58 encoded, ergo not a valid link to embed
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'go':
|
||||||
|
const formattedGroupId = `${id}`
|
||||||
|
return {
|
||||||
|
type: 'flickr_album',
|
||||||
|
source: 'flickr',
|
||||||
|
playerUri: `https://embedr.flickr.com/groups/${formattedGroupId.slice(
|
||||||
|
0,
|
||||||
|
-2,
|
||||||
|
)}@N${formattedGroupId.slice(-2)}`,
|
||||||
|
}
|
||||||
|
case 's':
|
||||||
|
return {
|
||||||
|
type: 'flickr_album',
|
||||||
|
source: 'flickr',
|
||||||
|
playerUri: `https://embedr.flickr.com/photosets/${id}`,
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// we don't know what this is so we can't embed it
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getPlayerAspect({
|
export function getPlayerAspect({
|
||||||
|
|
|
@ -65,6 +65,7 @@ export const schema = z.object({
|
||||||
spotify: z.enum(externalEmbedOptions).optional(),
|
spotify: z.enum(externalEmbedOptions).optional(),
|
||||||
appleMusic: z.enum(externalEmbedOptions).optional(),
|
appleMusic: z.enum(externalEmbedOptions).optional(),
|
||||||
soundcloud: z.enum(externalEmbedOptions).optional(),
|
soundcloud: z.enum(externalEmbedOptions).optional(),
|
||||||
|
flickr: z.enum(externalEmbedOptions).optional(),
|
||||||
})
|
})
|
||||||
.optional(),
|
.optional(),
|
||||||
mutedThreads: z.array(z.string()), // should move to server
|
mutedThreads: z.array(z.string()), // should move to server
|
||||||
|
|
Loading…
Reference in New Issue