mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-12 23:45:18 +00:00
All Version Download links added
This commit is contained in:
parent
c8b7c9b5dc
commit
f34afaf586
@ -4,8 +4,25 @@
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<meta name="theme-color" content="#000000" />
|
<meta name="theme-color" content="#000000" />
|
||||||
<link rel="shortcut icon" type="image/ico" href="/src/assets/favicon.ico" />
|
<link
|
||||||
<title>Solid App</title>
|
rel="apple-touch-icon"
|
||||||
|
sizes="180x180"
|
||||||
|
href="/src/assets/apple-touch-icon.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
sizes="32x32"
|
||||||
|
href="/src/assets/favicon-32x32.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
sizes="16x16"
|
||||||
|
href="/src/assets/favicon-16x16.png"
|
||||||
|
/>
|
||||||
|
<link rel="manifest" href="/src/assets/site.webmanifest" />
|
||||||
|
<title>Spotube</title>
|
||||||
<script
|
<script
|
||||||
async
|
async
|
||||||
src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-6419300932495863"
|
src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-6419300932495863"
|
||||||
|
@ -16,10 +16,15 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hope-ui/solid": "^0.6.2",
|
"@hope-ui/solid": "^0.6.2",
|
||||||
|
"@octokit/rest": "^19.0.3",
|
||||||
"@stitches/core": "^1.2.8",
|
"@stitches/core": "^1.2.8",
|
||||||
|
"isomorphic-fetch": "^3.0.0",
|
||||||
|
"remark-gfm": "^3.0.1",
|
||||||
"solid-app-router": "^0.4.1",
|
"solid-app-router": "^0.4.1",
|
||||||
|
"solid-cached-resource": "^0.3.0",
|
||||||
"solid-icons": "^0.5.0",
|
"solid-icons": "^0.5.0",
|
||||||
"solid-js": "^1.4.7",
|
"solid-js": "^1.4.7",
|
||||||
|
"solid-markdown": "^1.2.0",
|
||||||
"solid-transition-group": "^0.0.10"
|
"solid-transition-group": "^0.0.10"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,89 +1,21 @@
|
|||||||
import {
|
import { VStack } from "@hope-ui/solid";
|
||||||
Anchor,
|
|
||||||
Button,
|
|
||||||
ButtonGroup,
|
|
||||||
Heading,
|
|
||||||
IconButton,
|
|
||||||
Menu,
|
|
||||||
MenuContent,
|
|
||||||
MenuItem,
|
|
||||||
MenuTrigger,
|
|
||||||
VStack,
|
|
||||||
} from "@hope-ui/solid";
|
|
||||||
import type { Component } from "solid-js";
|
import type { Component } from "solid-js";
|
||||||
import { usePlatform, Platform } from "./hooks/usePlatform";
|
import Navbar from "./components/Navbar";
|
||||||
import { FaSolidCaretDown } from "solid-icons/fa";
|
import { Route, Router, Routes } from "solid-app-router";
|
||||||
|
import { Root } from "./pages/Root";
|
||||||
const baseURL = "https://github.com/KRTirtho/spotube/releases/latest/download/";
|
import AllVersions from "./pages/AllVersions";
|
||||||
|
|
||||||
const DownloadLinks = {
|
|
||||||
[Platform.linux]: [
|
|
||||||
{ name: "deb", url: baseURL + "Spotube-linux-x86_64.deb" },
|
|
||||||
{ name: "tar", url: baseURL + "Spotube-linux-x86_64.tar.xz" },
|
|
||||||
{ name: "AppImage", url: baseURL + "Spotube-linux-x86_64.AppImage" },
|
|
||||||
],
|
|
||||||
[Platform.android]: [
|
|
||||||
{
|
|
||||||
name: "apk",
|
|
||||||
url: baseURL + "Spotube-android-all-arch.apk",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[Platform.mac]: [{ name: "dmg", url: baseURL + "Spotube-macos-x86_64.dmg" }],
|
|
||||||
[Platform.windows]: [
|
|
||||||
{ name: "exe", url: baseURL + "Spotube-windows-x86_64-setup.exe" },
|
|
||||||
{ name: "nupkg", url: baseURL + "Spotube-windows-x86_64.nupkg " },
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
const App: Component = () => {
|
const App: Component = () => {
|
||||||
const platform = usePlatform();
|
|
||||||
|
|
||||||
const allPlatforms = Object.entries(Platform)
|
|
||||||
.map(([key, value]) => {
|
|
||||||
return DownloadLinks[value].map((s) => ({
|
|
||||||
...s,
|
|
||||||
name: `${value} (.${s.name})`,
|
|
||||||
}));
|
|
||||||
})
|
|
||||||
.flat(1);
|
|
||||||
|
|
||||||
const currentPlatform = DownloadLinks[platform][0];
|
|
||||||
return (
|
return (
|
||||||
<VStack spacing="$4">
|
<Router>
|
||||||
<Heading alignSelf="start" p="$2" size="3xl">
|
<VStack alignItems="stretch">
|
||||||
Spotube
|
<Navbar />
|
||||||
</Heading>
|
<Routes>
|
||||||
<Heading size="5xl">Spotube</Heading>
|
<Route path="/" component={Root} />
|
||||||
<Heading size="2xl">
|
<Route path="/all-versions" component={AllVersions} />
|
||||||
A fast, modern, lightweight & efficient Spotify Music Client for every
|
</Routes>
|
||||||
platform
|
</VStack>
|
||||||
</Heading>
|
</Router>
|
||||||
|
|
||||||
<Menu placement="bottom-end">
|
|
||||||
<ButtonGroup spacing="$0_5">
|
|
||||||
<Button
|
|
||||||
variant="subtle"
|
|
||||||
as={Anchor}
|
|
||||||
href={currentPlatform.url}
|
|
||||||
_hover={{ textDecoration: "none" }}
|
|
||||||
>
|
|
||||||
Download for {platform} (.{currentPlatform.name})
|
|
||||||
</Button>
|
|
||||||
<MenuTrigger as={IconButton} variant="subtle">
|
|
||||||
<FaSolidCaretDown />
|
|
||||||
</MenuTrigger>
|
|
||||||
</ButtonGroup>
|
|
||||||
<MenuContent>
|
|
||||||
{allPlatforms.map(({ name, url }) => {
|
|
||||||
return (
|
|
||||||
<MenuItem as={Anchor} href={url}>
|
|
||||||
{name}
|
|
||||||
</MenuItem>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</MenuContent>
|
|
||||||
</Menu>
|
|
||||||
</VStack>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BIN
website/src/assets/android-chrome-192x192.png
Normal file
BIN
website/src/assets/android-chrome-192x192.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
BIN
website/src/assets/android-chrome-512x512.png
Normal file
BIN
website/src/assets/android-chrome-512x512.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 136 KiB |
BIN
website/src/assets/apple-touch-icon.png
Normal file
BIN
website/src/assets/apple-touch-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
BIN
website/src/assets/favicon copy.ico
Normal file
BIN
website/src/assets/favicon copy.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
BIN
website/src/assets/favicon-16x16.png
Normal file
BIN
website/src/assets/favicon-16x16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 892 B |
BIN
website/src/assets/favicon-32x32.png
Normal file
BIN
website/src/assets/favicon-32x32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
1
website/src/assets/site.webmanifest
Normal file
1
website/src/assets/site.webmanifest
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
|
22
website/src/components/Navbar.tsx
Normal file
22
website/src/components/Navbar.tsx
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { Button, ButtonGroup, Heading, HStack } from "@hope-ui/solid";
|
||||||
|
import { NavLink } from "solid-app-router";
|
||||||
|
|
||||||
|
const Navbar = () => {
|
||||||
|
return (
|
||||||
|
<HStack as="nav" w="$full">
|
||||||
|
<Heading p="$2" size="3xl" mr="$2" as={NavLink} href="/">
|
||||||
|
Spotube
|
||||||
|
</Heading>
|
||||||
|
<ButtonGroup>
|
||||||
|
<Button variant="ghost" size="sm" as={NavLink} href="/all-versions">
|
||||||
|
All Versions
|
||||||
|
</Button>
|
||||||
|
<Button variant="ghost" size="sm" as={NavLink} href="/all-versions">
|
||||||
|
About
|
||||||
|
</Button>
|
||||||
|
</ButtonGroup>
|
||||||
|
</HStack>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Navbar;
|
@ -1,8 +1,35 @@
|
|||||||
/* @refresh reload */
|
/* @refresh reload */
|
||||||
import { render } from 'solid-js/web';
|
import { render } from "solid-js/web";
|
||||||
|
|
||||||
import './index.css';
|
import "./index.css";
|
||||||
import App from './App';
|
import App from "./App";
|
||||||
import { HopeProvider } from '@hope-ui/solid';
|
import { HopeProvider } from "@hope-ui/solid";
|
||||||
|
|
||||||
render(() => <HopeProvider><App /></HopeProvider>, document.getElementById('root') as HTMLElement);
|
render(
|
||||||
|
() => (
|
||||||
|
<HopeProvider
|
||||||
|
config={{
|
||||||
|
lightTheme: {
|
||||||
|
colors: {
|
||||||
|
primary1: "#ffffff",
|
||||||
|
primary2: "#e8f8ee",
|
||||||
|
primary3: "#bbeacc",
|
||||||
|
primary4: "#a5e3bb",
|
||||||
|
primary5: "#8edcaa",
|
||||||
|
primary6: "#61ce87",
|
||||||
|
primary7: "#4ac776",
|
||||||
|
primary8: "#34c065",
|
||||||
|
primary9: "#1aa74c",
|
||||||
|
primary10: "#179443",
|
||||||
|
primary11: "#116f32",
|
||||||
|
primary12: "#093719",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
initialColorMode: "system",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<App />
|
||||||
|
</HopeProvider>
|
||||||
|
),
|
||||||
|
document.getElementById("root") as HTMLElement
|
||||||
|
);
|
||||||
|
176
website/src/pages/AllVersions.tsx
Normal file
176
website/src/pages/AllVersions.tsx
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
import {
|
||||||
|
Accordion,
|
||||||
|
AccordionButton,
|
||||||
|
AccordionIcon,
|
||||||
|
AccordionItem,
|
||||||
|
AccordionPanel,
|
||||||
|
Anchor,
|
||||||
|
Container,
|
||||||
|
Heading,
|
||||||
|
HStack,
|
||||||
|
Stack,
|
||||||
|
Text,
|
||||||
|
VStack,
|
||||||
|
} from "@hope-ui/solid";
|
||||||
|
import { Octokit, RestEndpointMethodTypes } from "@octokit/rest";
|
||||||
|
import { createCachedResource } from "solid-cached-resource";
|
||||||
|
import SolidMarkdown from "solid-markdown";
|
||||||
|
import { Platform } from "../hooks/usePlatform";
|
||||||
|
import gfm from "remark-gfm";
|
||||||
|
|
||||||
|
enum AssetTypes {
|
||||||
|
sums = "sums",
|
||||||
|
linux = "linux",
|
||||||
|
mac = "mac",
|
||||||
|
windows = "windows",
|
||||||
|
android = "android",
|
||||||
|
}
|
||||||
|
|
||||||
|
const octokit = new Octokit();
|
||||||
|
const AllVersions = () => {
|
||||||
|
const [data] = createCachedResource("gh-releases", () => {
|
||||||
|
return octokit.repos.listReleases({
|
||||||
|
owner: "KRTirtho",
|
||||||
|
repo: "spotube",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<VStack alignItems="stretch" m="$3">
|
||||||
|
<Heading size="3xl">Previous Versions</Heading>
|
||||||
|
<Text my="$5">
|
||||||
|
If any of your version is not working correctly than you can download &
|
||||||
|
use previous versions of Spotube too
|
||||||
|
</Text>
|
||||||
|
<VStack alignItems="stretch" spacing="$3" mr="$1">
|
||||||
|
{data()?.data.map((release, i) => {
|
||||||
|
const releaseSome = release.assets
|
||||||
|
.map((asset) => {
|
||||||
|
const platform =
|
||||||
|
Object.keys(Platform).find((platform) =>
|
||||||
|
asset.name.toLowerCase().includes(platform)
|
||||||
|
) ?? "sums";
|
||||||
|
return {
|
||||||
|
type: AssetTypes[platform as keyof typeof AssetTypes],
|
||||||
|
asset,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.reduce((acc, val) => {
|
||||||
|
acc[val.type] = [...(acc[val.type] ?? []), val.asset];
|
||||||
|
return acc;
|
||||||
|
}, {} as any) as {
|
||||||
|
[key in AssetTypes]: RestEndpointMethodTypes["repos"]["listReleases"]["response"]["data"][0]["assets"];
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<VStack
|
||||||
|
py="$3"
|
||||||
|
alignItems="flex-start"
|
||||||
|
borderBottom="1px solid grey"
|
||||||
|
_last={{ borderBottom: "none" }}
|
||||||
|
>
|
||||||
|
<Heading size="xl">
|
||||||
|
Version{" "}
|
||||||
|
<Text as="span" color="$success8">
|
||||||
|
{release.tag_name}
|
||||||
|
</Text>{" "}
|
||||||
|
{i == 0 && "(Latest)"}
|
||||||
|
</Heading>
|
||||||
|
{Object.entries(releaseSome).map(([type, assets]) => {
|
||||||
|
return (
|
||||||
|
<HStack py="$2" alignItems="flex-start">
|
||||||
|
<Heading
|
||||||
|
w={90}
|
||||||
|
p="$2"
|
||||||
|
color="$info12"
|
||||||
|
border={`2px solid #404040`}
|
||||||
|
borderRadius="5px 0 0 5px"
|
||||||
|
borderRight="none"
|
||||||
|
>
|
||||||
|
{type[0].toUpperCase() + type.slice(1)}
|
||||||
|
</Heading>
|
||||||
|
<VStack
|
||||||
|
alignItems="flex-start"
|
||||||
|
border={`2px solid #404040`}
|
||||||
|
borderRadius={`0 5px 5px ${
|
||||||
|
assets.length !== 1 ? 5 : 0
|
||||||
|
}px`}
|
||||||
|
w="$72"
|
||||||
|
>
|
||||||
|
{assets.map((asset) => {
|
||||||
|
return (
|
||||||
|
<Anchor
|
||||||
|
color="$info11"
|
||||||
|
width="$full"
|
||||||
|
p="$2"
|
||||||
|
href={asset.name}
|
||||||
|
>
|
||||||
|
{asset.name}
|
||||||
|
</Anchor>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</VStack>
|
||||||
|
</HStack>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
<Accordion defaultIndex={i}>
|
||||||
|
<AccordionItem>
|
||||||
|
<AccordionButton>
|
||||||
|
Release Notes <AccordionIcon />
|
||||||
|
</AccordionButton>
|
||||||
|
<AccordionPanel>
|
||||||
|
<SolidMarkdown
|
||||||
|
components={{
|
||||||
|
a: (props) => (
|
||||||
|
<Anchor {...(props as any)} color="$info10" />
|
||||||
|
),
|
||||||
|
h1: (props) => (
|
||||||
|
<Heading
|
||||||
|
{...(props as any)}
|
||||||
|
size="4xl"
|
||||||
|
mt="$5"
|
||||||
|
mb="$1_5"
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
h2: (props) => (
|
||||||
|
<Heading
|
||||||
|
{...(props as any)}
|
||||||
|
size="3xl"
|
||||||
|
mt="$5"
|
||||||
|
mb="$1_5"
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
h3: (props) => (
|
||||||
|
<Heading
|
||||||
|
{...(props as any)}
|
||||||
|
size="2xl"
|
||||||
|
mt="$5"
|
||||||
|
mb="$1_5"
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
h4: (props) => (
|
||||||
|
<Heading {...(props as any)} size="md" />
|
||||||
|
),
|
||||||
|
h5: (props) => (
|
||||||
|
<Heading {...(props as any)} size="lg" />
|
||||||
|
),
|
||||||
|
h6: (props) => (
|
||||||
|
<Heading {...(props as any)} size="md" />
|
||||||
|
),
|
||||||
|
p: (props) => <Text {...(props as any)} size="" />,
|
||||||
|
}}
|
||||||
|
remarkPlugins={[gfm]}
|
||||||
|
>
|
||||||
|
{release.body ?? ""}
|
||||||
|
</SolidMarkdown>
|
||||||
|
</AccordionPanel>
|
||||||
|
</AccordionItem>
|
||||||
|
</Accordion>
|
||||||
|
</VStack>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</VStack>
|
||||||
|
</VStack>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AllVersions;
|
83
website/src/pages/Root.tsx
Normal file
83
website/src/pages/Root.tsx
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
import {
|
||||||
|
Heading,
|
||||||
|
Menu,
|
||||||
|
ButtonGroup,
|
||||||
|
Button,
|
||||||
|
Anchor,
|
||||||
|
MenuTrigger,
|
||||||
|
IconButton,
|
||||||
|
MenuContent,
|
||||||
|
MenuItem,
|
||||||
|
VStack,
|
||||||
|
} from "@hope-ui/solid";
|
||||||
|
import { FaSolidCaretDown } from "solid-icons/fa";
|
||||||
|
import { Platform, usePlatform } from "../hooks/usePlatform";
|
||||||
|
|
||||||
|
const baseURL = "https://github.com/KRTirtho/spotube/releases/latest/download/";
|
||||||
|
|
||||||
|
const DownloadLinks = {
|
||||||
|
[Platform.linux]: [
|
||||||
|
{ name: "deb", url: baseURL + "Spotube-linux-x86_64.deb" },
|
||||||
|
{ name: "tar", url: baseURL + "Spotube-linux-x86_64.tar.xz" },
|
||||||
|
{ name: "AppImage", url: baseURL + "Spotube-linux-x86_64.AppImage" },
|
||||||
|
],
|
||||||
|
[Platform.android]: [
|
||||||
|
{
|
||||||
|
name: "apk",
|
||||||
|
url: baseURL + "Spotube-android-all-arch.apk",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[Platform.mac]: [{ name: "dmg", url: baseURL + "Spotube-macos-x86_64.dmg" }],
|
||||||
|
[Platform.windows]: [
|
||||||
|
{ name: "exe", url: baseURL + "Spotube-windows-x86_64-setup.exe" },
|
||||||
|
{ name: "nupkg", url: baseURL + "Spotube-windows-x86_64.nupkg " },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Root = () => {
|
||||||
|
const platform = usePlatform();
|
||||||
|
|
||||||
|
const allPlatforms = Object.entries(Platform)
|
||||||
|
.map(([key, value]) => {
|
||||||
|
return DownloadLinks[value].map((s) => ({
|
||||||
|
...s,
|
||||||
|
name: `${value} (.${s.name})`,
|
||||||
|
}));
|
||||||
|
})
|
||||||
|
.flat(1);
|
||||||
|
|
||||||
|
const currentPlatform = DownloadLinks[platform][0];
|
||||||
|
return (
|
||||||
|
<VStack alignSelf="center" spacing="$4">
|
||||||
|
<Heading size="5xl">Spotube</Heading>
|
||||||
|
<Heading size="2xl">
|
||||||
|
A fast, modern, lightweight & efficient Spotify Music Client for every
|
||||||
|
platform
|
||||||
|
</Heading>
|
||||||
|
<Menu placement="bottom-end">
|
||||||
|
<ButtonGroup spacing="$0_5">
|
||||||
|
<Button
|
||||||
|
variant="subtle"
|
||||||
|
as={Anchor}
|
||||||
|
href={currentPlatform.url}
|
||||||
|
_hover={{ textDecoration: "none" }}
|
||||||
|
>
|
||||||
|
Download for {platform} (.{currentPlatform.name})
|
||||||
|
</Button>
|
||||||
|
<MenuTrigger as={IconButton} variant="subtle">
|
||||||
|
<FaSolidCaretDown />
|
||||||
|
</MenuTrigger>
|
||||||
|
</ButtonGroup>
|
||||||
|
<MenuContent>
|
||||||
|
{allPlatforms.map(({ name, url }) => {
|
||||||
|
return (
|
||||||
|
<MenuItem as={Anchor} href={url}>
|
||||||
|
{name}
|
||||||
|
</MenuItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</MenuContent>
|
||||||
|
</Menu>
|
||||||
|
</VStack>
|
||||||
|
);
|
||||||
|
};
|
@ -6,6 +6,11 @@ export default defineConfig({
|
|||||||
server: {
|
server: {
|
||||||
port: 3000,
|
port: 3000,
|
||||||
},
|
},
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
"node-fetch": "isomorphic-fetch",
|
||||||
|
},
|
||||||
|
},
|
||||||
build: {
|
build: {
|
||||||
target: "esnext",
|
target: "esnext",
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user