Multicolumn Bluesky client powered by Angular
1@let postRecord = record();
2
3<div
4 class="flex"
5>
6 <div
7 class="overflow-hidden shrink-0 h-5 w-9 flex items-center justify-center"
8 >
9 <span class="material-icons !text-[2.25em]">format_quote</span>
10 </div>
11
12 <div
13 class="flex flex-col flex-1 min-w-0 mt-1"
14 >
15 @if (postRecord | isEmbedRecordViewRecord) {
16 <ng-container
17 [ngTemplateOutlet]="viewRecord"
18 [ngTemplateOutletContext]="{record: postRecord, media: postRecord.embeds ? postRecord.embeds[0] : undefined }"
19 />
20 }
21
22 @if (postRecord | isEmbedRecordViewBlocked) {
23 <span>
24 Post blocked
25 </span>
26 }
27
28 @if (postRecord | isEmbedRecordViewNotFound) {
29 <span>
30 Post not found
31 </span>
32 }
33
34 @if (postRecord | isEmbedRecordViewDetached) {
35 <span>
36 Post detached
37 </span>
38 }
39
40 @if (postRecord | isFeedDefsGeneratorView) {
41 <ng-container
42 [ngTemplateOutlet]="feed"
43 [ngTemplateOutletContext]="{feed: postRecord}"
44 />
45 }
46
47 @if (postRecord | isGraphDefsListView) {
48 <ng-container
49 [ngTemplateOutlet]="userList"
50 [ngTemplateOutletContext]="{list: postRecord}"
51 />
52 }
53
54 <!-- Apparently there's no actual support yet? -->
55 @if (postRecord | isLabelerDefsLabelerView) {
56 <span>
57 Labeler record
58 </span>
59 }
60
61 @if (postRecord | isGraphDefsStarterPackViewBasic) {
62 <ng-container
63 [ngTemplateOutlet]="starterPack"
64 [ngTemplateOutletContext]="{starterPack: postRecord}"
65 />
66 }
67 </div>
68</div>
69
70<ng-template
71 #viewRecord
72 let-record="record"
73 let-media="media"
74>
75 <span
76 class="font-bold [text-box:trim-both_cap_alphabetic] shrink-1 grow-0 min-w-0 overflow-y-visible overflow-x-clip overflow-ellipsis whitespace-nowrap"
77 >{{record.author | displayName}}</span>
78
79 @if ((record.value | isFeedPostRecord) && record.value.text.length) {
80 <rich-text
81 [text]="record.value.text"
82 class="mt-2 text-sm"
83 />
84 }
85
86 @if (media) {
87 <ng-container
88 [ngTemplateOutlet]="mediaEmbeds"
89 [ngTemplateOutletContext]="{
90 media: media,
91 margin: (record.value | isFeedPostRecord) && record.value.text.length ? 'mt-2' : 'mt-3'
92 }"
93 />
94 }
95
96</ng-template>
97
98<ng-template
99 #mediaEmbeds
100 let-media="media"
101 let-margin="margin"
102>
103 @if (media | isEmbedImagesView) {
104 <images-embed
105 [images]="media.images"
106 class="cursor-pointer"
107 [class]="margin"
108 />
109 }
110
111 @if (media | isEmbedVideoView) {
112 <video-embed
113 [embed]="media"
114 [class]="margin"
115 />
116 }
117
118 @if (media | isEmbedExternalView) {
119 <external-embed
120 [external]="media.external"
121 [class]="margin"
122 />
123 }
124
125 @if (media | isEmbedRecordWithMediaView) {
126 @if (media.media | isEmbedImagesView) {
127 <images-embed
128 [images]="media.media.images"
129 class="cursor-pointer"
130 [class]="margin"
131 />
132 }
133
134 @if (media.media | isEmbedVideoView) {
135 <video-embed
136 [embed]="media.media"
137 [class]="margin"
138 />
139 }
140
141 @if (media.media | isEmbedExternalView) {
142 <external-embed
143 [external]="media.media.external"
144 [class]="margin"
145 />
146 }
147 }
148</ng-template>
149
150<ng-template
151 #feed
152 let-feed="feed"
153>
154 <span
155 class="text-bold overflow-hidden whitespace-nowrap text-ellipsis"
156 >{{feed.displayName}}</span>
157
158 <span
159 class="overflow-hidden whitespace-nowrap text-ellipsis"
160 >
161 @switch (feed.contentMode) {
162 @case (AppBskyFeedDefs.CONTENTMODEVIDEO) {
163 Video feed by {{ feed.creator | displayName }}
164 }
165 @default {
166 Feed by {{ feed.creator | displayName }}
167 }
168 }
169 </span>
170</ng-template>
171
172<ng-template
173 #userList
174 let-list="list"
175>
176 <span
177 class="text-bold overflow-hidden whitespace-nowrap text-ellipsis"
178 >{{list.name}}</span>
179
180 <span
181 class="overflow-hidden whitespace-nowrap text-ellipsis"
182 >
183 @switch (list.purpose) {
184 @case (AppBskyGraphDefs.MODLIST) {
185 Mute list by {{ list.creator | displayName }}
186 }
187 @default {
188 List by {{ list.creator | displayName }}
189 }
190 }
191 </span>
192</ng-template>
193
194<ng-template
195 #starterPack
196 let-starterpack="starterPack"
197>
198 <span
199 class="text-bold overflow-hidden whitespace-nowrap text-ellipsis"
200 >{{starterpack.record.name}}</span>
201
202 <span
203 class="overflow-hidden whitespace-nowrap text-ellipsis"
204 >
205 Starter pack by {{ starterpack.creator | displayName }}
206 </span>
207</ng-template>