about summary refs log tree commit diff
path: root/src/lib/link-meta/bsky.ts
blob: fba41260de818bf8de2ebfe98b9e087882981204 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import {LikelyType, LinkMeta} from './link-meta'
import {match as matchRoute} from 'view/routes'
import {convertBskyAppUrlIfNeeded, makeRecordUri} from '../strings/url-helpers'
import {RootStoreModel} from 'state/index'
import {PostThreadViewModel} from 'state/models/post-thread-view'

import {Home} from 'view/screens/Home'
import {Search} from 'view/screens/Search'
import {Notifications} from 'view/screens/Notifications'
import {PostThread} from 'view/screens/PostThread'
import {PostUpvotedBy} from 'view/screens/PostUpvotedBy'
import {PostRepostedBy} from 'view/screens/PostRepostedBy'
import {Profile} from 'view/screens/Profile'
import {ProfileFollowers} from 'view/screens/ProfileFollowers'
import {ProfileFollows} from 'view/screens/ProfileFollows'

// NOTE
// this is a hack around the lack of hosted social metadata
// remove once that's implemented
// -prf
export async function extractBskyMeta(
  store: RootStoreModel,
  url: string,
): Promise<LinkMeta> {
  url = convertBskyAppUrlIfNeeded(url)
  const route = matchRoute(url)
  let meta: LinkMeta = {
    likelyType: LikelyType.AtpData,
    url,
    title: route.defaultTitle,
  }

  if (route.Com === Home) {
    meta = {
      ...meta,
      title: 'Bluesky',
      description: 'A new kind of social network',
    }
  } else if (route.Com === Search) {
    meta = {
      ...meta,
      title: 'Search - Bluesky',
      description: 'A new kind of social network',
    }
  } else if (route.Com === Notifications) {
    meta = {
      ...meta,
      title: 'Notifications - Bluesky',
      description: 'A new kind of social network',
    }
  } else if (
    route.Com === PostThread ||
    route.Com === PostUpvotedBy ||
    route.Com === PostRepostedBy
  ) {
    // post and post-related screens
    const threadUri = makeRecordUri(
      route.params.name,
      'app.bsky.feed.post',
      route.params.rkey,
    )
    const threadView = new PostThreadViewModel(store, {
      uri: threadUri,
      depth: 0,
    })
    await threadView.setup().catch(_err => undefined)
    const title = [
      route.Com === PostUpvotedBy
        ? 'Likes on a post by'
        : route.Com === PostRepostedBy
        ? 'Reposts of a post by'
        : 'Post by',
      threadView.thread?.post.author.displayName ||
        threadView.thread?.post.author.handle ||
        'a bluesky user',
    ].join(' ')
    meta = {
      ...meta,
      title,
      description: threadView.thread?.postRecord?.text,
    }
  } else if (
    route.Com === Profile ||
    route.Com === ProfileFollowers ||
    route.Com === ProfileFollows
  ) {
    // profile and profile-related screens
    const profile = await store.profiles.getProfile(route.params.name)
    if (profile?.data) {
      meta = {
        ...meta,
        title: profile.data.displayName || profile.data.handle,
        description: profile.data.description,
      }
    }
  }

  return meta
}