tiny whitewind client
at main 113 lines 3.8 kB view raw
1<?php 2require_once 'vendor/autoload.php'; 3use League\CommonMark\Environment\Environment; 4use League\CommonMark\Exception\CommonMarkException; 5use League\CommonMark\Extension\Autolink\AutolinkExtension; 6use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension; 7use League\CommonMark\MarkdownConverter; 8 9$config = [ 10 'autolink' => [ 11 'allowed_protocols' => ['https'], 12 'default_protocol' => 'https', 13 ], 14]; 15$environment = new Environment($config); 16$environment->addExtension(new CommonMarkCoreExtension()); 17$environment->addExtension(new AutolinkExtension()); 18$converter = new MarkdownConverter($environment); 19 20function getSlingshot(string $user): mixed 21{ 22 return $_SESSION["slingshot"][$user] ??= 23 json_decode(file_get_contents("https://slingshot.microcosm.blue/xrpc/com.bad-example.identity.resolveMiniDoc?identifier=$user")); 24} 25 26session_start(); 27 28// short circuit if no other user is specified 29$user = $_GET["user"] ?? "benharri.org"; 30$format = $_GET["format"] ?? "html"; 31 32$id = getSlingshot($user); 33$user_url = "?user=$id->handle"; 34$at_uri = "at://$id->handle/com.whtwnd.blog.entry"; 35$at_permauri = "at://$id->did/com.whtwnd.blog.entry"; 36 37if (isset($_GET["p"])) { 38 // get single post record 39 $query = http_build_query([ 40 "repo" => $id->did, 41 "collection" => "com.whtwnd.blog.entry", 42 "rkey" => $_GET["p"] 43 ]); 44 $post = json_decode(file_get_contents("$id->pds/xrpc/com.atproto.repo.getRecord?$query"), true); 45 46 if ($format === "markdown") { 47 // print raw markdown and we're done 48 header("Content-Type: text/markdown; variant=GFM"); 49 echo '# ' . $post["value"]["title"] . PHP_EOL . PHP_EOL . $post["value"]["content"]; 50 die(); 51 } 52 53 $post_url = "$user_url&p={$_GET["p"]}"; 54 $at_uri .= "/{$_GET["p"]}"; 55 56} else { 57 // get all posts 58 // TODO: pagination 59 $q = http_build_query([ 60 "repo" => $id->did, 61 "collection" => "com.whtwnd.blog.entry", 62 "limit" => 100 63 ]); 64 $posts = json_decode(file_get_contents("$id->pds/xrpc/com.atproto.repo.listRecords?$q"), true)["records"]; 65} 66 67?> 68<!doctype html> 69<html lang="en"> 70<head> 71 <meta charset="utf-8"> 72 <meta http-equiv="x-ua-compatible" content="ie=edge"> 73 <meta name="viewport" content="width=device-width, initial-scale=1"> 74 <link rel="stylesheet" href="gruvbox.css"> 75 <link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='48' height='48' viewBox='0 0 16 16'><text x='0' y='14'>🖋️</text></svg>"> 76<?php if (isset($post_url)) { ?> 77 <link rel="alternate" type="text/markdown; variant=GFM" href="https://bhh.sh/pub/atblog/<?=$post_url?>&format=markdown"> 78<?php } ?> 79 <link rel="alternate" href="<?=$at_permauri?>"> 80 <title>atblog: <?=$post["value"]["title"] ?? $id->handle ?></title> 81</head> 82 83<body> 84<main> 85 <form method="GET"> 86 <input name="user" placeholder="jump to user"> 87 </form> 88 <p><a href="https://pdsls.dev/<?=$at_permauri?>"><?=$at_uri?></a></p> 89 90<?php if (isset($post) && isset($post_url)) { ?> 91 <p> 92 <a href="<?=$user_url?>">back to post list</a> 93 <a href="<?=$post_url?>&format=markdown">raw markdown</a> 94 </p> 95 96 <h1><?=$post["value"]["title"]?></h1> 97 <hr> 98 <?php try { 99 echo $converter->convert($post["value"]["content"])->getContent(); 100 } catch (CommonMarkException $e) { 101 echo "Failed to parse markdown {$e->getMessage()}"; 102 } ?> 103 104<?php } else if (isset($posts)) { ?> 105 <ul> 106<?php foreach ($posts as $post) { ?> 107 <li><?=substr($post["value"]["createdAt"], 0, 10)?> <a href="<?=$user_url?>&p=<?=explode('/', $post["uri"])[4]?>"><?=$post["value"]["title"]?></a></li> 108<?php } ?> 109 </ul> 110<?php } ?> 111</main> 112</body> 113</html>