Schedule posts to Bluesky with Cloudflare workers.
skyscheduler.work
cf
tool
bsky-tool
cloudflare
bluesky
schedule
bsky
service
social-media
cloudflare-workers
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 <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};