diff --git a/bun.lockb b/bun.lockb index 09b303c..b66914b 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index c86c054..ed010ef 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "big-word", "private": true, - "version": "0.0.0", + "version": "0.1.0", "type": "module", "scripts": { "dev": "vite", @@ -12,7 +12,8 @@ }, "dependencies": { "@tauri-apps/api": "^1", - "kaioken": "^0.10.0" + "kaioken": "^0.10.5", + "vite-plugin-kaioken": "^0.0.7" }, "devDependencies": { "@tauri-apps/cli": "^1", @@ -21,8 +22,7 @@ "postcss": "^8.4.35", "tailwindcss": "^3.4.1", "typescript": "^5.0.2", - "vite": "^5.0.0", - "vite-plugin-kaioken": "^0.0.7" + "vite": "^5.0.0" }, "config": { "commitizen": { diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 4fd5609..f573828 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -119,16 +119,6 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" -[[package]] -name = "big-word" -version = "0.0.0" -dependencies = [ - "serde", - "serde_json", - "tauri", - "tauri-build", -] - [[package]] name = "bitflags" version = "1.3.2" @@ -1378,6 +1368,16 @@ dependencies = [ "treediff", ] +[[package]] +name = "klectr_radio" +version = "0.1.0" +dependencies = [ + "serde", + "serde_json", + "tauri", + "tauri-build", +] + [[package]] name = "kuchikiki" version = "0.8.2" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 7a74bab..86f540c 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,7 +1,7 @@ [package] -name = "big-word" -version = "0.0.0" -description = "A Tauri App" +name = "klectr_radio" +version = "0.1.0" +description = "Your own personal radio app for Klecting the stations you love" authors = ["you"] edition = "2021" diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index e3c49f2..17371f3 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -46,7 +46,7 @@ "bundle": { "active": true, "targets": "all", - "identifier": "com.big-word.dev", + "identifier": "com.KlectrRadio.dev", "icon": [ "icons/32x32.png", "icons/128x128.png", diff --git a/src/App.tsx b/src/App.tsx index 4be92ac..3df3201 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,212 +1,32 @@ -import { exists, readTextFile, writeTextFile } from "@tauri-apps/api/fs" -import { Navs, useNavigator } from "./hooks/useNavigator" -import { appDataDir } from "@tauri-apps/api/path" -import { useEffect, useModel, useRef, useState } from "kaioken" +import { useEffect } from "kaioken" +import Main from "./pages/Main" +import Player from "./pages/Player" +import Add from "./pages/Add" +import useNavigationStore, { Navs } from "./hooks/navigationStores" +import { useStorage } from "./hooks/storageStores" +import { useStationsStore } from "./hooks/stationStores" -interface Station { - url: string - avatar: string - title: string -} export function App() { - const { nav, setNavitation } = useNavigator() - const [stations, setStations] = useState(null) - const [titleRef, title,] = useModel('') - const [streamRef, streamUrl,] = useModel('') - const [avatarRef, avatarUrl,] = useModel('') - const [selectedStation, setSelectedStation] = useState(null) - const appDataDirRef = useRef(null) + const { getStationsFile } = useStorage() + const { override } = useStationsStore() + const { value } = useNavigationStore() useEffect(() => { - appDataDir() - .then(async (res) => { - const path = `${res}/stations.json` - if (await exists(path)) { - console.log("file exists: ", path); - const jsonString = await readTextFile(path) - const json = JSON.parse(jsonString) as Station[] - console.log(json) - setStations(json) - appDataDirRef.current = path - return - } - - console.error("File does not exist... creating") - writeTextFile(path, "[]", { append: false }) - }) - .catch(err => console.error(err)) - - + getStationsFile() + .then(res => res && override(res)) + .catch() }, []) - function _handleStationAdd() { - console.log({ title, streamUrl, avatarUrl }) - const data: Station = { - url: streamUrl, - avatar: avatarUrl, - title: title - } - setStations(prev => { - const newStations = [...(prev ?? []), data] - // write file - writeTextFile(appDataDirRef.current!, JSON.stringify(newStations)) - return newStations - }) - console.log("Added station: ", data) - setNavitation(Navs.MAIN) + + + switch (value) { + case Navs.MAIN: + return
+ case Navs.ADD: + return + case Navs.PLAYER: + return + default: + return

404 Not Found

} - - function _handleStationClick(station: Station) { - return function() { - setSelectedStation(station) - setNavitation(Navs.PLAYER) - } - } - - if (nav === Navs.MAIN) { - if (!stations?.length) { - return ( -
-

No Stations Added

- -
- ) - } - return ( -
-
- -
- - -
- {stations.map((s) => ( - -
- - ))} - -
- - ) - - } - - if (nav === Navs.ADD) { - return ( -
- -
- - - - -
-
- ) - } - - function _handlePlayerBackClick() { - setNavitation(Navs.MAIN) - setSelectedStation(null) - } - - if (nav === Navs.PLAYER) { - return ( -
- -
-
- {/**/} - {selectedStation?.title} - {/**/} -

{selectedStation?.title}

- {/**/} -

Live Radio

-
- -
-
-
- ) - } - - return ( -
Not a navigation
- ) } -//
-// -//
-// -//

{selectedStation?.title}

-//

Live

-//
-// {/* progress bar */} -//
-// -//
-// {/* play pause button */} -//
-//
-//
-// -// -// -//{/**/} -//
-// -// -// -//
-// {/**/} -//
-//
-//
-// {/**/} -//
-// 1:57 -// 3:53 -//
+ diff --git a/src/hooks/navigationStores.ts b/src/hooks/navigationStores.ts new file mode 100644 index 0000000..5e7a5db --- /dev/null +++ b/src/hooks/navigationStores.ts @@ -0,0 +1,13 @@ +import { createStore } from "kaioken" + +export enum Navs { + MAIN, + ADD, + PLAYER, +} + +const useNavigationStore = createStore(Navs.MAIN, (set) => ({ + navigate: (value) => set(() => value), +})) + +export default useNavigationStore diff --git a/src/hooks/stationStores.ts b/src/hooks/stationStores.ts new file mode 100644 index 0000000..ee72682 --- /dev/null +++ b/src/hooks/stationStores.ts @@ -0,0 +1,39 @@ +import { writeTextFile } from "@tauri-apps/api/fs" +import { createStore } from "kaioken" + +export const useStationsStore = createStore( + null as Station[] | null, + (set) => ({ + add: (station: Station): Station[] => { + let newState: Station[] | null = null + set((state) => { + newState = [...(state ?? []), station] + return newState + }) + //@ts-ignore + return newState + }, + delete: (stationId) => + set( + (state) => state?.filter((station) => station.id !== stationId) ?? [] + ), + override: (stationsList: Station[]) => { + set((_state) => stationsList) + }, + }) +) + +export const useSelectStationStore = createStore( + null as Station | null, + (set) => ({ + make: (station) => set((_state) => station), + clear: () => set((_state) => null), + }) +) + +export interface Station { + id: string + url: string + avatar: string + title: string +} diff --git a/src/hooks/storageStores.ts b/src/hooks/storageStores.ts new file mode 100644 index 0000000..9c6b163 --- /dev/null +++ b/src/hooks/storageStores.ts @@ -0,0 +1,35 @@ +import { exists, readTextFile, writeTextFile } from "@tauri-apps/api/fs" +import { appDataDir } from "@tauri-apps/api/path" +import { createStore } from "kaioken" +import { Station } from "../hooks/stationStores" + +export const useStorageStore = createStore( + null as string | null, + (_set) => ({}) +) + +export function useStorage() { + async function _createStationsFile(path: string): Promise { + await writeTextFile(path, "[]", { append: false }) + return [] + } + + async function getStationsFile(): Promise { + let dir: null | string = null + try { + dir = await appDataDir() + } catch (err) { + console.error("getStationsFile: ", err) + return undefined + } + if (!dir) return undefined + const path = `${dir}stations.json` + if (!(await exists(path))) return await _createStationsFile(path) + const jsonString = await readTextFile(path) + const json = JSON.parse(jsonString) as Station[] + useStorageStore.setState(() => path) + return json + } + + return { getStationsFile } +} diff --git a/src/hooks/useNavigator.ts b/src/hooks/useNavigator.ts deleted file mode 100644 index 65e173f..0000000 --- a/src/hooks/useNavigator.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { useState } from "kaioken" -export enum Navs { - MAIN, - ADD, - PLAYER, -} - -export function useNavigator() { - const [nav, setNav] = useState(Navs.MAIN) - function _setNavitation(newNav: Navs) { - setNav(newNav) - } - return { - nav, - setNavitation: _setNavitation, - } -} diff --git a/src/main.ts b/src/main.ts index 364e6b6..4013b8a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,6 +1,6 @@ -import "./styles.css"; -import { mount } from "kaioken"; -import { App } from "./App"; +import { App } from "./App" +import "./styles.css" +import { mount } from "kaioken" -const root = document.getElementById("root")!; -mount(App, root); +const root = document.getElementById("root")! +mount(App, root) diff --git a/src/pages/Add.tsx b/src/pages/Add.tsx new file mode 100644 index 0000000..df7c4a0 --- /dev/null +++ b/src/pages/Add.tsx @@ -0,0 +1,41 @@ +import { writeTextFile } from "@tauri-apps/api/fs" +import { useModel } from "kaioken" +import { Station, useStationsStore } from "../hooks/stationStores" +import { useStorageStore } from "../hooks/storageStores" +import useNavigationStore, { Navs } from "../hooks/navigationStores" + +export default function Add() { + const { value } = useStorageStore() + const [titleRef, title,] = useModel('') + const [streamRef, streamUrl,] = useModel('') + const [avatarRef, avatarUrl,] = useModel('') + + function _handleStationAdd() { + const data: Station = { + id: Math.random().toString(16).slice(2), + url: streamUrl, + avatar: avatarUrl, + title: title + } + const store = useStationsStore.methods.add(data) + const valid = store && value + valid && void writeTextFile(value, JSON.stringify(store)) + useNavigationStore.setState(Navs.MAIN) + } + + return ( +
+ +
+ + + + +
+
+ ) +} diff --git a/src/pages/Main.tsx b/src/pages/Main.tsx new file mode 100644 index 0000000..5843912 --- /dev/null +++ b/src/pages/Main.tsx @@ -0,0 +1,49 @@ +import useNavigationStore, { Navs } from "../hooks/navigationStores" +import { Station, useSelectStationStore } from "../hooks/stationStores" +import { useStationsStore } from "../hooks/stationStores" + +export default function Main() { + const { make } = useSelectStationStore() + const { navigate } = useNavigationStore() + const stations = useStationsStore.getState() + + function _handleStationClick(station: Station) { + make(station) + navigate(Navs.PLAYER) + } + + if (!stations?.length) { + return ( +
+

No Stations Added

+ +
+ ) + } + + return ( +
+
+ +
+ + +
+ {stations.map((s) => ( + +
+ + ))} + +
+ + ) +} diff --git a/src/pages/Player.tsx b/src/pages/Player.tsx new file mode 100644 index 0000000..6f0ac8b --- /dev/null +++ b/src/pages/Player.tsx @@ -0,0 +1,34 @@ +import useNavigationStore, { Navs } from "../hooks/navigationStores" +import { useSelectStationStore } from "../hooks/stationStores" + +export default function Player() { + const { value: selectedStation, make } = useSelectStationStore() + const { navigate } = useNavigationStore() + + function _handlePlayerBackClick() { + navigate(Navs.MAIN) + make(null) + } + + return ( +
+ +
+
+ {/**/} + {selectedStation?.title} + {/**/} +

{selectedStation?.title}

+ {/**/} +

Live Radio

+
+ +
+
+
+ ) +}