personal web client for Bluesky
typescript solidjs bluesky atcute

refactor: upgrade atcute dependencies

mary.my.id feff0b2d 81d920fe

verified
Changed files
+332 -254
src
api
components
lib
atproto
preferences
states
views
+7 -7
package.json
··· 8 8 "fmt": "prettier --cache --write ." 9 9 }, 10 10 "dependencies": { 11 - "@atcute/bluemoji": "^1.0.4", 12 - "@atcute/bluesky": "^1.0.15", 11 + "@atcute/bluemoji": "^2.0.0", 12 + "@atcute/bluesky": "^2.0.0", 13 13 "@atcute/bluesky-richtext-parser": "^1.0.7", 14 - "@atcute/bluesky-richtext-segmenter": "^1.0.5", 14 + "@atcute/bluesky-richtext-segmenter": "^2.0.0", 15 15 "@atcute/bluesky-search-parser": "^0.1.0", 16 - "@atcute/cbor": "^2.2.0", 17 - "@atcute/cid": "^2.2.0", 18 - "@atcute/client": "^2.0.9", 19 - "@atcute/oauth-browser-client": "^1.0.16", 16 + "@atcute/cbor": "^2.2.1", 17 + "@atcute/cid": "^2.2.1", 18 + "@atcute/client": "^3.0.0", 19 + "@atcute/oauth-browser-client": "^1.0.17", 20 20 "@atcute/tid": "^1.0.2", 21 21 "@atlaskit/pragmatic-drag-and-drop": "^1.5.2", 22 22 "@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.0.3",
+53 -53
pnpm-lock.yaml
··· 31 31 .: 32 32 dependencies: 33 33 '@atcute/bluemoji': 34 - specifier: ^1.0.4 35 - version: 1.0.4(@atcute/bluesky@1.0.15(@atcute/client@2.0.9))(@atcute/client@2.0.9) 34 + specifier: ^2.0.0 35 + version: 2.0.0(@atcute/bluesky@2.0.0(@atcute/client@3.0.0))(@atcute/client@3.0.0) 36 36 '@atcute/bluesky': 37 - specifier: ^1.0.15 38 - version: 1.0.15(@atcute/client@2.0.9) 37 + specifier: ^2.0.0 38 + version: 2.0.0(@atcute/client@3.0.0) 39 39 '@atcute/bluesky-richtext-parser': 40 40 specifier: ^1.0.7 41 41 version: 1.0.7 42 42 '@atcute/bluesky-richtext-segmenter': 43 - specifier: ^1.0.5 44 - version: 1.0.5(@atcute/bluesky@1.0.15(@atcute/client@2.0.9))(@atcute/client@2.0.9) 43 + specifier: ^2.0.0 44 + version: 2.0.0(@atcute/bluesky@2.0.0(@atcute/client@3.0.0))(@atcute/client@3.0.0) 45 45 '@atcute/bluesky-search-parser': 46 46 specifier: ^0.1.0 47 47 version: 0.1.0 48 48 '@atcute/cbor': 49 - specifier: ^2.2.0 50 - version: 2.2.0 49 + specifier: ^2.2.1 50 + version: 2.2.1 51 51 '@atcute/cid': 52 - specifier: ^2.2.0 53 - version: 2.2.0 52 + specifier: ^2.2.1 53 + version: 2.2.1 54 54 '@atcute/client': 55 - specifier: ^2.0.9 56 - version: 2.0.9 55 + specifier: ^3.0.0 56 + version: 3.0.0 57 57 '@atcute/oauth-browser-client': 58 - specifier: ^1.0.16 59 - version: 1.0.16 58 + specifier: ^1.0.17 59 + version: 1.0.17 60 60 '@atcute/tid': 61 61 specifier: ^1.0.2 62 62 version: 1.0.2 ··· 174 174 peerDependencies: 175 175 ajv: '>=8' 176 176 177 - '@atcute/bluemoji@1.0.4': 178 - resolution: {integrity: sha512-Rzujybon6EFuycWPID5bzjYIVdPPWWjVfPqELhByJTLe2vq3SlEubUCmz3VfhDu/Bb8wlBP2tIT5w4oq3vJLrg==} 177 + '@atcute/bluemoji@2.0.0': 178 + resolution: {integrity: sha512-tgcsW4H50oWo6uHMkUVU2IgObfX63mYp/qxWfoLkKPFWbwz68SiwedaCY/E+Cw8anWGF0urFjDemmga7B5Z0QA==} 179 179 peerDependencies: 180 - '@atcute/bluesky': ^1.0.0 181 - '@atcute/client': ^1.0.0 || ^2.0.0 180 + '@atcute/bluesky': ^2.0.0 181 + '@atcute/client': ^3.0.0 182 182 183 183 '@atcute/bluesky-richtext-parser@1.0.7': 184 184 resolution: {integrity: sha512-nOvU699OXiGMbyswao7JJnY0C9WkwE7PVC/m5WWt0UN9fsXSOor9IZWw+v9SATp+94BTJoG38XyUomUaJnoQRA==} 185 185 186 - '@atcute/bluesky-richtext-segmenter@1.0.5': 187 - resolution: {integrity: sha512-D0FfmJVwppky9naL1OGKcQjtgO0lDLhkG4iCQHpShuHhEZ9FUdf3eUb/eQpVRNJGaJ4ShjEOHA6FlAizcjMkGQ==} 186 + '@atcute/bluesky-richtext-segmenter@2.0.0': 187 + resolution: {integrity: sha512-BummI6zgdXSx9f5TJg2oR2ervCJhG8zcbAMDLWjccNLt/0P38lIRsXqOBdIIAZoBtk8g5LpgnnICdiMsDM2iDQ==} 188 188 peerDependencies: 189 - '@atcute/bluesky': ^1.0.0 190 - '@atcute/client': ^1.0.0 || ^2.0.0 189 + '@atcute/bluesky': ^2.0.0 190 + '@atcute/client': ^3.0.0 191 191 192 192 '@atcute/bluesky-search-parser@0.1.0': 193 193 resolution: {integrity: sha512-bTClwD9VGwaECOyWe1mf8V6t+7/77e3tiUHTE6CSrHXOJ/yM8N2xbn+dIi2ki2JLHvgvBN9wsWpFLykgfWhBaw==} 194 194 195 - '@atcute/bluesky@1.0.15': 196 - resolution: {integrity: sha512-+EFiybmKQ97aBAgtaD+cKRJER5AMn3cZMkEwEg/pDdWyzxYJ9m1UgemmLdTgI8VrxPufKqdXS2nl7uO7TY6BPA==} 195 + '@atcute/bluesky@2.0.0': 196 + resolution: {integrity: sha512-G54WP8ribfH7dojidp6LJjNISauZr2AN9VxRi3k5XTLnT3S5l59e8l48psxTTv+GzBnY8u2GIHMlehBXt7X69A==} 197 197 peerDependencies: 198 - '@atcute/client': ^1.0.0 || ^2.0.0 198 + '@atcute/client': ^3.0.0 199 199 200 - '@atcute/cbor@2.2.0': 201 - resolution: {integrity: sha512-W3ttcDJHiB5N6MbfEpJbTINZSjg0KB8gpBds8UWOGmybqUnuz43HZkFSpF/Vom0KilYg6QWU/ZM4X8SXZE+kow==} 200 + '@atcute/cbor@2.2.1': 201 + resolution: {integrity: sha512-o+zCkfFQhRxpQmGYOAlRAK9xqq3VH66Mw0muUOlc+Wnk5X8CyZcIkdYorzYWTtyNO2/WHdMcUzZs93+Ajl6BbA==} 202 202 203 - '@atcute/cid@2.2.0': 204 - resolution: {integrity: sha512-ty+WjGcTfi1JJtcRNz6bsJMqT69lEIl4Ts7vl4U8SBHbxjbb6Tk/pcnQZVClKRYduRoZ1XhS9n5qOSIbIMctDA==} 203 + '@atcute/cid@2.2.1': 204 + resolution: {integrity: sha512-tSsVdgx8jj+n6l+MP8IN8rZCR9N4ltJ8EPMiRzo6uduAAygYiZkCRceCOZ57IMtToZcSgm3nxYr4g1aeUbHUcw==} 205 205 206 - '@atcute/client@2.0.9': 207 - resolution: {integrity: sha512-QNDm9gMP6x9LY77ArwY+urQOBtQW74/onEAz42c40JxRm6Rl9K9cU4ROvNKJ+5cpVmEm1sthEWVRmDr5CSZENA==} 206 + '@atcute/client@3.0.0': 207 + resolution: {integrity: sha512-6OsDqqkrqob/fMJ++s5vPc2MknQ6yfTzK+TY3MjXK3ZOkF0XseB5+QV1IiBWnEZ4X3aY21x2a3kv3YcvSQKxXQ==} 208 208 209 - '@atcute/multibase@1.1.2': 210 - resolution: {integrity: sha512-KFX+c7a/u2jSNcRw0rLaUHG/XEKf1A1c8XF5soHnsb1JMCShihf/anfZ1kJ4no/IlIp9HEHV3PQRQO2sWL6ASQ==} 209 + '@atcute/multibase@1.1.3': 210 + resolution: {integrity: sha512-vQQO0tDuQPguBvHdgV3ryn7R8U6beQ50KA/juYm+dCeT/3hOK2stMbX+IaW8JEuwkT5lJsU8wDIOicQT4mB7Ag==} 211 211 212 - '@atcute/oauth-browser-client@1.0.16': 213 - resolution: {integrity: sha512-BKkA4TPyaLIO+hVxcxZoDfLFUgsd3A47UyzWAbe3BpSoN8Kywy/CqWuAVlqdiUhO1iG+vVqGQhjKy4UxutaU4g==} 212 + '@atcute/oauth-browser-client@1.0.17': 213 + resolution: {integrity: sha512-0w3L/ZKQR3SK0VW7YvHF8fKKdSJu0nxVY8yxsbMbJ8JhT2RFUA5F+2yJT5O0341zot5zUKZ2iaGW2zccIcyz/w==} 214 214 215 215 '@atcute/tid@1.0.2': 216 216 resolution: {integrity: sha512-ahmjroNyeDPJhtuf3+HTJropaH04HmJ8fhntDu73Gpz/RkAF7+nkz6kcP2QTgfvMCgMPAJUdskAAP82GPDTY9w==} ··· 2707 2707 jsonpointer: 5.0.1 2708 2708 leven: 3.1.0 2709 2709 2710 - '@atcute/bluemoji@1.0.4(@atcute/bluesky@1.0.15(@atcute/client@2.0.9))(@atcute/client@2.0.9)': 2710 + '@atcute/bluemoji@2.0.0(@atcute/bluesky@2.0.0(@atcute/client@3.0.0))(@atcute/client@3.0.0)': 2711 2711 dependencies: 2712 - '@atcute/bluesky': 1.0.15(@atcute/client@2.0.9) 2713 - '@atcute/client': 2.0.9 2712 + '@atcute/bluesky': 2.0.0(@atcute/client@3.0.0) 2713 + '@atcute/client': 3.0.0 2714 2714 2715 2715 '@atcute/bluesky-richtext-parser@1.0.7': {} 2716 2716 2717 - '@atcute/bluesky-richtext-segmenter@1.0.5(@atcute/bluesky@1.0.15(@atcute/client@2.0.9))(@atcute/client@2.0.9)': 2717 + '@atcute/bluesky-richtext-segmenter@2.0.0(@atcute/bluesky@2.0.0(@atcute/client@3.0.0))(@atcute/client@3.0.0)': 2718 2718 dependencies: 2719 - '@atcute/bluesky': 1.0.15(@atcute/client@2.0.9) 2720 - '@atcute/client': 2.0.9 2719 + '@atcute/bluesky': 2.0.0(@atcute/client@3.0.0) 2720 + '@atcute/client': 3.0.0 2721 2721 2722 2722 '@atcute/bluesky-search-parser@0.1.0': {} 2723 2723 2724 - '@atcute/bluesky@1.0.15(@atcute/client@2.0.9)': 2724 + '@atcute/bluesky@2.0.0(@atcute/client@3.0.0)': 2725 2725 dependencies: 2726 - '@atcute/client': 2.0.9 2726 + '@atcute/client': 3.0.0 2727 2727 2728 - '@atcute/cbor@2.2.0': 2728 + '@atcute/cbor@2.2.1': 2729 2729 dependencies: 2730 - '@atcute/cid': 2.2.0 2731 - '@atcute/multibase': 1.1.2 2730 + '@atcute/cid': 2.2.1 2731 + '@atcute/multibase': 1.1.3 2732 2732 '@atcute/uint8array': 1.0.1 2733 2733 2734 - '@atcute/cid@2.2.0': 2734 + '@atcute/cid@2.2.1': 2735 2735 dependencies: 2736 - '@atcute/multibase': 1.1.2 2736 + '@atcute/multibase': 1.1.3 2737 2737 '@atcute/uint8array': 1.0.1 2738 2738 2739 - '@atcute/client@2.0.9': {} 2739 + '@atcute/client@3.0.0': {} 2740 2740 2741 - '@atcute/multibase@1.1.2': 2741 + '@atcute/multibase@1.1.3': 2742 2742 dependencies: 2743 2743 '@atcute/uint8array': 1.0.1 2744 2744 2745 - '@atcute/oauth-browser-client@1.0.16': 2745 + '@atcute/oauth-browser-client@1.0.17': 2746 2746 dependencies: 2747 - '@atcute/client': 2.0.9 2748 - '@atcute/multibase': 1.1.2 2747 + '@atcute/client': 3.0.0 2748 + '@atcute/multibase': 1.1.3 2749 2749 '@atcute/uint8array': 1.0.1 2750 2750 2751 2751 '@atcute/tid@1.0.2': {}
+3 -3
src/api/cache/profile-shadow.ts
··· 33 33 | AppBskyActorDefs.ProfileViewBasic 34 34 | AppBskyActorDefs.ProfileViewDetailed; 35 35 36 - const emitter = new EventEmitter<{ [uri: At.DID]: [] }>(); 36 + const emitter = new EventEmitter<{ [uri: At.Did]: [] }>(); 37 37 const shadows = new WeakMap<AllProfileView, ProfileShadow>(); 38 38 39 39 export const useProfileShadow = (profile: AccessorMaybe<AllProfileView>): Accessor<ProfileShadowView> => { ··· 66 66 }; 67 67 }; 68 68 69 - export const updateProfileShadow = (queryClient: QueryClient, did: At.DID, value: Partial<ProfileShadow>) => { 69 + export const updateProfileShadow = (queryClient: QueryClient, did: At.Did, value: Partial<ProfileShadow>) => { 70 70 for (const profile of findProfilesInCache(queryClient, did)) { 71 71 shadows.set(profile, { ...shadows.get(profile), ...value }); 72 72 } ··· 74 74 batch(() => emitter.emit(did)); 75 75 }; 76 76 77 - export function findProfilesInCache(queryClient: QueryClient, did: At.DID): Generator<AllProfileView> { 77 + export function findProfilesInCache(queryClient: QueryClient, did: At.Did): Generator<AllProfileView> { 78 78 return iterateQueryCache<AllProfileView>(queryClient, [ 79 79 findAllProfilesInBookmarkFeed(did), 80 80 findAllProfilesInNotificationFeed(did),
+1 -1
src/api/models/post-thread.tsx
··· 119 119 thread: Brand.Union<AppBskyFeedDefs.ThreadViewPost>; 120 120 preferences: ThreadViewPreferences; 121 121 moderationOptions: ModerationOptions; 122 - selfDid?: At.DID; 122 + selfDid?: At.Did; 123 123 }): ThreadData => { 124 124 const { followsFirst, sort, treeView } = preferences; 125 125
+1 -1
src/api/moderation/entities/generic.ts
··· 5 5 6 6 export const moderateGeneric = ( 7 7 item: { labels?: ComAtprotoLabelDefs.Label[] }, 8 - userDid: At.DID, 8 + userDid: At.Did, 9 9 opts: ModerationOptions, 10 10 ) => { 11 11 const accu: ModerationCause[] = [];
+5 -5
src/api/moderation/index.ts
··· 280 280 281 281 export interface ModerationLabeler { 282 282 /** DID of the labeler */ 283 - did: At.DID; 283 + did: At.Did; 284 284 /** Profile details of the labeler */ 285 285 profile: { 286 286 avatar?: string; ··· 309 309 /** Preferences for global-defined labels */ 310 310 labels: LabelPreferenceMapping; 311 311 /** Preferences for labels from subscribed labelers */ 312 - labelers: Record<At.DID, ModerationLabelerPreferences>; 312 + labelers: Record<At.Did, ModerationLabelerPreferences>; 313 313 /** Keyword filters */ 314 314 keywords: KeywordFilter[]; 315 315 316 316 /** List of users to hide reposts from */ 317 - hideReposts: At.DID[]; 317 + hideReposts: At.Did[]; 318 318 } 319 319 320 320 export interface ModerationOptions { 321 321 _filtersCache?: [raw: string, match: RegExp][]; 322 322 323 323 preferences: ModerationPreferences; 324 - labelerDefinitions: Record<At.DID, ModerationLabeler>; 324 + labelerDefinitions: Record<At.Did, ModerationLabeler>; 325 325 } 326 326 327 327 export const decideLabelModeration = ( 328 328 accu: ModerationCause[], 329 329 target: LabelTarget, 330 330 labels: Label[] | undefined, 331 - userDid: At.DID, 331 + userDid: At.Did, 332 332 opts: ModerationOptions, 333 333 ) => { 334 334 if (labels /* && labels.length > 0 */) {
+3 -3
src/api/mutations/post.ts
··· 5 5 import { useSession } from '~/lib/states/session'; 6 6 7 7 import { type PostShadowView, updatePostShadow } from '../cache/post-shadow'; 8 - import { parseAtUri } from '../types/at-uri'; 8 + import { parseCanonicalResourceUri } from '../types/at-uri'; 9 9 import { getCurrentDate } from '../utils/misc'; 10 10 import { createRecord, deleteRecord } from '../utils/records'; 11 11 import { createToggleMutationQueue } from '../utils/toggle-mutation'; ··· 45 45 46 46 return result.uri; 47 47 } else if (prevLikeUri) { 48 - const uri = parseAtUri(prevLikeUri); 48 + const uri = parseCanonicalResourceUri(prevLikeUri); 49 49 50 50 await deleteRecord(rpc, { 51 51 repo: currentAccount!.did, ··· 104 104 105 105 return result.uri; 106 106 } else if (prevRepostUri) { 107 - const uri = parseAtUri(prevRepostUri); 107 + const uri = parseCanonicalResourceUri(prevRepostUri); 108 108 109 109 await deleteRecord(rpc, { 110 110 repo: currentAccount!.did,
+2 -2
src/api/mutations/profile.ts
··· 5 5 import { useSession } from '~/lib/states/session'; 6 6 7 7 import { type ProfileShadowView, updateProfileShadow } from '../cache/profile-shadow'; 8 - import { parseAtUri } from '../types/at-uri'; 8 + import { parseCanonicalResourceUri } from '../types/at-uri'; 9 9 import { getCurrentDate } from '../utils/misc'; 10 10 import { createRecord, deleteRecord } from '../utils/records'; 11 11 import { createToggleMutationQueue } from '../utils/toggle-mutation'; ··· 42 42 43 43 return result.uri; 44 44 } else if (prevFollowUri) { 45 - const uri = parseAtUri(prevFollowUri); 45 + const uri = parseCanonicalResourceUri(prevFollowUri); 46 46 47 47 await deleteRecord(rpc, { 48 48 repo: currentAccount!.did,
+1 -1
src/api/queries-cache/bookmark-feed.ts
··· 35 35 }; 36 36 }; 37 37 38 - export const findAllProfiles = (did: At.DID): CacheMatcher<AppBskyActorDefs.ProfileViewBasic> => { 38 + export const findAllProfiles = (did: At.Did): CacheMatcher<AppBskyActorDefs.ProfileViewBasic> => { 39 39 return { 40 40 filter: { 41 41 queryKey: ['bookmarks-feed'],
+1 -1
src/api/queries-cache/notification-feed.ts
··· 38 38 }; 39 39 40 40 export const findAllProfiles = ( 41 - did: At.DID, 41 + did: At.Did, 42 42 ): CacheMatcher<AppBskyActorDefs.ProfileViewBasic | AppBskyActorDefs.ProfileView> => { 43 43 return { 44 44 filter: {
+1 -1
src/api/queries-cache/post-thread.ts
··· 54 54 }; 55 55 }; 56 56 57 - export const findAllProfiles = (did: At.DID): CacheMatcher<AppBskyActorDefs.ProfileViewBasic> => { 57 + export const findAllProfiles = (did: At.Did): CacheMatcher<AppBskyActorDefs.ProfileViewBasic> => { 58 58 return { 59 59 filter: { 60 60 queryKey: ['post-thread'],
+1 -1
src/api/queries-cache/profile-autocomplete.ts
··· 2 2 3 3 import type { CacheMatcher } from '../cache/utils'; 4 4 5 - export const findAllProfiles = (did: At.DID): CacheMatcher<AppBskyActorDefs.ProfileViewBasic> => { 5 + export const findAllProfiles = (did: At.Did): CacheMatcher<AppBskyActorDefs.ProfileViewBasic> => { 6 6 return { 7 7 filter: { 8 8 queryKey: ['profile-autocomplete'],
+1 -1
src/api/queries-cache/profile-list.ts
··· 4 4 import type { CacheMatcher } from '../cache/utils'; 5 5 import type { ProfilesListPage, ProfilesListWithSubjectPage } from '../types/profile-response'; 6 6 7 - export const findAllProfiles = (did: At.DID): CacheMatcher<AppBskyActorDefs.ProfileView> => { 7 + export const findAllProfiles = (did: At.Did): CacheMatcher<AppBskyActorDefs.ProfileView> => { 8 8 return { 9 9 filter: [ 10 10 { queryKey: ['profile-followers'] },
+1 -1
src/api/queries-cache/profile.ts
··· 2 2 3 3 import type { CacheMatcher } from '../cache/utils'; 4 4 5 - export const findAllProfiles = (did: At.DID): CacheMatcher<AppBskyActorDefs.ProfileViewDetailed> => { 5 + export const findAllProfiles = (did: At.Did): CacheMatcher<AppBskyActorDefs.ProfileViewDetailed> => { 6 6 return { 7 7 filter: { 8 8 queryKey: ['profile', did],
+1 -1
src/api/queries-cache/timeline.ts
··· 63 63 }; 64 64 }; 65 65 66 - export const findAllProfiles = (did: At.DID): CacheMatcher<AppBskyActorDefs.ProfileViewBasic> => { 66 + export const findAllProfiles = (did: At.Did): CacheMatcher<AppBskyActorDefs.ProfileViewBasic> => { 67 67 return { 68 68 filter: { 69 69 queryKey: ['timeline'],
+3 -2
src/api/queries/composer.ts
··· 1 + import type { At } from '@atcute/client/lexicons'; 1 2 import { createQuery } from '@mary/solid-query'; 2 3 3 4 const LINK_PROXY_ENDPOINT = 'https://cardyb.bsky.app/v1/extract'; ··· 12 13 } 13 14 14 15 export interface LinkMeta { 15 - uri: string; 16 + uri: At.GenericUri; 16 17 title: string; 17 18 description: string; 18 19 thumb: Blob | undefined; ··· 56 57 } 57 58 58 59 const meta: LinkMeta = { 59 - uri: $uri, 60 + uri: $uri as At.GenericUri, 60 61 title: data.title, 61 62 description: data.description, 62 63 thumb: thumb,
+3 -3
src/api/queries/feed.ts
··· 8 8 import { useSession } from '~/lib/states/session'; 9 9 import { omit } from '~/lib/utils/misc'; 10 10 11 - import { makeAtUri, parseAtUri } from '../types/at-uri'; 11 + import { makeAtUri, parseCanonicalResourceUri } from '../types/at-uri'; 12 12 import { isDid } from '../types/identity'; 13 13 14 14 import { resolveHandle } from './handle'; ··· 23 23 return { 24 24 queryKey: ['feed-meta', $feedUri], 25 25 async queryFn(ctx): Promise<AppBskyFeedDefs.GeneratorView> { 26 - const uri = parseAtUri($feedUri); 26 + const uri = parseCanonicalResourceUri($feedUri); 27 27 28 - let did: At.DID; 28 + let did: At.Did; 29 29 if (isDid(uri.repo)) { 30 30 did = uri.repo; 31 31 } else {
+3 -2
src/api/queries/handle.ts
··· 1 1 import { XRPC } from '@atcute/client'; 2 + import type { At } from '@atcute/client/lexicons'; 2 3 import { createQuery } from '@mary/solid-query'; 3 4 4 5 import { useAgent } from '~/lib/states/agent'; 5 6 6 - export const useResolveHandleQuery = (handle: () => string) => { 7 + export const useResolveHandleQuery = (handle: () => At.Handle) => { 7 8 const { rpc } = useAgent(); 8 9 9 10 return createQuery(() => { ··· 18 19 }); 19 20 }; 20 21 21 - export const resolveHandle = async (rpc: XRPC, handle: string, signal?: AbortSignal) => { 22 + export const resolveHandle = async (rpc: XRPC, handle: At.Handle, signal?: AbortSignal) => { 22 23 const { data } = await rpc.get('com.atproto.identity.resolveHandle', { 23 24 signal: signal, 24 25 params: {
+1 -1
src/api/queries/labeler.ts
··· 6 6 7 7 import { interpretLabelerDefinition } from '../moderation/labeler'; 8 8 9 - export const createLabelerMetaQuery = (did: () => At.DID) => { 9 + export const createLabelerMetaQuery = (did: () => At.Did) => { 10 10 const { rpc } = useAgent(); 11 11 12 12 const query = createQuery(() => {
+2 -1
src/api/queries/list-members.ts
··· 1 + import type { At } from '@atcute/client/lexicons'; 1 2 import { type QueryFunctionContext as QC, createInfiniteQuery } from '@mary/solid-query'; 2 3 3 4 import { useAgent } from '~/lib/states/agent'; 4 5 5 - export const createListMembersQuery = (listUri: () => string) => { 6 + export const createListMembersQuery = (listUri: () => At.ResourceUri) => { 6 7 const { rpc } = useAgent(); 7 8 8 9 return createInfiniteQuery(() => {
+3 -3
src/api/queries/list.ts
··· 8 8 import { useSession } from '~/lib/states/session'; 9 9 import { omit } from '~/lib/utils/misc'; 10 10 11 - import { makeAtUri, parseAtUri } from '../types/at-uri'; 11 + import { makeAtUri, parseCanonicalResourceUri } from '../types/at-uri'; 12 12 import { isDid } from '../types/identity'; 13 13 14 14 import { resolveHandle } from './handle'; ··· 23 23 return { 24 24 queryKey: ['list-meta', $listUri], 25 25 async queryFn(ctx) { 26 - const uri = parseAtUri($listUri); 26 + const uri = parseCanonicalResourceUri($listUri); 27 27 28 - let did: At.DID; 28 + let did: At.Did; 29 29 if (isDid(uri.repo)) { 30 30 did = uri.repo; 31 31 } else {
+2 -2
src/api/queries/notification-feed.tsx
··· 6 6 7 7 import { useAgent } from '~/lib/states/agent'; 8 8 9 - import { parseAtUri } from '../types/at-uri'; 9 + import { parseCanonicalResourceUri } from '../types/at-uri'; 10 10 import { dequal } from '../utils/dequal'; 11 11 import { resetInfiniteData } from '../utils/query'; 12 12 ··· 129 129 const subjectUri = item.reasonSubject; 130 130 131 131 // skip if they're not related to posts. 132 - if (!subjectUri || parseAtUri(subjectUri).collection !== 'app.bsky.feed.post') { 132 + if (!subjectUri || parseCanonicalResourceUri(subjectUri).collection !== 'app.bsky.feed.post') { 133 133 return; 134 134 } 135 135
+2 -2
src/api/queries/post-quotes.ts
··· 1 - import type { AppBskyFeedGetQuotes } from '@atcute/client/lexicons'; 1 + import type { AppBskyFeedGetQuotes, At } from '@atcute/client/lexicons'; 2 2 import { type QueryFunctionContext as QC, createInfiniteQuery } from '@mary/solid-query'; 3 3 4 4 import { useAgent } from '~/lib/states/agent'; 5 5 6 - export const createPostQuotesQuery = (uri: () => string) => { 6 + export const createPostQuotesQuery = (uri: () => At.ResourceUri) => { 7 7 const { rpc } = useAgent(); 8 8 9 9 return createInfiniteQuery(() => {
+2 -2
src/api/queries/post-thread.ts
··· 1 1 import { XRPCError } from '@atcute/client'; 2 - import type { AppBskyFeedDefs, Brand } from '@atcute/client/lexicons'; 2 + import type { AppBskyFeedDefs, At, Brand } from '@atcute/client/lexicons'; 3 3 import { createQuery } from '@mary/solid-query'; 4 4 5 5 import { useAgent } from '~/lib/states/agent'; ··· 11 11 12 12 type ThreadReturn = Brand.Union<AppBskyFeedDefs.ThreadViewPost | AppBskyFeedDefs.BlockedPost>; 13 13 14 - export const usePostThreadQuery = (uri: () => string) => { 14 + export const usePostThreadQuery = (uri: () => At.ResourceUri) => { 15 15 const { rpc } = useAgent(); 16 16 17 17 return createQuery((queryClient) => {
+3 -3
src/api/queries/post.ts
··· 4 4 import { useAgent } from '~/lib/states/agent'; 5 5 6 6 import { findPostsInCache } from '../cache/post-shadow'; 7 - import { makeAtUri, parseAtUri } from '../types/at-uri'; 7 + import { makeAtUri, parseCanonicalResourceUri } from '../types/at-uri'; 8 8 import { isDid } from '../types/identity'; 9 9 10 10 import { resolveHandle } from './handle'; ··· 18 18 return { 19 19 queryKey: ['post', $postUri], 20 20 async queryFn(ctx) { 21 - const uri = parseAtUri($postUri); 21 + const uri = parseCanonicalResourceUri($postUri); 22 22 23 - let did: At.DID; 23 + let did: At.Did; 24 24 if (isDid(uri.repo)) { 25 25 did = uri.repo; 26 26 } else {
+2 -1
src/api/queries/profile-feeds.ts
··· 1 + import type { At } from '@atcute/client/lexicons'; 1 2 import { type QueryFunctionContext as QC, createInfiniteQuery } from '@mary/solid-query'; 2 3 3 4 import { useAgent } from '~/lib/states/agent'; 4 5 5 - export const createProfileFeedsQuery = (didOrHandle: () => string) => { 6 + export const createProfileFeedsQuery = (didOrHandle: () => At.Identifier) => { 6 7 const { rpc } = useAgent(); 7 8 8 9 return createInfiniteQuery(() => {
+2 -2
src/api/queries/profile-followers.ts
··· 1 - import type { AppBskyActorDefs } from '@atcute/client/lexicons'; 1 + import type { AppBskyActorDefs, At } from '@atcute/client/lexicons'; 2 2 import { type InfiniteData, type QueryFunctionContext as QC, createInfiniteQuery } from '@mary/solid-query'; 3 3 4 4 import { useAgent } from '~/lib/states/agent'; 5 5 6 6 import { type ProfilesListWithSubjectPage, toProfilesListWithSubjectPage } from '../types/profile-response'; 7 7 8 - export const createProfileFollowersQuery = (didOrHandle: () => string) => { 8 + export const createProfileFollowersQuery = (didOrHandle: () => At.Identifier) => { 9 9 const { rpc } = useAgent(); 10 10 11 11 return createInfiniteQuery((queryClient) => {
+2 -2
src/api/queries/profile-following.ts
··· 1 - import type { AppBskyActorDefs } from '@atcute/client/lexicons'; 1 + import type { AppBskyActorDefs, At } from '@atcute/client/lexicons'; 2 2 import { type InfiniteData, type QueryFunctionContext as QC, createInfiniteQuery } from '@mary/solid-query'; 3 3 4 4 import { useAgent } from '~/lib/states/agent'; 5 5 6 6 import { type ProfilesListWithSubjectPage, toProfilesListWithSubjectPage } from '../types/profile-response'; 7 7 8 - export const createProfileFollowingQuery = (didOrHandle: () => string) => { 8 + export const createProfileFollowingQuery = (didOrHandle: () => At.Identifier) => { 9 9 const { rpc } = useAgent(); 10 10 11 11 return createInfiniteQuery((queryClient) => {
+2 -2
src/api/queries/profile-known-followers.ts
··· 1 - import type { AppBskyActorDefs } from '@atcute/client/lexicons'; 1 + import type { AppBskyActorDefs, At } from '@atcute/client/lexicons'; 2 2 import { type InfiniteData, type QueryFunctionContext as QC, createInfiniteQuery } from '@mary/solid-query'; 3 3 4 4 import { useAgent } from '~/lib/states/agent'; 5 5 6 6 import { type ProfilesListWithSubjectPage, toProfilesListWithSubjectPage } from '../types/profile-response'; 7 7 8 - export const createProfileKnownFollowersQuery = (didOrHandle: () => string) => { 8 + export const createProfileKnownFollowersQuery = (didOrHandle: () => At.Identifier) => { 9 9 const { rpc } = useAgent(); 10 10 11 11 return createInfiniteQuery((queryClient) => {
+2 -1
src/api/queries/profile-lists.ts
··· 1 + import type { At } from '@atcute/client/lexicons'; 1 2 import { type QueryFunctionContext as QC, createInfiniteQuery } from '@mary/solid-query'; 2 3 3 4 import { useAgent } from '~/lib/states/agent'; 4 5 5 - export const createProfileListsQuery = (didOrHandle: () => string) => { 6 + export const createProfileListsQuery = (didOrHandle: () => At.Identifier) => { 6 7 const { rpc } = useAgent(); 7 8 8 9 const collator = new Intl.Collator('en-US');
+2 -2
src/api/queries/profile.ts
··· 1 1 import { modifyMutable, reconcile } from 'solid-js/store'; 2 2 3 - import type { AppBskyActorDefs } from '@atcute/client/lexicons'; 3 + import type { AppBskyActorDefs, At } from '@atcute/client/lexicons'; 4 4 import { createQuery } from '@mary/solid-query'; 5 5 6 6 import { useAgent } from '~/lib/states/agent'; ··· 13 13 gcTime?: number; 14 14 } 15 15 16 - export const createProfileQuery = (didOrHandle: () => string, opts: ProfileQueryOptions = {}) => { 16 + export const createProfileQuery = (didOrHandle: () => At.Identifier, opts: ProfileQueryOptions = {}) => { 17 17 const { rpc } = useAgent(); 18 18 const { currentAccount } = useSession(); 19 19
+2 -1
src/api/queries/subject-likers.ts
··· 1 + import type { At } from '@atcute/client/lexicons'; 1 2 import type { QueryFunctionContext as QC } from '@mary/solid-query'; 2 3 import { createInfiniteQuery } from '@mary/solid-query'; 3 4 ··· 5 6 6 7 import type { ProfilesListPage } from '../types/profile-response'; 7 8 8 - export const createSubjectLikersQuery = (uri: () => string) => { 9 + export const createSubjectLikersQuery = (uri: () => At.ResourceUri) => { 9 10 const { rpc } = useAgent(); 10 11 11 12 return createInfiniteQuery(() => {
+2 -1
src/api/queries/subject-reposters.ts
··· 1 + import type { At } from '@atcute/client/lexicons'; 1 2 import type { QueryFunctionContext as QC } from '@mary/solid-query'; 2 3 import { createInfiniteQuery } from '@mary/solid-query'; 3 4 ··· 5 6 6 7 import { type ProfilesListPage, toProfilesListPage } from '../types/profile-response'; 7 8 8 - export const createSubjectRepostersQuery = (uri: () => string) => { 9 + export const createSubjectRepostersQuery = (uri: () => At.ResourceUri) => { 9 10 const { rpc } = useAgent(); 10 11 11 12 return createInfiniteQuery(() => {
+9 -7
src/api/queries/timeline.ts
··· 31 31 getModerationUI, 32 32 } from '../moderation'; 33 33 import { ContextContentList, PreferenceHide, TargetContent } from '../moderation/constants'; 34 - import { parseAtUri } from '../types/at-uri'; 34 + import { parseCanonicalResourceUri } from '../types/at-uri'; 35 35 import { unwrapRecordEmbed } from '../utils/bluesky/embed'; 36 36 import { unwrapRecordEmbedView } from '../utils/bluesky/embed-view'; 37 37 import { EQUALS_DEQUAL } from '../utils/dequal'; ··· 49 49 50 50 export interface FeedTimelineParams { 51 51 type: 'feed'; 52 - uri: string; 52 + uri: At.ResourceUri; 53 53 showReplies: boolean; 54 54 showReposts: boolean; 55 55 showQuotes: boolean; ··· 57 57 58 58 export interface ListTimelineParams { 59 59 type: 'list'; 60 - uri: string; 60 + uri: At.ResourceUri; 61 61 showReplies: boolean; 62 62 showQuotes: boolean; 63 63 } 64 64 65 65 export interface ProfileTimelineParams { 66 66 type: 'profile'; 67 - actor: At.DID; 67 + actor: At.Did; 68 68 tab: 'posts' | 'replies' | 'likes' | 'media'; 69 69 } 70 70 ··· 526 526 const post = item.post.record as PostRecord; 527 527 const record = unwrapRecordEmbed(post.embed); 528 528 529 - return record === undefined || parseAtUri(record.record.uri).collection === 'app.bsky.feed.post'; 529 + return ( 530 + record === undefined || parseCanonicalResourceUri(record.record.uri).collection === 'app.bsky.feed.post' 531 + ); 530 532 }; 531 533 }; 532 534 ··· 575 577 }; 576 578 }; 577 579 578 - const createHomeSliceFilter = (uid: At.DID, followsOnly: boolean): SliceFilter | undefined => { 580 + const createHomeSliceFilter = (uid: At.Did, followsOnly: boolean): SliceFilter | undefined => { 579 581 return (slice) => { 580 582 const items = slice.items; 581 583 const first = items[0]; ··· 607 609 }; 608 610 }; 609 611 610 - const createProfileSliceFilter = (did: At.DID): SliceFilter | undefined => { 612 + const createProfileSliceFilter = (did: At.Did): SliceFilter | undefined => { 611 613 return (slice) => { 612 614 const items = slice.items; 613 615 const first = items[0];
+14 -10
src/api/types/at-uri.ts
··· 5 5 export const ATURI_RE = 6 6 /^at:\/\/(did:[a-z]+:[a-zA-Z0-9._:%\-]*[a-zA-Z0-9._\-]|(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z][a-zA-Z0-9-]{0,61}[a-zA-Z0-9])\/([a-zA-Z0-9-.]+)\/((?!\.{1,2}$)[a-zA-Z0-9_~.:-]{1,512})(?:#(\/[a-zA-Z0-9._~:@!$&%')(*+,;=\-[\]/\\]*))?$/; 7 7 8 - export interface ParsedAtUri { 9 - repo: string; 10 - collection: string; 11 - rkey: string; 8 + export interface ParsedCanonicalResourceUri { 9 + repo: At.Did; 10 + collection: At.Nsid; 11 + rkey: At.RecordKey; 12 12 fragment: string | undefined; 13 13 } 14 14 15 - export const parseAtUri = (str: string): ParsedAtUri => { 15 + export const parseCanonicalResourceUri = (str: string): ParsedCanonicalResourceUri => { 16 16 const match = ATURI_RE.exec(str); 17 - assert(match !== null, `failed to parse at-uri for ${str}`); 17 + assert(match !== null, `failed to parse canonical-at-uri for ${str}`); 18 18 19 19 return { 20 - repo: match[1] as At.DID, 21 - collection: match[2], 22 - rkey: match[3], 20 + repo: match[1] as At.Did, 21 + collection: match[2] as At.Nsid, 22 + rkey: match[3] as At.RecordKey, 23 23 fragment: match[4], 24 24 }; 25 25 }; 26 26 27 - export const makeAtUri = (repo: string, collection: keyof Records | (string & {}), rkey: string) => { 27 + export const makeAtUri = ( 28 + repo: At.Identifier, 29 + collection: keyof Records | (string & {}), 30 + rkey: At.RecordKey, 31 + ): At.ResourceUri => { 28 32 return `at://${repo}/${collection}/${rkey}`; 29 33 };
+2 -2
src/api/utils/bluesky/embed-view.ts
··· 1 1 import type { AppBskyEmbedRecordWithMedia, AppBskyFeedDefs } from '@atcute/client/lexicons'; 2 2 3 - import { parseAtUri } from '~/api/types/at-uri'; 3 + import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 4 4 5 5 export interface EmbedsView { 6 6 media?: AppBskyEmbedRecordWithMedia.View['media']; ··· 47 47 case 'app.bsky.embed.record#viewNotFound': 48 48 case 'app.bsky.embed.record#viewDetached': 49 49 case 'app.bsky.embed.record#viewBlocked': { 50 - const uri = parseAtUri(embed.uri); 50 + const uri = parseCanonicalResourceUri(embed.uri); 51 51 if (uri.collection === 'app.bsky.feed.post') { 52 52 return embed; 53 53 }
+2 -2
src/api/utils/did.ts
··· 3 3 4 4 import { isDid } from '../types/identity'; 5 5 6 - const getDid = async (rpc: XRPC, actor: string, signal?: AbortSignal) => { 7 - let did: At.DID; 6 + const getDid = async (rpc: XRPC, actor: At.Handle, signal?: AbortSignal) => { 7 + let did: At.Did; 8 8 if (isDid(actor)) { 9 9 did = actor; 10 10 } else {
+7 -7
src/api/utils/records.ts
··· 9 9 type RecordType = keyof Records; 10 10 11 11 export interface CreateRecordOptions<K extends RecordType> { 12 - repo: At.DID; 12 + repo: At.Did; 13 13 collection: K; 14 14 rkey?: string; 15 15 record: Records[K]; ··· 24 24 }; 25 25 26 26 export interface PutRecordOptions<K extends RecordType> { 27 - repo: At.DID; 27 + repo: At.Did; 28 28 collection: K; 29 29 rkey: string; 30 30 record: Records[K]; 31 31 swapCommit?: string; 32 - swapRecord?: At.CID | null; 32 + swapRecord?: At.Cid | null; 33 33 validate?: boolean; 34 34 } 35 35 ··· 40 40 }; 41 41 42 42 export interface DeleteRecordOptions<K extends RecordType> { 43 - repo: At.DID; 43 + repo: At.Did; 44 44 collection: K; 45 45 rkey: string; 46 46 swapCommit?: string; ··· 54 54 }; 55 55 56 56 export interface GetRecordOptions<K extends RecordType> { 57 - repo: At.DID; 57 + repo: At.Did; 58 58 collection: K; 59 59 rkey: string; 60 60 cid?: string; ··· 77 77 78 78 export interface ListRecordsOptions<K extends RecordType> { 79 79 signal?: AbortSignal; 80 - repo: At.DID; 80 + repo: At.Did; 81 81 collection: K; 82 82 cursor?: string; 83 83 limit?: number; ··· 85 85 86 86 export interface ListRecordsOutput<T> extends ComAtprotoRepoListRecords.Output { 87 87 cursor?: string; 88 - records: { cid: At.CID; uri: At.Uri; value: T }[]; 88 + records: { cid: At.Cid; uri: At.ResourceUri; value: T }[]; 89 89 } 90 90 91 91 export const listRecords = async <K extends RecordType>(
+2 -2
src/components/bookmarks/bookmark-feed-item.tsx
··· 6 6 import { getModerationUI } from '~/api/moderation'; 7 7 import { ContextContentList } from '~/api/moderation/constants'; 8 8 import { moderatePost } from '~/api/moderation/entities/post'; 9 - import { parseAtUri } from '~/api/types/at-uri'; 9 + import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 10 10 11 11 import { history } from '~/globals/navigation'; 12 12 ··· 40 40 41 41 const shadow = usePostShadow(post); 42 42 43 - const uri = parseAtUri(post.uri); 43 + const uri = parseCanonicalResourceUri(post.uri); 44 44 const authorHref = `/${author.did}`; 45 45 const href = `/${author.did}/${uri.rkey}`; 46 46
+3 -2
src/components/composer/gifs/gif-search-dialog.tsx
··· 1 1 import { For, Match, Switch, createSignal } from 'solid-js'; 2 2 3 + import type { At } from '@atcute/client/lexicons'; 3 4 import { chunked } from '@mary/array-fns'; 4 5 5 6 import { type Gif, createGifSearchQuery } from '~/api/queries/composer-gif'; ··· 110 111 export default GifSearchDialog; 111 112 112 113 export interface GifMedia { 113 - embedUrl: string; 114 + embedUrl: At.GenericUri; 114 115 alt: string; 115 116 ratio: { width: number; height: number }; 116 117 ··· 128 129 const [, id, file] = /\/([^/]+?AAAAC)\/([^/]+?)\.gif\/?$/.exec(url)!; 129 130 130 131 return { 131 - embedUrl: url + `?hh=${dimensions[1]}&ww=${dimensions[0]}`, 132 + embedUrl: (url + `?hh=${dimensions[1]}&ww=${dimensions[0]}`) as At.GenericUri, 132 133 alt: gif.content_description, 133 134 ratio: { width: dimensions[0], height: dimensions[1] }, 134 135
+6 -6
src/components/composer/lib/api.ts
··· 26 26 import { uploadBlob } from '~/api/queries/blob'; 27 27 import type { LinkMeta } from '~/api/queries/composer'; 28 28 import { resolveHandle } from '~/api/queries/handle'; 29 - import { makeAtUri, parseAtUri } from '~/api/types/at-uri'; 29 + import { makeAtUri, parseCanonicalResourceUri } from '~/api/types/at-uri'; 30 30 import { isDid } from '~/api/types/identity'; 31 31 import { getRecord } from '~/api/utils/records'; 32 32 import { trimRichText } from '~/api/utils/richtext'; ··· 74 74 queryKey: ['post', replyUri], 75 75 staleTime: 30_000, 76 76 async queryFn(ctx) { 77 - const uri = parseAtUri(replyUri); 77 + const uri = parseCanonicalResourceUri(replyUri); 78 78 79 - let did: At.DID; 79 + let did: At.Did; 80 80 if (isDid(uri.repo)) { 81 81 did = uri.repo; 82 82 } else { ··· 113 113 } 114 114 115 115 if (state.redraftUri) { 116 - const uri = parseAtUri(state.redraftUri); 116 + const uri = parseCanonicalResourceUri(state.redraftUri); 117 117 118 118 writes.push({ 119 119 $type: 'com.atproto.repo.applyWrites#delete', ··· 669 669 if (type === 'link' || type === 'autolink') { 670 670 facets.push({ 671 671 index: index, 672 - features: [{ $type: 'app.bsky.richtext.facet#link', uri: token.url }], 672 + features: [{ $type: 'app.bsky.richtext.facet#link', uri: token.url as At.GenericUri }], 673 673 }); 674 674 } else if (type === 'mention') { 675 - const handle = token.handle; 675 + const handle = token.handle as At.Handle; 676 676 677 677 if (handle === 'handle.invalid') { 678 678 throw new InvalidHandleError(handle);
+2 -2
src/components/embeds/embed.tsx
··· 2 2 3 3 import { type ModerationCause, getModerationUI } from '~/api/moderation'; 4 4 import { ContextContentMedia } from '~/api/moderation/constants'; 5 - import { parseAtUri } from '~/api/types/at-uri'; 5 + import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 6 6 import { type MediaEmbedView, type RecordEmbedView, unwrapEmbedView } from '~/api/utils/bluesky/embed-view'; 7 7 8 8 import ContentHider from '../moderation/content-hider'; ··· 100 100 } 101 101 102 102 if (type === 'app.bsky.embed.record#viewNotFound' || type === 'app.bsky.embed.record#viewBlocked') { 103 - const uri = parseAtUri(embed.uri); 103 + const uri = parseCanonicalResourceUri(embed.uri); 104 104 105 105 if (type === 'app.bsky.embed.record#viewBlocked' && uri.collection === 'app.bsky.feed.post') { 106 106 return <QuoteBlockedEmbed embed={embed} uri={uri} />;
+2 -2
src/components/embeds/feed-embed.tsx
··· 5 5 6 6 import { moderateGeneric } from '~/api/moderation/entities/generic'; 7 7 import { precacheFeed } from '~/api/queries-cache/feed-precache'; 8 - import { parseAtUri } from '~/api/types/at-uri'; 8 + import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 9 9 10 10 import { inject } from '~/lib/states/singleton'; 11 11 import ModerationService from '~/lib/states/singletons/moderation'; ··· 26 26 27 27 const moderation = createMemo(() => moderateGeneric(feed, feed.creator.did, moderationOptions())); 28 28 29 - const href = `/${feed.creator.did}/feeds/${parseAtUri(feed.uri).rkey}`; 29 + const href = `/${feed.creator.did}/feeds/${parseCanonicalResourceUri(feed.uri).rkey}`; 30 30 31 31 return ( 32 32 <a
+2 -2
src/components/embeds/quote-blocked-embed.tsx
··· 1 1 import type { AppBskyEmbedRecord } from '@atcute/client/lexicons'; 2 2 3 - import type { ParsedAtUri } from '~/api/types/at-uri'; 3 + import type { ParsedCanonicalResourceUri } from '~/api/types/at-uri'; 4 4 5 5 import BlockOutlinedIcon from '../icons-central/block-outline'; 6 6 7 7 export interface QuoteBlockedEmbedProps { 8 8 embed: AppBskyEmbedRecord.ViewBlocked; 9 - uri: ParsedAtUri; 9 + uri: ParsedCanonicalResourceUri; 10 10 } 11 11 12 12 const QuoteBlockedEmbed = ({ embed, uri }: QuoteBlockedEmbedProps) => {
+2 -2
src/components/embeds/quote-embed.tsx
··· 5 5 import { getModerationUI } from '~/api/moderation'; 6 6 import { ContextContentMedia } from '~/api/moderation/constants'; 7 7 import { moderateQuote } from '~/api/moderation/entities/quote'; 8 - import { parseAtUri } from '~/api/types/at-uri'; 8 + import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 9 9 import { unwrapMediaEmbedView } from '~/api/utils/bluesky/embed-view'; 10 10 11 11 import { inject } from '~/lib/states/singleton'; ··· 32 32 const record = quote.value as AppBskyFeedPost.Record; 33 33 const author = quote.author; 34 34 35 - const uri = parseAtUri(quote.uri); 35 + const uri = parseCanonicalResourceUri(quote.uri); 36 36 const href = `/${author.did}/${uri.rkey}`; 37 37 38 38 const text = record.text.trim();
+3 -3
src/components/explore/my-feeds-section.tsx
··· 1 1 import { For, createMemo } from 'solid-js'; 2 2 3 - import { parseAtUri } from '~/api/types/at-uri'; 3 + import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 4 4 5 5 import type { SavedFeed } from '~/lib/preferences/account'; 6 6 import { useSession } from '~/lib/states/session'; ··· 55 55 let href: string; 56 56 switch (type) { 57 57 case 'generator': { 58 - const uri = parseAtUri(feed.info.uri); 58 + const uri = parseCanonicalResourceUri(feed.info.uri); 59 59 href = `/${uri.repo}/feeds/${uri.rkey}`; 60 60 break; 61 61 } 62 62 case 'list': { 63 - const uri = parseAtUri(feed.info.uri); 63 + const uri = parseCanonicalResourceUri(feed.info.uri); 64 64 href = `/${uri.repo}/lists/${uri.rkey}`; 65 65 break; 66 66 }
+2 -6
src/components/feeds/feed-info-prompt.tsx
··· 1 1 import type { AppBskyFeedDefs } from '@atcute/client/lexicons'; 2 2 3 - import { parseAtUri } from '~/api/types/at-uri'; 3 + import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 4 4 5 5 import { useModalContext } from '~/globals/modals'; 6 6 7 7 import { formatLong } from '~/lib/intl/number'; 8 8 9 9 import Avatar from '~/components/avatar'; 10 - import Button from '~/components/button'; 11 - import Divider from '~/components/divider'; 12 10 import * as Prompt from '~/components/prompt'; 13 11 14 - import HeartOutlinedIcon from '../icons-central/heart-outline'; 15 - 16 12 export interface FeedInfoPromptProps { 17 13 /** Expected to be static */ 18 14 feed: AppBskyFeedDefs.GeneratorView; ··· 24 20 const feed = props.feed; 25 21 26 22 const authorUrl = `/${feed.creator.did}`; 27 - const feedUrl = `${authorUrl}/feeds/${parseAtUri(feed.uri).rkey}`; 23 + const feedUrl = `${authorUrl}/feeds/${parseCanonicalResourceUri(feed.uri).rkey}`; 28 24 29 25 return ( 30 26 <Prompt.Container maxWidth="md">
+2 -2
src/components/feeds/feed-item.tsx
··· 5 5 6 6 import { moderateGeneric } from '~/api/moderation/entities/generic'; 7 7 import { precacheFeed } from '~/api/queries-cache/feed-precache'; 8 - import { parseAtUri } from '~/api/types/at-uri'; 8 + import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 9 9 10 10 import { history } from '~/globals/navigation'; 11 11 ··· 27 27 const moderationOptions = inject(ModerationService); 28 28 29 29 const creator = item.creator; 30 - const href = `/${creator.did}/feeds/${parseAtUri(item.uri).rkey}`; 30 + const href = `/${creator.did}/feeds/${parseCanonicalResourceUri(item.uri).rkey}`; 31 31 32 32 const moderation = createMemo(() => moderateGeneric(item, creator.did, moderationOptions())); 33 33
+2 -2
src/components/feeds/feed-overflow-menu.tsx
··· 2 2 3 3 import type { AppBskyFeedDefs } from '@atcute/client/lexicons'; 4 4 5 - import { parseAtUri } from '~/api/types/at-uri'; 5 + import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 6 6 7 7 import { useModalContext } from '~/globals/modals'; 8 8 ··· 83 83 icon={OpenInNewOutlinedIcon} 84 84 label="Open in Bluesky app" 85 85 onClick={() => { 86 - const uri = `https://bsky.app/profile/${feed.creator.did}/feed/${parseAtUri(feed.uri).rkey}`; 86 + const uri = `https://bsky.app/profile/${feed.creator.did}/feed/${parseCanonicalResourceUri(feed.uri).rkey}`; 87 87 88 88 close(); 89 89 window.open(uri, '_blank');
+2 -2
src/components/lists/lib/utils.ts
··· 1 1 import type { AppBskyGraphDefs } from '@atcute/client/lexicons'; 2 2 3 - import { parseAtUri } from '~/api/types/at-uri'; 3 + import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 4 4 5 5 export const getListPurposeLabel = (purpose: AppBskyGraphDefs.ListPurpose) => { 6 6 switch (purpose) { ··· 15 15 16 16 export const getListUrl = (list: AppBskyGraphDefs.ListView) => { 17 17 const did = list.creator.did; 18 - const { rkey } = parseAtUri(list.uri); 18 + const { rkey } = parseCanonicalResourceUri(list.uri); 19 19 20 20 switch (list.purpose) { 21 21 case 'app.bsky.graph.defs#curatelist':
+1 -1
src/components/main/sign-in-dialog.tsx
··· 27 27 } 28 28 29 29 export interface SignInDialogProps { 30 - relogin?: { did: At.DID; handle?: string }; 30 + relogin?: { did: At.Did; handle?: string }; 31 31 } 32 32 33 33 const SignInDialog = (props: SignInDialogProps) => {
+4 -4
src/components/moderation/block-account-prompt.tsx
··· 5 5 6 6 import { updateProfileShadow, useProfileShadow } from '~/api/cache/profile-shadow'; 7 7 import { createListMetaQuery } from '~/api/queries/list'; 8 - import { parseAtUri } from '~/api/types/at-uri'; 8 + import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 9 9 import { getCurrentDate } from '~/api/utils/misc'; 10 10 import { createRecord, deleteRecord } from '~/api/utils/records'; 11 11 ··· 126 126 const { close } = useModalContext(); 127 127 128 128 const { rpc } = useAgent(); 129 - const { repo, rkey } = parseAtUri(profile.viewer!.blocking!); 129 + const { repo, rkey } = parseCanonicalResourceUri(profile.viewer!.blocking!); 130 130 131 131 const mutation = createMutation((queryClient) => ({ 132 132 async mutationFn() { 133 133 return await deleteRecord(rpc, { 134 - repo: repo as At.DID, 134 + repo: repo as At.Did, 135 135 collection: 'app.bsky.graph.block', 136 136 rkey: rkey, 137 137 }); ··· 225 225 ); 226 226 }; 227 227 228 - const resetThreadQueries = (queryClient: QueryClient, did: At.DID) => { 228 + const resetThreadQueries = (queryClient: QueryClient, did: At.Did) => { 229 229 const substring = `at://${did}/`; 230 230 231 231 queryClient.resetQueries({
+2 -2
src/components/notifications/notification-item.tsx
··· 19 19 NotificationSlice, 20 20 RepostNotificationSlice, 21 21 } from '~/api/queries/notification-feed'; 22 - import { parseAtUri } from '~/api/types/at-uri'; 22 + import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 23 23 import { type MediaEmbedView, unwrapMediaEmbedView } from '~/api/utils/bluesky/embed-view'; 24 24 25 25 import { history } from '~/globals/navigation'; ··· 95 95 } 96 96 } else { 97 97 const post = item.view; 98 - const uri = parseAtUri(post.uri); 98 + const uri = parseCanonicalResourceUri(post.uri); 99 99 href = `/${uri.repo}/${uri.rkey}`; 100 100 } 101 101
+2 -2
src/components/profiles/profile-view-header.tsx
··· 6 6 import { getModerationUI } from '~/api/moderation'; 7 7 import { ContextProfileMedia, ContextProfileView } from '~/api/moderation/constants'; 8 8 import { moderateProfile } from '~/api/moderation/entities/profile'; 9 - import { parseAtUri } from '~/api/types/at-uri'; 9 + import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 10 10 11 11 import { openModal } from '~/globals/modals'; 12 12 ··· 259 259 <Match when={viewer()?.mutedByList}> 260 260 {(list) => { 261 261 const href = () => { 262 - const uri = parseAtUri(list().uri); 262 + const uri = parseCanonicalResourceUri(list().uri); 263 263 return `/${uri.repo}/lists/${uri.rkey}`; 264 264 }; 265 265
+2 -2
src/components/threads/highlighted-post.tsx
··· 7 7 import { ContextContentView } from '~/api/moderation/constants'; 8 8 import { moderatePost } from '~/api/moderation/entities/post'; 9 9 import { createPostLikeMutation, createPostRepostMutation } from '~/api/mutations/post'; 10 - import { parseAtUri } from '~/api/types/at-uri'; 10 + import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 11 11 12 12 import { primarySystemLanguage } from '~/globals/locales'; 13 13 import { openModal } from '~/globals/modals'; ··· 63 63 64 64 const shadow = usePostShadow(post); 65 65 66 - const uri = parseAtUri(post().uri); 66 + const uri = parseCanonicalResourceUri(post().uri); 67 67 const authorDid = author().did; 68 68 69 69 const isOurPost = currentAccount && authorDid === currentAccount.did;
+2 -2
src/components/threads/overflow-thread-item.tsx
··· 1 1 import type { OverflowAncestorItem, OverflowDescendantItem } from '~/api/models/post-thread'; 2 - import { parseAtUri } from '~/api/types/at-uri'; 2 + import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 3 3 4 4 import MoreHorizOutlinedIcon from '../icons-central/more-horiz-outline'; 5 5 ··· 20 20 return ( 21 21 <a 22 22 href={(() => { 23 - const uri = parseAtUri(props.item.uri); 23 + const uri = parseCanonicalResourceUri(props.item.uri); 24 24 return `/${uri.repo}/${uri.rkey}`; 25 25 })()} 26 26 class={
+2 -2
src/components/threads/post-thread-item.tsx
··· 9 9 import { ContextContentList } from '~/api/moderation/constants'; 10 10 import { moderatePost } from '~/api/moderation/entities/post'; 11 11 import { precacheProfile } from '~/api/queries-cache/profile-precache'; 12 - import { parseAtUri } from '~/api/types/at-uri'; 12 + import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 13 13 14 14 import { history } from '~/globals/navigation'; 15 15 ··· 54 54 55 55 const shadow = usePostShadow(post); 56 56 57 - const uri = parseAtUri(post().uri); 57 + const uri = parseCanonicalResourceUri(post().uri); 58 58 const authorHref = `/${author().did}`; 59 59 const href = `/${author().did}/${uri.rkey}`; 60 60
+2 -2
src/components/timeline/delete-post-prompt.tsx
··· 3 3 import { useQueryClient } from '@mary/solid-query'; 4 4 5 5 import { updatePostShadow } from '~/api/cache/post-shadow'; 6 - import { parseAtUri } from '~/api/types/at-uri'; 6 + import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 7 7 8 8 import { useAgent } from '~/lib/states/agent'; 9 9 import { useSession } from '~/lib/states/session'; ··· 24 24 const queryClient = useQueryClient(); 25 25 26 26 const onDelete = () => { 27 - const uri = parseAtUri(post.uri); 27 + const uri = parseCanonicalResourceUri(post.uri); 28 28 29 29 const promise = rpc.call('com.atproto.repo.applyWrites', { 30 30 data: {
+3 -3
src/components/timeline/post-feed-item.tsx
··· 9 9 import { ContextContentList } from '~/api/moderation/constants'; 10 10 import { moderatePost } from '~/api/moderation/entities/post'; 11 11 import { precacheProfile } from '~/api/queries-cache/profile-precache'; 12 - import { parseAtUri } from '~/api/types/at-uri'; 12 + import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 13 13 14 14 import { history } from '~/globals/navigation'; 15 15 ··· 36 36 /** Expected to be static */ 37 37 item: UiTimelineItem; 38 38 highlighted?: boolean; 39 - timelineDid?: At.DID; 39 + timelineDid?: At.Did; 40 40 } 41 41 42 42 const PostFeedItem = ({ item, highlighted, timelineDid }: PostFeedItemProps) => { ··· 55 55 56 56 const shadow = usePostShadow(post); 57 57 58 - const uri = parseAtUri(post.uri); 58 + const uri = parseCanonicalResourceUri(post.uri); 59 59 const authorHref = `/${authorDid}`; 60 60 const href = `/${authorDid}/${uri.rkey}`; 61 61
+2 -2
src/components/timeline/post-reply-context.tsx
··· 2 2 3 3 import type { UiTimelineItem } from '~/api/models/timeline'; 4 4 import { createProfileQuery } from '~/api/queries/profile'; 5 - import { parseAtUri } from '~/api/types/at-uri'; 5 + import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 6 6 7 7 import { useSession } from '~/lib/states/session'; 8 8 ··· 43 43 44 44 const raw = (post.record as AppBskyFeedPost.Record).reply?.parent; 45 45 if (raw) { 46 - const did = parseAtUri(raw.uri).repo; 46 + const did = parseCanonicalResourceUri(raw.uri).repo; 47 47 if (did === currentAccount?.did) { 48 48 return <div class="mb-0.5 flex text-de text-contrast-muted">Replying to you</div>; 49 49 }
+2 -2
src/components/timeline/post-share-menu.tsx
··· 1 1 import type { AppBskyFeedDefs, AppBskyFeedPost } from '@atcute/client/lexicons'; 2 2 3 - import { parseAtUri } from '~/api/types/at-uri'; 3 + import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 4 4 import { serializeRichText } from '~/api/utils/richtext-stringify'; 5 5 6 6 import { useModalContext } from '~/globals/modals'; ··· 21 21 const post = props.post; 22 22 23 23 const did = post.author.did; 24 - const { rkey } = parseAtUri(post.uri); 24 + const { rkey } = parseCanonicalResourceUri(post.uri); 25 25 26 26 return ( 27 27 <Menu.Container anchor={props.anchor} placement="bottom-end">
+2 -2
src/components/timeline/revise-post-prompt.tsx
··· 1 1 import type { AppBskyFeedDefs, AppBskyFeedPost, AppBskyFeedThreadgate } from '@atcute/client/lexicons'; 2 2 3 - import { parseAtUri } from '~/api/types/at-uri'; 3 + import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 4 4 import { type MediaEmbed, type RecordEmbed, unwrapEmbed } from '~/api/utils/bluesky/embed'; 5 5 import { serializeRichText } from '~/api/utils/richtext-stringify'; 6 6 ··· 133 133 const ref = embed.record; 134 134 135 135 const uri = ref.uri; 136 - const { collection } = parseAtUri(uri); 136 + const { collection } = parseCanonicalResourceUri(uri); 137 137 138 138 switch (collection) { 139 139 case 'app.bsky.feed.post': {
+1 -1
src/components/timeline/timeline-list.tsx
··· 9 9 10 10 export interface TimelineListProps { 11 11 params: TimelineParams; 12 - timelineDid?: At.DID; 12 + timelineDid?: At.Did; 13 13 } 14 14 15 15 const TimelineList = (props: TimelineListProps) => {
+1 -1
src/lib/atproto/labeler.ts
··· 3 3 import { mergeHeaders } from '@atcute/client/utils/http'; 4 4 5 5 export interface Labeler { 6 - did: At.DID; 6 + did: At.Did; 7 7 redact: boolean; 8 8 } 9 9
+4 -2
src/lib/preferences/account.ts
··· 28 28 29 29 export interface ModerationLabelerPreferences { 30 30 updated: number; 31 - definitions: Record<At.DID, ModerationLabeler>; 31 + definitions: Record<At.Did, ModerationLabeler>; 32 32 } 33 33 34 34 export type SavedFeed = SavedGeneratorFeed | SavedListFeed | SavedSearchFeed; ··· 53 53 } 54 54 55 55 export interface PersistedThreadgate { 56 - allow?: Array<{ type: 'following' } | { type: 'mention' } | { type: 'list'; uri: At.Uri }>; 56 + allow?: Array< 57 + { type: 'following' } | { type: 'follower' } | { type: 'mention' } | { type: 'list'; uri: At.ResourceUri } 58 + >; 57 59 } 58 60 59 61 export interface PersistedPostgate {
+2 -2
src/lib/preferences/sessions.ts
··· 2 2 3 3 export interface SessionPreferenceSchema { 4 4 $version: 1; 5 - active: At.DID | undefined; 5 + active: At.Did | undefined; 6 6 accounts: AccountData[]; 7 7 } 8 8 9 9 export interface AccountData { 10 10 /** Account DID */ 11 - readonly did: At.DID; 11 + readonly did: At.Did; 12 12 profile: AppBskyActorDefs.ProfileViewDetailed; 13 13 }
+4
src/lib/preferences/snippets/composer.ts
··· 11 11 switch (rule.$type) { 12 12 case 'app.bsky.feed.threadgate#followingRule': 13 13 return { type: 'following' }; 14 + case 'app.bsky.feed.threadgate#followerRule': 15 + return { type: 'follower' }; 14 16 case 'app.bsky.feed.threadgate#mentionRule': 15 17 return { type: 'mention' }; 16 18 case 'app.bsky.feed.threadgate#listRule': ··· 26 28 switch (rule.type) { 27 29 case 'following': 28 30 return { $type: 'app.bsky.feed.threadgate#followingRule' }; 31 + case 'follower': 32 + return { $type: 'app.bsky.feed.threadgate#followerRule' }; 29 33 case 'mention': 30 34 return { $type: 'app.bsky.feed.threadgate#mentionRule' }; 31 35 case 'list':
+1 -1
src/lib/states/agent.tsx
··· 14 14 import { useSession } from './session'; 15 15 16 16 export interface AgentContext { 17 - did: At.DID | null; 17 + did: At.Did | null; 18 18 rpc: XRPC; 19 19 handler: OAuthUserAgent | null; 20 20 persister: ReturnType<typeof createQueryPersister>;
+9 -9
src/lib/states/session.tsx
··· 27 27 import { assert } from '../utils/invariant'; 28 28 29 29 export interface CurrentAccountState { 30 - readonly did: At.DID; 30 + readonly did: At.Did; 31 31 readonly data: AccountData; 32 32 readonly preferences: PerAccountPreferenceSchema; 33 33 ··· 40 40 readonly currentAccount: CurrentAccountState | undefined; 41 41 42 42 getAccounts(): AccountData[]; 43 - resumeSession(did: At.DID): Promise<void>; 44 - removeAccount(did: At.DID): Promise<void>; 43 + resumeSession(did: At.Did): Promise<void>; 44 + removeAccount(did: At.Did): Promise<void>; 45 45 46 46 logout(): Promise<void>; 47 47 } ··· 60 60 }; 61 61 62 62 const createAccountState = ( 63 - did: At.DID, 63 + did: At.Did, 64 64 session: OAuthUserAgent | undefined, 65 65 rpc: XRPC, 66 66 ): CurrentAccountState => { ··· 75 75 76 76 const labelers = createMemo((): Labeler[] => { 77 77 return Object.entries(preferences.moderation.labelers).map(([did, info]): Labeler => { 78 - return { did: did as At.DID, redact: info.redact }; 78 + return { did: did as At.Did, redact: info.redact }; 79 79 }); 80 80 }); 81 81 ··· 144 144 getAccounts(): AccountData[] { 145 145 return sessions.accounts; 146 146 }, 147 - async resumeSession(did: At.DID): Promise<void> { 147 + async resumeSession(did: At.Did): Promise<void> { 148 148 const account = sessions.accounts.find((acc) => acc.did === did); 149 149 if (!account) { 150 150 return; ··· 197 197 }); 198 198 }, 199 199 200 - async removeAccount(did: At.DID): Promise<void> { 200 + async removeAccount(did: At.Did): Promise<void> { 201 201 const $state = untrack(state); 202 202 const isLoggedIn = $state !== undefined && $state.did === did; 203 203 ··· 246 246 return session; 247 247 }; 248 248 249 - const createAccountPreferences = (did: At.DID) => { 249 + const createAccountPreferences = (did: At.Did) => { 250 250 const key = `account-${did}`; 251 251 return createReactiveLocalStorage<PerAccountPreferenceSchema>(key, (version, prev) => { 252 252 if (version === 0) { ··· 282 282 }, 283 283 displayName: 'Popular With Friends', 284 284 description: '', 285 - avatar: '', 285 + avatar: '' as At.GenericUri, 286 286 indexedAt: '0000-00-00T00:00:00.000Z', 287 287 }, 288 288 },
+3 -3
src/lib/states/singletons/moderation.ts
··· 39 39 return currentAccount.preferences.moderation; 40 40 }); 41 41 42 - const fetchLabeler = createBatchedFetch<At.DID, At.DID, ModerationLabeler>({ 42 + const fetchLabeler = createBatchedFetch<At.Did, At.Did, ModerationLabeler>({ 43 43 limit: 20, 44 44 timeout: 1, 45 45 idFromQuery: (query) => query, ··· 61 61 const labelerDefs = createQueries(() => { 62 62 return { 63 63 queries: Object.keys(modPreferences().labelers).map((_did) => { 64 - const did = _did as At.DID; 64 + const did = _did as At.Did; 65 65 66 66 return { 67 67 queryKey: ['labeler-definition', did], ··· 76 76 const defs = mapDefined(results, (result) => result.data); 77 77 const fields = Object.fromEntries(defs.map((def) => [def.did, def])); 78 78 79 - return fields as Record<At.DID, ModerationLabeler>; 79 + return fields as Record<At.Did, ModerationLabeler>; 80 80 }, 81 81 }; 82 82 });
+1 -1
src/main.tsx
··· 48 48 const session = useSession(); 49 49 50 50 onMount(() => { 51 - const resumeAccount = async (did: At.DID | undefined) => { 51 + const resumeAccount = async (did: At.Did | undefined) => { 52 52 try { 53 53 if (did) { 54 54 await session.resumeSession(did);
+6 -1
src/views/post-likes.tsx
··· 1 + import type { At } from '@atcute/client/lexicons'; 2 + 1 3 import { createSubjectLikersQuery } from '~/api/queries/subject-likers'; 2 4 import { makeAtUri } from '~/api/types/at-uri'; 3 5 ··· 10 12 import VirtualItem from '~/components/virtual-item'; 11 13 12 14 const PostLikesPage = () => { 13 - const { did, rkey } = useParams(); 15 + const { did, rkey } = useParams<{ 16 + did: At.Did; 17 + rkey: At.RecordKey; 18 + }>(); 14 19 15 20 const uri = makeAtUri(did, 'app.bsky.feed.post', rkey); 16 21 const likers = createSubjectLikersQuery(() => uri);
+6 -1
src/views/post-quotes.tsx
··· 1 + import type { At } from '@atcute/client/lexicons'; 2 + 1 3 import { createPostQuotesQuery } from '~/api/queries/post-quotes'; 2 4 import { makeAtUri } from '~/api/types/at-uri'; 3 5 ··· 9 11 import VirtualItem from '~/components/virtual-item'; 10 12 11 13 const PostQuotesPage = () => { 12 - const { did, rkey } = useParams(); 14 + const { did, rkey } = useParams<{ 15 + did: At.Did; 16 + rkey: At.RecordKey; 17 + }>(); 13 18 14 19 const uri = makeAtUri(did, 'app.bsky.feed.post', rkey); 15 20 const quotes = createPostQuotesQuery(() => uri);
+6 -1
src/views/post-reposts.tsx
··· 1 + import type { At } from '@atcute/client/lexicons'; 2 + 1 3 import { createSubjectRepostersQuery } from '~/api/queries/subject-reposters'; 2 4 import { makeAtUri } from '~/api/types/at-uri'; 3 5 ··· 10 12 import VirtualItem from '~/components/virtual-item'; 11 13 12 14 const PostLikesPage = () => { 13 - const { did, rkey } = useParams(); 15 + const { did, rkey } = useParams<{ 16 + did: At.Did; 17 + rkey: At.RecordKey; 18 + }>(); 14 19 15 20 const uri = makeAtUri(did, 'app.bsky.feed.post', rkey); 16 21 const reposters = createSubjectRepostersQuery(() => uri);
+5 -2
src/views/post-thread.tsx
··· 38 38 import VirtualItem from '~/components/virtual-item'; 39 39 40 40 const PostThreadPage = () => { 41 - const { didOrHandle, rkey } = useParams(); 41 + const { didOrHandle, rkey } = useParams<{ 42 + didOrHandle: At.Identifier; 43 + rkey: At.RecordKey; 44 + }>(); 42 45 43 46 const queryClient = useQueryClient(); 44 47 ··· 102 105 const data = accessor(); 103 106 const type = data.$type; 104 107 105 - let did: At.DID | undefined; 108 + let did: At.Did | undefined; 106 109 107 110 if (type === 'app.bsky.feed.defs#threadViewPost') { 108 111 did = data.post.author.did;
+6 -1
src/views/profile-curation-list.tsx
··· 1 1 import { Match, Switch } from 'solid-js'; 2 2 3 + import type { At } from '@atcute/client/lexicons'; 4 + 3 5 import { createListMetaQuery } from '~/api/queries/list'; 4 6 import { makeAtUri } from '~/api/types/at-uri'; 5 7 ··· 11 13 import TimelineList from '~/components/timeline/timeline-list'; 12 14 13 15 const CurationListPage = () => { 14 - const { did, rkey } = useParams(); 16 + const { did, rkey } = useParams<{ 17 + did: At.Did; 18 + rkey: At.RecordKey; 19 + }>(); 15 20 16 21 const uri = makeAtUri(did, 'app.bsky.graph.list', rkey); 17 22 const meta = createListMetaQuery(() => uri);
+5 -1
src/views/profile-feed.tsx
··· 1 1 import { Match, Show, Switch } from 'solid-js'; 2 2 3 + import type { At } from '@atcute/client/lexicons'; 3 4 import { useQueryClient } from '@mary/solid-query'; 4 5 5 6 import { createFeedMetaQuery } from '~/api/queries/feed'; ··· 23 24 import TimelineList from '~/components/timeline/timeline-list'; 24 25 25 26 const FeedPage = () => { 26 - const { didOrHandle, rkey } = useParams(); 27 + const { didOrHandle, rkey } = useParams<{ 28 + didOrHandle: At.Identifier; 29 + rkey: At.RecordKey; 30 + }>(); 27 31 28 32 const queryClient = useQueryClient(); 29 33
+5 -1
src/views/profile-feeds.tsx
··· 1 + import type { At } from '@atcute/client/lexicons'; 2 + 1 3 import { createProfileQuery } from '~/api/queries/profile'; 2 4 import { createProfileFeedsQuery } from '~/api/queries/profile-feeds'; 3 5 ··· 9 11 import VirtualItem from '~/components/virtual-item'; 10 12 11 13 const ProfileFeedsPage = () => { 12 - const { did } = useParams(); 14 + const { did } = useParams<{ 15 + did: At.Did; 16 + }>(); 13 17 14 18 const feeds = createProfileFeedsQuery(() => did); 15 19 const profile = createProfileQuery(() => did);
+5 -1
src/views/profile-followers.tsx
··· 1 1 import { createMemo } from 'solid-js'; 2 2 3 + import type { At } from '@atcute/client/lexicons'; 4 + 3 5 import { createProfileFollowersQuery } from '~/api/queries/profile-followers'; 4 6 5 7 import { useParams, useTitle } from '~/lib/navigation/router'; ··· 11 13 import VirtualItem from '~/components/virtual-item'; 12 14 13 15 const ProfileFollowersPage = () => { 14 - const { did } = useParams(); 16 + const { did } = useParams<{ 17 + did: At.Did; 18 + }>(); 15 19 16 20 const followers = createProfileFollowersQuery(() => did); 17 21 const subject = createMemo(() => followers.data?.pages[0].subject);
+5 -1
src/views/profile-following.tsx
··· 1 1 import { createMemo } from 'solid-js'; 2 2 3 + import type { At } from '@atcute/client/lexicons'; 4 + 3 5 import { createProfileFollowingQuery } from '~/api/queries/profile-following'; 4 6 5 7 import { useParams, useTitle } from '~/lib/navigation/router'; ··· 11 13 import VirtualItem from '~/components/virtual-item'; 12 14 13 15 const ProfileFollowingPage = () => { 14 - const { did } = useParams(); 16 + const { did } = useParams<{ 17 + did: At.Did; 18 + }>(); 15 19 16 20 const following = createProfileFollowingQuery(() => did); 17 21 const subject = createMemo(() => following.data?.pages[0].subject);
+5 -1
src/views/profile-known-followers.tsx
··· 1 1 import { createMemo } from 'solid-js'; 2 2 3 + import type { At } from '@atcute/client/lexicons'; 4 + 3 5 import { createProfileKnownFollowersQuery } from '~/api/queries/profile-known-followers'; 4 6 5 7 import { useParams, useTitle } from '~/lib/navigation/router'; ··· 11 13 import VirtualItem from '~/components/virtual-item'; 12 14 13 15 const ProfileKnownFollowersPage = () => { 14 - const { did } = useParams(); 16 + const { did } = useParams<{ 17 + did: At.Did; 18 + }>(); 15 19 16 20 const followers = createProfileKnownFollowersQuery(() => did); 17 21 const subject = createMemo(() => followers.data?.pages[0].subject);
+4 -4
src/views/profile-labels.tsx
··· 49 49 const { did } = useParams(); 50 50 const { currentAccount } = useSession(); 51 51 52 - const query = createLabelerMetaQuery(() => did as At.DID); 52 + const query = createLabelerMetaQuery(() => did as At.Did); 53 53 54 54 const config = createMemo(() => { 55 55 if (!currentAccount) { ··· 57 57 } 58 58 59 59 const preferences = currentAccount.preferences; 60 - return preferences.moderation.labelers[did as At.DID]; 60 + return preferences.moderation.labelers[did as At.Did]; 61 61 }); 62 62 63 63 useTitle(() => { ··· 98 98 const preferences = currentAccount!.preferences; 99 99 const labelers = preferences.moderation.labelers; 100 100 101 - labelers[did as At.DID] = { 101 + labelers[did as At.Did] = { 102 102 labels: {}, 103 103 privileged: false, 104 104 redact: false, ··· 140 140 const preferences = currentAccount!.preferences; 141 141 const labelers = preferences.moderation.labelers; 142 142 143 - delete labelers[did as At.DID]; 143 + delete labelers[did as At.Did]; 144 144 }} 145 145 /> 146 146 ));
+5 -1
src/views/profile-list.tsx
··· 1 1 import { Match, Switch } from 'solid-js'; 2 2 3 + import type { At } from '@atcute/client/lexicons'; 3 4 import { useQueryClient } from '@mary/solid-query'; 4 5 5 6 import { createListMetaQuery } from '~/api/queries/list'; ··· 15 16 import * as Page from '~/components/page'; 16 17 17 18 const ListStubPage = () => { 18 - const { didOrHandle, rkey } = useParams(); 19 + const { didOrHandle, rkey } = useParams<{ 20 + didOrHandle: At.Identifier; 21 + rkey: At.RecordKey; 22 + }>(); 19 23 20 24 const queryClient = useQueryClient(); 21 25
+5 -1
src/views/profile-lists.tsx
··· 1 + import type { At } from '@atcute/client/lexicons'; 2 + 1 3 import { createProfileQuery } from '~/api/queries/profile'; 2 4 import { createProfileListsQuery } from '~/api/queries/profile-lists'; 3 5 ··· 8 10 import PagedList from '~/components/paged-list'; 9 11 10 12 const ProfileListsPage = () => { 11 - const { did } = useParams(); 13 + const { did } = useParams<{ 14 + did: At.Did; 15 + }>(); 12 16 13 17 const lists = createProfileListsQuery(() => did); 14 18 const profile = createProfileQuery(() => did);
+6 -3
src/views/profile-moderation-list.tsx
··· 1 1 import { Match, Show, Switch, createMemo } from 'solid-js'; 2 2 3 - import type { AppBskyGraphDefs } from '@atcute/client/lexicons'; 3 + import type { AppBskyGraphDefs, At } from '@atcute/client/lexicons'; 4 4 import { useQueryClient } from '@mary/solid-query'; 5 5 6 6 import { ContextContentMedia } from '~/api/moderation/constants'; ··· 29 29 import VirtualItem from '~/components/virtual-item'; 30 30 31 31 const ProfileModerationListPage = () => { 32 - const { did, rkey } = useParams(); 32 + const { did, rkey } = useParams<{ 33 + did: At.Did; 34 + rkey: At.RecordKey; 35 + }>(); 33 36 34 37 const uri = makeAtUri(did, 'app.bsky.graph.list', rkey); 35 38 const query = createListMetaQuery(() => uri); ··· 160 163 ); 161 164 }; 162 165 163 - const MembersList = ({ uri }: { uri: string }) => { 166 + const MembersList = ({ uri }: { uri: At.ResourceUri }) => { 164 167 const members = createListMembersQuery(() => uri); 165 168 166 169 return (
+5 -1
src/views/profile-search.tsx
··· 1 1 import { createSignal } from 'solid-js'; 2 2 3 + import type { At } from '@atcute/client/lexicons'; 4 + 3 5 import { createProfileQuery } from '~/api/queries/profile'; 4 6 import { isDid } from '~/api/types/identity'; 5 7 ··· 14 16 import SearchSuggestionsView from '~/components/search/search-suggestions-view'; 15 17 16 18 const ProfileSearchPage = () => { 17 - const { didOrHandle } = useParams(); 19 + const { didOrHandle } = useParams<{ 20 + didOrHandle: At.Identifier; 21 + }>(); 18 22 19 23 const [query, setQuery] = createSignal(''); 20 24 const profile = createProfileQuery(() => didOrHandle);
+4 -2
src/views/profile.tsx
··· 1 1 import { Match, Show, Switch, createMemo } from 'solid-js'; 2 2 3 3 import { XRPCError } from '@atcute/client'; 4 - import type { AppBskyActorDefs } from '@atcute/client/lexicons'; 4 + import type { AppBskyActorDefs, At } from '@atcute/client/lexicons'; 5 5 import { useQueryClient } from '@mary/solid-query'; 6 6 7 7 import { useProfileShadow } from '~/api/cache/profile-shadow'; ··· 31 31 import VirtualItem from '~/components/virtual-item'; 32 32 33 33 const ProfilePage = () => { 34 - const { didOrHandle } = useParams(); 34 + const { didOrHandle } = useParams<{ 35 + didOrHandle: At.Identifier; 36 + }>(); 35 37 36 38 const queryClient = useQueryClient(); 37 39 const profile = createProfileQuery(() => didOrHandle);