+7
-7
package.json
+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
+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
+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
+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
+1
-1
src/api/moderation/entities/generic.ts
+5
-5
src/api/moderation/index.ts
+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
+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
+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
+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
+1
-1
src/api/queries-cache/notification-feed.ts
+1
-1
src/api/queries-cache/post-thread.ts
+1
-1
src/api/queries-cache/post-thread.ts
+1
-1
src/api/queries-cache/profile-autocomplete.ts
+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
+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
+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
+1
-1
src/api/queries-cache/timeline.ts
+3
-2
src/api/queries/composer.ts
+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
+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
+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
+1
-1
src/api/queries/labeler.ts
+2
-1
src/api/queries/list-members.ts
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
-3
src/components/composer/embeds/link-embed.tsx
+3
-3
src/components/composer/embeds/link-embed.tsx
···
1
1
import { Match, Switch, onCleanup } from 'solid-js';
2
2
3
-
import type { AppBskyEmbedExternal } from '@atcute/client/lexicons';
3
+
import type { AppBskyEmbedExternal, At } from '@atcute/client/lexicons';
4
4
5
5
import { createLinkMetaQuery } from '~/api/queries/composer';
6
6
···
38
38
{(state) => {
39
39
const meta = state.external;
40
40
41
-
let thumbUrl: string | undefined;
41
+
let thumbUrl: At.GenericUri | undefined;
42
42
if (meta.thumb) {
43
43
const did = currentAccount!.did;
44
44
const cid = meta.thumb.ref.$link;
···
85
85
title: data.title,
86
86
description: data.description,
87
87
uri: data.uri,
88
-
thumb: thumbUrl,
88
+
thumb: thumbUrl as At.GenericUri,
89
89
},
90
90
};
91
91
+3
-2
src/components/composer/gifs/gif-search-dialog.tsx
+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
+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);
+8
-6
src/components/composer/lib/link-detection.ts
+8
-6
src/components/composer/lib/link-detection.ts
···
1
+
import type { At } from '@atcute/client/lexicons';
2
+
1
3
import { makeAtUri } from '~/api/types/at-uri';
2
4
import { safeUrlParse } from '~/api/utils/strings';
3
5
···
15
17
16
18
if (host === 'bsky.app') {
17
19
if ((match = BSKY_POST_LINK_RE.exec(path))) {
18
-
const handleOrDid = match[1];
20
+
const didOrHandle = match[1] as At.Identifier;
19
21
const rkey = match[2];
20
22
21
23
return {
22
24
type: 'quote',
23
-
uri: makeAtUri(handleOrDid, 'app.bsky.feed.post', rkey),
25
+
uri: makeAtUri(didOrHandle, 'app.bsky.feed.post', rkey),
24
26
origin: false,
25
27
};
26
28
}
27
29
28
30
if ((match = BSKY_FEED_LINK_RE.exec(path))) {
29
-
const handleOrDid = match[1];
31
+
const didOrHandle = match[1] as At.Identifier;
30
32
const rkey = match[2];
31
33
32
34
return {
33
35
type: 'feed',
34
-
uri: makeAtUri(handleOrDid, 'app.bsky.feed.generator', rkey),
36
+
uri: makeAtUri(didOrHandle, 'app.bsky.feed.generator', rkey),
35
37
};
36
38
}
37
39
38
40
if ((match = BSKY_LIST_LINK_RE.exec(path))) {
39
-
const handleOrDid = match[1];
41
+
const didOrHandle = match[1] as At.Identifier;
40
42
const rkey = match[2];
41
43
42
44
return {
43
45
type: 'list',
44
-
uri: makeAtUri(handleOrDid, 'app.bsky.graph.list', rkey),
46
+
uri: makeAtUri(didOrHandle, 'app.bsky.graph.list', rkey),
45
47
};
46
48
}
47
49
}
+2
-2
src/components/embeds/embed.tsx
+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
+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
+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
+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
+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
+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
+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/lists/lib/utils.ts
+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
+1
-1
src/components/main/sign-in-dialog.tsx
+4
-4
src/components/moderation/block-account-prompt.tsx
+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
+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
+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
+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
+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
+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
+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
+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
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/revise-post-prompt.tsx
+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
+1
-1
src/components/timeline/timeline-list.tsx
+1
-1
src/lib/atproto/labeler.ts
+1
-1
src/lib/atproto/labeler.ts
+4
-2
src/lib/preferences/account.ts
+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
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
+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
+1
-1
src/lib/states/agent.tsx
+9
-9
src/lib/states/session.tsx
+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
+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
+1
-1
src/main.tsx
+6
-1
src/views/post-likes.tsx
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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);