Skip to content

Commit e60cd5f

Browse files
committed
buncha refactoring, added themes, added tests, fixed settings persistence, idk buncha stuff
1 parent 1604e51 commit e60cd5f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+3612
-553
lines changed

package.json

+3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"preview": "vite preview",
1010
"tauri": "tauri",
1111
"test": "vitest",
12+
"test:run": "vitest run",
1213
"test:ui": "vitest --ui",
1314
"test:coverage": "vitest run --coverage",
1415
"test:watch": "vitest --watch"
@@ -20,6 +21,7 @@
2021
"@radix-ui/react-dropdown-menu": "^2.1.4",
2122
"@radix-ui/react-label": "^2.1.1",
2223
"@radix-ui/react-progress": "^1.1.1",
24+
"@radix-ui/react-radio-group": "^1.2.2",
2325
"@radix-ui/react-scroll-area": "^1.2.2",
2426
"@radix-ui/react-select": "^2.1.4",
2527
"@radix-ui/react-separator": "^1.1.1",
@@ -33,6 +35,7 @@
3335
"@tauri-apps/plugin-http": "^2.2.0",
3436
"@tauri-apps/plugin-opener": "^2",
3537
"@tauri-apps/plugin-process": "^2.2.0",
38+
"@tauri-apps/plugin-store": "^2.2.0",
3639
"@tauri-apps/plugin-updater": "~2.3.1",
3740
"@types/react-syntax-highlighter": "^15.5.13",
3841
"@types/uuid": "^10.0.0",

pnpm-lock.yaml

+44
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src-tauri/capabilities/default.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,4 @@
5858
},
5959
"updater:default"
6060
]
61-
}
61+
}

src-tauri/tauri.conf.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://schema.tauri.app/config/2",
33
"productName": "litepost",
4-
"version": "0.1.0",
4+
"version": "0.1.1",
55
"identifier": "com.litepost.app",
66
"build": {
77
"beforeDevCommand": "pnpm dev",

src/App.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { useTabs } from "./hooks/useTabs"
88
import { useUrlParams } from "./hooks/useUrlParams"
99
import { useRequest } from "./hooks/useRequest"
1010
import { useHistory } from "./hooks/useHistory"
11+
import { useThemeClass } from "./hooks/useThemeClass"
1112
import { HistoryItem, Tab } from "./types"
1213
import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels"
1314
import { Toaster } from "sonner"
@@ -16,6 +17,7 @@ import { UpdateChecker } from './components/UpdateChecker'
1617

1718
function App() {
1819
const { history, addHistoryItem, removeHistoryItem, clearHistory } = useHistory()
20+
const themeClass = useThemeClass()
1921
const {
2022
tabs,
2123
activeTab,
@@ -99,7 +101,7 @@ function App() {
99101
}
100102

101103
return (
102-
<div className="dark h-screen overflow-hidden">
104+
<div className={`${themeClass} h-screen overflow-hidden`}>
103105
<Toaster theme="dark" position="bottom-right" />
104106
<div className="h-full flex flex-col bg-background text-foreground min-w-0">
105107
<TitleBar

src/components/AuthConfigurator.tsx

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
22
import { Input } from "@/components/ui/input"
33
import { AuthConfig, AuthType } from "@/types"
4+
import { useThemeClass } from "@/hooks/useThemeClass"
45

56
interface AuthConfiguratorProps {
67
auth: AuthConfig
@@ -15,18 +16,20 @@ const AUTH_TYPES = [
1516
]
1617

1718
export function AuthConfigurator({ auth, onAuthChange }: AuthConfiguratorProps) {
19+
const themeClass = useThemeClass()
20+
1821
return (
1922
<div className="space-y-4">
2023
<Select value={auth.type} onValueChange={(value: AuthType) => onAuthChange({ ...auth, type: value })}>
2124
<SelectTrigger className="w-[200px] bg-background border-input focus:ring-0 focus-visible:ring-1">
2225
<SelectValue placeholder="Authentication Type" />
2326
</SelectTrigger>
24-
<SelectContent className="bg-gray-800 border-border">
27+
<SelectContent className={`${themeClass} bg-background border-border`}>
2528
{AUTH_TYPES.map((type) => (
2629
<SelectItem
2730
key={type.value}
2831
value={type.value}
29-
className="hover:bg-muted focus:bg-muted text-white"
32+
className="hover:bg-accent focus:bg-accent text-foreground"
3033
>
3134
{type.label}
3235
</SelectItem>
@@ -77,11 +80,11 @@ export function AuthConfigurator({ auth, onAuthChange }: AuthConfiguratorProps)
7780
<SelectTrigger className="w-[200px] bg-background border-input focus:ring-0 focus-visible:ring-1">
7881
<SelectValue placeholder="Add to" />
7982
</SelectTrigger>
80-
<SelectContent className="bg-gray-800 border-border">
81-
<SelectItem value="header" className="hover:bg-muted focus:bg-muted text-white">
83+
<SelectContent className={`${themeClass} bg-background border-border`}>
84+
<SelectItem value="header" className="hover:bg-accent focus:bg-accent text-foreground">
8285
Header
8386
</SelectItem>
84-
<SelectItem value="query" className="hover:bg-muted focus:bg-muted text-white">
87+
<SelectItem value="query" className="hover:bg-accent focus:bg-accent text-foreground">
8588
Query Parameter
8689
</SelectItem>
8790
</SelectContent>

src/components/CodeSnippetViewer.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
SelectValue,
1313
} from "@/components/ui/select"
1414
import { ScrollArea } from "@/components/ui/scroll-area"
15+
import { useThemeClass } from "@/hooks/useThemeClass"
1516

1617
interface CodeSnippetViewerProps {
1718
method: string
@@ -33,6 +34,7 @@ export function CodeSnippetViewer({
3334
cookies,
3435
}: CodeSnippetViewerProps) {
3536
const [selectedLanguage, setSelectedLanguage] = useState(CODE_SNIPPETS[0].value)
37+
const themeClass = useThemeClass()
3638

3739
const codeSnippet = useMemo(() => {
3840
const generator = CODE_SNIPPETS.find(s => s.value === selectedLanguage)?.generator
@@ -57,12 +59,12 @@ export function CodeSnippetViewer({
5759
<SelectTrigger className="w-[200px] bg-background border-input focus:ring-0 focus-visible:ring-1">
5860
<SelectValue placeholder="Select Language" />
5961
</SelectTrigger>
60-
<SelectContent className="bg-gray-800 border-border">
62+
<SelectContent className={`${themeClass} bg-background border-border`}>
6163
{CODE_SNIPPETS.map((lang) => (
6264
<SelectItem
6365
key={lang.value}
6466
value={lang.value}
65-
className="hover:bg-muted focus:bg-muted text-white"
67+
className="hover:bg-accent focus:bg-accent text-foreground"
6668
>
6769
{lang.label}
6870
</SelectItem>

src/components/CollapsibleJSON.tsx

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import { useState, memo } from "react"
2+
import { Button } from "./ui/button"
3+
import { ChevronRight, ChevronDown } from "lucide-react"
4+
5+
interface CollapsibleJSONProps {
6+
data: any
7+
level?: number
8+
isExpanded?: boolean
9+
maxAutoExpandDepth?: number
10+
maxAutoExpandArraySize?: number
11+
maxAutoExpandObjectSize?: number
12+
}
13+
14+
// Memoize the JSON node to prevent unnecessary re-renders
15+
export const CollapsibleJSON = memo(function CollapsibleJSON({
16+
data,
17+
level = 0,
18+
isExpanded = true,
19+
maxAutoExpandDepth = 2,
20+
maxAutoExpandArraySize = 10,
21+
maxAutoExpandObjectSize = 5
22+
}: CollapsibleJSONProps) {
23+
const shouldAutoExpand = () => {
24+
if (level >= maxAutoExpandDepth) return false
25+
26+
const isObject = typeof data === 'object' && data !== null
27+
if (!isObject) return true
28+
29+
const entries = Object.entries(data)
30+
if (Array.isArray(data) && entries.length > maxAutoExpandArraySize) return false
31+
if (!Array.isArray(data) && entries.length > maxAutoExpandObjectSize) return false
32+
33+
return true
34+
}
35+
36+
const [expanded, setExpanded] = useState(isExpanded && shouldAutoExpand())
37+
const isObject = typeof data === 'object' && data !== null
38+
const isArray = Array.isArray(data)
39+
40+
if (!isObject) {
41+
return (
42+
<span className={typeof data === 'string' ? 'text-green-400' : 'text-blue-400'}>
43+
{JSON.stringify(data)}
44+
</span>
45+
)
46+
}
47+
48+
const entries = Object.entries(data)
49+
const isEmpty = entries.length === 0
50+
51+
if (isEmpty) {
52+
return <span>{isArray ? '[]' : '{}'}</span>
53+
}
54+
55+
const toggleExpand = (e: React.MouseEvent) => {
56+
e.stopPropagation()
57+
setExpanded(!expanded)
58+
}
59+
60+
return (
61+
<div className="relative" style={{ paddingLeft: level > 0 ? '0.5rem' : 0 }}>
62+
<div className="flex items-center gap-0.5 cursor-pointer hover:bg-muted/50 rounded px-0.5" onClick={toggleExpand}>
63+
<Button variant="ghost" size="icon" className="h-4 w-4 p-0">
64+
{expanded ? <ChevronDown className="h-3 w-3" /> : <ChevronRight className="h-3 w-3" />}
65+
</Button>
66+
<span>{isArray ? '[' : '{'}</span>
67+
{!expanded && (
68+
<span className="text-muted-foreground text-xs ml-1">
69+
{isArray ? `${entries.length} items` : `${entries.length} properties`}
70+
</span>
71+
)}
72+
</div>
73+
{expanded && (
74+
<div className="pl-3 border-l border-muted-foreground/20">
75+
{entries.map(([key, value]) => (
76+
<div key={key} className="flex items-start py-0.5">
77+
<div className="flex-1 flex">
78+
<span className="text-yellow-400 whitespace-nowrap">
79+
{!isArray && `"${key}"`}{isArray && key}
80+
</span>
81+
<span className="mx-1">:</span>
82+
<div className="flex-1 min-w-0">
83+
<CollapsibleJSON
84+
data={value}
85+
level={level + 1}
86+
maxAutoExpandDepth={maxAutoExpandDepth}
87+
maxAutoExpandArraySize={maxAutoExpandArraySize}
88+
maxAutoExpandObjectSize={maxAutoExpandObjectSize}
89+
/>
90+
</div>
91+
</div>
92+
</div>
93+
))}
94+
</div>
95+
)}
96+
<div className={expanded ? "pl-3" : ""}>
97+
<span>{isArray ? ']' : '}'}</span>
98+
</div>
99+
</div>
100+
)
101+
})

src/components/CollectionsPanel.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
import { useState, forwardRef, useRef } from "react"
2424
import { toast } from "sonner"
2525
import { cn } from "@/lib/utils"
26+
import { useThemeClass } from "@/hooks/useThemeClass"
2627

2728
const methodColors: Record<string, string> = {
2829
GET: "bg-blue-500/10 text-blue-500",
@@ -58,6 +59,7 @@ export const CollectionsPanel = forwardRef<HTMLButtonElement, CollectionsPanelPr
5859

5960
const [expandedCollections, setExpandedCollections] = useState<Set<string>>(new Set())
6061
const fileInputRef = useRef<HTMLInputElement>(null)
62+
const themeClass = useThemeClass()
6163

6264
const toggleCollection = (id: string) => {
6365
setExpandedCollections(prev => {
@@ -173,7 +175,7 @@ export const CollectionsPanel = forwardRef<HTMLButtonElement, CollectionsPanelPr
173175
</Button>
174176
</SheetTrigger>
175177
<SheetContent
176-
className="dark w-[600px] sm:w-[800px] sm:max-w-none border-l border-border bg-background text-foreground [&_button>svg]:text-foreground [&_.close-button]:hover:bg-muted/60"
178+
className={`${themeClass} w-[600px] sm:w-[800px] sm:max-w-none border-l border-border bg-background text-foreground [&_button>svg]:text-foreground [&_.close-button]:hover:bg-muted/60`}
177179
side="right"
178180
>
179181
<SheetHeader>

src/components/EnvironmentManager.tsx

+5-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Label } from "@/components/ui/label"
55
import { useEnvironmentStore } from "@/store/environments"
66
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
77
import { KeyValueList } from "./KeyValueList"
8+
import { useThemeClass } from "@/hooks/useThemeClass"
89

910
export function EnvironmentManager() {
1011
const {
@@ -15,6 +16,7 @@ export function EnvironmentManager() {
1516
deleteEnvironment,
1617
setActiveEnvironment,
1718
} = useEnvironmentStore()
19+
const themeClass = useThemeClass()
1820

1921
const handleAddEnvironment = () => {
2022
addEnvironment("New Environment")
@@ -59,13 +61,13 @@ export function EnvironmentManager() {
5961
<SelectTrigger className="w-full bg-background text-foreground">
6062
<SelectValue placeholder="No environment selected" />
6163
</SelectTrigger>
62-
<SelectContent className="dark bg-popover text-popover-foreground">
63-
<SelectItem value="null">None</SelectItem>
64+
<SelectContent className={`${themeClass} bg-background border-border`}>
65+
<SelectItem value="null" className="hover:bg-accent focus:bg-accent text-foreground">None</SelectItem>
6466
{environments.map((env) => (
6567
<SelectItem
6668
key={env.id}
6769
value={env.id}
68-
className="hover:bg-accent/50"
70+
className="hover:bg-accent focus:bg-accent text-foreground"
6971
>
7072
{env.name}
7173
</SelectItem>

0 commit comments

Comments
 (0)