Skip to content

Commit

Permalink
layout
Browse files Browse the repository at this point in the history
  • Loading branch information
lacymorrow committed Nov 28, 2023
1 parent 43e3e20 commit 2a3da03
Show file tree
Hide file tree
Showing 14 changed files with 193 additions and 113 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@
"main": "./src/main/main.ts",
"scripts": {
"build": "concurrently \"npm run build:main\" \"npm run build:renderer\"",
"build:dll": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.dev.dll.ts",
"build:main": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.main.prod.ts",
"build:renderer": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.prod.ts",
"build:dll": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.dev.dll.ts",
"postinstall": "ts-node .erb/scripts/check-native-dep.js && electron-builder install-app-deps && npm run build:dll",
"lint": "cross-env NODE_ENV=development eslint . --ext .js,.jsx,.ts,.tsx",
"package": "ts-node ./.erb/scripts/clean.js dist && npm run build && electron-builder build -mwl --publish never && npm run build:dll",
Expand Down Expand Up @@ -138,6 +138,7 @@
"react-dom": "^18.2.0",
"react-hook-form": "^7.48.2",
"react-router-dom": "^6.19.0",
"react-wrap-balancer": "^1.1.0",
"tailwind-merge": "^2.0.0",
"tailwindcss-animate": "^1.0.7",
"uuid-by-string": "^4.0.0",
Expand Down
12 changes: 6 additions & 6 deletions src/main/main.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
/* eslint global-require: off, no-console: off, promise/always-return: off */

import path from 'path';
import { app, BrowserWindow, shell } from 'electron';
import log from 'electron-log/main';
import path from 'path';
import { AutoUpdate } from './auto-update';
import MenuBuilder from './menu';
import { is, resolveHtmlPath } from './util';
import { AutoUpdate } from './auto-update';

import { debugInfo, DEFAULT_PATH } from './constants';
import eventListeners from './event-listeners';
import { scanMedia } from './file';
import { clearCache, clearLibrary } from './store';
import { debugInfo, DEFAULT_PATH } from './constants';
import win from './win';
import ipc from './ipc';
import { clearCache } from './store';
import win from './win';

console.time('startup');

Expand Down Expand Up @@ -129,7 +129,7 @@ const ready = async () => {
// todo: load previous session

// if no session, begin fresh scan
clearLibrary();
// clearLibrary(); // todo: remove
clearCache();
};

Expand Down
13 changes: 9 additions & 4 deletions src/main/media.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import getUuidByString from 'uuid-by-string';
import { PARSE_METHOD } from '../config/config';
import { FileType, MediaType } from '../types/file';
import queue from './q';
import { upsertMediaLibrary, getCachedObject } from './store';
import { getCachedObject, upsertMediaLibrary } from './store';
import { fileNameRegex, isDigit } from './util';

export const prettyFileName = (name: string) => {
Expand Down Expand Up @@ -64,20 +64,25 @@ export const addMediaToLibrary = (media: FileType) => {
const title = prettyFileName(filename);

// METADATA DEFAULTS
const now = Date.now();
let updatedMedia: MediaType = {
...media,
id,
title,
prettyFileName: title,
liked: false,
dateAdded: Date.now(),
dateUpdated: Date.now(),
dateAdded: now,
};

// check if path in cache
const cached = getCachedObject(filepath);
if (cached) {
updatedMedia = { ...updatedMedia, ...cached };
updatedMedia = {
...updatedMedia,
...cached,
// Overwrite dateAdded and dateUpdated from cache
dateAdded: now,
};
} else {
// Gleen meta info from filename and update library
const meta = parseFileMeta(filename);
Expand Down
Empty file removed src/main/meta.ts
Empty file.
4 changes: 3 additions & 1 deletion src/main/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ const schema: Store.Schema<StoreType> = {
const store = new Store<StoreType>({ schema });

const libraryWasUpdated = throttle(() => {
win.mainWindow?.webContents.send(ipcChannels.LIBRARY_UPDATED);
win?.mainWindow?.webContents.send(ipcChannels.LIBRARY_UPDATED);
}, THROTTLE_DELAY);

export const resetStore = () => {
Expand Down Expand Up @@ -312,6 +312,8 @@ export const upsertMediaLibrary = (media: MediaType) => {
return;
}

media.dateUpdated = Date.now();

upsertMedia(media);
afterUpsertMediaLibrary(id);
};
Expand Down
13 changes: 9 additions & 4 deletions src/renderer/App.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// bug: "no media" placeholder needs to be shown in all different sizes
// bug: cannot horizontally scroll in media browser "watch now"
// bug: files are added with zero metadata (allow this?)

// todo: network status
// todo: sort/filter media
// todo: search media (?filer)
Expand All @@ -10,15 +14,16 @@
// todo: show/hide sidebar
// todo: show progress
// todo: show current processing info
// todo: scrollarea for genre/playlist

import { MemoryRouter as Router, Routes, Route } from 'react-router-dom';
import { GlobalContextProvider } from '@/renderer/context/global-context';
import { Layout } from '@/renderer/components/layout/Layout';
import { MediaLayout } from '@/renderer/components/layout/MediaLayout';
import { nav } from '@/renderer/config/nav';
import { Media } from '@/renderer/pages/Media';
import { GlobalContextProvider } from '@/renderer/context/global-context';
import { Genre } from '@/renderer/pages/Genre';
import { Media } from '@/renderer/pages/Media';
import Settings from '@/renderer/pages/Settings';
import { MediaLayout } from '@/renderer/components/media/MediaLayout';
import { Route, MemoryRouter as Router, Routes } from 'react-router-dom';
import { Playlist } from './pages/Playlist';

import '@/renderer/styles/globals.scss';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react';
import { Sidebar } from '../layout/Sidebar';
import { Sidebar } from './Sidebar';

export function MediaLayout({ children }: { children: React.ReactNode }) {
return (
<>
<Sidebar className="hidden lg:block w-60 lg:w-80" />
<Sidebar className="hidden lg:block w-80" />
<div className="grow lg:border-l basis-full min-w-0">{children}</div>
</>
);
Expand Down
56 changes: 56 additions & 0 deletions src/renderer/components/layout/PageHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/* eslint-disable react/prop-types */
/* eslint-disable jsx-a11y/heading-has-content */
import React from 'react';
import Balance from 'react-wrap-balancer';

import { cn } from '@/lib/utils';

function PageHeader({
className,
children,
...props
}: React.HTMLAttributes<HTMLDivElement>) {
return (
<section
className={cn(
'flex max-w-[980px] flex-col items-start gap-2 px-4 pt-8 md:pt-12',
className,
)}
{...props}
>
{children}
</section>
);
}

function PageHeaderHeading({
className,
...props
}: React.HTMLAttributes<HTMLHeadingElement>) {
return (
<h1
className={cn(
'text-3xl font-bold leading-tight tracking-tighter md:text-5xl lg:leading-[1.1]',
className,
)}
{...props}
/>
);
}

function PageHeaderDescription({
className,
...props
}: React.HTMLAttributes<HTMLParagraphElement>) {
return (
<Balance
className={cn(
'max-w-[750px] text-lg text-muted-foreground sm:text-xl',
className,
)}
{...props}
/>
);
}

export { PageHeader, PageHeaderDescription, PageHeaderHeading };
147 changes: 73 additions & 74 deletions src/renderer/components/layout/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React from 'react';
import { Link, useLocation } from 'react-router-dom';
import { cn } from '@/lib/utils';
import { Button, buttonVariants } from '@/components/ui/button';
import { ScrollArea } from '@/components/ui/scroll-area';
import { cn } from '@/lib/utils';
import { nav } from '@/renderer/config/nav';
import { BookmarkIcon, MixerHorizontalIcon } from '@radix-ui/react-icons';
import React from 'react';
import { Link, useLocation } from 'react-router-dom';
import { GlobalContext } from '../../context/global-context';
import Icons from '../images/Icons';
import { DialogDeletePlaylist } from '../dialog/DialogDeletePlaylist';
import Icons from '../images/Icons';

const linkProps = {
draggable: false,
Expand All @@ -23,57 +23,59 @@ export function Sidebar({ className }: SidebarProps) {
React.useContext(GlobalContext);

return (
<ScrollArea className={cn('container-sidebar select-none', className)}>
<div className="h-full space-y-4 p-4 flex flex-col justify-between">
<div>
<div className="py-2">
<h2 className="mb-2 px-2 text-lg font-semibold tracking-tight">
Library
</h2>
<div className="flex flex-col">
<ScrollArea className={cn('container-sidebar', className)}>
<div className="h-full space-y-4 p-4 flex flex-col justify-between">
<div>
<div className="py-2">
<h2 className="mb-2 px-2 text-lg font-semibold tracking-tight">
Library
</h2>

<div className="space-y-1">
{nav.map((item) => {
if (item.name === 'Settings' || item.name === 'Liked') {
return null;
}
return (
<Link
key={item.name}
to={item.path}
{...linkProps}
className={cn(
buttonVariants({
variant:
pathname === item.path ? 'secondary' : 'ghost',
}),
'w-full justify-start',
)}
>
{item.icon && item.icon}
{item.name}
</Link>
);
})}

<div className="space-y-1">
{nav.map((item) => {
if (item.name === 'Settings' || item.name === 'Liked') {
return null;
}
return (
<Link
key={item.name}
to={item.path}
{...linkProps}
<Link to="/liked" {...linkProps}>
<Button
variant={pathname === '/liked' ? 'secondary' : 'ghost'}
className={cn(
buttonVariants({
variant: pathname === item.path ? 'secondary' : 'ghost',
}),
'w-full justify-start',
liked.length < 1 && 'font-normal',
)}
>
{item.icon && item.icon}
{item.name}
</Link>
);
})}

<Link to="/liked" {...linkProps}>
<Button
variant={pathname === '/liked' ? 'secondary' : 'ghost'}
className={cn(
'w-full justify-start',
liked.length < 1 && 'font-normal',
)}
>
<BookmarkIcon className="mr-2" />
Liked {liked.length > 0 && <>({liked.length})</>}
</Button>
</Link>
<BookmarkIcon className="mr-2" />
Liked {liked.length > 0 && <>({liked.length})</>}
</Button>
</Link>
</div>
</div>
</div>
{genresArray.length > 0 && (
<div className="py-2">
<h2 className="relative px-2 text-lg font-semibold tracking-tight">
Genres
</h2>
<ScrollArea className="max-h-[300px]">

{genresArray.length > 0 && (
<>
<h2 className="relative p-2 text-lg font-semibold tracking-tight">
Genres
</h2>
<div className="space-y-1">
{genresArray.map((value) => {
const genrePath = `/genres/${value.id}`;
Expand All @@ -96,16 +98,14 @@ export function Sidebar({ className }: SidebarProps) {
);
})}
</div>
</ScrollArea>
</div>
)}
</>
)}

{playlistsArray.length > 0 && (
<div className="py-2">
<h2 className="relative px-2 text-lg font-semibold tracking-tight">
Playlists
</h2>
<ScrollArea className="max-h-[300px]">
{playlistsArray.length > 0 && (
<>
<h2 className="relative p-2 text-lg font-semibold tracking-tight">
Playlists
</h2>
<div className="space-y-1">
{playlistsArray.map((playlist) => {
const itemPath = `/playlists/${playlist.id}`;
Expand All @@ -132,23 +132,22 @@ export function Sidebar({ className }: SidebarProps) {
);
})}
</div>
</ScrollArea>
</div>
)}
</div>

<div>
<Link to="/settings" {...linkProps}>
<Button
variant={pathname === '/settings/*' ? 'secondary' : 'ghost'}
className="w-full justify-start"
>
<MixerHorizontalIcon className="mr-2 h-4 w-4" />
Settings
</Button>
</Link>
</>
)}
</div>
</div>
</ScrollArea>
<div className="p-4">
<Link to="/settings" {...linkProps}>
<Button
variant={pathname === '/settings/*' ? 'secondary' : 'ghost'}
className="w-full justify-start"
>
<MixerHorizontalIcon className="mr-2 h-4 w-4" />
Settings
</Button>
</Link>
</div>
</ScrollArea>
</div>
);
}
Loading

0 comments on commit 2a3da03

Please sign in to comment.