Skip to content

Commit 94e50d1

Browse files
committed
refactor 👌
1 parent 898e1a5 commit 94e50d1

18 files changed

+290
-576
lines changed

‎.yarn/install-state.gz

-27.6 KB
Binary file not shown.

‎main/background.ts

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
import { initDatabase } from "./helpers/db/createDB";
2626
import { parseFile } from "music-metadata";
2727
import fs from "fs";
28+
import { Howl } from "howler";
2829

2930
const isProd = process.env.NODE_ENV === "production";
3031

@@ -110,6 +111,7 @@ ipcMain.on("set-rpc-state", (_, { details, state, timestamp }) => {
110111
largeImageKey: "logo",
111112
largeImageText: `v${app.getVersion()}`,
112113
instance: false,
114+
type: "LISTENING",
113115
};
114116

115117
if (timestamp) {

‎package.json

-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@
4646
"music-metadata": "^7.14.0",
4747
"next-themes": "^0.3.0",
4848
"react-hook-form": "^7.52.1",
49-
"recharts": "^2.12.7",
5049
"sonner": "^1.5.0",
5150
"tailwind-gradient-mask-image": "^1.2.0",
5251
"tailwind-merge": "^2.4.0",

‎renderer/components/main/navbar.tsx

+30
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import {
22
IconArrowRight,
3+
IconDeviceDesktop,
34
IconFocusCentered,
45
IconInbox,
6+
IconMoon,
57
IconPlus,
68
IconSearch,
9+
IconSun,
710
IconVinyl,
811
} from "@tabler/icons-react";
912
import {
@@ -46,6 +49,7 @@ import {
4649
import { zodResolver } from "@hookform/resolvers/zod";
4750
import { useForm } from "react-hook-form";
4851
import { z } from "zod";
52+
import { useTheme } from "next-themes";
4953

5054
const formSchema = z.object({
5155
name: z.string().min(2, {
@@ -68,6 +72,27 @@ const Navbar = () => {
6872
const [search, setSearch] = useState("");
6973
const [loading, setLoading] = useState(false);
7074
const { setQueueAndPlay } = usePlayer();
75+
const { theme, setTheme } = useTheme();
76+
77+
const handleThemeToggle = () => {
78+
if (theme === "light") {
79+
setTheme("dark");
80+
} else if (theme === "dark") {
81+
setTheme("system");
82+
} else {
83+
setTheme("light");
84+
}
85+
};
86+
87+
const renderIcon = () => {
88+
if (theme === "light") {
89+
return <IconSun stroke={2} className="w-5" />;
90+
} else if (theme === "dark") {
91+
return <IconMoon stroke={2} className="w-5" />;
92+
} else {
93+
return <IconDeviceDesktop stroke={2} className="w-5" />;
94+
}
95+
};
7196

7297
useEffect(() => {
7398
const down = (e) => {
@@ -77,6 +102,8 @@ const Navbar = () => {
77102
}
78103
};
79104

105+
console.log(theme);
106+
80107
document.addEventListener("keydown", down);
81108
return () => document.removeEventListener("keydown", down);
82109
}, []);
@@ -230,6 +257,9 @@ const Navbar = () => {
230257
</Tooltip>
231258
</div>
232259
</TooltipProvider>
260+
<Button variant="ghost" onClick={handleThemeToggle} asChild>
261+
{renderIcon()}
262+
</Button>
233263
<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
234264
<DialogContent>
235265
<div className="flex h-full w-full items-start gap-6">

‎renderer/components/main/player.tsx

+14-6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
IconArrowsShuffle2,
55
IconCheck,
66
IconClock,
7+
IconDisc,
78
IconHeart,
89
IconInfoCircle,
910
IconListTree,
@@ -15,6 +16,7 @@ import {
1516
IconPlayerSkipForward,
1617
IconPlus,
1718
IconRepeat,
19+
IconRipple,
1820
IconVinyl,
1921
IconVolume,
2022
IconVolumeOff,
@@ -408,9 +410,9 @@ export const Player = () => {
408410
</div>
409411
<div className="!absolute right-0 top-0 w-full">
410412
<div
411-
className={`wora-border ${showSpectrogram ? "block" : "hidden"} relative mt-2 h-full w-full rounded-xl bg-white/70 backdrop-blur-xl dark:bg-black/70`}
413+
className={`wora-border ${soundRef.current && soundRef.current.playing() && showSpectrogram ? "block" : "hidden"} relative mt-2 h-full w-full rounded-xl bg-black`}
412414
>
413-
<div className="h-utility w-full px-6 pt-6">
415+
<div className="h-utility w-full p-6">
414416
{soundRef.current && <Spectrogram howl={soundRef.current} />}
415417
</div>
416418
</div>
@@ -560,7 +562,7 @@ export const Player = () => {
560562
<div className="absolute -left-24 mt-0.5">
561563
<Tooltip delayDuration={0}>
562564
<TooltipTrigger>
563-
<IconWaveSine stroke={2} className="w-3.5" />
565+
<IconRipple stroke={2} className="w-3.5" />
564566
</TooltipTrigger>
565567
<TooltipContent side="left" sideOffset={25}>
566568
<p>
@@ -727,9 +729,15 @@ export const Player = () => {
727729
</div>
728730
</DialogContent>
729731
</Dialog>
730-
<Button variant="ghost" onClick={toggleSpectrogram}>
731-
<IconWaveSine stroke={2} size={15} />
732-
</Button>
732+
{soundRef.current && soundRef.current.playing() ? (
733+
<Button variant="ghost" onClick={toggleSpectrogram}>
734+
<IconWaveSine stroke={2} size={15} />
735+
</Button>
736+
) : (
737+
<Button variant="ghost">
738+
<IconWaveSine stroke={2} size={15} />
739+
</Button>
740+
)}
733741
<Button variant="ghost" onClick={toggleQueue}>
734742
<IconListTree stroke={2} size={15} />
735743
</Button>

‎renderer/components/ui/actions.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ function Actions() {
2525
}, []);
2626

2727
return (
28-
<div className="absolute top-0 z-50 flex h-11 w-full items-center justify-end px-8 py-2.5">
28+
<div className="drag absolute top-0 z-50 flex h-11 w-full items-center justify-end px-8 py-2.5">
2929
<div className="relative flex h-full w-full items-center justify-center">
30-
<div className="drag flex h-full items-center gap-2">
30+
<div className="flex h-full items-center gap-2">
3131
<Image
3232
src={"/assets/Logo [Dark].ico"}
3333
alt="logo"
@@ -44,7 +44,7 @@ function Actions() {
4444
/>
4545
Wora v{data && data.appVersion}
4646
</div>
47-
<div className="absolute -right-2 top-0 flex h-full items-center gap-2.5">
47+
<div className="no-drag absolute -right-2 top-0 flex h-full items-center gap-2.5">
4848
{data && data.isNotMac && (
4949
<>
5050
<Button

‎renderer/components/ui/input.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
1111
<input
1212
type={type}
1313
className={cn(
14-
"flex h-9 w-full rounded-lg bg-black/5 px-3 py-1 text-xs transition duration-300 focus:bg-black/10 focus:outline-none dark:bg-white/10 dark:focus:bg-white/15",
14+
"flex h-9 w-full rounded-lg bg-black/5 px-3 py-1 text-xs ring-inset transition duration-300 focus:outline-none focus:ring-2 focus:ring-black dark:bg-white/10 dark:focus:ring-white",
1515
className,
1616
)}
1717
ref={ref}

‎renderer/components/ui/spectrogram.tsx

+35-19
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@ interface SpectrogramProps {
66
}
77

88
const Spectrogram: React.FC<SpectrogramProps> = ({ howl }) => {
9+
const containerRef = useRef<HTMLDivElement | null>(null);
910
const canvasRef = useRef<HTMLCanvasElement | null>(null);
1011
const analyserRef = useRef<AnalyserNode | null>(null);
1112
const animationRef = useRef<number | null>(null);
1213
const [isSetup, setIsSetup] = useState(false);
1314
const [isPlaying, setIsPlaying] = useState(false);
15+
const LEFT_MARGIN = 20; // Space for y-axis labels
16+
const AXIS_RIGHT_PADDING = 30; // Space between y-axis labels and graph
1417

1518
const setupAudio = useCallback(() => {
1619
setIsSetup(false);
@@ -26,7 +29,6 @@ const Spectrogram: React.FC<SpectrogramProps> = ({ howl }) => {
2629
}
2730

2831
analyserRef.current = audioContext.createAnalyser();
29-
analyserRef.current.fftSize = 2048;
3032

3133
const sound = howl as any;
3234
if (!sound._sounds || !sound._sounds[0] || !sound._sounds[0]._node) {
@@ -66,15 +68,15 @@ const Spectrogram: React.FC<SpectrogramProps> = ({ howl }) => {
6668

6769
const barWidth = 1;
6870
const height = canvas.height - 20;
69-
const leftMargin = 30;
71+
const graphStart = LEFT_MARGIN + AXIS_RIGHT_PADDING;
7072

7173
const imageData = ctx.getImageData(
72-
leftMargin + barWidth,
74+
graphStart + barWidth,
7375
0,
74-
canvas.width - leftMargin - barWidth,
76+
canvas.width - graphStart - barWidth,
7577
height,
7678
);
77-
ctx.putImageData(imageData, leftMargin, 0);
79+
ctx.putImageData(imageData, graphStart, 0);
7880

7981
ctx.clearRect(canvas.width - barWidth, 0, barWidth, height);
8082

@@ -99,22 +101,22 @@ const Spectrogram: React.FC<SpectrogramProps> = ({ howl }) => {
99101
canvas: HTMLCanvasElement,
100102
) => {
101103
ctx.save();
102-
ctx.clearRect(0, 0, 30, canvas.height);
104+
ctx.clearRect(0, 0, LEFT_MARGIN + AXIS_RIGHT_PADDING, canvas.height);
103105
ctx.clearRect(0, canvas.height - 20, canvas.width, 20);
104106

105107
ctx.fillStyle = "white";
106-
ctx.font = "10px Maven Pro";
108+
ctx.font = "10.5px Maven Pro";
107109
for (let i = 0; i <= 10; i++) {
108110
const freq = (i / 10) * 22.05;
109111
const y = canvas.height - 20 - (i / 10) * (canvas.height - 20);
110-
ctx.fillText(`${freq.toFixed(2)}`, 5, y);
112+
ctx.fillText(`${freq.toFixed(2)}k`, 5, y);
111113
}
112114

113115
const currentTime = howl.seek();
114116
ctx.fillText(
115-
`${currentTime.toFixed(1)}s`,
116-
canvas.width - 30,
117-
canvas.height - 5,
117+
`Time: ${currentTime.toFixed(1)}s`,
118+
canvas.width / 2,
119+
canvas.height,
118120
);
119121

120122
ctx.restore();
@@ -144,6 +146,15 @@ const Spectrogram: React.FC<SpectrogramProps> = ({ howl }) => {
144146
}
145147
}, []);
146148

149+
const resizeCanvas = useCallback(() => {
150+
const canvas = canvasRef.current;
151+
const container = containerRef.current;
152+
if (canvas && container) {
153+
canvas.width = container.clientWidth;
154+
canvas.height = container.clientHeight;
155+
}
156+
}, []);
157+
147158
useEffect(() => {
148159
const initializeSpectrogram = () => {
149160
if (howl.state() === "loaded") {
@@ -169,6 +180,12 @@ const Spectrogram: React.FC<SpectrogramProps> = ({ howl }) => {
169180

170181
initializeSpectrogram();
171182

183+
// Set up ResizeObserver
184+
const resizeObserver = new ResizeObserver(resizeCanvas);
185+
if (containerRef.current) {
186+
resizeObserver.observe(containerRef.current);
187+
}
188+
172189
return () => {
173190
stopSpectrogram();
174191
if (analyserRef.current) {
@@ -177,17 +194,16 @@ const Spectrogram: React.FC<SpectrogramProps> = ({ howl }) => {
177194
howl.off("play", handlePlay);
178195
howl.off("pause", handlePauseOrStop);
179196
howl.off("end", handlePauseOrStop);
197+
resizeObserver.disconnect();
180198
};
181-
}, [howl, startSpectrogram, stopSpectrogram]);
199+
}, [howl, startSpectrogram, stopSpectrogram, resizeCanvas]);
182200

183201
return (
184-
<div className="w-full rounded-xl bg-black p-5">
185-
<canvas
186-
ref={canvasRef}
187-
width="1315"
188-
height="400"
189-
className="w-full antialiased"
190-
/>
202+
<div
203+
ref={containerRef}
204+
className="h-full w-full rounded-xl px-6 pb-8 gradient-mask-r-90"
205+
>
206+
<canvas ref={canvasRef} className="h-full w-full antialiased" />
191207
</div>
192208
);
193209
};

‎renderer/components/ui/tabs.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const TabsTrigger = React.forwardRef<
2929
<TabsPrimitive.Trigger
3030
ref={ref}
3131
className={cn(
32-
"wora-transition inline-flex items-center justify-center whitespace-nowrap rounded-lg px-3 py-1.5 text-xs font-medium ring-offset-white focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-black/10 data-[state=active]:text-black data-[state=active]:shadow dark:data-[state=active]:bg-white/15 dark:data-[state=active]:text-white",
32+
"wora-transition inline-flex items-center justify-center whitespace-nowrap rounded-lg px-3 py-1.5 text-xs font-medium ring-offset-white focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-white/70 data-[state=active]:text-black data-[state=active]:shadow dark:data-[state=active]:bg-black/30 dark:data-[state=active]:text-white",
3333
className,
3434
)}
3535
{...props}

‎renderer/pages/_app.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { PlayerProvider } from "@/context/playerContext";
77
import { useRouter } from "next/router";
88
import { Toaster } from "@/components/ui/sonner";
99
import { ThemeProvider } from "@/components/themeProvider";
10+
import { ScrollArea } from "@/components/ui/scroll-area";
1011

1112
export default function App({ Component, pageProps }) {
1213
const router = useRouter();
@@ -18,7 +19,7 @@ export default function App({ Component, pageProps }) {
1819
disableTransitionOnChange
1920
enableSystem
2021
>
21-
<main className="select-none rounded-lg bg-white font-sans text-xs text-black antialiased dark:bg-black dark:text-white">
22+
<main className="select-none overflow-hidden rounded-lg bg-white font-sans text-xs text-black antialiased dark:bg-black dark:text-white">
2223
<Head>
2324
<title>Wora</title>
2425
</Head>
@@ -36,7 +37,10 @@ export default function App({ Component, pageProps }) {
3637
</div>
3738
<div className="h-screen flex-grow p-8 pl-0 pt-10">
3839
<div className="wora-transition relative flex h-full w-full flex-col">
39-
<Component {...pageProps} />
40+
<ScrollArea className="mt-2.5 h-full w-full gradient-mask-b-80">
41+
<Component {...pageProps} />
42+
<div className="h-[16vh] w-full"></div>
43+
</ScrollArea>
4044
<Player />
4145
</div>
4246
</div>

‎renderer/pages/albums.tsx

+8-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import React, { useEffect, useState } from "react";
2-
import { ScrollArea } from "@/components/ui/scroll-area";
32
import AlbumCard from "@/components/ui/album";
43

54
export default function Albums() {
@@ -12,18 +11,16 @@ export default function Albums() {
1211
}, []);
1312

1413
return (
15-
<ScrollArea className="mt-2.5 h-full w-full gradient-mask-b-80">
14+
<div className="flex flex-col gap-8">
1615
<div className="flex flex-col gap-8">
17-
<div className="flex flex-col gap-8">
18-
<div className="flex flex-col">
19-
<div className="mt-4 text-base font-medium">Albums</div>
20-
<div className="opacity-50">All of your albums in one place.</div>
21-
</div>
22-
<div className="grid w-full grid-cols-5 gap-8 pb-[32vh]">
23-
{albums && albums.map((album) => <AlbumCard album={album} />)}
24-
</div>
16+
<div className="flex flex-col">
17+
<div className="mt-4 text-base font-medium">Albums</div>
18+
<div className="opacity-50">All of your albums in one place.</div>
19+
</div>
20+
<div className="grid w-full grid-cols-5 gap-8">
21+
{albums && albums.map((album) => <AlbumCard album={album} />)}
2522
</div>
2623
</div>
27-
</ScrollArea>
24+
</div>
2825
);
2926
}

0 commit comments

Comments
 (0)