Skip to content

Commit

Permalink
feat(panel): added bookmarks to live console
Browse files Browse the repository at this point in the history
  • Loading branch information
tabarra committed Feb 23, 2024
1 parent ad04584 commit f63c123
Show file tree
Hide file tree
Showing 6 changed files with 197 additions and 117 deletions.
9 changes: 3 additions & 6 deletions docs/dev_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@
- [x] fix(core/playerlistmanager): dont wipe license cache on restart
- core/components/PlayerlistManager/index.ts -> handleServerStop
- repro: connect + disconnect, restart twice, and the id wont be on the list anymore
- [ ] merge prs
- [ ] feat(menu): add keymapping for tp to waypoint (PR #886)
- [ ] fix(nui/PlayerModel): require OneSync for bring and goto (PR #851)
- [ ] translations
- [x] merge prs (7 merged, 4 closed)
- [x] follow up recipe maintainers regarding fxmanifest description
- [x] live console bookmarks

- assorted changes
- [ ] FIXME: apparently pressing enter on the text form of the license key when setting up the server using tx doenst work?
Expand All @@ -22,9 +21,7 @@ seems like it just refreshes the page
- add snapshot and gc to advanced actions
- fix disallowed intents message

- follow up recipe maintainers regarding fxmanifest description
- rtl issue
- live console bookmarks

- [ ] build: generate fxmanifest files list dynamically
- [ ] easter egg with some old music? https://www.youtube.com/watch?v=nNoaXej0Jeg
Expand Down
45 changes: 45 additions & 0 deletions panel/src/hooks/liveConsole.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { useAtom } from "jotai";
import { atomWithStorage } from "jotai/utils";


/**
* Atoms
*/
const liveConsoleHistoryAtom = atomWithStorage<string[]>('liveConsoleCommandHistory', []);
const liveConsoleBookmarksAtom = atomWithStorage<string[]>('liveConsoleCommandBookmarks', []);
const historyMaxLength = 50;


/**
* Hooks
*/
export const useLiveConsoleHistory = () => {
const [history, setHistory] = useAtom(liveConsoleHistoryAtom);
return {
history,
setHistory,
appendHistory: (cmd: string) => {
const newHistory = history.filter((h) => h !== cmd);
if (newHistory.unshift(cmd) > historyMaxLength) newHistory.pop();
setHistory(newHistory);
},
wipeHistory: () => {
setHistory([]);
}
};
};

export const useLiveConsoleBookmarks = () => {
const [bookmarks, setBookmarks] = useAtom(liveConsoleBookmarksAtom);
return {
bookmarks,
addBookmark: (cmd: string) => {
if (!bookmarks.includes(cmd)) {
setBookmarks([cmd, ...bookmarks]);
}
},
removeBookmark: (cmd: string) => {
setBookmarks(bookmarks.filter((b) => b !== cmd));
}
};
}
24 changes: 17 additions & 7 deletions panel/src/pages/LiveConsole/LiveConsole.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,23 @@ import { ChevronsDownIcon, Loader2Icon } from "lucide-react";
import LiveConsoleFooter from "./LiveConsoleFooter";
import LiveConsoleHeader from "./LiveConsoleHeader";
import LiveConsoleSearchBar from "./LiveConsoleSearchBar";
// import LiveConsoleSaveSheet from "./LiveConsoleSaveSheet";
import LiveConsoleSaveSheet from "./LiveConsoleSaveSheet";

import ScrollDownAddon from "./ScrollDownAddon";
import terminalOptions from "./xtermOptions";
import './xtermOverrides.css';
import '@xterm/xterm/css/xterm.css';
import { getSocket, openExternalLink } from '@/lib/utils';
import { handleHotkeyEvent } from '@/lib/hotkeyEventListener';
import { useAdminPerms } from '@/hooks/auth';
import LiveConsoleSaveSheet from './LiveConsoleSaveSheet';


const keyDebounceTime = 150; //ms

export default function LiveConsole() {
// const [isSaveSheetOpen, setIsSaveSheetOpen] = useState(false);
const [isSaveSheetOpen, setIsSaveSheetOpen] = useState(false);
const [isConnected, setIsConnected] = useState(false);
const [showSearchBar, setShowSearchBar] = useState(false);
const termInputRef = useRef<HTMLInputElement>(null);
const setPageTitle = useSetPageTitle();
const refreshPage = useContentRefresh();
setPageTitle('Live Console');
Expand Down Expand Up @@ -245,8 +244,14 @@ export default function LiveConsole() {
setShowSearchBar(!showSearchBar);
}
const toggleSaveSheet = () => {
//TODO: implement
// setIsSaveSheetOpen(!isSaveSheetOpen);
setIsSaveSheetOpen(!isSaveSheetOpen);
}
const inputSuggestions = (cmd: string) => {
if (termInputRef.current) {
termInputRef.current.value = cmd;
termInputRef.current.focus();
}
setIsSaveSheetOpen(false);
}


Expand All @@ -267,7 +272,11 @@ export default function LiveConsole() {
</div>
) : null}

{/* <LiveConsoleSaveSheet isOpen={isSaveSheetOpen} closeSheet={() => setIsSaveSheetOpen(false)} /> */}
<LiveConsoleSaveSheet
isOpen={isSaveSheetOpen}
closeSheet={() => setIsSaveSheetOpen(false)}
toTermInput={(cmd) => inputSuggestions(cmd)}
/>

{/* Terminal container */}
<div ref={containerRef} className='absolute top-1 left-2 right-0 bottom-0' />
Expand All @@ -290,6 +299,7 @@ export default function LiveConsole() {
</div>

<LiveConsoleFooter
termInputRef={termInputRef}
isConnected={isConnected}
consoleWrite={consoleWrite}
consoleClear={consoleClear}
Expand Down
34 changes: 16 additions & 18 deletions panel/src/pages/LiveConsole/LiveConsoleFooter.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import React, { useEffect, useRef, useState } from 'react';
import { useAtom } from 'jotai';
import { atomWithStorage } from 'jotai/utils';
import { Input } from "@/components/ui/input";
import { cn, openExternalLink } from "@/lib/utils";
import { BookMarkedIcon, FileDownIcon, SearchIcon, Trash2Icon } from "lucide-react";
import { useAdminPerms } from '@/hooks/auth';
import { useLiveConsoleHistory } from '@/hooks/liveConsole';


type ConsoleFooterButtonProps = {
Expand All @@ -17,11 +16,14 @@ type ConsoleFooterButtonProps = {
function ConsoleFooterButton({ icon: Icon, title, disabled, onClick }: ConsoleFooterButtonProps) {
return (
<div
tabIndex={0}
className={cn(
"group bg-secondary xs:bg-transparent 2xl:hover:bg-secondary w-full rounded-lg px-1.5 py-2 cursor-pointer flex items-center justify-center",
`group bg-secondary xs:bg-transparent 2xl:hover:bg-secondary w-full rounded-lg px-1.5 py-2 cursor-pointer flex items-center justify-center
transition-all ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2`,
disabled && 'opacity-50 pointer-events-none'
)}
onClick={() => !disabled && onClick()}
onKeyDown={(e) => (e.code === 'Enter' || e.code === 'Space') && !disabled && onClick()}
>
<Icon className="w-6 h-6 2xl:w-5 2xl:h-5 text-muted-foreground group-hover:scale-110 group-hover:text-secondary-foreground inline" />
<span className="hidden 2xl:inline ml-1 align-middle">
Expand All @@ -32,24 +34,20 @@ function ConsoleFooterButton({ icon: Icon, title, disabled, onClick }: ConsoleFo
}


// Create the history atom outside of the component
// TODO: move this to hooks?
export const historyAtom = atomWithStorage<string[]>('liveConsoleCommandHistory', []);
const historyMaxLength = 100;

type LiveConsoleFooterProps = {
isConnected: boolean;
consoleWrite: (data: string) => void;
consoleWrite: (_data: string) => void;
consoleClear: () => void;
toggleSaveSheet: () => void;
toggleSearchBar: () => void;
termInputRef: React.RefObject<HTMLInputElement>;
}

export default function LiveConsoleFooter(props: LiveConsoleFooterProps) {
const [history, setHistory] = useAtom(historyAtom);
const { history, appendHistory } = useLiveConsoleHistory();
const [histIndex, setHistIndex] = useState(-1);
const savedInput = useRef('');
const termInputRef = useRef<HTMLInputElement>(null);
const termInputRef = props.termInputRef;
const { hasPerm } = useAdminPerms();
const hasWritePerm = hasPerm('console.write');

Expand All @@ -58,7 +56,7 @@ export default function LiveConsoleFooter(props: LiveConsoleFooterProps) {
if (props.isConnected && termInputRef.current) {
termInputRef.current.focus();
}
}, [props.isConnected]);
}, [props.isConnected, termInputRef]);

const handleArrowUp = () => {
if (!termInputRef.current) return;
Expand Down Expand Up @@ -90,12 +88,8 @@ export default function LiveConsoleFooter(props: LiveConsoleFooterProps) {
setHistIndex(-1);
termInputRef.current.value = '';
savedInput.current = '';

if (currentInput) {
const newHistory = history.filter((cmd) => cmd !== currentInput);
newHistory.unshift(currentInput);
if (newHistory.length > historyMaxLength) newHistory.pop();
setHistory(newHistory);
appendHistory(currentInput);
props.consoleWrite(currentInput);
}
};
Expand Down Expand Up @@ -144,7 +138,11 @@ export default function LiveConsoleFooter(props: LiveConsoleFooterProps) {
/>
</div>
<div className="flex flex-row justify-evenly gap-3 2xl:gap-1 select-none">
{/* <ConsoleFooterButton icon={BookMarkedIcon} title="Saved" onClick={props.toggleSaveSheet} /> */}
<ConsoleFooterButton
icon={BookMarkedIcon}
title="Saved"
onClick={props.toggleSaveSheet}
/>
<ConsoleFooterButton
icon={SearchIcon}
title="Search"
Expand Down
Loading

0 comments on commit f63c123

Please sign in to comment.