···11-<script>
22- let { url } = $props();
11+<script lang="ts">
22+ let { url }: { url: string } = $props();
3344 let hostname = $derived(new URL(url).hostname);
55</script>
+2-2
src/components/posts/FeedPostParent.svelte
···11-<script>
11+<script lang="ts">
22 import { linkToPostById } from '../../router.js';
33 import { atURI } from '../../utils.js';
4455- let { uri } = $props();
55+ let { uri }: { uri: string } = $props();
66 let { repo, rkey } = $derived(atURI(uri));
77</script>
88
+10-5
src/components/posts/HiddenRepliesLink.svelte
···11-<script>
11+<script lang="ts">
22 import { showBiohazardDialog } from '../../skythread.js';
33 import { account } from '../../models/account.svelte.js';
44- import { parseThreadPost } from '../../models/posts.js';
44+ import { Post, parseThreadPost } from '../../models/posts.js';
55 import { linkToPostThread } from '../../router.js';
66 import { getContext } from 'svelte';
7788- let { onLoad, onError } = $props();
99- let { post } = getContext('post');
88+ type Props = {
99+ onLoad: (posts: (AnyPost | null)[]) => void,
1010+ onError: (error: Error) => void
1111+ }
1212+1313+ let { onLoad, onError }: Props = $props();
1414+ let { post }: { post: Post } = getContext('post');
1015 let loading = $state(false);
11161212- function onLinkClick(e) {
1717+ function onLinkClick(e: Event) {
1318 e.preventDefault();
14191520 if (account.biohazardEnabled === true) {
+11-6
src/components/posts/LoadMoreLink.svelte
···11-<script>
22- import { parseThreadPost } from '../../models/posts.js';
11+<script lang="ts">
22+ import { Post, parseThreadPost } from '../../models/posts.js';
33 import { linkToPostThread } from '../../router.js';
44 import { getContext } from 'svelte';
5566- let { onLoad, onError } = $props();
77- let { post } = getContext('post');
66+ type Props = {
77+ onLoad: (root: Post) => void,
88+ onError: (error: Error) => void
99+ }
1010+1111+ let { onLoad, onError }: Props = $props();
1212+ let { post }: { post: Post } = getContext('post');
813 let loading = $state(false);
9141010- async function onLinkClick(e) {
1515+ async function onLinkClick(e: Event) {
1116 e.preventDefault();
1217 loading = true;
1318···17221823 loading = false;
1924 window.subtreeRoot = root;
2020- onLoad(root);
2525+ onLoad(root as Post); // TODO
2126 } catch (error) {
2227 loading = false;
2328 onError(error);
+3-2
src/components/posts/MissingPostView.svelte
···11-<script>
11+<script lang="ts">
22 import { getContext } from 'svelte';
33+ import { Post } from '../../models/posts';
34 import ReferencedPostAuthorLink from './ReferencedPostAuthorLink.svelte';
4555- let { post } = getContext('post');
66+ let { post }: { post: Post } = getContext('post');
67</script>
7889<p class="blocked-header">
+7-8
src/components/posts/PostBody.svelte
···11-<script>
11+<script lang="ts">
22 import { getContext } from 'svelte';
33 import { sanitizeHTML } from '../../utils.js';
44+ import { Post } from '../../models/posts.js';
45 import RichTextFromFacets from '../RichTextFromFacets.svelte';
5666- let { post } = getContext('post');
77- let { highlightedMatches = undefined } = $props();
77+ let { post }: { post: Post } = getContext('post');
88+ let { highlightedMatches = undefined }: { highlightedMatches?: string[] } = $props();
8999- let bodyElement;
1010+ let bodyElement: HTMLElement;
10111111- /** @param {string[]} terms */
1212-1313- function highlightSearchResults(terms) {
1212+ function highlightSearchResults(terms: string[]) {
1413 let regexp = new RegExp(`\\b(${terms.join('|')})\\b`, 'gi');
1514 let walker = document.createTreeWalker(bodyElement, NodeFilter.SHOW_TEXT);
1616- let ranges = [];
1515+ let ranges: Range[] = [];
17161817 while (walker.nextNode()) {
1918 let node = walker.currentNode;
+13-13
src/components/posts/PostComponent.svelte
···11-<script>
11+<script lang="ts">
22 import { setContext } from 'svelte';
33 import { HiddenRepliesError } from '../../api/api.js';
44 import { account } from '../../models/account.svelte.js';
55 import { Post, BlockedPost, DetachedQuotePost } from '../../models/posts.js';
66- import { InlineLinkEmbed } from '../../models/embeds.js';
66+ import { Embed, InlineLinkEmbed } from '../../models/embeds.js';
77 import { isValidURL, showError } from '../../utils.js';
8899 import BlockedPostView from './BlockedPostView.svelte';
···3232 let { post, context, highlightedMatches = undefined, ...props } = $props();
33333434 let collapsed = $state(false);
3535- let replies = $state(post.replies);
3535+ let replies: AnyPost[] = $state(post.replies);
3636 let repliesLoaded = $state(false);
3737- let missingHiddenReplies = $state();
3838- let hiddenRepliesError = $state();
3737+ let missingHiddenReplies: number | undefined = $state();
3838+ let hiddenRepliesError: Error | undefined = $state();
39394040 setContext('post', { post, context });
41414242 // TODO: make Post reactive
4343- let quoteCount = $state(post.quoteCount);
4343+ let quoteCount: number | undefined = $state(post.quoteCount);
44444545- export function setQuoteCount(x) {
4545+ export function setQuoteCount(x: number) {
4646 quoteCount = x;
4747 }
48484949- function shouldRenderReply(reply) {
4949+ function shouldRenderReply(reply: AnyPost): boolean {
5050 if (reply instanceof Post) {
5151 return true;
5252 } else if (reply instanceof BlockedPost) {
···5656 }
5757 }
58585959- function shouldRenderEmbed(embed) {
5959+ function shouldRenderEmbed(embed: Embed): boolean {
6060 if (post.originalFediURL) {
6161 if (embed instanceof InlineLinkEmbed && embed.title && embed.title.startsWith('Original post on ')) {
6262 return false;
···6666 return true;
6767 }
68686969- function onMoreRepliesLoaded(newPost) {
6969+ function onMoreRepliesLoaded(newPost: Post) {
7070 replies = post.replies = newPost.replies;
7171 repliesLoaded = true;
7272 }
73737474- function onHiddenRepliesLoaded(newReplies) {
7575- let okReplies = newReplies.filter(x => x);
7474+ function onHiddenRepliesLoaded(newReplies: (AnyPost | null)[]) {
7575+ let okReplies = newReplies.filter(x => x !== null);
7676 replies.push(...okReplies);
7777 post.replies = replies;
7878···8080 repliesLoaded = true;
8181 }
82828383- function onRepliesLoadingError(error) {
8383+ function onRepliesLoadingError(error: Error) {
8484 repliesLoaded = true;
85858686 if (error instanceof HiddenRepliesError) {
+4-9
src/components/posts/PostFooter.svelte
···11-<script>
11+<script lang="ts">
22 import { getContext } from 'svelte';
33 import { linkToPostThread, linkToQuotesPage } from '../../router.js';
44 import { account } from '../../models/account.svelte.js';
55+ import { Post } from '../../models/posts.js';
56 import { showLoginDialog } from '../../skythread.js';
67 import { showError } from '../../utils.js';
7888- let { post, context } = getContext('post');
99- let { quoteCount } = $props();
99+ let { post, context }: { post: Post, context: PostContext } = getContext('post');
1010+ let { quoteCount }: { quoteCount: number | undefined } = $props();
10111112 let isLiked = $state(post.liked);
1213 let likeCount = $state(post.likeCount);
1314 let isUnavailableForLiking = $state(false);
14151515- /** @returns {Promise<void>} */
1616-1716 async function onHeartClick() {
1817 try {
1918 if (post.hasViewerInfo) {
···2827 }
2928 }
30293131- /** @returns {Promise<void>} */
3232-3330 async function checkIfCanBeLiked() {
3431 let data = await accountAPI.loadViewerInfo();
3532···4340 isUnavailableForLiking = true;
4441 }
4542 }
4646-4747- /** @returns {Promise<void>} */
48434944 async function likePost() {
5045 if (!isLiked) {
+4-3
src/components/posts/PostHeader.svelte
···11-<script>
11+<script lang="ts">
22 import { getContext } from 'svelte';
33+ import { Post } from '../../models/posts.js';
34 import { PostPresenter } from '../../utils/post_presenter.js';
45 import PostSubtreeLink from './PostSubtreeLink.svelte';
5666- let { post, context } = getContext('post');
77+ let { post, context }: { post: Post, context: PostContext } = getContext('post');
78 let presenter = new PostPresenter(post, context);
8999- let avatar;
1010+ let avatar: HTMLImageElement;
10111112 $effect(() => {
1213 if (avatar) {
+3-2
src/components/posts/PostSubtreeLink.svelte
···11-<script>
11+<script lang="ts">
22 import { linkToPostThread } from '../../router.js';
33+ import { Post } from '../../models/posts.js';
3444- let { post, title = '' } = $props();
55+ let { post, title = '' }: { post: Post, title?: string } = $props();
56</script>
6778<a href="{linkToPostThread(post)}" class="action" {title}>
+3-2
src/components/posts/PostTagsRow.svelte
···11-<script>
11+<script lang="ts">
22 import { getContext } from 'svelte';
33+ import { Post } from '../../models/posts.js';
34 import { linkToHashtagPage } from '../../router.js';
4555- let { post } = getContext('post');
66+ let { post }: { post: Post } = getContext('post');
67</script>
7889<p class="tags">