diff --git a/README.md b/README.md index ed0571dd..e4c55008 100644 --- a/README.md +++ b/README.md @@ -1,63 +1,44 @@ -# react-nodegui-starter +# Spotube +Spotube is a [qt](https://qt.io) based lightweight spotify client which uses [nodegui/react-nodegui](https://github.com/nodegui/react-nodegui) as frontend & nodejs as backend. It utilizes the power of Spotify & Youtube's public API & creates a hazardless, performant & resource friendly User Experience -**Clone and run for a quick way to see React NodeGui in action.** +## Features +Following are the features that currently spotube offers: +- Open Source +- No telementry, diagnostics or user data collection +- Lightweight & resource friendly +- Near native performance & seemless with default desktop themes (Win10, Win7, OSX, QT-default) +- Playback control is on user's machine instead of server based +- Small size & less data hungry +- No spotify or youtube ads since it uses all public & free APIs (But it's recommended to support the creators by watching/liking/subscribing to the artists youtube channel or add as favourite track in spotify. Mostly buying spotify premium is the best way to support their valuable creations) -logo +## Installation +I'm always releasing newer versions of binary of the software each 2-3 month with minor changes & each 6-8 month with major changes. Grab the binaries -## To Use +Windows: [.exe]() -To clone and run this repository you'll need [Git](https://git-scm.com) and [Node.js](https://nodejs.org/en/download/) (which comes with [npm](http://npmjs.com)) installed on your computer. From your command line: +OSX: **I hate apple** (Just kidding, actually don't have a mac) -```bash -# Clone this repository -git clone https://github.com/nodegui/react-nodegui-starter -# Install CMake -brew install cmake -# Go into the repository -cd react-nodegui-starter -# Install dependencies -npm install -# Run the dev server -npm run dev -# Open andother terminal and run the app -npm start -``` +Linux: [.appimage]() -## Installation & Resources for learning React NodeGui -- [Documentation](https://react.nodegui.org) - all of React NodeGui's documentation. -- [NodeGui](https://nodegui.org) - all of NodeGui's documentation. +**I'll/try to upload the package binaries to linux debian/arch/ubuntu/snap/flatpack/redhat stores or software centers or repositories** -## Packaging app as a distributable +## Configuration +There are some configurations that needs to be done to start using this software -In order to distribute your finished app, you can use [@nodegui/packer](https://github.com/nodegui/packer) +You need a spotify account & a web app for -### Step 1: (_**Run this command only once**_) +- clientId +- clientSecret -```sh -npx nodegui-packer --init MyAppName -``` +See these screenshots: -This will produce the deploy directory containing the template. You can modify this to suite your needs. Like add icons, change the name, description and add other native features or dependencies. Make sure you commit this directory. +[1]() -### Step 2: (_**Run this command every time you want to build a new distributable**_) +[2]() -Next you can run the pack command: +[3]() -```sh -npm run build -``` +[4]() -This will produce the js bundle along with assets inside the `./dist` directory - -```sh -npx nodegui-packer --pack ./dist -``` - -This will build the distributable using @nodegui/packer based on your template. The output of the command is found under the build directory. You should gitignore the build directory. - -More details about packer can be found here: https://github.com/nodegui/packer - -## License - -MIT +**[Important]!**: No personal data or any kind of sensitive information won't be collected from spotify. Don't believe? See the code for yourself \ No newline at end of file diff --git a/spotube.sublime-workspace b/spotube.sublime-workspace new file mode 100644 index 00000000..0b687e00 --- /dev/null +++ b/spotube.sublime-workspace @@ -0,0 +1,327 @@ +{ + "auto_complete": + { + "selected_items": + [ + ] + }, + "buffers": + [ + { + "file": "src/components/Player.tsx", + "settings": + { + "buffer_size": 8355, + "line_ending": "Unix" + } + }, + { + "file": "src/routes.tsx", + "settings": + { + "buffer_size": 688, + "line_ending": "Unix" + } + } + ], + "build_system": "", + "build_system_choices": + [ + ], + "build_varint": "", + "command_palette": + { + "height": 0.0, + "last_filter": "", + "selected_items": + [ + [ + "Types: Sh", + "TypeScript: Show Error List" + ], + [ + "pro", + "Project: Save As" + ], + [ + "insta", + "Package Control: Install Package" + ], + [ + "re", + "Package Control: Remove Package" + ], + [ + "lsp type", + "Preferences: LSP-typescript Settings" + ], + [ + "install ", + "Package Control: Install Package" + ], + [ + "LSP: enale", + "LSP: Enable Language Server in Project" + ], + [ + "remove", + "Package Control: Remove Package" + ], + [ + "theme", + "UI: Select Theme" + ], + [ + "termi", + "Terminus: Close" + ], + [ + "Sync Up", + "Sync Settings: Upload" + ], + [ + "Sync crea", + "Sync Settings: Create and Upload" + ], + [ + "package ins", + "Package Control: Install Package" + ], + [ + "pac", + "Install Package Control" + ] + ], + "width": 0.0 + }, + "console": + { + "height": 170.0, + "history": + [ + ] + }, + "distraction_free": + { + "menu_visible": true, + "show_minimap": false, + "show_open_files": false, + "show_tabs": false, + "side_bar_visible": false, + "status_bar_visible": false + }, + "file_history": + [ + "/home/krtirtho/development/desktop-dev/spotube/spotube.sublime-project", + "/home/krtirtho/.config/sublime-text-3/Packages/User/Preferences.sublime-settings", + "/home/krtirtho/.config/sublime-text-3/Packages/TypeScript/Preferences.sublime-settings", + "/home/krtirtho/.config/sublime-text-3/Packages/TypeScript/TypeScriptReact.sublime-settings", + "/home/krtirtho/.config/sublime-text-3/Packages/TypeScript/TypeScript.sublime-settings", + "/home/krtirtho/.config/sublime-text-3/Packages/Default/Default (Linux).sublime-keymap", + "/home/krtirtho/.config/sublime-text-3/Packages/User/Default (Linux).sublime-keymap", + "/home/krtirtho/.config/sublime-text-3/Packages/Sync Settings/SyncSettings.sublime-settings", + "/home/krtirtho/.config/sublime-text-3/Packages/User/SyncSettings.sublime-settings" + ], + "find": + { + "height": 26.0 + }, + "find_in_files": + { + "height": 0.0, + "where_history": + [ + ] + }, + "find_state": + { + "case_sensitive": false, + "find_history": + [ + ], + "highlight": true, + "in_selection": false, + "preserve_case": false, + "regex": false, + "replace_history": + [ + ], + "reverse": false, + "show_context": true, + "use_buffer2": true, + "whole_word": false, + "wrap": true + }, + "groups": + [ + { + "selected": 1, + "sheets": + [ + { + "buffer": 0, + "file": "src/components/Player.tsx", + "semi_transient": false, + "settings": + { + "buffer_size": 8355, + "regions": + { + }, + "selection": + [ + [ + 2966, + 2966 + ] + ], + "settings": + { + "syntax": "Packages/TypeScript/TypeScriptReact.tmLanguage", + "tab_size": 2, + "translate_tabs_to_spaces": true, + "use_tab_stops": false + }, + "translation.x": 0.0, + "translation.y": 1275.0, + "zoom_level": 1.0 + }, + "stack_index": 1, + "type": "text" + }, + { + "buffer": 1, + "file": "src/routes.tsx", + "semi_transient": false, + "settings": + { + "buffer_size": 688, + "regions": + { + }, + "selection": + [ + [ + 688, + 688 + ] + ], + "settings": + { + "color_scheme": "Packages/GitHub Theme/schemes/GitHub Dark.sublime-color-scheme", + "syntax": "Packages/TypeScript/TypeScriptReact.tmLanguage", + "tab_size": 2, + "translate_tabs_to_spaces": true, + "typescript_plugin_format_options": + { + "convertTabsToSpaces": true, + "indentSize": 2, + "tabSize": 2 + }, + "use_tab_stops": false + }, + "translation.x": 0.0, + "translation.y": 0.0, + "zoom_level": 1.0 + }, + "stack_index": 0, + "type": "text" + } + ] + } + ], + "incremental_find": + { + "height": 26.0 + }, + "input": + { + "height": 38.0 + }, + "layout": + { + "cells": + [ + [ + 0, + 0, + 1, + 1 + ] + ], + "cols": + [ + 0.0, + 1.0 + ], + "rows": + [ + 0.0, + 1.0 + ] + }, + "menu_visible": true, + "output.diagnostics": + { + "height": 0.0 + }, + "output.doc": + { + "height": 0.0 + }, + "output.errorlist": + { + "height": 140.0 + }, + "output.find_results": + { + "height": 0.0 + }, + "pinned_build_system": "", + "project": "spotube.sublime-project", + "replace": + { + "height": 48.0 + }, + "save_all_on_build": true, + "select_file": + { + "height": 0.0, + "last_filter": "", + "selected_items": + [ + ], + "width": 0.0 + }, + "select_project": + { + "height": 0.0, + "last_filter": "", + "selected_items": + [ + ], + "width": 0.0 + }, + "select_symbol": + { + "height": 0.0, + "last_filter": "", + "selected_items": + [ + ], + "width": 0.0 + }, + "selected_group": 0, + "settings": + { + }, + "show_minimap": true, + "show_open_files": true, + "show_tabs": true, + "side_bar_visible": true, + "side_bar_width": 225.0, + "status_bar_visible": true, + "template_settings": + { + } +} diff --git a/src/app.tsx b/src/app.tsx index 62b4404c..61be7374 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -139,12 +139,10 @@ function RootApp() { - {/* */} - + {isLoggedIn && } - - {/* */} + diff --git a/src/components/Home.tsx b/src/components/Home.tsx index 79b1bd23..3b413aeb 100644 --- a/src/components/Home.tsx +++ b/src/components/Home.tsx @@ -1,38 +1,43 @@ -import React, { useContext, useEffect, useState } from "react"; -import { Button, ScrollArea, BoxView } from "@nodegui/react-nodegui"; +import React from "react"; +import { Button, ScrollArea, BoxView, View } from "@nodegui/react-nodegui"; import { useHistory } from "react-router"; import CachedImage from "./shared/CachedImage"; import { CursorShape, Direction } from "@nodegui/nodegui"; -import useSpotifyApi from "../hooks/useSpotifyApi"; -import showError from "../helpers/showError"; -import authContext from "../context/authContext"; -import useSpotifyApiError from "../hooks/useSpotifyApiError"; +import { QueryCacheKeys } from "../conf"; +import useSpotifyQuery from "../hooks/useSpotifyQuery"; +import ErrorApplet from "./shared/ErrorApplet"; function Home() { - const spotifyApi = useSpotifyApi(); - const { access_token } = useContext(authContext); - const [categories, setCategories] = useState([]); - const handleSpotifyError = useSpotifyApiError(spotifyApi); - - useEffect(() => { - if (categories.length === 0) { + const { + data: categories, + isError, + isRefetchError, + refetch, + } = useSpotifyQuery( + QueryCacheKeys.categories, + (spotifyApi) => spotifyApi .getCategories({ country: "US" }) - .then((categoriesReceived) => setCategories(categoriesReceived.body.categories.items)) - .catch((error) => { - showError(error, "[Spotify genre loading failed]: "); - handleSpotifyError(error); - }); - } - }, [access_token]); + .then((categoriesReceived) => categoriesReceived.body.categories.items), + { initialData: [] } + ); return ( - - {categories.map((category, index) => { - return ; + + {(isError || isRefetchError) && ( + + )} + {categories?.map((category, index) => { + return ( + + ); })} - + ); } @@ -46,40 +51,52 @@ interface CategoryCardProps { const CategoryCard = ({ id, name }: CategoryCardProps) => { const history = useHistory(); - const [playlists, setPlaylists] = useState([]); - const spotifyApi = useSpotifyApi(); - const handleSpotifyError = useSpotifyApiError(spotifyApi); - - useEffect(() => { - if (playlists.length === 0) { + const { data: playlists, isError } = useSpotifyQuery< + SpotifyApi.PlaylistObjectSimplified[] + >( + [QueryCacheKeys.categoryPlaylists, id], + (spotifyApi) => spotifyApi .getPlaylistsForCategory(id, { limit: 4 }) - .then((playlistsRes) => setPlaylists(playlistsRes.body.playlists.items)) - .catch((error) => { - showError(error, `[Failed to get playlists of category ${name}]: `); - handleSpotifyError(error); - }); - } - }, []); + .then((playlistsRes) => playlistsRes.body.playlists.items), + { initialData: [] } + ); function goToGenre() { history.push(`/genre/playlists/${id}`, { name }); } - + if (isError) { + return <>; + } return ( - -