@atcute/bluesky-moderation 1.0.1

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.
Files changed (55) hide show
  1. package/LICENSE +17 -0
  2. package/README.md +174 -0
  3. package/dist/behaviors.d.ts +41 -0
  4. package/dist/behaviors.js +56 -0
  5. package/dist/behaviors.js.map +1 -0
  6. package/dist/decision.d.ts +85 -0
  7. package/dist/decision.js +214 -0
  8. package/dist/decision.js.map +1 -0
  9. package/dist/index.d.ts +12 -0
  10. package/dist/index.js +13 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/internal/keyword-filter.d.ts +8 -0
  13. package/dist/internal/keyword-filter.js +27 -0
  14. package/dist/internal/keyword-filter.js.map +1 -0
  15. package/dist/keyword-filter.d.ts +26 -0
  16. package/dist/keyword-filter.js +61 -0
  17. package/dist/keyword-filter.js.map +1 -0
  18. package/dist/label.d.ts +73 -0
  19. package/dist/label.js +286 -0
  20. package/dist/label.js.map +1 -0
  21. package/dist/subjects/feed-generator.d.ts +3 -0
  22. package/dist/subjects/feed-generator.js +10 -0
  23. package/dist/subjects/feed-generator.js.map +1 -0
  24. package/dist/subjects/list.d.ts +3 -0
  25. package/dist/subjects/list.js +27 -0
  26. package/dist/subjects/list.js.map +1 -0
  27. package/dist/subjects/notification.d.ts +3 -0
  28. package/dist/subjects/notification.js +10 -0
  29. package/dist/subjects/notification.js.map +1 -0
  30. package/dist/subjects/post.d.ts +3 -0
  31. package/dist/subjects/post.js +215 -0
  32. package/dist/subjects/post.js.map +1 -0
  33. package/dist/subjects/profile.d.ts +3 -0
  34. package/dist/subjects/profile.js +27 -0
  35. package/dist/subjects/profile.js.map +1 -0
  36. package/dist/types.d.ts +39 -0
  37. package/dist/types.js +2 -0
  38. package/dist/types.js.map +1 -0
  39. package/dist/ui.d.ts +10 -0
  40. package/dist/ui.js +145 -0
  41. package/dist/ui.js.map +1 -0
  42. package/lib/behaviors.ts +65 -0
  43. package/lib/decision.ts +363 -0
  44. package/lib/index.ts +63 -0
  45. package/lib/internal/keyword-filter.ts +45 -0
  46. package/lib/keyword-filter.ts +95 -0
  47. package/lib/label.ts +353 -0
  48. package/lib/subjects/feed-generator.ts +22 -0
  49. package/lib/subjects/list.ts +41 -0
  50. package/lib/subjects/notification.ts +22 -0
  51. package/lib/subjects/post.ts +316 -0
  52. package/lib/subjects/profile.ts +42 -0
  53. package/lib/types.ts +61 -0
  54. package/lib/ui.ts +183 -0
  55. package/package.json +36 -0
@@ -0,0 +1,215 @@
1
+ import { unwrapEmbed, unwrapRecordEmbed } from '@atcute/bluesky';
2
+ import { LabelTarget } from '../behaviors.js';
3
+ import { considerBlockedBy, considerBlocking, considerHidden, considerKeywordMute, considerLabels, createModerationDecision, downgradeDecision, mergeModerationDecisions, } from '../decision.js';
4
+ import { matchesKeywordFilters } from '../internal/keyword-filter.js';
5
+ import { moderateProfile } from './profile.js';
6
+ export const moderatePost = (subject, opts) => {
7
+ return mergeModerationDecisions(decideSubject(subject, opts), moderateProfile(subject.author, opts), downgradeDecision(decideEmbed(subject.embed, opts)));
8
+ };
9
+ const decideSubject = (subject, opts) => {
10
+ const author = subject.author;
11
+ const decision = createModerationDecision(author.did, opts);
12
+ considerLabels(decision, LabelTarget.Content, subject.labels, opts);
13
+ if (checkHiddenPost(subject, opts.prefs.hiddenPosts)) {
14
+ considerHidden(decision);
15
+ }
16
+ if (!decision.isMe && opts.prefs.keywordFilters?.length) {
17
+ const match = checkKeywordFilters(subject, opts.prefs.keywordFilters);
18
+ if (match !== null) {
19
+ considerKeywordMute(decision, match);
20
+ }
21
+ }
22
+ return decision;
23
+ };
24
+ const decideEmbed = (embed, opts) => {
25
+ const link = unwrapRecordEmbed(embed);
26
+ if (link) {
27
+ switch (link.$type) {
28
+ case 'app.bsky.embed.record#viewRecord': {
29
+ const author = link.author;
30
+ const decision = createModerationDecision(author.did, opts);
31
+ considerLabels(decision, LabelTarget.Content, link.labels, opts);
32
+ return mergeModerationDecisions(decision, moderateProfile(author, opts));
33
+ }
34
+ case 'app.bsky.embed.record#viewBlocked': {
35
+ const author = link.author;
36
+ const viewer = author.viewer;
37
+ const decision = createModerationDecision(author.did, opts);
38
+ if (viewer?.blocking) {
39
+ considerBlocking(decision, viewer.blockingByList ?? null);
40
+ }
41
+ if (viewer?.blockedBy) {
42
+ considerBlockedBy(decision);
43
+ }
44
+ return decision;
45
+ }
46
+ }
47
+ }
48
+ };
49
+ const checkHiddenPost = (subject, hiddenPosts) => {
50
+ if (!hiddenPosts?.length) {
51
+ return false;
52
+ }
53
+ if (hiddenPosts.includes(subject.uri)) {
54
+ return true;
55
+ }
56
+ const record = unwrapRecordEmbed(subject.embed);
57
+ if (record) {
58
+ switch (record.$type) {
59
+ case 'app.bsky.embed.record#viewBlocked':
60
+ case 'app.bsky.embed.record#viewDetached':
61
+ case 'app.bsky.embed.record#viewNotFound':
62
+ case 'app.bsky.embed.record#viewRecord': {
63
+ return hiddenPosts.includes(subject.uri);
64
+ }
65
+ }
66
+ }
67
+ return false;
68
+ };
69
+ const checkKeywordFilters = (subject, filters) => {
70
+ if (!filters?.length) {
71
+ return null;
72
+ }
73
+ let match;
74
+ const author = subject.author;
75
+ {
76
+ const record = subject.record;
77
+ const tags = [
78
+ ...(record.tags ?? []),
79
+ ...(record.facets ?? []).flatMap((facet) => {
80
+ return facet.features
81
+ .filter((feature) => feature.$type === 'app.bsky.richtext.facet#tag')
82
+ .map((feature) => feature.tag);
83
+ }),
84
+ ];
85
+ if ((match = matchesKeywordFilters({
86
+ filters: filters,
87
+ text: record.text,
88
+ tags: tags,
89
+ actor: author,
90
+ }))) {
91
+ return match;
92
+ }
93
+ }
94
+ {
95
+ const embed = subject.embed;
96
+ if ((match = checkEmbedKeywordFilters(filters, embed, author))) {
97
+ return match;
98
+ }
99
+ }
100
+ return null;
101
+ };
102
+ const checkEmbedKeywordFilters = (filters, embed, author) => {
103
+ let match;
104
+ const { media, record: link } = unwrapEmbed(embed);
105
+ if (media) {
106
+ switch (media.$type) {
107
+ case 'app.bsky.embed.external#view': {
108
+ const external = media.external;
109
+ if ((match = matchesKeywordFilters({
110
+ filters: filters,
111
+ text: `${external.title} ${external.description}`,
112
+ actor: author,
113
+ }))) {
114
+ return match;
115
+ }
116
+ break;
117
+ }
118
+ case 'app.bsky.embed.images#view': {
119
+ const images = media.images;
120
+ for (let i = 0, il = images.length; i < il; i++) {
121
+ const image = images[i];
122
+ if (!image.alt) {
123
+ continue;
124
+ }
125
+ if ((match = matchesKeywordFilters({
126
+ filters: filters,
127
+ text: image.alt,
128
+ actor: author,
129
+ }))) {
130
+ return match;
131
+ }
132
+ }
133
+ break;
134
+ }
135
+ case 'app.bsky.embed.video#view': {
136
+ if (!media.alt) {
137
+ break;
138
+ }
139
+ if ((match = matchesKeywordFilters({
140
+ filters: filters,
141
+ text: media.alt,
142
+ actor: author,
143
+ }))) {
144
+ return match;
145
+ }
146
+ }
147
+ }
148
+ }
149
+ if (link) {
150
+ switch (link.$type) {
151
+ case 'app.bsky.embed.record#viewRecord': {
152
+ {
153
+ const author = link.author;
154
+ const record = link.value;
155
+ const tags = [
156
+ ...(record.tags ?? []),
157
+ ...(record.facets ?? []).flatMap((facet) => {
158
+ return facet.features
159
+ .filter((feature) => feature.$type === 'app.bsky.richtext.facet#tag')
160
+ .map((feature) => feature.tag);
161
+ }),
162
+ ];
163
+ if ((match = matchesKeywordFilters({
164
+ filters: filters,
165
+ text: record.text,
166
+ tags: tags,
167
+ actor: author,
168
+ }))) {
169
+ return match;
170
+ }
171
+ }
172
+ {
173
+ const embed = link.embeds?.[0];
174
+ if ((match = checkEmbedKeywordFilters(filters, embed, author))) {
175
+ return match;
176
+ }
177
+ }
178
+ break;
179
+ }
180
+ case 'app.bsky.feed.defs#generatorView': {
181
+ if ((match = matchesKeywordFilters({
182
+ filters: filters,
183
+ text: `${link.displayName} ${link.description ?? ''}`,
184
+ actor: link.creator,
185
+ }))) {
186
+ return match;
187
+ }
188
+ break;
189
+ }
190
+ case 'app.bsky.graph.defs#listView': {
191
+ if ((match = matchesKeywordFilters({
192
+ filters: filters,
193
+ text: `${link.name} ${link.description ?? ''}`,
194
+ actor: link.creator,
195
+ }))) {
196
+ return match;
197
+ }
198
+ break;
199
+ }
200
+ case 'app.bsky.graph.defs#starterPackViewBasic': {
201
+ const record = link.record;
202
+ if ((match = matchesKeywordFilters({
203
+ filters: filters,
204
+ text: `${record.name} ${record.description ?? ''}`,
205
+ actor: link.creator,
206
+ }))) {
207
+ return match;
208
+ }
209
+ break;
210
+ }
211
+ }
212
+ }
213
+ return null;
214
+ };
215
+ //# sourceMappingURL=post.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"post.js","sourceRoot":"","sources":["../../lib/subjects/post.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type ModerationDecision } from '../decision.js';
2
+ import type { ModerationOptions, ProfileSubject } from '../types.js';
3
+ export declare const moderateProfile: (subject: ProfileSubject, opts: ModerationOptions) => ModerationDecision;
@@ -0,0 +1,27 @@
1
+ import { LabelTarget } from '../behaviors.js';
2
+ import { considerBlockedBy, considerBlocking, considerLabel, considerPermanentMute, createModerationDecision, } from '../decision.js';
3
+ export const moderateProfile = (subject, opts) => {
4
+ const decision = createModerationDecision(subject.did, opts);
5
+ const viewer = subject.viewer;
6
+ if (viewer) {
7
+ if (viewer.muted) {
8
+ considerPermanentMute(decision, viewer.mutedByList ?? null);
9
+ }
10
+ if (viewer.blocking) {
11
+ considerBlocking(decision, viewer.blockingByList ?? null);
12
+ }
13
+ if (viewer.blockedBy) {
14
+ considerBlockedBy(decision);
15
+ }
16
+ }
17
+ if (subject.labels?.length) {
18
+ for (const label of subject.labels) {
19
+ const target = !label.uri.endsWith('/app.bsky.actor.profile/self') || label.val === '!no-unauthenticated'
20
+ ? LabelTarget.Account
21
+ : LabelTarget.Profile;
22
+ considerLabel(decision, target, label, opts);
23
+ }
24
+ }
25
+ return decision;
26
+ };
27
+ //# sourceMappingURL=profile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile.js","sourceRoot":"","sources":["../../lib/subjects/profile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EACN,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,qBAAqB,EACrB,wBAAwB,GAExB,MAAM,gBAAgB,CAAC;AAGxB,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,OAAuB,EAAE,IAAuB,EAAsB,EAAE;IACvG,MAAM,QAAQ,GAAG,wBAAwB,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAE7D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,IAAI,MAAM,EAAE,CAAC;QACZ,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAClB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC;QAC7D,CAAC;QAED,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACrB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,cAAc,IAAI,IAAI,CAAC,CAAC;QAC3D,CAAC;QAED,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YACtB,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAC7B,CAAC;IACF,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;QAC5B,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACpC,MAAM,MAAM,GACX,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,8BAA8B,CAAC,IAAI,KAAK,CAAC,GAAG,KAAK,qBAAqB;gBACzF,CAAC,CAAC,WAAW,CAAC,OAAO;gBACrB,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC;YAExB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAC9C,CAAC;IACF,CAAC;IAED,OAAO,QAAQ,CAAC;AACjB,CAAC,CAAC"}
@@ -0,0 +1,39 @@
1
+ import type { AppBskyActorDefs, AppBskyFeedDefs, AppBskyGraphDefs, AppBskyNotificationListNotifications, At, ChatBskyActorDefs, ComAtprotoLabelDefs } from '@atcute/client/lexicons';
2
+ import type { KeywordFilter } from './keyword-filter.js';
3
+ import type { InterpretedLabelMapping, LabelPreference } from './label.js';
4
+ export type Label = ComAtprotoLabelDefs.Label;
5
+ export interface LabelerPreference {
6
+ /** preferences for labels issued by this labeler */
7
+ labelPrefs: Record<string, LabelPreference | undefined>;
8
+ }
9
+ export interface ModerationPreferences {
10
+ /** whether adult content is allowed to be shown */
11
+ adultContentEnabled?: boolean;
12
+ /** preferences for global-defined labels */
13
+ globalLabelPrefs?: Record<string, LabelPreference | undefined>;
14
+ /** preferences for labelers */
15
+ prefsByLabelers?: {
16
+ [D in At.Did]?: LabelerPreference;
17
+ };
18
+ /** list of hidden posts */
19
+ hiddenPosts?: At.CanonicalResourceUri[];
20
+ /** list of temporarily muted users */
21
+ temporaryMutes?: At.Did[];
22
+ /** list of keyword filters */
23
+ keywordFilters?: KeywordFilter[];
24
+ }
25
+ export interface ModerationOptions {
26
+ /** DID of the viewer */
27
+ viewerDid: At.Did | undefined;
28
+ /** moderation preferences */
29
+ prefs: ModerationPreferences;
30
+ /** interpreted label definitions from labelers */
31
+ labelDefs?: {
32
+ [D in At.Did]?: InterpretedLabelMapping;
33
+ };
34
+ }
35
+ export type FeedGeneratorSubject = AppBskyFeedDefs.GeneratorView;
36
+ export type ListSubject = AppBskyGraphDefs.ListView | AppBskyGraphDefs.ListViewBasic;
37
+ export type NotificationSubject = AppBskyNotificationListNotifications.Notification;
38
+ export type PostSubject = AppBskyFeedDefs.PostView;
39
+ export type ProfileSubject = AppBskyActorDefs.ProfileViewBasic | AppBskyActorDefs.ProfileView | AppBskyActorDefs.ProfileViewDetailed | ChatBskyActorDefs.ProfileViewBasic;
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../lib/types.ts"],"names":[],"mappings":""}
package/dist/ui.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ import { DisplayContext } from './behaviors.js';
2
+ import { type ModerationCause, type ModerationDecision } from './decision.js';
3
+ export interface DisplayRestrictions {
4
+ noOverride: boolean;
5
+ filters: ModerationCause[];
6
+ blurs: ModerationCause[];
7
+ alerts: ModerationCause[];
8
+ informs: ModerationCause[];
9
+ }
10
+ export declare const getDisplayRestrictions: (decision: ModerationDecision, context: DisplayContext) => DisplayRestrictions;
package/dist/ui.js ADDED
@@ -0,0 +1,145 @@
1
+ import { BLOCK_BEHAVIOR, DisplayContext, HIDE_BEHAVIOR, KEYWORD_MUTE_BEHAVIOR, LabelTarget, ModerationAction, MUTE_BEHAVIOR, } from './behaviors.js';
2
+ import { ModerationCauseType } from './decision.js';
3
+ import { LabelPreference } from './label.js';
4
+ export const getDisplayRestrictions = (decision, context) => {
5
+ const filters = [];
6
+ const blurs = [];
7
+ const alerts = [];
8
+ const informs = [];
9
+ let noOverride = false;
10
+ for (const cause of decision.causes) {
11
+ switch (cause.type) {
12
+ case ModerationCauseType.Label: {
13
+ if (cause.pref === LabelPreference.Hide && !decision.isMe) {
14
+ if (context === DisplayContext.ProfileList && cause.target == LabelTarget.Account) {
15
+ filters.push(cause);
16
+ }
17
+ else if (context === DisplayContext.ContentList &&
18
+ (cause.target === LabelTarget.Account || cause.target === LabelTarget.Content)) {
19
+ filters.push(cause);
20
+ }
21
+ }
22
+ if (!cause.downgraded) {
23
+ switch (cause.behavior[context]) {
24
+ case ModerationAction.Blur: {
25
+ noOverride ||= cause.noOverride && !decision.isMe;
26
+ blurs.push(cause);
27
+ break;
28
+ }
29
+ case ModerationAction.Alert: {
30
+ alerts.push(cause);
31
+ break;
32
+ }
33
+ case ModerationAction.Inform: {
34
+ informs.push(cause);
35
+ break;
36
+ }
37
+ }
38
+ }
39
+ break;
40
+ }
41
+ case ModerationCauseType.MutedPermanent:
42
+ case ModerationCauseType.MutedTemporary: {
43
+ if (context === DisplayContext.ProfileList || context === DisplayContext.ContentList) {
44
+ filters.push(cause);
45
+ }
46
+ if (!cause.downgraded) {
47
+ switch (MUTE_BEHAVIOR[context]) {
48
+ case ModerationAction.Blur: {
49
+ blurs.push(cause);
50
+ break;
51
+ }
52
+ case ModerationAction.Alert: {
53
+ alerts.push(cause);
54
+ break;
55
+ }
56
+ case ModerationAction.Inform: {
57
+ informs.push(cause);
58
+ break;
59
+ }
60
+ }
61
+ }
62
+ break;
63
+ }
64
+ case ModerationCauseType.MutedKeyword: {
65
+ if (context === DisplayContext.ContentList) {
66
+ filters.push(cause);
67
+ }
68
+ if (!cause.downgraded) {
69
+ switch (KEYWORD_MUTE_BEHAVIOR[context]) {
70
+ case ModerationAction.Blur: {
71
+ blurs.push(cause);
72
+ break;
73
+ }
74
+ case ModerationAction.Alert: {
75
+ alerts.push(cause);
76
+ break;
77
+ }
78
+ case ModerationAction.Inform: {
79
+ informs.push(cause);
80
+ break;
81
+ }
82
+ }
83
+ }
84
+ break;
85
+ }
86
+ case ModerationCauseType.Hidden: {
87
+ if (context === DisplayContext.ProfileList || context === DisplayContext.ContentList) {
88
+ filters.push(cause);
89
+ }
90
+ if (!cause.downgraded) {
91
+ switch (HIDE_BEHAVIOR[context]) {
92
+ case ModerationAction.Blur: {
93
+ blurs.push(cause);
94
+ break;
95
+ }
96
+ case ModerationAction.Alert: {
97
+ alerts.push(cause);
98
+ break;
99
+ }
100
+ case ModerationAction.Inform: {
101
+ informs.push(cause);
102
+ break;
103
+ }
104
+ }
105
+ }
106
+ break;
107
+ }
108
+ case ModerationCauseType.BlockedBy:
109
+ case ModerationCauseType.Blocking: {
110
+ if (context === DisplayContext.ProfileList || context === DisplayContext.ContentList) {
111
+ filters.push(cause);
112
+ }
113
+ if (!cause.downgraded) {
114
+ switch (BLOCK_BEHAVIOR[context]) {
115
+ case ModerationAction.Blur: {
116
+ noOverride = true;
117
+ blurs.push(cause);
118
+ break;
119
+ }
120
+ case ModerationAction.Alert: {
121
+ alerts.push(cause);
122
+ break;
123
+ }
124
+ case ModerationAction.Inform: {
125
+ informs.push(cause);
126
+ break;
127
+ }
128
+ }
129
+ }
130
+ break;
131
+ }
132
+ }
133
+ }
134
+ return {
135
+ noOverride,
136
+ filters: filters.sort(sortByPriority),
137
+ blurs: blurs.sort(sortByPriority),
138
+ alerts: alerts.sort(sortByPriority),
139
+ informs: informs.sort(sortByPriority),
140
+ };
141
+ };
142
+ const sortByPriority = (a, b) => {
143
+ return a.priority - b.priority;
144
+ };
145
+ //# sourceMappingURL=ui.js.map
package/dist/ui.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../lib/ui.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ export const enum LabelTarget {
2
+ /** label is intended for account's content */
3
+ Content = 'content',
4
+ /** label is intended for account's profile */
5
+ Profile = 'profile',
6
+ /** label is intended for account's content and profile */
7
+ Account = 'account',
8
+ }
9
+
10
+ export const enum DisplayContext {
11
+ /** content in expanded view */
12
+ ContentView = 'contentView',
13
+ /** images or video contained in content */
14
+ ContentMedia = 'contentMedia',
15
+ /** content in a list/feed */
16
+ ContentList = 'contentList',
17
+
18
+ /** profile in expanded view */
19
+ ProfileView = 'profileView',
20
+ /** profile's avatar or banner */
21
+ ProfileMedia = 'profileMedia',
22
+ /** profile in a list */
23
+ ProfileList = 'profileList',
24
+ }
25
+
26
+ export const enum ModerationAction {
27
+ /** should cause blurring */
28
+ Blur = 'blur',
29
+ /** should cause an alert */
30
+ Alert = 'alert',
31
+ /** should cause a notice */
32
+ Inform = 'inform',
33
+ }
34
+
35
+ export type BehaviorMapping = { [C in DisplayContext]?: ModerationAction };
36
+ export type LabelBehaviorMatrix = { [T in LabelTarget]: BehaviorMapping };
37
+
38
+ export const BLOCK_BEHAVIOR: BehaviorMapping = {
39
+ [DisplayContext.ProfileList]: ModerationAction.Blur,
40
+ [DisplayContext.ProfileView]: ModerationAction.Alert,
41
+ [DisplayContext.ProfileMedia]: ModerationAction.Blur,
42
+
43
+ [DisplayContext.ContentList]: ModerationAction.Blur,
44
+ [DisplayContext.ContentView]: ModerationAction.Blur,
45
+ };
46
+
47
+ export const MUTE_BEHAVIOR: BehaviorMapping = {
48
+ [DisplayContext.ProfileList]: ModerationAction.Inform,
49
+ [DisplayContext.ProfileView]: ModerationAction.Alert,
50
+
51
+ [DisplayContext.ContentList]: ModerationAction.Blur,
52
+ [DisplayContext.ContentView]: ModerationAction.Inform,
53
+ };
54
+
55
+ export const KEYWORD_MUTE_BEHAVIOR: BehaviorMapping = {
56
+ [DisplayContext.ContentList]: ModerationAction.Blur,
57
+ [DisplayContext.ContentView]: ModerationAction.Blur,
58
+ };
59
+
60
+ export const HIDE_BEHAVIOR: BehaviorMapping = {
61
+ [DisplayContext.ContentList]: ModerationAction.Blur,
62
+ [DisplayContext.ContentView]: ModerationAction.Blur,
63
+ };
64
+
65
+ export const NOOP_BEHAVIOR: BehaviorMapping = {};