diff options
| author | s-ol <s+removethis@s-ol.nu> | 2022-01-13 17:29:38 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2022-01-13 17:29:38 +0000 |
| commit | 31159ddff5bc489ab6216a72304e1f7c7ce4a432 (patch) | |
| tree | e0c6efe46d4590c77ceabb4094c8ecd7c4289e00 /client/src/ui/Menu.js | |
| parent | move everything into server/ (diff) | |
| parent | move everything into client/ (diff) | |
| download | fedidag-31159ddff5bc489ab6216a72304e1f7c7ce4a432.tar.gz fedidag-31159ddff5bc489ab6216a72304e1f7c7ce4a432.zip | |
Merge server and client repositories
Diffstat (limited to 'client/src/ui/Menu.js')
| -rw-r--r-- | client/src/ui/Menu.js | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/client/src/ui/Menu.js b/client/src/ui/Menu.js new file mode 100644 index 0000000..6f32280 --- /dev/null +++ b/client/src/ui/Menu.js @@ -0,0 +1,139 @@ +import { h, Fragment } from 'preact'; +import { useState, useEffect } from 'preact/hooks'; +import cn from 'classnames'; +import { API_PREFIX } from '../config'; +import css from './css'; + +const fetchJSON = async (url) => { + const res = await fetch(API_PREFIX + url, { credentials: 'include' }); + if (res.status !== 200) + throw new Error("wrong status"); + + return res.json(); +}; + +css` +a.discussion { + display: flex; + + padding: 0.25rem 0.5rem; + text-size: 2rem; + line-height: 2rem; + text-decoration: none; + + border-radius: 0.3rem; + + color: var(--theme-note-fg); + background: var(--theme-note-bg); +} + +a.discussion .access { + opacity: 0.5; + margin-right: 0.75rem; +} + +a.discussion .name { + flex: 1 1 auto; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +a.discussion > a { + margin-left: 0.75rem; + text-decoration: underline; + color: inherit; + opacity: 0.5; + + transition: opacity 0.3s; +} +a.discussion > a:hover { + opacity: 1; +} +`; + +const DiscussionLink = ({ id, name, url, attributedTo, user }) => { + const writable = attributedTo && attributedTo.indexOf(user) > -1; + + return ( + <a class="discussion" href={`?document=${id}`}> + <span class="access">{writable ? 'W' : 'R'}</span> + <span class="name">{name}</span> + {url && ( + <a href={url.href}>ext</a> + )} + </a> + ); +}; + +css` +ul.discussions { + list-style: none; + padding: 0; + + width: 26rem; +} + +ul.discussions > li { + margin: 0.2rem 0; +} +`; + +const DiscussionList = ({ discussions, user }) => { + return ( + <ul class="discussions"> + {discussions.map((discussion) => ( + <li> + <DiscussionLink {...discussion} user={user} /> + </li> + ))} + </ul> + ); +}; + +css` +div.menu { + margin: 1rem 2rem; +} +`; +export const Menu = () => { + const [user, setUser] = useState(null); + const [discussions, setDiscussions] = useState([]); + + useEffect(() => { + fetchJSON('/discdag/list') + .then(({ user, discussions }) => { + setUser(user ?? null); + setDiscussions(discussions); + }); + }, []); + + if (user === null) { + return ( + <div class="menu"> + <h2>Discussions</h2> + loading... + </div> + ); + } + + return ( + <div class="menu"> + <h2>Discussions</h2> + {/*user && user.name !== 'Guest' + ? ( + <> + <span>logged in as {user.name}</span> + <button>log out</button> + </> + ) + : ( + <> + <span>not logged in</span> + <button>log in</button> + </> + )*/} + <DiscussionList discussions={discussions} user={user?.id} /> + </div> + ); +}; |
