mirror of
https://github.com/tsirysndr/music-player.git
synced 2026-01-09 13:18:05 -05:00
feat(webui): show Snackbar on connnected/disconnected to a device
This commit is contained in:
2
.github/workflows/release-for-arm.yml
vendored
2
.github/workflows/release-for-arm.yml
vendored
@@ -5,7 +5,7 @@ on:
|
||||
jobs:
|
||||
release:
|
||||
name: release ${{ matrix.target }}
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
||||
@@ -16,7 +16,7 @@ use music_player_types::types::{self, Connected};
|
||||
|
||||
use super::{
|
||||
connect_to, connect_to_current_device,
|
||||
objects::device::{App, Device},
|
||||
objects::device::{App, ConnectedDevice, Device, DisconnectedDevice},
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
@@ -114,6 +114,8 @@ impl DevicesMutation {
|
||||
None => return Err(Error::new("No source found")),
|
||||
}
|
||||
|
||||
SimpleBroker::<ConnectedDevice>::publish(device.clone().into());
|
||||
|
||||
Ok(types::Device::from(device.clone())
|
||||
.is_connected(Some(&device.clone()))
|
||||
.into())
|
||||
@@ -132,6 +134,7 @@ impl DevicesMutation {
|
||||
match connected_device.remove("current_device") {
|
||||
Some(device) => {
|
||||
io_device.clear_source();
|
||||
SimpleBroker::<DisconnectedDevice>::publish(device.clone().into());
|
||||
Ok(Some(device.clone().into()))
|
||||
}
|
||||
None => Ok(None),
|
||||
@@ -162,4 +165,12 @@ impl DevicesSubscription {
|
||||
});
|
||||
SimpleBroker::<Device>::subscribe()
|
||||
}
|
||||
|
||||
async fn on_connected(&self, ctx: &Context<'_>) -> impl Stream<Item = ConnectedDevice> {
|
||||
SimpleBroker::<ConnectedDevice>::subscribe()
|
||||
}
|
||||
|
||||
async fn on_disconnected(&self, ctx: &Context<'_>) -> impl Stream<Item = DisconnectedDevice> {
|
||||
SimpleBroker::<DisconnectedDevice>::subscribe()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,3 +64,115 @@ impl From<types::Device> for Device {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Serialize)]
|
||||
pub struct ConnectedDevice {
|
||||
pub id: ID,
|
||||
pub name: String,
|
||||
pub host: String,
|
||||
pub port: u16,
|
||||
pub service: String,
|
||||
pub app: String,
|
||||
pub is_connected: bool,
|
||||
}
|
||||
|
||||
#[Object]
|
||||
impl ConnectedDevice {
|
||||
async fn id(&self) -> &str {
|
||||
&self.id
|
||||
}
|
||||
|
||||
async fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
|
||||
async fn host(&self) -> &str {
|
||||
&self.host
|
||||
}
|
||||
|
||||
async fn port(&self) -> u16 {
|
||||
self.port
|
||||
}
|
||||
|
||||
async fn service(&self) -> &str {
|
||||
&self.service
|
||||
}
|
||||
|
||||
async fn app(&self) -> &str {
|
||||
&self.app
|
||||
}
|
||||
|
||||
async fn is_connected(&self) -> bool {
|
||||
self.is_connected
|
||||
}
|
||||
}
|
||||
|
||||
impl From<types::Device> for ConnectedDevice {
|
||||
fn from(device: types::Device) -> Self {
|
||||
Self {
|
||||
id: ID::from(device.id),
|
||||
name: device.name,
|
||||
host: device.host,
|
||||
port: device.port,
|
||||
service: device.service,
|
||||
app: device.app,
|
||||
is_connected: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Serialize)]
|
||||
pub struct DisconnectedDevice {
|
||||
pub id: ID,
|
||||
pub name: String,
|
||||
pub host: String,
|
||||
pub port: u16,
|
||||
pub service: String,
|
||||
pub app: String,
|
||||
pub is_connected: bool,
|
||||
}
|
||||
|
||||
#[Object]
|
||||
impl DisconnectedDevice {
|
||||
async fn id(&self) -> &str {
|
||||
&self.id
|
||||
}
|
||||
|
||||
async fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
|
||||
async fn host(&self) -> &str {
|
||||
&self.host
|
||||
}
|
||||
|
||||
async fn port(&self) -> u16 {
|
||||
self.port
|
||||
}
|
||||
|
||||
async fn service(&self) -> &str {
|
||||
&self.service
|
||||
}
|
||||
|
||||
async fn app(&self) -> &str {
|
||||
&self.app
|
||||
}
|
||||
|
||||
async fn is_connected(&self) -> bool {
|
||||
self.is_connected
|
||||
}
|
||||
}
|
||||
|
||||
impl From<types::Device> for DisconnectedDevice {
|
||||
fn from(device: types::Device) -> Self {
|
||||
Self {
|
||||
id: ID::from(device.id),
|
||||
name: device.name,
|
||||
host: device.host,
|
||||
port: device.port,
|
||||
service: device.service,
|
||||
app: device.app,
|
||||
is_connected: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"files": {
|
||||
"main.css": "/static/css/main.5e35567c.css",
|
||||
"main.js": "/static/js/main.a5489166.js",
|
||||
"main.js": "/static/js/main.de307e91.js",
|
||||
"static/js/787.26bf0a29.chunk.js": "/static/js/787.26bf0a29.chunk.js",
|
||||
"static/media/RockfordSans-ExtraBold.otf": "/static/media/RockfordSans-ExtraBold.1513e8fd97078bfb7708.otf",
|
||||
"static/media/RockfordSans-Bold.otf": "/static/media/RockfordSans-Bold.c9f599ae01b13e565598.otf",
|
||||
@@ -10,11 +10,11 @@
|
||||
"static/media/RockfordSans-Light.otf": "/static/media/RockfordSans-Light.b4a12e8abb38f7d105c4.otf",
|
||||
"index.html": "/index.html",
|
||||
"main.5e35567c.css.map": "/static/css/main.5e35567c.css.map",
|
||||
"main.a5489166.js.map": "/static/js/main.a5489166.js.map",
|
||||
"main.de307e91.js.map": "/static/js/main.de307e91.js.map",
|
||||
"787.26bf0a29.chunk.js.map": "/static/js/787.26bf0a29.chunk.js.map"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/css/main.5e35567c.css",
|
||||
"static/js/main.a5489166.js"
|
||||
"static/js/main.de307e91.js"
|
||||
]
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>Music Player</title><script defer="defer" src="/static/js/main.a5489166.js"></script><link href="/static/css/main.5e35567c.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>Music Player</title><script defer="defer" src="/static/js/main.de307e91.js"></script><link href="/static/css/main.5e35567c.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
webui/musicplayer/build/static/js/main.de307e91.js.map
Normal file
1
webui/musicplayer/build/static/js/main.de307e91.js.map
Normal file
File diff suppressed because one or more lines are too long
@@ -377,6 +377,129 @@
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "ConnectedDevice",
|
||||
"description": null,
|
||||
"fields": [
|
||||
{
|
||||
"name": "app",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "host",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "id",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "isConnected",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "Boolean",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "port",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "Int",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "service",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"inputFields": null,
|
||||
"interfaces": [],
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "CurrentlyPlayingSong",
|
||||
@@ -571,6 +694,129 @@
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "DisconnectedDevice",
|
||||
"description": null,
|
||||
"fields": [
|
||||
{
|
||||
"name": "app",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "host",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "id",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "isConnected",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "Boolean",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "port",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "Int",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "service",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"inputFields": null,
|
||||
"interfaces": [],
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "SCALAR",
|
||||
"name": "Float",
|
||||
@@ -2891,6 +3137,38 @@
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "onConnected",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "OBJECT",
|
||||
"name": "ConnectedDevice",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "onDisconnected",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "OBJECT",
|
||||
"name": "DisconnectedDevice",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "onNewDevice",
|
||||
"description": null,
|
||||
|
||||
@@ -71,6 +71,9 @@ const ConnectModal: FC<ConnectModalProps> = ({
|
||||
disconnectFromDevice,
|
||||
}) => {
|
||||
const _connectToDevice = (id: string) => {
|
||||
if (currentDevice?.id === id) {
|
||||
return;
|
||||
}
|
||||
connectToDevice(id);
|
||||
onClose();
|
||||
};
|
||||
|
||||
@@ -20,7 +20,7 @@ const ConnectButton = styled.button<{
|
||||
connected?: boolean;
|
||||
}>`
|
||||
border: none;
|
||||
background-color: #ab28fc0d;
|
||||
background-color: #fbf5ff;
|
||||
height: 32px;
|
||||
${(props) => (props.connected ? "width: 272px;" : "40px")}
|
||||
display: flex;
|
||||
@@ -30,7 +30,6 @@ const ConnectButton = styled.button<{
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
overflow: hidden;
|
||||
`;
|
||||
|
||||
const ConnectText = styled.span`
|
||||
@@ -41,6 +40,8 @@ const ConnectText = styled.span`
|
||||
text-overflow: ellipsis;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
`;
|
||||
|
||||
export type SidebarProps = {
|
||||
|
||||
@@ -13,3 +13,21 @@ export const NEW_DEVICE = gql`
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const ON_DEVICE_CONNECTED = gql`
|
||||
subscription OnDeviceConnected {
|
||||
onConnected {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const ON_DEVICE_DISCONNECTED = gql`
|
||||
subscription OnDeviceDisconnected {
|
||||
onDisconnected {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -45,6 +45,17 @@ export type Artist = {
|
||||
website: Scalars['String'];
|
||||
};
|
||||
|
||||
export type ConnectedDevice = {
|
||||
__typename?: 'ConnectedDevice';
|
||||
app: Scalars['String'];
|
||||
host: Scalars['String'];
|
||||
id: Scalars['String'];
|
||||
isConnected: Scalars['Boolean'];
|
||||
name: Scalars['String'];
|
||||
port: Scalars['Int'];
|
||||
service: Scalars['String'];
|
||||
};
|
||||
|
||||
export type CurrentlyPlayingSong = {
|
||||
__typename?: 'CurrentlyPlayingSong';
|
||||
index: Scalars['Int'];
|
||||
@@ -64,6 +75,17 @@ export type Device = {
|
||||
service: Scalars['String'];
|
||||
};
|
||||
|
||||
export type DisconnectedDevice = {
|
||||
__typename?: 'DisconnectedDevice';
|
||||
app: Scalars['String'];
|
||||
host: Scalars['String'];
|
||||
id: Scalars['String'];
|
||||
isConnected: Scalars['Boolean'];
|
||||
name: Scalars['String'];
|
||||
port: Scalars['Int'];
|
||||
service: Scalars['String'];
|
||||
};
|
||||
|
||||
export type Folder = {
|
||||
__typename?: 'Folder';
|
||||
id: Scalars['String'];
|
||||
@@ -365,6 +387,8 @@ export type Subscription = {
|
||||
currentlyPlayingSong: Track;
|
||||
folder: FolderChanged;
|
||||
folders: Array<Folder>;
|
||||
onConnected: ConnectedDevice;
|
||||
onDisconnected: DisconnectedDevice;
|
||||
onNewDevice: Device;
|
||||
playerState: PlayerState;
|
||||
playlist: PlaylistChanged;
|
||||
@@ -454,6 +478,16 @@ export type OnNewDeviceSubscriptionVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
export type OnNewDeviceSubscription = { __typename?: 'Subscription', onNewDevice: { __typename?: 'Device', id: string, app: string, name: string, service: string, host: string, port: number, isConnected: boolean } };
|
||||
|
||||
export type OnDeviceConnectedSubscriptionVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type OnDeviceConnectedSubscription = { __typename?: 'Subscription', onConnected: { __typename?: 'ConnectedDevice', id: string, name: string } };
|
||||
|
||||
export type OnDeviceDisconnectedSubscriptionVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type OnDeviceDisconnectedSubscription = { __typename?: 'Subscription', onDisconnected: { __typename?: 'DisconnectedDevice', id: string, name: string } };
|
||||
|
||||
export type AlbumFragmentFragment = { __typename?: 'Album', id: string, title: string, artist: string, year?: number | null, cover?: string | null };
|
||||
|
||||
export type ArtistFragmentFragment = { __typename?: 'Artist', id: string, name: string, picture: string };
|
||||
@@ -950,6 +984,66 @@ export function useOnNewDeviceSubscription(baseOptions?: Apollo.SubscriptionHook
|
||||
}
|
||||
export type OnNewDeviceSubscriptionHookResult = ReturnType<typeof useOnNewDeviceSubscription>;
|
||||
export type OnNewDeviceSubscriptionResult = Apollo.SubscriptionResult<OnNewDeviceSubscription>;
|
||||
export const OnDeviceConnectedDocument = gql`
|
||||
subscription OnDeviceConnected {
|
||||
onConnected {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useOnDeviceConnectedSubscription__
|
||||
*
|
||||
* To run a query within a React component, call `useOnDeviceConnectedSubscription` and pass it any options that fit your needs.
|
||||
* When your component renders, `useOnDeviceConnectedSubscription` returns an object from Apollo Client that contains loading, error, and data properties
|
||||
* you can use to render your UI.
|
||||
*
|
||||
* @param baseOptions options that will be passed into the subscription, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||
*
|
||||
* @example
|
||||
* const { data, loading, error } = useOnDeviceConnectedSubscription({
|
||||
* variables: {
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useOnDeviceConnectedSubscription(baseOptions?: Apollo.SubscriptionHookOptions<OnDeviceConnectedSubscription, OnDeviceConnectedSubscriptionVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useSubscription<OnDeviceConnectedSubscription, OnDeviceConnectedSubscriptionVariables>(OnDeviceConnectedDocument, options);
|
||||
}
|
||||
export type OnDeviceConnectedSubscriptionHookResult = ReturnType<typeof useOnDeviceConnectedSubscription>;
|
||||
export type OnDeviceConnectedSubscriptionResult = Apollo.SubscriptionResult<OnDeviceConnectedSubscription>;
|
||||
export const OnDeviceDisconnectedDocument = gql`
|
||||
subscription OnDeviceDisconnected {
|
||||
onDisconnected {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useOnDeviceDisconnectedSubscription__
|
||||
*
|
||||
* To run a query within a React component, call `useOnDeviceDisconnectedSubscription` and pass it any options that fit your needs.
|
||||
* When your component renders, `useOnDeviceDisconnectedSubscription` returns an object from Apollo Client that contains loading, error, and data properties
|
||||
* you can use to render your UI.
|
||||
*
|
||||
* @param baseOptions options that will be passed into the subscription, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||
*
|
||||
* @example
|
||||
* const { data, loading, error } = useOnDeviceDisconnectedSubscription({
|
||||
* variables: {
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useOnDeviceDisconnectedSubscription(baseOptions?: Apollo.SubscriptionHookOptions<OnDeviceDisconnectedSubscription, OnDeviceDisconnectedSubscriptionVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useSubscription<OnDeviceDisconnectedSubscription, OnDeviceDisconnectedSubscriptionVariables>(OnDeviceDisconnectedDocument, options);
|
||||
}
|
||||
export type OnDeviceDisconnectedSubscriptionHookResult = ReturnType<typeof useOnDeviceDisconnectedSubscription>;
|
||||
export type OnDeviceDisconnectedSubscriptionResult = Apollo.SubscriptionResult<OnDeviceDisconnectedSubscription>;
|
||||
export const GetAlbumsDocument = gql`
|
||||
query GetAlbums($offset: Int, $limit: Int) {
|
||||
albums(offset: $offset, limit: $limit) {
|
||||
|
||||
@@ -1,21 +1,32 @@
|
||||
import { useSnackbar } from "baseui/snackbar";
|
||||
import _ from "lodash";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Device } from "../Types/Device";
|
||||
import {
|
||||
useConnectedDeviceQuery,
|
||||
useConnectToDeviceMutation,
|
||||
useDisconnectFromDeviceMutation,
|
||||
useListDevicesQuery,
|
||||
useOnDeviceConnectedSubscription,
|
||||
useOnDeviceDisconnectedSubscription,
|
||||
useOnNewDeviceSubscription,
|
||||
} from "./GraphQL";
|
||||
|
||||
export const useDevices = () => {
|
||||
const navigate = useNavigate();
|
||||
const [currentDevice, setCurrentDevice] =
|
||||
useState<Device | undefined>(undefined);
|
||||
const [devices, setDevices] = useState<Device[]>([]);
|
||||
const { data } = useOnNewDeviceSubscription();
|
||||
const { data: listDevicesData } = useListDevicesQuery();
|
||||
const { data: connectedDeviceData } = useConnectedDeviceQuery();
|
||||
const { data: connectedDeviceData, refetch } = useConnectedDeviceQuery();
|
||||
const [connectToDevice] = useConnectToDeviceMutation();
|
||||
const [disconnectFromDevice] = useDisconnectFromDeviceMutation();
|
||||
const { data: deviceConnectedData } = useOnDeviceConnectedSubscription();
|
||||
const { data: deviceDisconnectedData } =
|
||||
useOnDeviceDisconnectedSubscription();
|
||||
const { enqueue } = useSnackbar();
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
@@ -54,14 +65,49 @@ export const useDevices = () => {
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [data, listDevicesData]);
|
||||
|
||||
const currentDevice: Device | undefined = connectedDeviceData
|
||||
? {
|
||||
useEffect(() => {
|
||||
if (deviceConnectedData) {
|
||||
enqueue({
|
||||
message: `Connected to ${deviceConnectedData.onConnected.name}`,
|
||||
});
|
||||
refetch()
|
||||
.then((result) => {
|
||||
if (result.data?.connectedDevice) {
|
||||
setCurrentDevice({
|
||||
id: result.data.connectedDevice.id,
|
||||
type: result.data.connectedDevice.app,
|
||||
name: result.data.connectedDevice.name,
|
||||
isConnected: result.data.connectedDevice.isConnected,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((e) => console.error(e));
|
||||
navigate(0);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [deviceConnectedData]);
|
||||
|
||||
useEffect(() => {
|
||||
if (deviceDisconnectedData) {
|
||||
enqueue({
|
||||
message: `Disconnected from ${deviceDisconnectedData.onDisconnected.name}`,
|
||||
});
|
||||
refetch().catch((e) => console.error(e));
|
||||
setCurrentDevice(undefined);
|
||||
navigate(0);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [deviceDisconnectedData]);
|
||||
|
||||
useEffect(() => {
|
||||
connectedDeviceData &&
|
||||
setCurrentDevice({
|
||||
id: connectedDeviceData.connectedDevice.id,
|
||||
type: connectedDeviceData.connectedDevice.app,
|
||||
name: connectedDeviceData.connectedDevice.name,
|
||||
isConnected: connectedDeviceData.connectedDevice.isConnected,
|
||||
}
|
||||
: undefined;
|
||||
});
|
||||
}, [connectedDeviceData]);
|
||||
|
||||
return { devices, currentDevice, connectToDevice, disconnectFromDevice };
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@ import reportWebVitals from "./reportWebVitals";
|
||||
import { Provider as StyletronProvider } from "styletron-react";
|
||||
import { Client as Styletron } from "styletron-engine-atomic";
|
||||
import { BaseProvider } from "baseui";
|
||||
import { PLACEMENT, SnackbarProvider } from "baseui/snackbar";
|
||||
import { theme } from "./Theme";
|
||||
import {
|
||||
ApolloClient,
|
||||
@@ -22,7 +23,7 @@ import { createTauriLink } from "./TauriLink";
|
||||
|
||||
let link: ApolloLink;
|
||||
|
||||
if (process.env.REACT_APP_NATIVE_WRAPPER === 'tauri') {
|
||||
if (process.env.REACT_APP_NATIVE_WRAPPER === "tauri") {
|
||||
link = createTauriLink();
|
||||
} else {
|
||||
const uri =
|
||||
@@ -34,11 +35,11 @@ if (process.env.REACT_APP_NATIVE_WRAPPER === 'tauri') {
|
||||
const httpLink = createHttpLink({
|
||||
uri,
|
||||
});
|
||||
|
||||
|
||||
const wsLink = new WebSocketLink(
|
||||
new SubscriptionClient(uri.replace("http", "ws"))
|
||||
);
|
||||
|
||||
|
||||
const splitLink = split(
|
||||
({ query }) => {
|
||||
const definition = getMainDefinition(query);
|
||||
@@ -67,7 +68,9 @@ render(
|
||||
<ApolloProvider client={client}>
|
||||
<StyletronProvider value={engine}>
|
||||
<BaseProvider theme={theme}>
|
||||
<App />
|
||||
<SnackbarProvider placement={PLACEMENT.bottom}>
|
||||
<App />
|
||||
</SnackbarProvider>
|
||||
</BaseProvider>
|
||||
</StyletronProvider>
|
||||
</ApolloProvider>
|
||||
|
||||
Reference in New Issue
Block a user