@atproto/api 0.18.13 → 0.18.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/dist/agent.d.ts +9 -0
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +35 -0
- package/dist/agent.js.map +1 -1
- package/dist/client/lexicons.d.ts +38 -2
- package/dist/client/lexicons.d.ts.map +1 -1
- package/dist/client/lexicons.js +19 -0
- package/dist/client/lexicons.js.map +1 -1
- package/dist/client/types/app/bsky/actor/defs.d.ts +11 -1
- package/dist/client/types/app/bsky/actor/defs.d.ts.map +1 -1
- package/dist/client/types/app/bsky/actor/defs.js +9 -0
- package/dist/client/types/app/bsky/actor/defs.js.map +1 -1
- package/dist/predicate.d.ts +1 -0
- package/dist/predicate.d.ts.map +1 -1
- package/dist/predicate.js +2 -1
- package/dist/predicate.js.map +1 -1
- package/dist/rich-text/detection.d.ts.map +1 -1
- package/dist/rich-text/detection.js +25 -0
- package/dist/rich-text/detection.js.map +1 -1
- package/dist/rich-text/util.d.ts +1 -0
- package/dist/rich-text/util.d.ts.map +1 -1
- package/dist/rich-text/util.js +2 -1
- package/dist/rich-text/util.js.map +1 -1
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
- package/src/agent.ts +44 -0
- package/src/client/lexicons.ts +20 -0
- package/src/client/types/app/bsky/actor/defs.ts +20 -0
- package/src/predicate.ts +3 -0
- package/src/rich-text/detection.ts +29 -0
- package/src/rich-text/util.ts +3 -0
- package/src/types.ts +4 -0
- package/tests/atp-agent.test.ts +180 -0
- package/tests/moderation-prefs.test.ts +16 -0
- package/tests/rich-text-detection.test.ts +68 -0
|
@@ -269,6 +269,7 @@ export type Preferences = (
|
|
|
269
269
|
| $Typed<LabelersPref>
|
|
270
270
|
| $Typed<PostInteractionSettingsPref>
|
|
271
271
|
| $Typed<VerificationPrefs>
|
|
272
|
+
| $Typed<LiveEventPreferences>
|
|
272
273
|
| { $type: string }
|
|
273
274
|
)[]
|
|
274
275
|
|
|
@@ -618,6 +619,25 @@ export function validateVerificationPrefs<V>(v: V) {
|
|
|
618
619
|
return validate<VerificationPrefs & V>(v, id, hashVerificationPrefs)
|
|
619
620
|
}
|
|
620
621
|
|
|
622
|
+
/** Preferences for live events. */
|
|
623
|
+
export interface LiveEventPreferences {
|
|
624
|
+
$type?: 'app.bsky.actor.defs#liveEventPreferences'
|
|
625
|
+
/** A list of feed IDs that the user has hidden from live events. */
|
|
626
|
+
hiddenFeedIds?: string[]
|
|
627
|
+
/** Whether to hide all feeds from live events. */
|
|
628
|
+
hideAllFeeds: boolean
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
const hashLiveEventPreferences = 'liveEventPreferences'
|
|
632
|
+
|
|
633
|
+
export function isLiveEventPreferences<V>(v: V) {
|
|
634
|
+
return is$typed(v, id, hashLiveEventPreferences)
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
export function validateLiveEventPreferences<V>(v: V) {
|
|
638
|
+
return validate<LiveEventPreferences & V>(v, id, hashLiveEventPreferences)
|
|
639
|
+
}
|
|
640
|
+
|
|
621
641
|
/** Default post interaction settings for the account. These values should be applied as default values when creating new posts. These refs should mirror the threadgate and postgate records exactly. */
|
|
622
642
|
export interface PostInteractionSettingsPref {
|
|
623
643
|
$type?: 'app.bsky.actor.defs#postInteractionSettingsPref'
|
package/src/predicate.ts
CHANGED
|
@@ -47,3 +47,6 @@ export const isValidThreadViewPref = asPredicate(
|
|
|
47
47
|
export const isValidVerificationPrefs = asPredicate(
|
|
48
48
|
AppBskyActorDefs.validateVerificationPrefs,
|
|
49
49
|
)
|
|
50
|
+
export const isValidLiveEventPreferences = asPredicate(
|
|
51
|
+
AppBskyActorDefs.validateLiveEventPreferences,
|
|
52
|
+
)
|
|
@@ -2,6 +2,7 @@ import TLDs from 'tlds'
|
|
|
2
2
|
import { AppBskyRichtextFacet } from '../client'
|
|
3
3
|
import { UnicodeString } from './unicode'
|
|
4
4
|
import {
|
|
5
|
+
CASHTAG_REGEX,
|
|
5
6
|
MENTION_REGEX,
|
|
6
7
|
TAG_REGEX,
|
|
7
8
|
TRAILING_PUNCTUATION_REGEX,
|
|
@@ -103,6 +104,34 @@ export function detectFacets(text: UnicodeString): Facet[] | undefined {
|
|
|
103
104
|
})
|
|
104
105
|
}
|
|
105
106
|
}
|
|
107
|
+
{
|
|
108
|
+
// cashtags
|
|
109
|
+
const re = CASHTAG_REGEX
|
|
110
|
+
while ((match = re.exec(text.utf16))) {
|
|
111
|
+
const leading = match[1]
|
|
112
|
+
let ticker = match[2]
|
|
113
|
+
|
|
114
|
+
if (!ticker) continue
|
|
115
|
+
|
|
116
|
+
// Normalize to uppercase
|
|
117
|
+
ticker = ticker.toUpperCase()
|
|
118
|
+
|
|
119
|
+
const index = match.index + leading.length
|
|
120
|
+
|
|
121
|
+
facets.push({
|
|
122
|
+
index: {
|
|
123
|
+
byteStart: text.utf16IndexToUtf8Index(index),
|
|
124
|
+
byteEnd: text.utf16IndexToUtf8Index(index + 1 + ticker.length), // +1 for $
|
|
125
|
+
},
|
|
126
|
+
features: [
|
|
127
|
+
{
|
|
128
|
+
$type: 'app.bsky.richtext.facet#tag',
|
|
129
|
+
tag: '$' + ticker, // Store with $ prefix
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
}
|
|
106
135
|
return facets.length > 0 ? facets : undefined
|
|
107
136
|
}
|
|
108
137
|
|
package/src/rich-text/util.ts
CHANGED
|
@@ -10,3 +10,6 @@ export const TRAILING_PUNCTUATION_REGEX = /\p{P}+$/gu
|
|
|
10
10
|
export const TAG_REGEX =
|
|
11
11
|
// eslint-disable-next-line no-misleading-character-class
|
|
12
12
|
/(^|\s)[##]((?!\ufe0f)[^\s\u00AD\u2060\u200A\u200B\u200C\u200D\u20e2]*[^\d\s\p{P}\u00AD\u2060\u200A\u200B\u200C\u200D\u20e2]+[^\s\u00AD\u2060\u200A\u200B\u200C\u200D\u20e2]*)?/gu
|
|
13
|
+
|
|
14
|
+
export const CASHTAG_REGEX =
|
|
15
|
+
/(^|\s|\()\$([A-Za-z][A-Za-z0-9]{0,4})(?=\s|$|[.,;:!?)"'\u2019])/gu
|
package/src/types.ts
CHANGED
|
@@ -158,4 +158,8 @@ export interface BskyPreferences {
|
|
|
158
158
|
}
|
|
159
159
|
postInteractionSettings: AppBskyActorDefs.PostInteractionSettingsPref
|
|
160
160
|
verificationPrefs: AppBskyActorDefs.VerificationPrefs
|
|
161
|
+
liveEventPreferences: {
|
|
162
|
+
hiddenFeedIds: string[]
|
|
163
|
+
hideAllFeeds: boolean
|
|
164
|
+
}
|
|
161
165
|
}
|
package/tests/atp-agent.test.ts
CHANGED
|
@@ -285,6 +285,10 @@ describe('agent', () => {
|
|
|
285
285
|
verificationPrefs: {
|
|
286
286
|
hideBadges: false,
|
|
287
287
|
},
|
|
288
|
+
liveEventPreferences: {
|
|
289
|
+
hiddenFeedIds: [],
|
|
290
|
+
hideAllFeeds: false,
|
|
291
|
+
},
|
|
288
292
|
})
|
|
289
293
|
|
|
290
294
|
await agent.setAdultContentEnabled(true)
|
|
@@ -333,6 +337,10 @@ describe('agent', () => {
|
|
|
333
337
|
verificationPrefs: {
|
|
334
338
|
hideBadges: false,
|
|
335
339
|
},
|
|
340
|
+
liveEventPreferences: {
|
|
341
|
+
hiddenFeedIds: [],
|
|
342
|
+
hideAllFeeds: false,
|
|
343
|
+
},
|
|
336
344
|
})
|
|
337
345
|
|
|
338
346
|
await agent.setAdultContentEnabled(false)
|
|
@@ -381,6 +389,10 @@ describe('agent', () => {
|
|
|
381
389
|
verificationPrefs: {
|
|
382
390
|
hideBadges: false,
|
|
383
391
|
},
|
|
392
|
+
liveEventPreferences: {
|
|
393
|
+
hiddenFeedIds: [],
|
|
394
|
+
hideAllFeeds: false,
|
|
395
|
+
},
|
|
384
396
|
})
|
|
385
397
|
|
|
386
398
|
await agent.setContentLabelPref('misinfo', 'hide')
|
|
@@ -429,6 +441,10 @@ describe('agent', () => {
|
|
|
429
441
|
verificationPrefs: {
|
|
430
442
|
hideBadges: false,
|
|
431
443
|
},
|
|
444
|
+
liveEventPreferences: {
|
|
445
|
+
hiddenFeedIds: [],
|
|
446
|
+
hideAllFeeds: false,
|
|
447
|
+
},
|
|
432
448
|
})
|
|
433
449
|
|
|
434
450
|
await agent.setContentLabelPref('spam', 'ignore')
|
|
@@ -481,6 +497,10 @@ describe('agent', () => {
|
|
|
481
497
|
verificationPrefs: {
|
|
482
498
|
hideBadges: false,
|
|
483
499
|
},
|
|
500
|
+
liveEventPreferences: {
|
|
501
|
+
hiddenFeedIds: [],
|
|
502
|
+
hideAllFeeds: false,
|
|
503
|
+
},
|
|
484
504
|
})
|
|
485
505
|
|
|
486
506
|
await agent.addSavedFeed('at://bob.com/app.bsky.feed.generator/fake')
|
|
@@ -536,6 +556,10 @@ describe('agent', () => {
|
|
|
536
556
|
verificationPrefs: {
|
|
537
557
|
hideBadges: false,
|
|
538
558
|
},
|
|
559
|
+
liveEventPreferences: {
|
|
560
|
+
hiddenFeedIds: [],
|
|
561
|
+
hideAllFeeds: false,
|
|
562
|
+
},
|
|
539
563
|
})
|
|
540
564
|
|
|
541
565
|
await agent.addPinnedFeed('at://bob.com/app.bsky.feed.generator/fake')
|
|
@@ -591,6 +615,10 @@ describe('agent', () => {
|
|
|
591
615
|
verificationPrefs: {
|
|
592
616
|
hideBadges: false,
|
|
593
617
|
},
|
|
618
|
+
liveEventPreferences: {
|
|
619
|
+
hiddenFeedIds: [],
|
|
620
|
+
hideAllFeeds: false,
|
|
621
|
+
},
|
|
594
622
|
})
|
|
595
623
|
|
|
596
624
|
await agent.removePinnedFeed('at://bob.com/app.bsky.feed.generator/fake')
|
|
@@ -646,6 +674,10 @@ describe('agent', () => {
|
|
|
646
674
|
verificationPrefs: {
|
|
647
675
|
hideBadges: false,
|
|
648
676
|
},
|
|
677
|
+
liveEventPreferences: {
|
|
678
|
+
hiddenFeedIds: [],
|
|
679
|
+
hideAllFeeds: false,
|
|
680
|
+
},
|
|
649
681
|
})
|
|
650
682
|
|
|
651
683
|
await agent.removeSavedFeed('at://bob.com/app.bsky.feed.generator/fake')
|
|
@@ -701,6 +733,10 @@ describe('agent', () => {
|
|
|
701
733
|
verificationPrefs: {
|
|
702
734
|
hideBadges: false,
|
|
703
735
|
},
|
|
736
|
+
liveEventPreferences: {
|
|
737
|
+
hiddenFeedIds: [],
|
|
738
|
+
hideAllFeeds: false,
|
|
739
|
+
},
|
|
704
740
|
})
|
|
705
741
|
|
|
706
742
|
await agent.addPinnedFeed('at://bob.com/app.bsky.feed.generator/fake')
|
|
@@ -756,6 +792,10 @@ describe('agent', () => {
|
|
|
756
792
|
verificationPrefs: {
|
|
757
793
|
hideBadges: false,
|
|
758
794
|
},
|
|
795
|
+
liveEventPreferences: {
|
|
796
|
+
hiddenFeedIds: [],
|
|
797
|
+
hideAllFeeds: false,
|
|
798
|
+
},
|
|
759
799
|
})
|
|
760
800
|
|
|
761
801
|
await agent.addPinnedFeed('at://bob.com/app.bsky.feed.generator/fake2')
|
|
@@ -817,6 +857,10 @@ describe('agent', () => {
|
|
|
817
857
|
verificationPrefs: {
|
|
818
858
|
hideBadges: false,
|
|
819
859
|
},
|
|
860
|
+
liveEventPreferences: {
|
|
861
|
+
hiddenFeedIds: [],
|
|
862
|
+
hideAllFeeds: false,
|
|
863
|
+
},
|
|
820
864
|
})
|
|
821
865
|
|
|
822
866
|
await agent.removeSavedFeed('at://bob.com/app.bsky.feed.generator/fake')
|
|
@@ -872,6 +916,10 @@ describe('agent', () => {
|
|
|
872
916
|
verificationPrefs: {
|
|
873
917
|
hideBadges: false,
|
|
874
918
|
},
|
|
919
|
+
liveEventPreferences: {
|
|
920
|
+
hiddenFeedIds: [],
|
|
921
|
+
hideAllFeeds: false,
|
|
922
|
+
},
|
|
875
923
|
})
|
|
876
924
|
|
|
877
925
|
await agent.setPersonalDetails({ birthDate: '2023-09-11T18:05:42.556Z' })
|
|
@@ -932,6 +980,10 @@ describe('agent', () => {
|
|
|
932
980
|
verificationPrefs: {
|
|
933
981
|
hideBadges: false,
|
|
934
982
|
},
|
|
983
|
+
liveEventPreferences: {
|
|
984
|
+
hiddenFeedIds: [],
|
|
985
|
+
hideAllFeeds: false,
|
|
986
|
+
},
|
|
935
987
|
})
|
|
936
988
|
|
|
937
989
|
await agent.setFeedViewPrefs('home', { hideReplies: true })
|
|
@@ -992,6 +1044,10 @@ describe('agent', () => {
|
|
|
992
1044
|
verificationPrefs: {
|
|
993
1045
|
hideBadges: false,
|
|
994
1046
|
},
|
|
1047
|
+
liveEventPreferences: {
|
|
1048
|
+
hiddenFeedIds: [],
|
|
1049
|
+
hideAllFeeds: false,
|
|
1050
|
+
},
|
|
995
1051
|
})
|
|
996
1052
|
|
|
997
1053
|
await agent.setFeedViewPrefs('home', { hideReplies: false })
|
|
@@ -1052,6 +1108,10 @@ describe('agent', () => {
|
|
|
1052
1108
|
verificationPrefs: {
|
|
1053
1109
|
hideBadges: false,
|
|
1054
1110
|
},
|
|
1111
|
+
liveEventPreferences: {
|
|
1112
|
+
hiddenFeedIds: [],
|
|
1113
|
+
hideAllFeeds: false,
|
|
1114
|
+
},
|
|
1055
1115
|
})
|
|
1056
1116
|
|
|
1057
1117
|
await agent.setFeedViewPrefs('other', { hideReplies: true })
|
|
@@ -1119,6 +1179,10 @@ describe('agent', () => {
|
|
|
1119
1179
|
verificationPrefs: {
|
|
1120
1180
|
hideBadges: false,
|
|
1121
1181
|
},
|
|
1182
|
+
liveEventPreferences: {
|
|
1183
|
+
hiddenFeedIds: [],
|
|
1184
|
+
hideAllFeeds: false,
|
|
1185
|
+
},
|
|
1122
1186
|
})
|
|
1123
1187
|
|
|
1124
1188
|
await agent.setThreadViewPrefs({ sort: 'random' })
|
|
@@ -1186,6 +1250,10 @@ describe('agent', () => {
|
|
|
1186
1250
|
verificationPrefs: {
|
|
1187
1251
|
hideBadges: false,
|
|
1188
1252
|
},
|
|
1253
|
+
liveEventPreferences: {
|
|
1254
|
+
hiddenFeedIds: [],
|
|
1255
|
+
hideAllFeeds: false,
|
|
1256
|
+
},
|
|
1189
1257
|
})
|
|
1190
1258
|
|
|
1191
1259
|
await agent.setThreadViewPrefs({ sort: 'oldest' })
|
|
@@ -1253,6 +1321,10 @@ describe('agent', () => {
|
|
|
1253
1321
|
verificationPrefs: {
|
|
1254
1322
|
hideBadges: false,
|
|
1255
1323
|
},
|
|
1324
|
+
liveEventPreferences: {
|
|
1325
|
+
hiddenFeedIds: [],
|
|
1326
|
+
hideAllFeeds: false,
|
|
1327
|
+
},
|
|
1256
1328
|
})
|
|
1257
1329
|
|
|
1258
1330
|
await agent.setInterestsPref({ tags: ['foo', 'bar'] })
|
|
@@ -1320,6 +1392,10 @@ describe('agent', () => {
|
|
|
1320
1392
|
verificationPrefs: {
|
|
1321
1393
|
hideBadges: false,
|
|
1322
1394
|
},
|
|
1395
|
+
liveEventPreferences: {
|
|
1396
|
+
hiddenFeedIds: [],
|
|
1397
|
+
hideAllFeeds: false,
|
|
1398
|
+
},
|
|
1323
1399
|
})
|
|
1324
1400
|
})
|
|
1325
1401
|
|
|
@@ -1518,6 +1594,10 @@ describe('agent', () => {
|
|
|
1518
1594
|
verificationPrefs: {
|
|
1519
1595
|
hideBadges: false,
|
|
1520
1596
|
},
|
|
1597
|
+
liveEventPreferences: {
|
|
1598
|
+
hiddenFeedIds: [],
|
|
1599
|
+
hideAllFeeds: false,
|
|
1600
|
+
},
|
|
1521
1601
|
})
|
|
1522
1602
|
|
|
1523
1603
|
await agent.setAdultContentEnabled(false)
|
|
@@ -1587,6 +1667,10 @@ describe('agent', () => {
|
|
|
1587
1667
|
verificationPrefs: {
|
|
1588
1668
|
hideBadges: false,
|
|
1589
1669
|
},
|
|
1670
|
+
liveEventPreferences: {
|
|
1671
|
+
hiddenFeedIds: [],
|
|
1672
|
+
hideAllFeeds: false,
|
|
1673
|
+
},
|
|
1590
1674
|
})
|
|
1591
1675
|
|
|
1592
1676
|
await agent.setContentLabelPref('porn', 'ignore')
|
|
@@ -1657,6 +1741,10 @@ describe('agent', () => {
|
|
|
1657
1741
|
verificationPrefs: {
|
|
1658
1742
|
hideBadges: false,
|
|
1659
1743
|
},
|
|
1744
|
+
liveEventPreferences: {
|
|
1745
|
+
hiddenFeedIds: [],
|
|
1746
|
+
hideAllFeeds: false,
|
|
1747
|
+
},
|
|
1660
1748
|
})
|
|
1661
1749
|
|
|
1662
1750
|
await agent.removeLabeler('did:plc:other')
|
|
@@ -1723,6 +1811,10 @@ describe('agent', () => {
|
|
|
1723
1811
|
verificationPrefs: {
|
|
1724
1812
|
hideBadges: false,
|
|
1725
1813
|
},
|
|
1814
|
+
liveEventPreferences: {
|
|
1815
|
+
hiddenFeedIds: [],
|
|
1816
|
+
hideAllFeeds: false,
|
|
1817
|
+
},
|
|
1726
1818
|
})
|
|
1727
1819
|
|
|
1728
1820
|
await agent.addPinnedFeed('at://bob.com/app.bsky.feed.generator/fake')
|
|
@@ -1789,6 +1881,10 @@ describe('agent', () => {
|
|
|
1789
1881
|
verificationPrefs: {
|
|
1790
1882
|
hideBadges: false,
|
|
1791
1883
|
},
|
|
1884
|
+
liveEventPreferences: {
|
|
1885
|
+
hiddenFeedIds: [],
|
|
1886
|
+
hideAllFeeds: false,
|
|
1887
|
+
},
|
|
1792
1888
|
})
|
|
1793
1889
|
|
|
1794
1890
|
await agent.setPersonalDetails({ birthDate: '2023-09-11T18:05:42.556Z' })
|
|
@@ -1855,6 +1951,10 @@ describe('agent', () => {
|
|
|
1855
1951
|
verificationPrefs: {
|
|
1856
1952
|
hideBadges: false,
|
|
1857
1953
|
},
|
|
1954
|
+
liveEventPreferences: {
|
|
1955
|
+
hiddenFeedIds: [],
|
|
1956
|
+
hideAllFeeds: false,
|
|
1957
|
+
},
|
|
1858
1958
|
})
|
|
1859
1959
|
|
|
1860
1960
|
await agent.setFeedViewPrefs('home', {
|
|
@@ -1932,6 +2032,10 @@ describe('agent', () => {
|
|
|
1932
2032
|
verificationPrefs: {
|
|
1933
2033
|
hideBadges: false,
|
|
1934
2034
|
},
|
|
2035
|
+
liveEventPreferences: {
|
|
2036
|
+
hiddenFeedIds: [],
|
|
2037
|
+
hideAllFeeds: false,
|
|
2038
|
+
},
|
|
1935
2039
|
})
|
|
1936
2040
|
|
|
1937
2041
|
const res = await agent.app.bsky.actor.getPreferences()
|
|
@@ -3676,6 +3780,82 @@ describe('agent', () => {
|
|
|
3676
3780
|
})
|
|
3677
3781
|
})
|
|
3678
3782
|
|
|
3783
|
+
describe('updateLiveEventPreferences', () => {
|
|
3784
|
+
let agent: AtpAgent
|
|
3785
|
+
|
|
3786
|
+
beforeAll(async () => {
|
|
3787
|
+
agent = new AtpAgent({ service: network.pds.url })
|
|
3788
|
+
|
|
3789
|
+
await agent.createAccount({
|
|
3790
|
+
handle: 'live-event-prefs.test',
|
|
3791
|
+
email: 'live-event-prefs@test.com',
|
|
3792
|
+
password: 'password',
|
|
3793
|
+
})
|
|
3794
|
+
})
|
|
3795
|
+
|
|
3796
|
+
it('default state', async () => {
|
|
3797
|
+
const prefs = await agent.getPreferences()
|
|
3798
|
+
expect(prefs.liveEventPreferences).toEqual({
|
|
3799
|
+
hiddenFeedIds: [],
|
|
3800
|
+
hideAllFeeds: false,
|
|
3801
|
+
})
|
|
3802
|
+
})
|
|
3803
|
+
|
|
3804
|
+
it('hideFeed adds a feed id', async () => {
|
|
3805
|
+
await agent.updateLiveEventPreferences({
|
|
3806
|
+
type: 'hideFeed',
|
|
3807
|
+
id: 'feed1',
|
|
3808
|
+
})
|
|
3809
|
+
const prefs = await agent.getPreferences()
|
|
3810
|
+
expect(prefs.liveEventPreferences).toEqual({
|
|
3811
|
+
hiddenFeedIds: ['feed1'],
|
|
3812
|
+
hideAllFeeds: false,
|
|
3813
|
+
})
|
|
3814
|
+
})
|
|
3815
|
+
|
|
3816
|
+
it('hideFeed adds another feed id', async () => {
|
|
3817
|
+
await agent.updateLiveEventPreferences({
|
|
3818
|
+
type: 'hideFeed',
|
|
3819
|
+
id: 'feed2',
|
|
3820
|
+
})
|
|
3821
|
+
const prefs = await agent.getPreferences()
|
|
3822
|
+
expect(prefs.liveEventPreferences).toEqual({
|
|
3823
|
+
hiddenFeedIds: ['feed1', 'feed2'],
|
|
3824
|
+
hideAllFeeds: false,
|
|
3825
|
+
})
|
|
3826
|
+
})
|
|
3827
|
+
|
|
3828
|
+
it('unhideFeed removes a feed id', async () => {
|
|
3829
|
+
await agent.updateLiveEventPreferences({
|
|
3830
|
+
type: 'unhideFeed',
|
|
3831
|
+
id: 'feed1',
|
|
3832
|
+
})
|
|
3833
|
+
const prefs = await agent.getPreferences()
|
|
3834
|
+
expect(prefs.liveEventPreferences).toEqual({
|
|
3835
|
+
hiddenFeedIds: ['feed2'],
|
|
3836
|
+
hideAllFeeds: false,
|
|
3837
|
+
})
|
|
3838
|
+
})
|
|
3839
|
+
|
|
3840
|
+
it('toggleHideAllFeeds toggles the flag', async () => {
|
|
3841
|
+
await agent.updateLiveEventPreferences({ type: 'toggleHideAllFeeds' })
|
|
3842
|
+
const prefs = await agent.getPreferences()
|
|
3843
|
+
expect(prefs.liveEventPreferences).toEqual({
|
|
3844
|
+
hiddenFeedIds: ['feed2'],
|
|
3845
|
+
hideAllFeeds: true,
|
|
3846
|
+
})
|
|
3847
|
+
})
|
|
3848
|
+
|
|
3849
|
+
it('toggleHideAllFeeds toggles back', async () => {
|
|
3850
|
+
await agent.updateLiveEventPreferences({ type: 'toggleHideAllFeeds' })
|
|
3851
|
+
const prefs = await agent.getPreferences()
|
|
3852
|
+
expect(prefs.liveEventPreferences).toEqual({
|
|
3853
|
+
hiddenFeedIds: ['feed2'],
|
|
3854
|
+
hideAllFeeds: false,
|
|
3855
|
+
})
|
|
3856
|
+
})
|
|
3857
|
+
})
|
|
3858
|
+
|
|
3679
3859
|
// end
|
|
3680
3860
|
})
|
|
3681
3861
|
})
|
|
@@ -93,6 +93,10 @@ describe('agent', () => {
|
|
|
93
93
|
verificationPrefs: {
|
|
94
94
|
hideBadges: false,
|
|
95
95
|
},
|
|
96
|
+
liveEventPreferences: {
|
|
97
|
+
hiddenFeedIds: [],
|
|
98
|
+
hideAllFeeds: false,
|
|
99
|
+
},
|
|
96
100
|
})
|
|
97
101
|
})
|
|
98
102
|
|
|
@@ -149,6 +153,10 @@ describe('agent', () => {
|
|
|
149
153
|
verificationPrefs: {
|
|
150
154
|
hideBadges: false,
|
|
151
155
|
},
|
|
156
|
+
liveEventPreferences: {
|
|
157
|
+
hiddenFeedIds: [],
|
|
158
|
+
hideAllFeeds: false,
|
|
159
|
+
},
|
|
152
160
|
})
|
|
153
161
|
expect(agent.labelers).toStrictEqual(['did:plc:other'])
|
|
154
162
|
|
|
@@ -190,6 +198,10 @@ describe('agent', () => {
|
|
|
190
198
|
verificationPrefs: {
|
|
191
199
|
hideBadges: false,
|
|
192
200
|
},
|
|
201
|
+
liveEventPreferences: {
|
|
202
|
+
hiddenFeedIds: [],
|
|
203
|
+
hideAllFeeds: false,
|
|
204
|
+
},
|
|
193
205
|
})
|
|
194
206
|
expect(agent.labelers).toStrictEqual([])
|
|
195
207
|
})
|
|
@@ -253,6 +265,10 @@ describe('agent', () => {
|
|
|
253
265
|
verificationPrefs: {
|
|
254
266
|
hideBadges: false,
|
|
255
267
|
},
|
|
268
|
+
liveEventPreferences: {
|
|
269
|
+
hiddenFeedIds: [],
|
|
270
|
+
hideAllFeeds: false,
|
|
271
|
+
},
|
|
256
272
|
})
|
|
257
273
|
})
|
|
258
274
|
|
|
@@ -371,6 +371,74 @@ describe('detectFacets', () => {
|
|
|
371
371
|
expect(detectedIndices).toEqual(indices)
|
|
372
372
|
})
|
|
373
373
|
})
|
|
374
|
+
|
|
375
|
+
describe('correctly detects cashtags inline', () => {
|
|
376
|
+
const inputs: [
|
|
377
|
+
string,
|
|
378
|
+
string[],
|
|
379
|
+
{ byteStart: number; byteEnd: number }[],
|
|
380
|
+
][] = [
|
|
381
|
+
['$AAPL', ['$AAPL'], [{ byteStart: 0, byteEnd: 5 }]],
|
|
382
|
+
['$aapl', ['$AAPL'], [{ byteStart: 0, byteEnd: 5 }]], // normalized to uppercase
|
|
383
|
+
['$A', ['$A'], [{ byteStart: 0, byteEnd: 2 }]],
|
|
384
|
+
['$a', ['$A'], [{ byteStart: 0, byteEnd: 2 }]], // single char normalized
|
|
385
|
+
[
|
|
386
|
+
'$BTC $ETH',
|
|
387
|
+
['$BTC', '$ETH'],
|
|
388
|
+
[
|
|
389
|
+
{ byteStart: 0, byteEnd: 4 },
|
|
390
|
+
{ byteStart: 5, byteEnd: 9 },
|
|
391
|
+
],
|
|
392
|
+
],
|
|
393
|
+
['$100', [], []], // starts with digit - not a cashtag
|
|
394
|
+
['$GOOGL', ['$GOOGL'], [{ byteStart: 0, byteEnd: 6 }]], // 5 chars - max length
|
|
395
|
+
['$TOOLONG', [], []], // >5 chars
|
|
396
|
+
['check $LEGO now', ['$LEGO'], [{ byteStart: 6, byteEnd: 11 }]],
|
|
397
|
+
['($GOOG)', ['$GOOG'], [{ byteStart: 1, byteEnd: 6 }]],
|
|
398
|
+
['$AAPL.', ['$AAPL'], [{ byteStart: 0, byteEnd: 5 }]], // trailing punctuation
|
|
399
|
+
[
|
|
400
|
+
'$AAPL, $MSFT!',
|
|
401
|
+
['$AAPL', '$MSFT'],
|
|
402
|
+
[
|
|
403
|
+
{ byteStart: 0, byteEnd: 5 },
|
|
404
|
+
{ byteStart: 7, byteEnd: 12 },
|
|
405
|
+
],
|
|
406
|
+
],
|
|
407
|
+
['no$SPACE', [], []], // must have leading space or start
|
|
408
|
+
['$', [], []], // just dollar sign
|
|
409
|
+
['$ AAPL', [], []], // space after $
|
|
410
|
+
['$123ABC', [], []], // starts with digit
|
|
411
|
+
['$ABC12', ['$ABC12'], [{ byteStart: 0, byteEnd: 6 }]], // digits after letters OK (5 chars)
|
|
412
|
+
['$ABC123', [], []], // 6 chars - too long
|
|
413
|
+
]
|
|
414
|
+
|
|
415
|
+
it.each(inputs)('%s', (input, tags, indices) => {
|
|
416
|
+
const rt = new RichText({ text: input })
|
|
417
|
+
rt.detectFacetsWithoutResolution()
|
|
418
|
+
|
|
419
|
+
const detectedTags: string[] = []
|
|
420
|
+
const detectedIndices: { byteStart: number; byteEnd: number }[] = []
|
|
421
|
+
|
|
422
|
+
for (const { facet } of rt.segments()) {
|
|
423
|
+
if (!facet) continue
|
|
424
|
+
for (const feature of facet.features) {
|
|
425
|
+
if (isTag(feature) && feature.tag.startsWith('$')) {
|
|
426
|
+
detectedTags.push(feature.tag)
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
if (
|
|
430
|
+
facet.features.some(
|
|
431
|
+
(f) => isTag(f) && (f as any).tag?.startsWith('$'),
|
|
432
|
+
)
|
|
433
|
+
) {
|
|
434
|
+
detectedIndices.push(facet.index)
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
expect(detectedTags).toEqual(tags)
|
|
439
|
+
expect(detectedIndices).toEqual(indices)
|
|
440
|
+
})
|
|
441
|
+
})
|
|
374
442
|
})
|
|
375
443
|
|
|
376
444
|
function segmentToOutput(segment: RichTextSegment): string[] {
|