mirror of
https://github.com/hanzoai/social.git
synced 2026-10-17 11:18:21 +00:00
A social publishing surface on @hanzo/gui + @hanzo/ui, written against the platform's own /v1/social and /v1/integration. Six screens: the org roll-up, a composer, the posts in every state, a month calendar, the networks with their consent and their handles, and the delivery record. Two facts shape it. A post carries one channel, so the composer stores one post per network — which is also what makes writing separately for a single network free, since it is a different content on that row. Media is a list of addresses, so a video is ordinary content rather than a second kind of post, and each network's own rules are checked before the post is stored rather than discovered at a publish hours later. State is drawn in luminance on a palette with no hues, and the inversion is spent once per screen on the thing a person has to act on. Refusals are the platform's own sentence, read off the RFC 7807 detail the SDK's extractor drops — a 503 that names the missing credentials is the whole of what anyone can act on. Co-authored-by: Hanzo Dev <[email protected]>
54 lines
2.0 KiB
HTML
54 lines
2.0 KiB
HTML
<!doctype html>
|
|
<html lang="en" data-theme="dark">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<base href="/" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
|
<meta name="color-scheme" content="dark light" />
|
|
<title>Hanzo Social</title>
|
|
<meta
|
|
name="description"
|
|
content="Write once. Publish to every account you own, now or on a schedule."
|
|
/>
|
|
<style>
|
|
/* The two things only the host document can answer: how tall the app is,
|
|
and that its one child is a flex item. @hanzo/ui's stylesheet resets and
|
|
paints everything else. Without this the app grows to fit its content
|
|
instead of filling the window, and every pane that scrolls inside it
|
|
scrolls the page instead. */
|
|
#root {
|
|
display: flex;
|
|
height: 100dvh;
|
|
}
|
|
</style>
|
|
<script>
|
|
/* Keep gui's theme class in step with next-themes'. One decision, two
|
|
names: next-themes writes `light` on <html> and gui reads `t_light` /
|
|
`t_dark`, so without this the account's choice moves one of them and the
|
|
page stays painted the other way.
|
|
|
|
`was` is not an optimisation — a `classList.toggle` that changes nothing
|
|
still writes the attribute, and an observer reacting to its own write is
|
|
a loop. Comparing first makes the callback a no-op unless the theme
|
|
moved. Inline and in <head>, because the first paint happens before any
|
|
module runs. */
|
|
;(function () {
|
|
var e = document.documentElement, was
|
|
function s() {
|
|
var l = e.classList.contains('light')
|
|
if (l === was) return
|
|
was = l
|
|
e.classList.toggle('t_light', l)
|
|
e.classList.toggle('t_dark', !l)
|
|
}
|
|
s()
|
|
new MutationObserver(s).observe(e, { attributes: true, attributeFilter: ['class'] })
|
|
})()
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<div id="root"></div>
|
|
<script type="module" src="/src/main.tsx"></script>
|
|
</body>
|
|
</html>
|