Schedule posts to Bluesky with Cloudflare workers. skyscheduler.work
cf tool bsky-tool cloudflare bluesky schedule bsky service social-media cloudflare-workers

minor updates

just some easy to change settings that are safe

+58 -5
+1
assets/main.js
··· 1 function pushToast(msg, isSuccess) { 2 Toastify({ 3 text: msg, 4 style: { 5 background: isSuccess ? 'green' : 'red' 6 }
··· 1 function pushToast(msg, isSuccess) { 2 Toastify({ 3 text: msg, 4 + duration: !isSuccess ? 10000 : Toastify.defaults.duration, 5 style: { 6 background: isSuccess ? 'green' : 'red' 7 }
+16
assets/stylesheet.css
··· 134 135 .credits a { 136 margin-left: 5px; 137 }
··· 134 135 .credits a { 136 margin-left: 5px; 137 + } 138 + 139 + .warning-box { 140 + position: relative; 141 + padding: 3px; 142 + background: linear-gradient(to right, orange, orangered); 143 + margin-bottom: 5px; 144 + } 145 + 146 + .warning { 147 + color: white; 148 + } 149 + 150 + #accountResponse .btn-error *, #accountDelete .btn-error * { 151 + margin-left: 5px; 152 + color: white; 153 }
+9 -2
src/endpoints/account.tsx
··· 53 const body = await c.req.parseBody(); 54 const validation = AccountUpdateSchema.safeParse(body); 55 if (!validation.success) { 56 - console.log(validation.error); 57 - return c.html(<b class="btn-error">Failed Validation</b>); 58 } 59 60 const auth = c.get("auth");
··· 53 const body = await c.req.parseBody(); 54 const validation = AccountUpdateSchema.safeParse(body); 55 if (!validation.success) { 56 + const errorMsgs = JSON.parse(validation.error.message); 57 + return c.html(<div class="btn-error"> 58 + <b>Failed Validation</b>: 59 + <ul> 60 + {errorMsgs.map((el: { message: string; }) => { 61 + return <li>{el.message}</li>; 62 + })} 63 + </ul> 64 + </div>); 65 } 66 67 const auth = c.get("auth");
+1 -1
src/layout/footer.tsx
··· 3 return ( 4 <> 5 <a class="secondary" target="_blank" href="https://github.com/SocksTheWolf/SkyScheduler">SkyScheduler</a> &copy; {new Date().getFullYear()} 6 - <span class="credits"><a href="https://socksthewolf.com">SocksTheWolf</a> - 7 <a class="secondary" target="_blank" href="https://ko-fi.com/socksthewolf">Tip/Donate</a></span> 8 </> 9 );
··· 3 return ( 4 <> 5 <a class="secondary" target="_blank" href="https://github.com/SocksTheWolf/SkyScheduler">SkyScheduler</a> &copy; {new Date().getFullYear()} 6 + <span class="credits"><a rel="author" href="https://socksthewolf.com">SocksTheWolf</a> - 7 <a class="secondary" target="_blank" href="https://ko-fi.com/socksthewolf">Tip/Donate</a></span> 8 </> 9 );
+1
src/layout/postList.tsx
··· 17 } 18 19 export function ScheduledPost(content: Post) { 20 const postID = randomstring.generate(7); 21 22 return html`
··· 17 } 18 19 export function ScheduledPost(content: Post) { 20 + // Throwaway gibberish generator to make htmx link up properly across a lot of posts 21 const postID = randomstring.generate(7); 22 23 return html`
+29 -1
src/types.d.ts
··· 37 // Basically a copy of the schema 38 export type Post = { 39 postid: string; 40 user: string; 41 text: string; 42 embeds?: EmbedData[]; ··· 52 uri: string; 53 cid: string; 54 userId: string; 55 - } 56 57 export type PostResponseObject = { 58 uri: string; ··· 61 62 export interface LooseObj { 63 [key: string]: any; 64 };
··· 37 // Basically a copy of the schema 38 export type Post = { 39 postid: string; 40 + // SkyScheduler User Id 41 user: string; 42 text: string; 43 embeds?: EmbedData[]; ··· 53 uri: string; 54 cid: string; 55 userId: string; 56 + }; 57 + 58 + export type Violation = { 59 + userId: string; 60 + tosViolation: boolean; 61 + userPassInvalid: boolean; 62 + accountSuspended: boolean; 63 + accountGone: boolean; 64 + createdAt: string; 65 + }; 66 67 export type PostResponseObject = { 68 uri: string; ··· 71 72 export interface LooseObj { 73 [key: string]: any; 74 + }; 75 + 76 + export enum PlatformLoginResponse { 77 + None = 0, 78 + Ok, 79 + InvalidCreds, 80 + Suspended, 81 + Deactivated, 82 + TakenDown, 83 + InvalidAccount, 84 + PlatformOutage, 85 + UnhandledError 86 + }; 87 + 88 + export enum PWAutoCompleteSettings { 89 + Off, 90 + NewPass, 91 + CurrentPass 92 };
+1 -1
src/validation/accountUpdateSchema.ts
··· 15 .or(z.literal("")), 16 bskyAppPassword: z.string().trim() 17 .max(BSKY_MAX_APP_PASSWORD_LENGTH, "app password too long") 18 - .regex(appPasswordRegex) 19 .optional() 20 .or(z.literal("")), 21 bskyUserPDS: z.url("PDS should be in the format of an URL").trim()
··· 15 .or(z.literal("")), 16 bskyAppPassword: z.string().trim() 17 .max(BSKY_MAX_APP_PASSWORD_LENGTH, "app password too long") 18 + .regex(appPasswordRegex, "not a valid bsky app password") 19 .optional() 20 .or(z.literal("")), 21 bskyUserPDS: z.url("PDS should be in the format of an URL").trim()