Added guests.

This commit is contained in:
sarah committed 2026-09-21 21:09:25 +02:00
1 parent 6743dd7626
commit 9736a55e00
10 files changed
+200 -84

No files matched your search

+32 -27
View File
@@ -22,6 +22,7 @@ export default function DirectoryPane({
UseHyphenBullets,
UseAsciiFolderIcons,
ConfirmBeforeDelete,
IsGuest,
}) {
const [Entries, SetEntries] = useState([]);
const [LoadError, SetLoadError] = useState(null);
@@ -139,10 +140,12 @@ export default function DirectoryPane({
return (
<div className="DirectoryPane">
<div className="PreviewToolbar">
<button onClick={OpenCreateFileModal}>New File</button>
<button onClick={OpenCreateDirectoryModal}>New Directory</button>
</div>
{!IsGuest && (
<div className="PreviewToolbar">
<button onClick={OpenCreateFileModal}>New File</button>
<button onClick={OpenCreateDirectoryModal}>New Directory</button>
</div>
)}
{LoadError && <div className="SidebarError">{LoadError}</div>}
<div className="DirectoryList">
{Entries.map((Entry) => (
@@ -159,29 +162,31 @@ export default function DirectoryPane({
: GetFileIcon(UseHyphenBullets)}
</span>
<span className="TreeLabel">{Entry.Name}</span>
<span className="TreeRowActions">
<button
className="TreeRowActionButton"
onClick={(Event) => HandleRequestLockEdit(Event, Entry)}
title="Access control"
>
🔒
</button>
<button
className="TreeRowActionButton"
onClick={(Event) => HandleRename(Event, Entry)}
title="Rename / move"
>
✎
</button>
<button
className="TreeRowActionButton"
onClick={(Event) => HandleDelete(Event, Entry)}
title="Delete"
>
✕
</button>
</span>
{!IsGuest && (
<span className="TreeRowActions">
<button
className="TreeRowActionButton"
onClick={(Event) => HandleRequestLockEdit(Event, Entry)}
title="Access control"
>
🔒
</button>
<button
className="TreeRowActionButton"
onClick={(Event) => HandleRename(Event, Entry)}
title="Rename / move"
>
✎
</button>
<button
className="TreeRowActionButton"
onClick={(Event) => HandleDelete(Event, Entry)}
title="Delete"
>
✕
</button>
</span>
)}
</div>
))}
{Entries.length === 0 && !LoadError && (
+6 -1
View File
@@ -2,7 +2,7 @@ import React, { useState } from "react";
import { Bootstrap, Login } from "../Api.js";
export default function LoginScreen({ IsBootstrap, OnAuthenticated }) {
export default function LoginScreen({ IsBootstrap, OnAuthenticated, OnContinueAsGuest }) {
const [Username, SetUsername] = useState("");
const [Password, SetPassword] = useState("");
const [ConfirmPassword, SetConfirmPassword] = useState("");
@@ -74,6 +74,11 @@ export default function LoginScreen({ IsBootstrap, OnAuthenticated }) {
<button type="submit" disabled={IsSubmitting}>
{IsSubmitting ? "..." : IsBootstrap ? "Create account & log in" : "Log in"}
</button>
{!IsBootstrap && OnContinueAsGuest && (
<button type="button" className="LoginGuestButton" onClick={OnContinueAsGuest}>
Continue as Guest
</button>
)}
</form>
</div>
);
+10 -6
View File
@@ -170,6 +170,7 @@ export default function PreviewPane({
ShowGitBlame,
ShowBlameAvatars,
StickyToolbar,
IsGuest,
}) {
const [Content, SetContent] = useState("");
const [ResolvedContent, SetResolvedContent] = useState("");
@@ -259,7 +260,7 @@ export default function PreviewPane({
return (
<div className="PreviewFrame">
<div className={ToolbarClass}>
<button onClick={() => SetIsEditing(true)}>Edit</button>
{!IsGuest && <button onClick={() => SetIsEditing(true)}>Edit</button>}
</div>
<iframe title={FilePath} sandbox="" src={GetRawFileUrl(RootName, FilePath)} />
</div>
@@ -270,7 +271,7 @@ export default function PreviewPane({
return (
<div className="PreviewMarkdown">
<div className={ToolbarClass}>
<button onClick={() => SetIsEditing(true)}>Edit</button>
{!IsGuest && <button onClick={() => SetIsEditing(true)}>Edit</button>}
</div>
<div
className="MarkdownBody"
@@ -292,7 +293,7 @@ export default function PreviewPane({
return (
<div className="PreviewText">
<div className={ToolbarClass}>
<button onClick={() => SetIsEditing(true)}>Edit</button>
{!IsGuest && <button onClick={() => SetIsEditing(true)}>Edit</button>}
</div>
<pre className="TextBody">{ResolvedContent}</pre>
</div>
@@ -306,14 +307,17 @@ export default function PreviewPane({
{(FileType === "markdown" || FileType === "text" || FileType === "html") && (
<button onClick={() => SetIsEditing(false)}>View</button>
)}
<button onClick={HandleSave} disabled={IsSaving}>
{IsSaving ? "Saving…" : "Save"}
</button>
{!IsGuest && (
<button onClick={HandleSave} disabled={IsSaving}>
{IsSaving ? "Saving…" : "Save"}
</button>
)}
{SaveError && <span className="SaveErrorText">{SaveError}</span>}
</div>
<CodeMirror
value={Content}
height="100%"
editable={!IsGuest}
extensions={[
...GetLanguageExtension(FileType),
...(ShowGitBlame ? [BuildBlameGutter(BlameMap, ShowBlameAvatars)] : []),
+37 -18
View File
@@ -30,6 +30,7 @@ function TreeNode({
UseAsciiFolderIcons,
NavigateIntoDirectories,
ConfirmBeforeDelete,
IsGuest,
}) {
const [IsExpanded, SetIsExpanded] = useState(false);
const [Children, SetChildren] = useState(null);
@@ -134,17 +135,19 @@ function TreeNode({
: GetFileIcon(UseHyphenBullets)}
</span>
<span className="TreeLabel">{Entry.Name}</span>
<span className="TreeRowActions">
<button className="TreeRowActionButton" onClick={HandleLockClick} title="Access control">
🔒
</button>
<button className="TreeRowActionButton" onClick={HandleRename} title="Rename / move">
✎
</button>
<button className="TreeRowActionButton" onClick={HandleDelete} title="Delete">
✕
</button>
</span>
{!IsGuest && (
<span className="TreeRowActions">
<button className="TreeRowActionButton" onClick={HandleLockClick} title="Access control">
🔒
</button>
<button className="TreeRowActionButton" onClick={HandleRename} title="Rename / move">
✎
</button>
<button className="TreeRowActionButton" onClick={HandleDelete} title="Delete">
✕
</button>
</span>
)}
</div>
{IsExpanded && Children && (
<div className="TreeChildren">
@@ -167,6 +170,7 @@ function TreeNode({
UseAsciiFolderIcons={UseAsciiFolderIcons}
NavigateIntoDirectories={NavigateIntoDirectories}
ConfirmBeforeDelete={ConfirmBeforeDelete}
IsGuest={IsGuest}
/>
))}
</div>
@@ -175,7 +179,7 @@ function TreeNode({
);
}
function UserBadge({ CurrentUser, OnOpenSettings }) {
function UserBadge({ CurrentUser, OnOpenSettings, OnRequestLogin }) {
const [AvatarFailed, SetAvatarFailed] = useState(false);
useEffect(() => {
@@ -184,6 +188,16 @@ function UserBadge({ CurrentUser, OnOpenSettings }) {
if (!CurrentUser) return null;
if (CurrentUser.IsGuest) {
return (
<span className="UserBadge" onClick={OnRequestLogin} title="Browsing as Guest - click to log in">
<span className="UserBadgeInitial" style={{ background: `var(--${CurrentUser.Colour || "Purple"})` }}>
G
</span>
</span>
);
}
const AvatarUrl = CurrentUser.AvatarNonce
? `${GetAvatarUrl(CurrentUser.Username)}&v=${CurrentUser.AvatarNonce}`
: GetAvatarUrl(CurrentUser.Username);
@@ -221,12 +235,14 @@ export default function Sidebar({
OnEntryRenamed,
OnEntryDeleted,
OnOpenSettings,
OnRequestLogin,
OnEntryCreated,
UseHyphenBullets,
UseAsciiFolderIcons,
NavigateIntoDirectories,
NewEntryButtonsAtTop,
ConfirmBeforeDelete,
IsGuest,
}) {
const [RootEntries, SetRootEntries] = useState([]);
const [LoadError, SetLoadError] = useState(null);
@@ -299,13 +315,15 @@ export default function Sidebar({
SaraView
</span>
<span className="SidebarHeaderRight">
<UserBadge CurrentUser={CurrentUser} OnOpenSettings={OnOpenSettings} />
<button className="SettingsButton" onClick={OnOpenSettings}>
⚙
</button>
<UserBadge CurrentUser={CurrentUser} OnOpenSettings={OnOpenSettings} OnRequestLogin={OnRequestLogin} />
{!IsGuest && (
<button className="SettingsButton" onClick={OnOpenSettings}>
⚙
</button>
)}
</span>
</div>
{NewEntryButtonsAtTop && (
{NewEntryButtonsAtTop && !IsGuest && (
<div className="SidebarNewEntry SidebarNewEntryTop">
<button onClick={OpenCreateFileModal}>New File</button>
<button onClick={OpenCreateDirectoryModal}>New Directory</button>
@@ -332,10 +350,11 @@ export default function Sidebar({
UseAsciiFolderIcons={UseAsciiFolderIcons}
NavigateIntoDirectories={NavigateIntoDirectories}
ConfirmBeforeDelete={ConfirmBeforeDelete}
IsGuest={IsGuest}
/>
))}
</div>
{!NewEntryButtonsAtTop && (
{!NewEntryButtonsAtTop && !IsGuest && (
<div className="SidebarNewEntry">
<button onClick={OpenCreateFileModal}>New File</button>
<button onClick={OpenCreateDirectoryModal}>New Directory</button>