Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
HolbyFPV committed Oct 24, 2024
1 parent d059015 commit 55c477b
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 123 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/boilerplate-solid-ts/dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<title>Zebar</title>
<script type="module" crossorigin src="./assets/index-CWdujjjG.js"></script>
<script type="module" crossorigin src="./assets/index-lccBZ8eH.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index-DhTpoJOY.css">
</head>
<body>
Expand Down
10 changes: 9 additions & 1 deletion packages/client-api/src/providers/create-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ import type {
KomorebiProviderConfig,
KomorebiProvider,
} from './komorebi/komorebi-provider-types';
import type {
MediaProviderConfig,
MediaProvider,
} from './media/media-provider-types';
import { createMediaProvider } from './media/create-media-provider';
import { createMemoryProvider } from './memory/create-memory-provider';
import type {
MemoryProviderConfig,
Expand All @@ -59,7 +64,7 @@ export interface ProviderConfigMap {
host: HostProviderConfig;
ip: IpProviderConfig;
komorebi: KomorebiProviderConfig;
// media: MediaProviderConfig;
media: MediaProviderConfig;
memory: MemoryProviderConfig;
network: NetworkProviderConfig;
weather: WeatherProviderConfig;
Expand All @@ -74,6 +79,7 @@ export interface ProviderMap {
host: HostProvider;
ip: IpProvider;
komorebi: KomorebiProvider;
media: MediaProvider;
memory: MemoryProvider;
network: NetworkProvider;
weather: WeatherProvider;
Expand Down Expand Up @@ -115,6 +121,8 @@ export function createProvider<T extends ProviderConfig>(
return createIpProvider(config) as any;
case 'komorebi':
return createKomorebiProvider(config) as any;
case 'media':
return createMediaProvider(config) as any;
case 'memory':
return createMemoryProvider(config) as any;
case 'network':
Expand Down
1 change: 1 addition & 0 deletions packages/client-api/src/providers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export * from './host/host-provider-types';
export * from './ip/ip-provider-types';
export * from './keyboard/keyboard-provider-types';
export * from './komorebi/komorebi-provider-types';
export * from './media/media-provider-types';
export * from './memory/memory-provider-types';
export * from './network/network-provider-types';
export * from './weather/weather-provider-types';
Expand Down
29 changes: 29 additions & 0 deletions packages/client-api/src/providers/media/create-media-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {z} from 'zod';
import {createBaseProvider} from '../create-base-provider';
import {onProviderEmit} from '~/desktop';
import type {
MediaOutput,
MediaProvider,
MediaProviderConfig,
} from './media-provider-types';

const mediaProviderConfigSchema = z.object({
type: z.literal('media'),
refreshInterval: z.coerce.number().default(5 * 1000),
});

export function createMediaProvider(
config: MediaProviderConfig,
): MediaProvider {
const mergedConfig = mediaProviderConfigSchema.parse(config);

return createBaseProvider(mergedConfig, async queue => {
return onProviderEmit<MediaOutput>(mergedConfig, ({result}) => {
if ('error' in result) {
queue.error(result.error);
} else {
queue.output(result.output);
}
});
});
}
21 changes: 21 additions & 0 deletions packages/client-api/src/providers/media/media-provider-types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type {Provider} from '../create-base-provider';

export interface MediaProviderConfig {
type: 'media';
/**
* How often this provider refreshes in milliseconds.
*/
refreshInterval?: number;
}

export interface MediaOutput {
title: string;
subTitle: string;
trackNumber: number;
artist: string;
albumTitle: string;
isPlaying: boolean;
isSpotify: boolean;
}

export type MediaProvider = Provider<MediaProviderConfig, MediaOutput>;
1 change: 1 addition & 0 deletions packages/desktop/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
netdev = "0.24"
regex = "1"
lazy_static = "1.5.0"

[target.'cfg(target_os = "windows")'.dependencies]
komorebi-client = { git = "https://github.com/LGUG2Z/komorebi", tag = "v0.1.28" }
Expand Down
162 changes: 45 additions & 117 deletions packages/desktop/src/providers/media/media_provider.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
use std::sync::Arc;

use anyhow::{Context, Ok, Result};
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use tokio::{sync::mpsc::Sender, time};
use tokio::{
sync::{mpsc::Sender, Mutex},
time,
};
use windows::{
Foundation::{EventRegistrationToken, TypedEventHandler},
Media::Control::{
Expand All @@ -12,17 +17,15 @@ use windows::{
SessionsChangedEventArgs,
},
};

use lazy_static::lazy_static;
use crate::{
impl_interval_provider,
providers::{Provider, ProviderOutput, ProviderResult},
};

#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct MediaProviderConfig {
pub refresh_interval: u64,
}
pub struct MediaProviderConfig {}

#[derive(Debug, Clone, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
Expand All @@ -38,31 +41,51 @@ pub struct MediaOutput {

pub struct MediaProvider {
_config: MediaProviderConfig,
current_session: Option<GlobalSystemMediaTransportControlsSession>,
current_session:
Arc<Mutex<Option<GlobalSystemMediaTransportControlsSession>>>,
session_changed_event_handler: TypedEventHandler<
GlobalSystemMediaTransportControlsSessionManager,
SessionsChangedEventArgs,
>,
media_properties_changed_event_handler: TypedEventHandler<
media_properties_event_handler: TypedEventHandler<
GlobalSystemMediaTransportControlsSession,
MediaPropertiesChangedEventArgs,
>,
playback_info_event_handler: TypedEventHandler<
GlobalSystemMediaTransportControlsSession,
PlaybackInfoChangedEventArgs,
>,
}

impl MediaProvider {
// lazy_static! {
// static ref CURRENT_SESSION: Arc<Mutex<Option<GlobalSystemMediaTransportControlsSession>>> =
// Arc::new(Mutex::new(None));
// }

pub fn new(config: MediaProviderConfig) -> MediaProvider {
MediaProvider {
_config: config,
current_session: None,
current_session: Arc::new(Mutex::new(None)),
session_changed_event_handler: TypedEventHandler::new(
MediaProvider::current_session_changed,
),
media_properties_changed_event_handler: TypedEventHandler::new(
media_properties_event_handler: TypedEventHandler::new(
MediaProvider::media_properties_changed,
),
playback_info_event_handler: TypedEventHandler::new(
MediaProvider::playback_info_changed,
),
}
}

fn playback_info_changed(
session: &Option<GlobalSystemMediaTransportControlsSession>,
_args: &Option<PlaybackInfoChangedEventArgs>,
) -> windows::core::Result<()> {
windows::core::Result::Ok(())
}

fn media_properties_changed(
session: &Option<GlobalSystemMediaTransportControlsSession>,
_args: &Option<MediaPropertiesChangedEventArgs>,
Expand All @@ -78,14 +101,19 @@ impl MediaProvider {
) -> windows::core::Result<()> {
if let Some(session_manager) = session_manager {
let session = session_manager.GetCurrentSession()?;
// self.current_session = Some(session);
let mut current_session = self.current_session.lock().unwrap();
*current_session = Some(session);
}
windows::core::Result::Ok(())
}

fn print_current_media_info(&self) -> anyhow::Result<()> {
let media_properties =
&self.current_session?.TryGetMediaPropertiesAsync()?.get()?;
let media_properties = &self
.current_session
.lock()
.unwrap()
.TryGetMediaPropertiesAsync()?
.get()?;
println!("Title: {}", media_properties.Title()?);
println!("Artist: {}", media_properties.Artist()?);
println!("Album: {}", media_properties.AlbumTitle()?);
Expand All @@ -107,108 +135,11 @@ impl MediaProvider {
.context("Failed to aquire initial media session")?;
println!("Initial current session obtained.");

MediaProvider::print_current_media_info(&current_session);

// -------------------------------

let media_properties_changed_handler = TypedEventHandler::new(
move |session: &Option<
GlobalSystemMediaTransportControlsSession,
>,
_| {
println!("Media properties changed event triggered.");
let session = session
.as_ref()
.expect("No session available on media properties change.");
MediaProvider::print_current_media_info(session);
windows::core::Result::Ok(())
},
);

current_session.MediaPropertiesChanged(
&self.media_properties_changed_event_handler,
)?;

// current_session.MediaPropertiesChanged(&
// media_properties_changed_handler)?;

// if let Err(e) = current_session
// .MediaPropertiesChanged(&media_properties_changed_handler)
// {
// eprintln!(
// "Failed to attach media properties changed handler: {:?}",
// e
// );
// } else {
// println!("Media properties changed handler attached.");
// }

let session_changed_handler = TypedEventHandler::new(
|session_manager: &Option<
GlobalSystemMediaTransportControlsSessionManager,
>,
_| {
println!("Session changed event triggered.");
if let Some(session_manager) = session_manager {
if let Ok(current_session) = session_manager.GetCurrentSession()
{
println!("Current session obtained.");
if let Err(e) =
MediaProvider::print_current_media_info(&current_session)
{
eprintln!("Failed to get media properties: {:?}", e);
}

// Attach an event listener to the current session for media
// property changes
let media_properties_changed_handler = TypedEventHandler::new(
move |session: &Option<
GlobalSystemMediaTransportControlsSession,
>,
_| {
println!("Media properties changed event triggered.");
if let Some(session) = session {
if let Err(e) =
MediaProvider::print_current_media_info(session)
{
eprintln!("Failed to get media properties: {:?}", e);
}
} else {
println!(
"No session available on media properties change."
);
}
Ok(())
},
);

if let Err(e) = current_session
.MediaPropertiesChanged(&media_properties_changed_handler)
{
eprintln!(
"Failed to attach media properties changed handler: {:?}",
e
);
} else {
println!("Media properties changed handler attached.");
}
} else {
println!("No current session available.");
}
} else {
println!("No session manager available.");
}
Ok(())
},
);

if let Err(e) =
session_manager.CurrentSessionChanged(&session_changed_handler)
{
eprintln!("Failed to attach session changed handler: {:?}", e);
} else {
println!("Event handler for session changes attached.");
}
self.print_current_media_info()?;

current_session
.MediaPropertiesChanged(&self.media_properties_event_handler)?;

Ok(())
}
}
Expand All @@ -219,9 +150,6 @@ impl Provider for MediaProvider {
if let Err(err) = self.create_session_manager() {
emit_result_tx.send(Err(err).into()).await;
}
// if let Err(err) = self.bind_media_events() {
// emit_result_tx.send(Err(err).into()).await;
// }
}
}

Expand Down
10 changes: 6 additions & 4 deletions packages/desktop/src/providers/provider_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ use tracing::{info, warn};

use super::{
battery::BatteryProvider, cpu::CpuProvider, host::HostProvider,
ip::IpProvider, media::MediaProvider, memory::MemoryProvider, network::NetworkProvider,
weather::WeatherProvider, Provider, ProviderConfig, ProviderOutput,
SharedProviderState,
ip::IpProvider, media::MediaProvider, memory::MemoryProvider,
network::NetworkProvider, weather::WeatherProvider, Provider,
ProviderConfig, ProviderOutput, SharedProviderState,
};
#[cfg(windows)]
use super::{keyboard::KeyboardProvider, komorebi::KomorebiProvider};
Expand Down Expand Up @@ -177,7 +177,9 @@ impl ProviderRef {
Box::new(MediaProvider::new(config))
}
ProviderConfig::Memory(config) => {
Box::new(MediaProvider::new(super::media::MediaProviderConfig { refresh_interval: 0 }));
Box::new(MediaProvider::new(super::media::MediaProviderConfig {
refresh_interval: 0,
}));
Box::new(MemoryProvider::new(config, shared_state.sysinfo.clone()))
}
ProviderConfig::Network(config) => Box::new(NetworkProvider::new(
Expand Down

0 comments on commit 55c477b

Please sign in to comment.