21 feature app redesign #23
@ -14,8 +14,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "^1",
|
||||
"kaioken": "^0.10.5",
|
||||
"vite-plugin-kaioken": "^0.0.7"
|
||||
"kaioken": "^0.17.0",
|
||||
"vite-plugin-kaioken": "^0.3.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "^1",
|
||||
|
433
src-tauri/Cargo.lock
generated
433
src-tauri/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -11,9 +11,10 @@ edition = "2021"
|
||||
tauri-build = { version = "1", features = [] }
|
||||
|
||||
[dependencies]
|
||||
tauri = { version = "1", features = [ "fs-read-file", "fs-create-dir", "fs-exists", "fs-write-file", "path-all", "shell-open"] }
|
||||
tauri = { version = "1", features = [ "macos-private-api", "fs-read-file", "fs-create-dir", "fs-exists", "fs-write-file", "path-all", "shell-open"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
window-vibrancy = "0.4.0"
|
||||
|
||||
[features]
|
||||
# This feature is used for production builds or when a dev server is not specified, DO NOT REMOVE!!
|
||||
|
@ -1,15 +1,25 @@
|
||||
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
|
||||
#[tauri::command]
|
||||
fn greet(name: &str) -> String {
|
||||
format!("Hello, {}! You've been greeted from Rust!", name)
|
||||
}
|
||||
use tauri::Manager;
|
||||
use window_vibrancy::{apply_vibrancy, NSVisualEffectMaterial};
|
||||
|
||||
fn main() {
|
||||
tauri::Builder::default()
|
||||
.invoke_handler(tauri::generate_handler![greet])
|
||||
.setup(|app| {
|
||||
let window = app.get_window("main").unwrap();
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
apply_vibrancy(&window, NSVisualEffectMaterial::HudWindow, None, Some(16.0))
|
||||
.expect("Unsupported platform! 'apply_vibrancy' is only supported on macOS");
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
apply_blur(&window, Some((18, 18, 18, 125)))
|
||||
.expect("Unsupported platform! 'apply_blur' is only supported on Windows");
|
||||
|
||||
Ok(())
|
||||
})
|
||||
// .invoke_handler(tauri::generate_handler![greet])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
|
@ -32,13 +32,15 @@
|
||||
"all": true
|
||||
}
|
||||
},
|
||||
"macOSPrivateApi": true,
|
||||
"windows": [
|
||||
{
|
||||
"title": "KlectrRadio",
|
||||
"width": 300,
|
||||
"width": 800,
|
||||
"height": 600,
|
||||
"decorations": true,
|
||||
"resizable": true
|
||||
"resizable": true,
|
||||
"minWidth": 800,
|
||||
"minHeight": 600
|
||||
}
|
||||
],
|
||||
"security": {
|
||||
|
42
src/App.tsx
42
src/App.tsx
@ -1,9 +1,7 @@
|
||||
import { Route, Router, useEffect } from "kaioken"
|
||||
import Main from "./pages/Main"
|
||||
import { useEffect } from "kaioken"
|
||||
import { useStorage } from "./hooks/storageStores"
|
||||
import { useStationsStore } from "./hooks/stationStores"
|
||||
import Add from "./pages/Add"
|
||||
import Player from "./pages/Player"
|
||||
import { Popular, Navigation, LocalRadio, RecommendedRadio, MusicPlayer } from "./components"
|
||||
|
||||
export function App() {
|
||||
const { getStationsFile } = useStorage()
|
||||
@ -16,11 +14,37 @@ export function App() {
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<Router basePath="">
|
||||
<Route path="/" element={Main} />
|
||||
<Route path="/add" element={Add} />
|
||||
<Route path="/player" element={Player} />
|
||||
</Router>
|
||||
<div className="flex flex-row gap-2 px-2">
|
||||
|
||||
{/* Left Section __________*/}
|
||||
<div className="pt-2 min-h-[98vh] max-h-[98vh] min-w-[150px] flex flex-col gap-4 justify-start">
|
||||
<div className="w-full flex justify-center">
|
||||
<input type="text" className="rounded-md border p-1 w-full" placeholder="Search" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2 className="text-gray-500 text-sm">Music</h2>
|
||||
<Navigation />
|
||||
</div>
|
||||
|
||||
<button className="px-4 border border-blue-500 rounded-md text-blue-500 hover:bg-blue-100 w-full">Create New +</button>
|
||||
</div>
|
||||
|
||||
|
||||
{/* Right Section __________*/}
|
||||
<div className="flex-1 min-h-[98vh] max-h-[98vh] flex h-0 p-2 min-w-0">
|
||||
<div className="bg-gray-200 w-full border rounded-xl p-4 flex-col flex gap-4">
|
||||
<MusicPlayer />
|
||||
<Popular />
|
||||
{/* Bottom Section __________*/}
|
||||
|
||||
<div id="bottom" className="flex-1 rounded-xl flex flex-row gap-4 min-h-0">
|
||||
<LocalRadio />
|
||||
<RecommendedRadio />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
5
src/components/index.ts
Normal file
5
src/components/index.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export * from "./music_player"
|
||||
export * from "./popular"
|
||||
export * from "./navigation"
|
||||
export * from "./local_radio"
|
||||
export * from "./recommended_radio"
|
90
src/components/local_radio/index.tsx
Normal file
90
src/components/local_radio/index.tsx
Normal file
@ -0,0 +1,90 @@
|
||||
export function LocalRadio() {
|
||||
return (
|
||||
<div id="bottom-l" className="flex flex-col min-h-0 overflow-y-hidden font-bold p-2 bg-white flex-1 rounded-xl shadow-md gap-2">
|
||||
<h2 >Local Radio</h2>
|
||||
|
||||
<div className="flex flex-col gap-4 overflow-y-scroll h-full">
|
||||
{dummyData.map(x => (
|
||||
<div className="flex flex-row min-w-[100px] gap-2 items-center">
|
||||
<img src={x.image} width={50} className="rounded-xl" />
|
||||
<h3 className="text-xl text-gray-500">{x.title}</h3>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const dummyData = [
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
}
|
||||
]
|
||||
|
66
src/components/music_player/index.tsx
Normal file
66
src/components/music_player/index.tsx
Normal file
@ -0,0 +1,66 @@
|
||||
export function MusicPlayer() {
|
||||
return (
|
||||
<div className="flex justify-between p-2 bg-gray-300 flex-[0.5] rounded-xl max-h-[100px] gap-2 items-center pb-5">
|
||||
<div className="flex gap-2 items-center flex-[0.5]">
|
||||
<img
|
||||
width={50}
|
||||
className="rounded-xl"
|
||||
src="https://www.thispersondoesnotexist.com"
|
||||
alt="station art"
|
||||
/>
|
||||
|
||||
<div className="flex flex-col" style={{ overflowX: 'hidden' }}>
|
||||
<p className="text-sm" style={{ textOverflow: 'ellipsis', whiteSpace: 'nowrap', overflow: 'hidden' }}>Camden to Chinatown</p>
|
||||
<p className="text-sm" style={{ textOverflow: 'ellipsis', whiteSpace: 'nowrap', overflow: 'hidden' }}>Loafy Building, Raimu</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 flex flex-col items-center">
|
||||
<div className="flex gap-1 justify-center">
|
||||
<svg
|
||||
id="playbutton"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
className="lucide lucide-play w-5"
|
||||
>
|
||||
<polygon points="6 3 20 12 6 21 6 3" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-1">
|
||||
<p>0:40</p>
|
||||
<input type="range" />
|
||||
<p>1:44</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-row flex-[0.5] gap-1 justify-end items-end">
|
||||
<svg
|
||||
id="volume"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
className="lucide lucide-volume-1 w-5"
|
||||
>
|
||||
<polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5" />
|
||||
<path d="M15.54 8.46a5 5 0 0 1 0 7.07" />
|
||||
</svg>
|
||||
<input type="range" />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
18
src/components/navigation/index.tsx
Normal file
18
src/components/navigation/index.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
export function Navigation() {
|
||||
return (
|
||||
<ul>
|
||||
<li className="flex gap-2 hover:bg-blue-100 rounded-md p-1 cursor-pointer hover:text-blue-500">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" className="lucide lucide-radio-tower w-[15px]">
|
||||
<path d="M4.9 16.1C1 12.2 1 5.8 4.9 1.9" />
|
||||
<path d="M7.8 4.7a6.14 6.14 0 0 0-.8 7.5" />
|
||||
<circle cx="12" cy="9" r="2" />
|
||||
<path d="M16.2 4.8c2 2 2.26 5.11.8 7.47" />
|
||||
<path d="M19.1 1.9a9.96 9.96 0 0 1 0 14.1" />
|
||||
<path d="M9.5 18h5" />
|
||||
<path d="m8 22 4-11 4 11" />
|
||||
|
||||
</svg>Radio
|
||||
</li>
|
||||
</ul>
|
||||
)
|
||||
}
|
67
src/components/popular/index.tsx
Normal file
67
src/components/popular/index.tsx
Normal file
@ -0,0 +1,67 @@
|
||||
export function Popular() {
|
||||
return (
|
||||
<div className="bg-gray-300 flex-1 rounded-xl flex flex-col max-h-[200px] overflow-hidden">
|
||||
<div id="middle-main" className="font-bold p-4 bg-white flex-1 rounded-xl shadow-md flex flex-col gap-2">
|
||||
<h2>Popular</h2>
|
||||
<div className="flex gap-4 overflow-y-scroll">
|
||||
{dummyData.map(x => (
|
||||
<div className="flex flex-col min-w-[100px]">
|
||||
<img src={x.image} width={100} className="rounded-xl" />
|
||||
<p className="text-[.8rem] text-gray-500">{x.title}</p>
|
||||
<small className="text-[.6rem] text-gray-300">{x.location}</small>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const dummyData = [
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
]
|
||||
|
65
src/components/recommended_radio/index.tsx
Normal file
65
src/components/recommended_radio/index.tsx
Normal file
@ -0,0 +1,65 @@
|
||||
export function RecommendedRadio() {
|
||||
return (
|
||||
<div id="bottom-r" className="flex-col flex font-bold p-2 bg-white flex-1 rounded-xl shadow-md gap-2">
|
||||
<h2>Recommended For You</h2>
|
||||
|
||||
<div className="flex flex-col gap-4 overflow-y-scroll h-full">
|
||||
{dummyData.map(x => (
|
||||
<div className="flex flex-row min-w-[100px] items-center gap-2">
|
||||
<img src={x.image} width={50} className="rounded-xl" />
|
||||
<h3 className="text-xl text-gray-500">{x.title}</h3>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const dummyData = [
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
{
|
||||
location: 'Florida, USA',
|
||||
title: '93.3 FLZ',
|
||||
image: 'https://thispersondoesnotexist.com'
|
||||
},
|
||||
]
|
||||
|
@ -9,8 +9,16 @@
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
/* background-color: #000022dd; */
|
||||
@apply bg-gray-100 mt-6;
|
||||
@apply bg-gray-100;
|
||||
}
|
||||
|
||||
html,
|
||||
body,
|
||||
#root {
|
||||
margin: 0 !important;
|
||||
overlay: hidden;
|
||||
max-width: 100vw;
|
||||
max-height: 100vh;
|
||||
}
|
||||
|
||||
.paper {
|
||||
|
Loading…
Reference in New Issue
Block a user