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 name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<link rel="shortcut icon" type="image/ico" href="/src/assets/favicon.ico" />
|
||||
<title>Solid App</title>
|
||||
<link
|
||||
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
|
||||
async
|
||||
src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-6419300932495863"
|
||||
|
@ -16,10 +16,15 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@hope-ui/solid": "^0.6.2",
|
||||
"@octokit/rest": "^19.0.3",
|
||||
"@stitches/core": "^1.2.8",
|
||||
"isomorphic-fetch": "^3.0.0",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"solid-app-router": "^0.4.1",
|
||||
"solid-cached-resource": "^0.3.0",
|
||||
"solid-icons": "^0.5.0",
|
||||
"solid-js": "^1.4.7",
|
||||
"solid-markdown": "^1.2.0",
|
||||
"solid-transition-group": "^0.0.10"
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,89 +1,21 @@
|
||||
import {
|
||||
Anchor,
|
||||
Button,
|
||||
ButtonGroup,
|
||||
Heading,
|
||||
IconButton,
|
||||
Menu,
|
||||
MenuContent,
|
||||
MenuItem,
|
||||
MenuTrigger,
|
||||
VStack,
|
||||
} from "@hope-ui/solid";
|
||||
import { VStack } from "@hope-ui/solid";
|
||||
import type { Component } from "solid-js";
|
||||
import { usePlatform, Platform } from "./hooks/usePlatform";
|
||||
import { FaSolidCaretDown } from "solid-icons/fa";
|
||||
|
||||
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 " },
|
||||
],
|
||||
};
|
||||
import Navbar from "./components/Navbar";
|
||||
import { Route, Router, Routes } from "solid-app-router";
|
||||
import { Root } from "./pages/Root";
|
||||
import AllVersions from "./pages/AllVersions";
|
||||
|
||||
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 (
|
||||
<VStack spacing="$4">
|
||||
<Heading alignSelf="start" p="$2" size="3xl">
|
||||
Spotube
|
||||
</Heading>
|
||||
<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>
|
||||
<Router>
|
||||
<VStack alignItems="stretch">
|
||||
<Navbar />
|
||||
<Routes>
|
||||
<Route path="/" component={Root} />
|
||||
<Route path="/all-versions" component={AllVersions} />
|
||||
</Routes>
|
||||
</VStack>
|
||||
</Router>
|
||||
);
|
||||
};
|
||||
|
||||
|
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 */
|
||||
import { render } from 'solid-js/web';
|
||||
import { render } from "solid-js/web";
|
||||
|
||||
import './index.css';
|
||||
import App from './App';
|
||||
import { HopeProvider } from '@hope-ui/solid';
|
||||
import "./index.css";
|
||||
import App from "./App";
|
||||
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: {
|
||||
port: 3000,
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
"node-fetch": "isomorphic-fetch",
|
||||
},
|
||||
},
|
||||
build: {
|
||||
target: "esnext",
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user