Schedule posts to Bluesky with Cloudflare workers. skyscheduler.work
cf tool bsky-tool cloudflare bluesky schedule bsky service social-media cloudflare-workers
at main 55 lines 2.3 kB view raw
1import { raw } from "hono/html"; 2import { Post } from "../../classes/post"; 3import { 4 AddPostToThreadButton, AddRepostsButton, 5 DeletePostButton, EditPostButton 6} from "../buttons/posts"; 7import { RepostCountElement, RepostStatusIcon } from "./repostData"; 8 9type PostDataHeaderOptions = { 10 content: Post; 11 posted: boolean; 12}; 13 14export function PostDataHeader(props: PostDataHeaderOptions) { 15 const content: Post = props.content; 16 17 // if this post can be manipulated in some way 18 const canBeEdited = !props.posted && !content.isRepost; 19 const canBeDeleted = (!props.posted || (content.isRepost && content.repostCount! > 0)); 20 const canAddReposts = !content.isChildPost && props.posted && content.canAddMoreRepostRules(); 21 22 // show the header if any of the above cases is true 23 const canSeeHeader = canBeEdited || canBeDeleted || canAddReposts; 24 return (<header class="postItemHeader" data-item={content.postid} data-root={content.rootPost || content.postid} 25 data-parent={content.isChildPost ? content.parentPost : undefined} 26 data-repost={content.isRepost || undefined} 27 hidden={canSeeHeader ? undefined : true}> 28 <RepostStatusIcon isRepost={content.isRepost} /> 29 {canBeEdited ? <EditPostButton id={content.postid} /> : null} 30 {canBeEdited ? <AddPostToThreadButton /> : null} 31 {canAddReposts ? <AddRepostsButton /> : null} 32 {canBeDeleted ? <DeletePostButton id={content.postid} isRepost={content.isRepost} child={content.isChildPost} /> : null} 33 </header>); 34}; 35 36 37type PostDataFooterOptions = { 38 content: Post; 39 posted: boolean; 40}; 41 42export function PostDataFooter(props: PostDataFooterOptions) { 43 const content: Post = props.content; 44 const hasPosted: boolean = props.posted; 45 return (<footer><small> 46 <a class="secondary" hidden={!hasPosted} tabindex={hasPosted ? undefined : -1} 47 data-uri={content.uri} 48 href={content.getURI() || undefined} 49 target="_blank" title="link to post">{content.isRepost ? "Repost on" : "Posted on"}</a> 50 <span hidden={hasPosted}>Scheduled for</span>: 51 &nbsp;<span class="timestamp">{raw(content.scheduledDate!)}</span> 52 {content.hasEmbeds() ? ' | Embeds: ' + content.embeds!.length : null} 53 <RepostCountElement count={content.repostCount} repostInfo={content.repostInfo} /> 54 </small></footer>); 55};