Thread viewer for Bluesky
at master 85 lines 2.2 kB view raw
1<script lang="ts"> 2 import LikeStatsTable from '../components/LikeStatsTable.svelte'; 3 import { LikeStats, type LikeStat } from '../services/like_stats.js'; 4 import { numberOfDays } from '../utils.js'; 5 6 let timeRangeDays = $state(7); 7 let progress: number | undefined = $state(); 8 let scanInProgress = $derived(progress !== undefined); 9 let givenLikesUsers: LikeStat[] | undefined = $state(); 10 let receivedLikesUsers: LikeStat[] | undefined = $state(); 11 12 let likeStats = new LikeStats(); 13 14 async function startScan(e: Event) { 15 e.preventDefault(); 16 17 try { 18 if (!scanInProgress) { 19 givenLikesUsers = undefined; 20 receivedLikesUsers = undefined; 21 22 let result = await likeStats.findLikes(timeRangeDays, (p) => { progress = p }); 23 24 givenLikesUsers = result.givenLikes; 25 receivedLikesUsers = result.receivedLikes; 26 progress = undefined; 27 } else { 28 likeStats.abortScan(); 29 progress = undefined; 30 } 31 } catch (error) { 32 if (error.name !== 'AbortError') { 33 throw error; 34 } 35 } 36 } 37</script> 38 39<main> 40<h2>Like statistics</h2> 41 42<form onsubmit={startScan}> 43 <p> 44 Time range: <input id="like_stats_range" type="range" min="1" max="60" bind:value={timeRangeDays}> 45 <label for="like_stats_range">{numberOfDays(timeRangeDays)}</label> 46 </p> 47 48 <p> 49 <input type="submit" value="{scanInProgress ? 'Cancel' : 'Start scan'}"> 50 51 {#if scanInProgress} 52 <progress value={progress} style="display: inline;"></progress> 53 {/if} 54 </p> 55</form> 56 57{#if givenLikesUsers && receivedLikesUsers} 58 <LikeStatsTable cssClass="given-likes" header="❤️ Likes from you:" users={givenLikesUsers} /> 59 <LikeStatsTable cssClass="received-likes" header="💛 Likes on your posts:" users={receivedLikesUsers} /> 60{/if} 61</main> 62 63<style> 64 input[type="range"] { 65 width: 250px; 66 vertical-align: middle; 67 } 68 69 input[type="submit"] { 70 font-size: 12pt; 71 margin: 5px 0px; 72 padding: 5px 10px; 73 } 74 75 progress { 76 width: 300px; 77 margin-left: 10px; 78 vertical-align: middle; 79 display: none; 80 } 81 82 :global(.scan-result.given-likes) { 83 margin-right: 100px; 84 } 85</style>