PageSourceSearch

https://impro.social/js/navigation.943b37659b.js

js impro.social collected 2026-09-25 22:27:42 UTC 4,168 bytes, 138 lines download raw bytes

1import { getRKey, parseUri, hasValidHandle } from "/js/dataHelpers.js";
2import { isNil } from "/js/utils.js";
3
4function encodePathSegment(segment) {
5  return encodeURIComponent(segment).replace(/%3A/g, ":").replace(/%40/g, "@");
6}
7
8function profileIdentifier(profile) {
9  return hasValidHandle(profile) ? profile.handle : profile.did;
10}
11
12export function linkToHashtag(hashtag) {
13  return `/hashtag/${encodePathSegment(hashtag)}`;
14}
15
16export function linkToProfile(profile) {
17  return `/profile/${encodePathSegment(profileIdentifier(profile))}`;
18}
19
20export function linkToProfileByDid(did) {
21  return `/profile/${encodePathSegment(did)}`;
22}
23
24export function linkToLabeler(labeler) {
25  return linkToProfile(labeler.creator);
26}
27
28export function linkToPost(post) {
29  return `/profile/${encodePathSegment(profileIdentifier(post.author))}/post/${encodePathSegment(getRKey(post))}`;
30}
31
32export function linkToPostFromUri(postUri) {
33  const { repo, rkey } = parseUri(postUri);
34  return `/profile/${encodePathSegment(repo)}/post/${encodePathSegment(rkey)}`;
35}
36
37export function linkToPostLikes(post) {
38  return `/profile/${encodePathSegment(profileIdentifier(post.author))}/post/${encodePathSegment(getRKey(post))}/likes`;
39}
40
41export function linkToPostQuotes(post) {
42  return `/profile/${encodePathSegment(profileIdentifier(post.author))}/post/${encodePathSegment(getRKey(post))}/quotes`;
43}
44
45export function linkToPostReposts(post) {
46  return `/profile/${encodePathSegment(profileIdentifier(post.author))}/post/${encodePathSegment(getRKey(post))}/reposts`;
47}
48
49export function linkToProfileFollowers(profile) {
50  return `/profile/${encodePathSegment(profileIdentifier(profile))}/followers`;
51}
52
53export function linkToProfileFollowing(profile) {
54  return `/profile/${encodePathSegment(profileIdentifier(profile))}/following`;
55}
56
57export function linkToProfileKnownFollowers(profile) {
58  return `/profile/${encodePathSegment(profileIdentifier(profile))}/known-followers`;
59}
60
61export function linkToFeed(feedGenerator) {
62  return `/profile/${encodePathSegment(profileIdentifier(feedGenerator.creator))}/feed/${encodePathSegment(
63    getRKey(feedGenerator),
64  )}`;
65}
66
67export function linkToList(list) {
68  return `/profile/${encodePathSegment(profileIdentifier(list.creator))}/lists/${encodePathSegment(
69    getRKey(list),
70  )}`;
71}
72
73export function linkToSearchPostsByProfile(profile) {
74  const searchString = `from:@${profile.handle} `;
75  const query = new URLSearchParams();
76  query.set("q", searchString);
77  query.set("tab", "top");
78  return `/search?${query.toString()}`;
79}
80
81function getPermalinkOrigin() {
82  return "https://bsky.app";
83}
84
85export function getPermalinkForPost(post) {
86  return getPermalinkOrigin() + linkToPost(post);
87}
88
89export function getPermalinkForProfile(profile) {
90  return getPermalinkOrigin() + linkToProfile(profile);
91}
92
93export function getPermalinkForConvo(convoId) {
94  return `${getPermalinkOrigin()}/messages/${encodePathSegment(convoId)}`;
95}
96
97export function linkToGroupChatDetails(convoId) {
98  return `/messages/${encodePathSegment(convoId)}/settings`;
99}
100
101export function linkToPluginSettings(pluginId) {
102  return `/plugin/${encodePathSegment(pluginId)}/settings`;
103}
104
105export function linkToCommunityPlugin(pluginId) {
106  return `/plugins/community/${encodePathSegment(pluginId)}`;
107}
108
109export function getPermalinkForCommunityPlugin(pluginId) {
110  return "https://impro.social" + linkToCommunityPlugin(pluginId);
111}
112
113export function linkToLogin({ query = {} } = {}) {
114  const params = new URLSearchParams();
115  for (const [key, value] of Object.entries(query)) {
116    if (isNil(value)) continue;
117    params.set(key, String(value));
118  }
119  const { pathname, search, hash } = window.location;
120  if (pathname !== "/login" && pathname !== "/") {
121    params.set("returnTo", pathname + search + hash);
122  }
123  const queryString = params.toString();
124  return queryString ? "/login?" + queryString : "/login";
125}
126
127export function validateReturnToParam(raw) {
128  if (typeof raw !== "string" || raw.length === 0) {
129    return null;
130  }
131  if (!raw.startsWith("/")) {
132    return null;
133  }
134  if (raw.startsWith("//") || raw.startsWith("/\\")) {
135    return null;
136  }
137  return raw;
138}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.