···11import { AtUri } from "@atp/syntax";
22import { DataPlane } from "../data-plane/index.ts";
33import { ids } from "../lex/lexicons.ts";
44-import { Record as LabelerRecord } from "../lex/types/app/bsky/labeler/service.ts";
44+import { Record as LabelerRecord } from "../lex/types/so/sprk/labeler/service.ts";
55import { Label } from "../lex/types/com/atproto/label/defs.ts";
66import { ParsedLabelers } from "../util.ts";
77import {
+125-1
views/index.ts
···11import { HydrationState } from "../hydration/index.ts";
22import {
33+ isRecord as isPostRecord,
44+ Record as PostRecord,
55+} from "../lex/types/so/sprk/feed/post.ts";
66+import { Record as LikeRecord } from "../lex/types/so/sprk/feed/like.ts";
77+import { Record as RepostRecord } from "../lex/types/so/sprk/feed/repost.ts";
88+import { Record as FollowRecord } from "../lex/types/so/sprk/graph/follow.ts";
99+import {
1010+ isRecord as isProfileRecord,
1111+ Record as ProfileRecord,
1212+} from "../lex/types/so/sprk/actor/profile.ts";
1313+import { Label } from "../lex/types/com/atproto/label/defs.ts";
1414+import {
315 FeedViewPost,
416 isPostView,
517 isReplyView,
···4860} from "../lex/types/so/sprk/media/video.ts";
4961import type { Main as VideoMediaMainType } from "../lex/types/so/sprk/media/video.ts";
5062import { AudioView } from "../lex/types/so/sprk/sound/defs.ts";
5151-import { AtUri, INVALID_HANDLE } from "@atp/syntax";
6363+import { AtUri, INVALID_HANDLE, normalizeDatetimeAlways } from "@atp/syntax";
5264import { Main as StrongRef } from "../lex/types/com/atproto/repo/strongRef.ts";
5365import { cidFromBlobJson } from "./util.ts";
5466import { uriToDid } from "../utils/uris.ts";
···6072} from "../lex/types/so/sprk/feed/getPostThread.ts";
6173import { $Typed, Un$Typed } from "../lex/util.ts";
6274import { BlobRef } from "@atp/lexicon";
7575+import {
7676+ isRecord as isLabelerRecord,
7777+ Record as LabelerRecord,
7878+} from "../lex/types/so/sprk/labeler/service.ts";
7979+import {
8080+ LabelerView,
8181+ LabelerViewDetailed,
8282+} from "../lex/types/so/sprk/labeler/defs.ts";
8383+import { isSelfLabels } from "../lex/types/com/atproto/label/defs.ts";
63846485export class Views {
6586 public indexedAtEpoch?: Date | undefined;
···82103 this.thumbCdn = opts?.thumbCdn;
83104 }
84105106106+ // Labels
107107+ // ------------
108108+109109+ selfLabels({
110110+ uri,
111111+ cid,
112112+ record,
113113+ }: {
114114+ uri?: string;
115115+ cid?: string;
116116+ record?:
117117+ | PostRecord
118118+ | LikeRecord
119119+ | RepostRecord
120120+ | FollowRecord
121121+ | ProfileRecord
122122+ | LabelerRecord;
123123+ }): Label[] {
124124+ if (!uri || !cid || !record) return [];
125125+126126+ // Only these have a "labels" property:
127127+ if (
128128+ !isPostRecord(record) &&
129129+ !isProfileRecord(record) &&
130130+ !isLabelerRecord(record)
131131+ ) {
132132+ return [];
133133+ }
134134+135135+ // Ignore if no labels defines
136136+ if (!isSelfLabels(record.labels) || !record.labels.values.length) {
137137+ return [];
138138+ }
139139+140140+ const src = uriToDid(uri); // record creator
141141+ const cts = typeof record.createdAt === "string"
142142+ ? normalizeDatetimeAlways(record.createdAt)
143143+ : new Date(0).toISOString();
144144+ return record.labels.values.map(({ val }) => {
145145+ return { src, uri, cid, val, cts };
146146+ });
147147+ }
148148+149149+ labeler(
150150+ did: string,
151151+ state: HydrationState,
152152+ ): Un$Typed<LabelerView> | undefined {
153153+ const labeler = state.labelers?.get(did);
154154+ if (!labeler) return;
155155+ const creator = this.profile(did, state);
156156+ if (!creator) return;
157157+ const viewer = state.labelerViewers?.get(did);
158158+ const aggs = state.labelerAggs?.get(did);
159159+160160+ const uri = AtUri.make(did, ids.SoSprkLabelerService, "self").toString();
161161+ const labels = [
162162+ ...(state.labels?.getBySubject(uri) ?? []),
163163+ ...this.selfLabels({
164164+ uri,
165165+ cid: labeler.cid.toString(),
166166+ record: labeler.record,
167167+ }),
168168+ ];
169169+170170+ return {
171171+ uri,
172172+ cid: labeler.cid.toString(),
173173+ creator,
174174+ likeCount: aggs?.likes ?? 0,
175175+ viewer: viewer
176176+ ? {
177177+ like: viewer.like,
178178+ }
179179+ : undefined,
180180+ indexedAt: this.indexedAt(labeler).toISOString(),
181181+ labels,
182182+ };
183183+ }
184184+185185+ labelerDetailed(
186186+ did: string,
187187+ state: HydrationState,
188188+ ): Un$Typed<LabelerViewDetailed> | undefined {
189189+ const baseView = this.labeler(did, state);
190190+ if (!baseView) return;
191191+ const labeler = state.labelers?.get(did);
192192+ if (!labeler) return;
193193+194194+ return {
195195+ ...baseView,
196196+ policies: labeler.record.policies,
197197+ reasonTypes: labeler.record.reasonTypes,
198198+ subjectTypes: labeler.record.subjectTypes,
199199+ subjectCollections: labeler.record.subjectCollections,
200200+ };
201201+ }
202202+203203+ // Threads
204204+ // ------------
205205+85206 thread(
86207 skeleton: { anchor: string; uris: string[] },
87208 state: HydrationState,
···188309 ...(like ? { rootAuthorLike: like } : {}),
189310 };
190311 }
312312+313313+ // Feed
314314+ // ------------
191315192316 post(
193317 uri: string,
+1-1
views/types.ts
···1313 PostView,
1414 ReplyView,
1515} from "../lex/types/so/sprk/feed/defs.ts";
1616-import { LabelerView } from "../lex/types/app/bsky/labeler/defs.ts";
1616+import { LabelerView } from "../lex/types/so/sprk/labeler/defs.ts";
17171818export {
1919 isMain as isImagesMedia,