Skip to content

Commit

Permalink
Merge pull request #8 from isaxk/dev
Browse files Browse the repository at this point in the history
Bookmarks sidebar feature
  • Loading branch information
isaxk authored Sep 1, 2024
2 parents 034d9ef + ba6142c commit c9cf1e4
Show file tree
Hide file tree
Showing 9 changed files with 325 additions and 53 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
"bits-ui": "^0.21.13",
"electron-context-menu": "^4.0.2",
"electron-json-config": "^2.1.0",
"lucide-svelte": "^0.435.0"
"lucide-svelte": "^0.435.0",
"moment": "^2.30.1"
},
"devDependencies": {
"@electron-toolkit/eslint-config-prettier": "^2.0.0",
Expand Down
7 changes: 7 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 43 additions & 7 deletions src/main/tabs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,22 @@ function windowOpenHandler(details): WindowOpenHandlerResponse {
}

async function updateCustomCss(key: string, view: WebContentsView) {
let ytCss = JSON.parse(store.get(key, "")!);
let ytCss = JSON.parse(store.get(key, JSON.stringify(""))!);
console.log(ytCss);
return new Promise<string | null>(async (resolve) => {
if (ytCss === "") {
resolve(null);
return;
}
if (ytCss.enabled === true) {
if (ytCss.type === "url") {
await loadCss(ytCss.url).then(async (css) => {
resolve(await view.webContents.insertCSS(css));
});
} else {
} else if (ytCss.type === "editor") {
resolve(await view.webContents.insertCSS(ytCss.css));
} else {
resolve(null);
}
} else {
resolve(null);
Expand All @@ -39,13 +46,14 @@ const store = factory();

let currentTab: number | null = 0;
let isFullscreen: boolean = false;
let isSidebar: boolean = false;

export async function createTabManager(mainWindow: BrowserWindow) {
function bounds() {
return {
x: 0,
y: isFullscreen ? 0 : 40,
width: mainWindow.getBounds().width,
width: mainWindow.getBounds().width - (isSidebar && !isFullscreen ? 300 : 0),
height: mainWindow.getBounds().height - (isFullscreen ? 0 : 40),
};
}
Expand Down Expand Up @@ -73,7 +81,6 @@ export async function createTabManager(mainWindow: BrowserWindow) {
view.webContents.send("remoteControl:execute", command, value);
});


let loaded = false;
let oldCssKey: string | null = null;

Expand All @@ -92,7 +99,6 @@ export async function createTabManager(mainWindow: BrowserWindow) {
});
});


// async function updateCustomCss() {
// let ytCss = JSON.parse(store.get("music-css", "")!);
// if (ytCss.enabled) {
Expand Down Expand Up @@ -125,6 +131,9 @@ export async function createTabManager(mainWindow: BrowserWindow) {
set: () => {
mainWindow.contentView.addChildView(view);
},
bounds: () => {
view.setBounds(bounds());
},
data: () => {
return {
title: view.webContents.getTitle(),
Expand Down Expand Up @@ -183,6 +192,9 @@ export async function createTabManager(mainWindow: BrowserWindow) {
set: () => {
mainWindow.contentView.addChildView(view);
},
bounds: () => {
view.setBounds(bounds());
},
data: () => {
return {
title: view.webContents.getTitle(),
Expand All @@ -195,7 +207,7 @@ export async function createTabManager(mainWindow: BrowserWindow) {
};
}

function createTab() {
function createTab(url="https://www.youtube.com") {
const view = new WebContentsView({
webPreferences: {
transparent: true,
Expand All @@ -212,7 +224,7 @@ export async function createTabManager(mainWindow: BrowserWindow) {
view.setBounds(bounds());
});
view.setBounds(bounds());
view.webContents.loadURL("https://www.youtube.com");
view.webContents.loadURL(url);
view.webContents.setWindowOpenHandler(windowOpenHandler);

let id = Date.now();
Expand Down Expand Up @@ -270,6 +282,9 @@ export async function createTabManager(mainWindow: BrowserWindow) {
set: () => {
mainWindow.contentView.addChildView(view);
},
bounds: () => {
view.setBounds(bounds());
},
data: () => {
return {
title: view.webContents.getTitle(),
Expand Down Expand Up @@ -341,6 +356,8 @@ export async function createTabManager(mainWindow: BrowserWindow) {
updateTabs();
});

setInterval(updateTabs, 500);

ipcMain.on("page-action", (_, i) => {
if (currentTab !== null) {
switch (i) {
Expand Down Expand Up @@ -378,6 +395,25 @@ export async function createTabManager(mainWindow: BrowserWindow) {
}
});

ipcMain.on("open-sidebar", () => {
isSidebar = true;
tabs.forEach((tab) => {
tab.bounds();
});
});

ipcMain.on("close-sidebar", () => {
isSidebar = false;
tabs.forEach((tab) => {
tab.bounds();
});
});

ipcMain.on("open-bookmark", (_, url) => {
tabs = [...tabs, createTab(url)];
switchTab(tabs.length-1);
});

ipcMain.on("close-miniplayer", () => {
if (currentTab !== null) {
tabs[currentTab].view.setVisible(true);
Expand Down
9 changes: 9 additions & 0 deletions src/preload/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,18 @@ export const api = {
openMiniplayer: () => {
ipcRenderer.send("open-miniplayer");
},
openSidebar: () => {
ipcRenderer.send("open-sidebar");
},
closeMiniplayer: () => {
ipcRenderer.send("close-miniplayer");
},
closeSidebar: () => {
ipcRenderer.send("close-sidebar");
},
openBookmark: (url:string) => {
ipcRenderer.send("open-bookmark", url);
},
onVideoDataChange: (listener: Function) => {
ipcRenderer.on("video-data-changed", (_, data: musicData) => {
listener(data);
Expand Down
20 changes: 17 additions & 3 deletions src/renderer/src/App.svelte
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
<script lang="ts">
import { onMount } from "svelte";
import MenuBar from "./views/MenuBar.svelte";
import { activeView, musicDataStore, theme } from "./lib/stores";
import { activeView, musicDataStore, showBookmarks, theme } from "./lib/stores";
import Settings from "./views/Settings.svelte";
import MiniPlayer from "./views/MiniPlayer.svelte";
import type { musicData, playerState } from "./lib/types";
import Spinner from "./components/ui/Spinner.svelte";
import Bookmarks from "./views/Bookmarks.svelte";
onMount(async () => {
theme.set(await window.api.getTheme());
Expand Down Expand Up @@ -41,10 +43,22 @@
{#if $theme !== null}
<div class="{$theme} contents">
<main
class="h-screen bg-white text-black transition-all dark:bg-[#121212] dark:text-white"
class="flex h-screen flex-col bg-white transition-all dark:bg-[#121212] text-black dark:text-white"
>
{#if $activeView === "topbar"}
<MenuBar {active} {tabs} />
<main
class="flex h-screen flex-col bg-white transition-all dark:bg-[#121212] "
>
<MenuBar {active} {tabs} />
<div class="flex h-full flex-grow">
<div class="flex flex-grow items-center justify-center">
<Spinner />
</div>
{#if $showBookmarks}
<Bookmarks {tabs} {active} />
{/if}
</div>
</main>
{:else if $activeView === "settings"}
<Settings />
{:else if $activeView === "miniplayer"}
Expand Down
105 changes: 105 additions & 0 deletions src/renderer/src/components/bookmarks/Bookmark.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<script lang="ts">
import { Trash } from "lucide-svelte";
import IconButton from "../ui/IconButton.svelte";
import { fly, slide } from "svelte/transition";
import moment from "moment";
import { onDestroy, onMount } from "svelte";
import { Tooltip } from "bits-ui";
function YouTubeGetID(url) {
url = url.split(/(vi\/|v=|\/v\/|youtu\.be\/|\/embed\/)/);
return url[2] !== undefined ? url[2].split(/[^0-9a-z_\-]/i)[0] : url[0];
}
export let title;
export let url;
export let date;
export let store;
// @ts-ignore
export let i:number;
$: {
title = title.replace(" - YouTube", "");
let length = title.length;
title = title.substring(0, 35);
title = title + (length > 34 ? "..." : "");
}
let display = "";
let interval;
function refreshTime() {
display = moment(date).fromNow();
}
onMount(() => {
refreshTime();
interval = setInterval(refreshTime, 5000);
});
onDestroy(() => {
clearInterval(interval);
});
$: id = YouTubeGetID(url);
</script>

<div
class="w-full items-center gap-1 rounded border text-left dark:border-neutral-800"
transition:slide={{ duration: 200 }}
>
{#if id.length === 11}
<img
src="https://img.youtube.com/vi/{id}/0.jpg"
alt=""
class="h-14 w-full rounded-t object-cover object-center"
/>
{/if}
<div class="flex min-w-0">
<button
class="flex w-full min-w-0 flex-grow flex-col px-4 py-2 text-left"
on:click={() => {
window.api.openBookmark(url);
}}
>
<div
class="text-md mb-1 w-full min-w-0 overflow-x-hidden text-ellipsis font-bold leading-5"
>
{title}
</div>
<div
class="w-full min-w-0 overflow-x-hidden text-ellipsis text-nowrap text-xs font-extralight text-zinc-300"
>
{url.replace("https://www.youtube.com/", "/")}
</div>
<Tooltip.Root openDelay={0}>
<Tooltip.Trigger class="text-left text-xs font-medium">
Saved {display}
</Tooltip.Trigger>
<Tooltip.Content
transition={fly}
transitionConfig={{ y: 8, duration: 150 }}
sideOffset={8}
side="bottom"
align="center"
>
<div class="bg-neutral-900">
<Tooltip.Arrow
class="rounded-[2px] border-l border-t border-neutral-700"
/>
</div>
<div
class="rounded-md border border-neutral-700 bg-neutral-900 p-2 text-xs text-white"
>
{moment(date).format("HH:MM - Do MMM YYYY")}
</div>
</Tooltip.Content>
</Tooltip.Root>
</button>
<div class="flex w-10 items-center">
<div>
<IconButton icon={Trash} on:click={() => store.remove(url)} />
</div>
</div>
</div>
</div>
45 changes: 41 additions & 4 deletions src/renderer/src/lib/stores.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,47 @@ import { writable } from "svelte/store";
import type { musicStore } from "./types";

export const activeView = writable("topbar");
export const showBookmarks = writable(false);
export const musicDataStore = writable<musicStore | null>({
data: null,
volume: 50,
progress: 0,
state: -1,
data: null,
volume: 50,
progress: 0,
state: -1,
});
export const theme = writable<"light" | "dark" | null>(null);

export function createBookmarksStore(): {
subscribe: any;
add: Function;
remove: Function;
} {
const { subscribe, set, update } = writable([]);

if (localStorage.tabs) {
set(JSON.parse(localStorage.tabs));
}

subscribe((tabs) => {
localStorage.tabs = JSON.stringify(tabs);
});

return {
subscribe,
add: (title, url) => {
update((tabs) => {
if (tabs.some((tab) => tab.url === url)) {
return tabs;
} else {
return [...tabs, { title, url, date: Date.now() }];
}
});
},
remove: (url: string) => {
update((tabs) => {
return tabs.filter((tab) => {
return tab.url !== url;
});
});
},
};
}
Loading

0 comments on commit c9cf1e4

Please sign in to comment.