mirror of
https://git.srhtnin.garden/sarah/SaraView.git
synced 2026-10-14 10:38:11 +02:00
Initial commit
This commit is contained in:
commit
8aa223bc7b
40 files changed
+4320
No files matched your search
@@ -0,0 +1,258 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
import Sidebar from "./Components/Sidebar.jsx";
|
||||
import Breadcrumb from "./Components/Breadcrumb.jsx";
|
||||
import PreviewPane from "./Components/PreviewPane.jsx";
|
||||
import DirectoryPane from "./Components/DirectoryPane.jsx";
|
||||
import TagPanel from "./Components/TagPanel.jsx";
|
||||
import SettingsPanel from "./Components/SettingsPanel.jsx";
|
||||
import LoginScreen from "./Components/LoginScreen.jsx";
|
||||
import { FetchAuthStatus, FetchMe, FetchRoots, FetchSettings, FetchTheme } from "./Api.js";
|
||||
import { PaletteRoles } from "./ThemeRoles.js";
|
||||
|
||||
function ApplyTheme(Palette) {
|
||||
const RootStyle = document.documentElement.style;
|
||||
PaletteRoles.forEach((Role) => {
|
||||
if (Palette[Role]) {
|
||||
RootStyle.setProperty(`--${Role}`, Palette[Role]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function ApplyFont(Settings) {
|
||||
const RootStyle = document.documentElement.style;
|
||||
RootStyle.setProperty(
|
||||
"--FontFamily",
|
||||
`"${Settings.FontFamily}", "Cascadia Mono", monospace`
|
||||
);
|
||||
RootStyle.setProperty("--FontSize", `${Settings.FontSize}px`);
|
||||
}
|
||||
|
||||
function GetParentPath(FilePath) {
|
||||
return FilePath.includes("/") ? FilePath.slice(0, FilePath.lastIndexOf("/")) : "";
|
||||
}
|
||||
|
||||
export default function App() {
|
||||
const [AuthState, SetAuthState] = useState("Loading"); // Loading | Bootstrap | LoggedOut | LoggedIn
|
||||
const [CurrentUser, SetCurrentUser] = useState(null);
|
||||
|
||||
const [Roots, SetRoots] = useState([]);
|
||||
const [ActiveRoot, SetActiveRoot] = useState(null);
|
||||
const [ViewPath, SetViewPath] = useState("");
|
||||
const [ViewIsDirectory, SetViewIsDirectory] = useState(true);
|
||||
const [ViewFileType, SetViewFileType] = useState(null);
|
||||
const [CurrentDirectoryPath, SetCurrentDirectoryPath] = useState("");
|
||||
const [SidebarKey, SetSidebarKey] = useState(0);
|
||||
const [Settings, SetSettings] = useState(null);
|
||||
const [IsSettingsOpen, SetIsSettingsOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
FetchAuthStatus().then((Status) => {
|
||||
if (!Status.SetupComplete) {
|
||||
SetAuthState("Bootstrap");
|
||||
return;
|
||||
}
|
||||
|
||||
FetchMe()
|
||||
.then((User) => {
|
||||
SetCurrentUser(User);
|
||||
SetAuthState("LoggedIn");
|
||||
})
|
||||
.catch(() => SetAuthState("LoggedOut"));
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (AuthState !== "LoggedIn") return;
|
||||
|
||||
FetchRoots().then((Fetched) => {
|
||||
SetRoots(Fetched);
|
||||
if (Fetched.length > 0) {
|
||||
SetActiveRoot(Fetched[0].Name);
|
||||
}
|
||||
});
|
||||
|
||||
FetchSettings().then((FetchedSettings) => {
|
||||
SetSettings(FetchedSettings);
|
||||
ApplyFont(FetchedSettings);
|
||||
FetchTheme(FetchedSettings.ThemeName).then(ApplyTheme);
|
||||
});
|
||||
}, [AuthState]);
|
||||
|
||||
function HandleAuthenticated(User) {
|
||||
SetCurrentUser(User);
|
||||
SetAuthState("LoggedIn");
|
||||
}
|
||||
|
||||
function HandleLoggedOut() {
|
||||
SetCurrentUser(null);
|
||||
SetAuthState("LoggedOut");
|
||||
}
|
||||
|
||||
function HandleProfileUpdated(UpdatedUser) {
|
||||
SetCurrentUser((Existing) => ({ ...Existing, ...UpdatedUser }));
|
||||
}
|
||||
|
||||
function HandleSettingsChanged(NewSettings) {
|
||||
SetSettings(NewSettings);
|
||||
ApplyFont(NewSettings);
|
||||
FetchTheme(NewSettings.ThemeName).then(ApplyTheme);
|
||||
SetSidebarKey((Key) => Key + 1);
|
||||
}
|
||||
|
||||
function HandleSelectFile(FilePath, FileType) {
|
||||
SetViewPath(FilePath);
|
||||
SetViewIsDirectory(false);
|
||||
SetViewFileType(FileType);
|
||||
SetCurrentDirectoryPath(GetParentPath(FilePath));
|
||||
}
|
||||
|
||||
function HandleNavigateDirectory(DirectoryPath) {
|
||||
SetViewPath(DirectoryPath);
|
||||
SetViewIsDirectory(true);
|
||||
SetViewFileType(null);
|
||||
SetCurrentDirectoryPath(DirectoryPath);
|
||||
}
|
||||
|
||||
function HandleBrowseDirectory(DirectoryPath) {
|
||||
SetCurrentDirectoryPath(DirectoryPath);
|
||||
}
|
||||
|
||||
function HandleEntrySelect(EntryPath, IsDirectory, FileType) {
|
||||
if (IsDirectory) {
|
||||
HandleNavigateDirectory(EntryPath);
|
||||
} else {
|
||||
HandleSelectFile(EntryPath, FileType);
|
||||
}
|
||||
}
|
||||
|
||||
function RefreshSidebar() {
|
||||
SetSidebarKey((Key) => Key + 1);
|
||||
}
|
||||
|
||||
function HandleEntryRenamed(OldPath, NewPath, IsDirectory) {
|
||||
RefreshSidebar();
|
||||
|
||||
if (!ViewIsDirectory && ViewPath === OldPath) {
|
||||
HandleSelectFile(NewPath, ViewFileType);
|
||||
} else if (ViewIsDirectory && ViewPath === OldPath) {
|
||||
HandleNavigateDirectory(NewPath);
|
||||
} else if (CurrentDirectoryPath === OldPath) {
|
||||
SetCurrentDirectoryPath(NewPath);
|
||||
}
|
||||
}
|
||||
|
||||
function HandleEntryDeleted(DeletedPath) {
|
||||
RefreshSidebar();
|
||||
|
||||
if (ViewPath === DeletedPath || ViewPath.startsWith(`${DeletedPath}/`)) {
|
||||
HandleNavigateDirectory(GetParentPath(DeletedPath));
|
||||
} else if (CurrentDirectoryPath === DeletedPath || CurrentDirectoryPath.startsWith(`${DeletedPath}/`)) {
|
||||
SetCurrentDirectoryPath(GetParentPath(DeletedPath));
|
||||
}
|
||||
}
|
||||
|
||||
if (AuthState === "Loading") {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (AuthState === "Bootstrap") {
|
||||
return <LoginScreen IsBootstrap OnAuthenticated={HandleAuthenticated} />;
|
||||
}
|
||||
|
||||
if (AuthState === "LoggedOut") {
|
||||
return <LoginScreen IsBootstrap={false} OnAuthenticated={HandleAuthenticated} />;
|
||||
}
|
||||
|
||||
// Only take up a TopBar row at all if there's something to put in it —
|
||||
// otherwise turning breadcrumbs off with a single root left a blank strip.
|
||||
const ShowTopBar = (Settings && Settings.ShowBreadcrumbs) || Roots.length > 1;
|
||||
const ConfirmBeforeDelete = Settings ? Settings.ConfirmBeforeDelete : true;
|
||||
|
||||
return (
|
||||
<div className="AppShell">
|
||||
<Sidebar
|
||||
key={SidebarKey}
|
||||
RootName={ActiveRoot}
|
||||
SelectedFile={ViewIsDirectory ? null : ViewPath}
|
||||
CurrentDirectoryPath={CurrentDirectoryPath}
|
||||
CurrentUser={CurrentUser}
|
||||
OnSelectFile={HandleSelectFile}
|
||||
OnNavigateDirectory={HandleNavigateDirectory}
|
||||
OnBrowseDirectory={HandleBrowseDirectory}
|
||||
OnEntryRenamed={HandleEntryRenamed}
|
||||
OnEntryDeleted={HandleEntryDeleted}
|
||||
OnOpenSettings={() => SetIsSettingsOpen(true)}
|
||||
OnEntryCreated={RefreshSidebar}
|
||||
UseHyphenBullets={Settings ? Settings.UseHyphenBullets : true}
|
||||
UseAsciiFolderIcons={Settings ? Settings.UseAsciiFolderIcons : true}
|
||||
NavigateIntoDirectories={Settings ? Settings.NavigateIntoDirectories : false}
|
||||
NewEntryButtonsAtTop={Settings ? Settings.NewEntryButtonsAtTop : false}
|
||||
ConfirmBeforeDelete={ConfirmBeforeDelete}
|
||||
/>
|
||||
<div className="MainColumn">
|
||||
{ShowTopBar && (
|
||||
<div className="TopBar">
|
||||
{Settings && Settings.ShowBreadcrumbs ? (
|
||||
<Breadcrumb
|
||||
RootName={ActiveRoot}
|
||||
FilePath={ViewPath}
|
||||
IsDirectory={ViewIsDirectory}
|
||||
OnNavigate={HandleNavigateDirectory}
|
||||
/>
|
||||
) : (
|
||||
<span />
|
||||
)}
|
||||
{Roots.length > 1 && (
|
||||
<select
|
||||
className="RootSwitcher"
|
||||
value={ActiveRoot || ""}
|
||||
onChange={(Event) => SetActiveRoot(Event.target.value)}
|
||||
>
|
||||
{Roots.map((Root) => (
|
||||
<option key={Root.Name} value={Root.Name}>
|
||||
{Root.Name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<div className="MainBody">
|
||||
{ViewIsDirectory ? (
|
||||
<DirectoryPane
|
||||
RootName={ActiveRoot}
|
||||
DirectoryPath={ViewPath}
|
||||
OnEntrySelect={HandleEntrySelect}
|
||||
OnEntryCreated={RefreshSidebar}
|
||||
OnEntryRenamed={HandleEntryRenamed}
|
||||
OnEntryDeleted={HandleEntryDeleted}
|
||||
UseHyphenBullets={Settings ? Settings.UseHyphenBullets : true}
|
||||
UseAsciiFolderIcons={Settings ? Settings.UseAsciiFolderIcons : true}
|
||||
ConfirmBeforeDelete={ConfirmBeforeDelete}
|
||||
/>
|
||||
) : (
|
||||
<PreviewPane
|
||||
RootName={ActiveRoot}
|
||||
FilePath={ViewPath}
|
||||
FileType={ViewFileType}
|
||||
OnNavigateLink={HandleSelectFile}
|
||||
ShowGitBlame={Settings ? Settings.ShowGitBlame : false}
|
||||
StickyToolbar={Settings ? Settings.StickyToolbar : true}
|
||||
/>
|
||||
)}
|
||||
{!ViewIsDirectory && <TagPanel RootName={ActiveRoot} FilePath={ViewPath} />}
|
||||
</div>
|
||||
</div>
|
||||
{IsSettingsOpen && (
|
||||
<SettingsPanel
|
||||
CurrentUser={CurrentUser}
|
||||
OnClose={() => SetIsSettingsOpen(false)}
|
||||
OnSettingsChanged={HandleSettingsChanged}
|
||||
OnLoggedOut={HandleLoggedOut}
|
||||
OnProfileUpdated={HandleProfileUpdated}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user