mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-20 16:43:53 +01:00
Add hotkey dialog and rust-only analytics
This commit is contained in:
@@ -1,89 +1,109 @@
|
||||
use log::{debug, warn};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::types::JsonValue;
|
||||
use tauri::{async_runtime, AppHandle, Manager};
|
||||
|
||||
use crate::is_dev;
|
||||
|
||||
// serializable
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub enum AnalyticsResource {
|
||||
App,
|
||||
// Workspace,
|
||||
// Environment,
|
||||
// Folder,
|
||||
// HttpRequest,
|
||||
// HttpResponse,
|
||||
Workspace,
|
||||
Environment,
|
||||
Folder,
|
||||
HttpRequest,
|
||||
HttpResponse,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub enum AnalyticsAction {
|
||||
Launch,
|
||||
// Create,
|
||||
// Update,
|
||||
// Upsert,
|
||||
// Delete,
|
||||
// Send,
|
||||
// Duplicate,
|
||||
Create,
|
||||
Update,
|
||||
Upsert,
|
||||
Delete,
|
||||
DeleteMany,
|
||||
Send,
|
||||
Duplicate,
|
||||
}
|
||||
|
||||
fn resource_name(resource: AnalyticsResource) -> &'static str {
|
||||
match resource {
|
||||
AnalyticsResource::App => "app",
|
||||
// AnalyticsResource::Workspace => "workspace",
|
||||
// AnalyticsResource::Environment => "environment",
|
||||
// AnalyticsResource::Folder => "folder",
|
||||
// AnalyticsResource::HttpRequest => "http_request",
|
||||
// AnalyticsResource::HttpResponse => "http_response",
|
||||
AnalyticsResource::Workspace => "workspace",
|
||||
AnalyticsResource::Environment => "environment",
|
||||
AnalyticsResource::Folder => "folder",
|
||||
AnalyticsResource::HttpRequest => "http_request",
|
||||
AnalyticsResource::HttpResponse => "http_response",
|
||||
}
|
||||
}
|
||||
|
||||
fn action_name(action: AnalyticsAction) -> &'static str {
|
||||
match action {
|
||||
AnalyticsAction::Launch => "launch",
|
||||
// AnalyticsAction::Create => "create",
|
||||
// AnalyticsAction::Update => "update",
|
||||
// AnalyticsAction::Upsert => "upsert",
|
||||
// AnalyticsAction::Delete => "delete",
|
||||
// AnalyticsAction::Send => "send",
|
||||
// AnalyticsAction::Duplicate => "duplicate",
|
||||
AnalyticsAction::Create => "create",
|
||||
AnalyticsAction::Update => "update",
|
||||
AnalyticsAction::Upsert => "upsert",
|
||||
AnalyticsAction::Delete => "delete",
|
||||
AnalyticsAction::DeleteMany => "delete_many",
|
||||
AnalyticsAction::Send => "send",
|
||||
AnalyticsAction::Duplicate => "duplicate",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn track_event(
|
||||
pub fn track_event_blocking(
|
||||
app_handle: &AppHandle,
|
||||
resource: AnalyticsResource,
|
||||
action: AnalyticsAction,
|
||||
attributes: Option<JsonValue>,
|
||||
) {
|
||||
async_runtime::block_on(async move {
|
||||
let event = format!("{}.{}", resource_name(resource), action_name(action));
|
||||
let attributes_json = attributes.unwrap_or("{}".to_string().into()).to_string();
|
||||
let info = app_handle.package_info();
|
||||
let tz = datetime::sys_timezone().unwrap_or("unknown".to_string());
|
||||
let params = vec![
|
||||
("e", event.clone()),
|
||||
("a", attributes_json.clone()),
|
||||
("id", "site_zOK0d7jeBy2TLxFCnZ".to_string()),
|
||||
("v", info.version.clone().to_string()),
|
||||
("os", get_os().to_string()),
|
||||
("tz", tz),
|
||||
("xy", get_window_size(app_handle)),
|
||||
];
|
||||
let url = "https://t.yaak.app/t/e".to_string();
|
||||
let req = reqwest::Client::builder()
|
||||
.build()
|
||||
.unwrap()
|
||||
.get(&url)
|
||||
.query(¶ms);
|
||||
track_event(app_handle, resource, action, attributes).await;
|
||||
});
|
||||
}
|
||||
|
||||
if is_dev() {
|
||||
debug!("Send event (dev): {}", event);
|
||||
} else if let Err(e) = req.send().await {
|
||||
warn!(
|
||||
pub async fn track_event(
|
||||
app_handle: &AppHandle,
|
||||
resource: AnalyticsResource,
|
||||
action: AnalyticsAction,
|
||||
attributes: Option<JsonValue>,
|
||||
) {
|
||||
let event = format!("{}.{}", resource_name(resource), action_name(action));
|
||||
let attributes_json = attributes.unwrap_or("{}".to_string().into()).to_string();
|
||||
let info = app_handle.package_info();
|
||||
let tz = datetime::sys_timezone().unwrap_or("unknown".to_string());
|
||||
let site = match is_dev() {
|
||||
true => "site_TkHWjoXwZPq3HfhERb",
|
||||
false => "site_zOK0d7jeBy2TLxFCnZ",
|
||||
};
|
||||
let base_url = match is_dev() {
|
||||
true => "http://localhost:7194",
|
||||
false => "https://t.yaak.app"
|
||||
};
|
||||
let params = vec![
|
||||
("e", event.clone()),
|
||||
("a", attributes_json.clone()),
|
||||
("id", site.to_string()),
|
||||
("v", info.version.clone().to_string()),
|
||||
("os", get_os().to_string()),
|
||||
("tz", tz),
|
||||
("xy", get_window_size(app_handle)),
|
||||
];
|
||||
let req = reqwest::Client::builder()
|
||||
.build()
|
||||
.unwrap()
|
||||
.get(format!("{base_url}/t/e"))
|
||||
.query(¶ms);
|
||||
|
||||
if let Err(e) = req.send().await {
|
||||
warn!(
|
||||
"Error sending analytics event: {} {} {:?}",
|
||||
e, event, params
|
||||
);
|
||||
} else {
|
||||
debug!("Send event: {}: {:?}", event, params);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
debug!("Send event: {}: {:?}", event, params);
|
||||
}
|
||||
}
|
||||
|
||||
fn get_os() -> &'static str {
|
||||
|
||||
@@ -16,6 +16,7 @@ use fern::colors::ColoredLevelConfig;
|
||||
use log::{debug, info, warn};
|
||||
use rand::random;
|
||||
use serde::Serialize;
|
||||
use serde_json::Value;
|
||||
use sqlx::{Pool, Sqlite, SqlitePool};
|
||||
use sqlx::migrate::Migrator;
|
||||
use sqlx::types::Json;
|
||||
@@ -29,7 +30,7 @@ use tokio::sync::Mutex;
|
||||
|
||||
use window_ext::TrafficLightWindowExt;
|
||||
|
||||
use crate::analytics::{AnalyticsAction, AnalyticsResource, track_event};
|
||||
use crate::analytics::{AnalyticsAction, AnalyticsResource};
|
||||
use crate::plugin::{ImportResources, ImportResult};
|
||||
use crate::send::actually_send_request;
|
||||
use crate::updates::{update_mode_from_str, UpdateMode, YaakUpdater};
|
||||
@@ -224,6 +225,22 @@ async fn response_err(
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn track_event(
|
||||
window: Window<Wry>,
|
||||
resource: AnalyticsResource,
|
||||
action: AnalyticsAction,
|
||||
attributes: Option<Value>,
|
||||
) -> Result<(), String> {
|
||||
analytics::track_event(
|
||||
&window.app_handle(),
|
||||
resource,
|
||||
action,
|
||||
attributes,
|
||||
).await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn set_update_mode(
|
||||
update_mode: &str,
|
||||
@@ -726,6 +743,7 @@ fn main() {
|
||||
send_request,
|
||||
set_key_value,
|
||||
set_update_mode,
|
||||
track_event,
|
||||
update_environment,
|
||||
update_folder,
|
||||
update_request,
|
||||
@@ -762,7 +780,7 @@ fn main() {
|
||||
w.restore_state(StateFlags::all())
|
||||
.expect("Failed to restore window state");
|
||||
|
||||
track_event(
|
||||
analytics::track_event_blocking(
|
||||
app_handle,
|
||||
AnalyticsResource::App,
|
||||
AnalyticsAction::Launch,
|
||||
|
||||
@@ -35,8 +35,11 @@ pub async fn actually_send_request(
|
||||
}
|
||||
|
||||
let client = reqwest::Client::builder()
|
||||
.redirect(Policy::none())
|
||||
// .danger_accept_invalid_certs(true)
|
||||
.redirect(Policy::none()) // TODO: Handle redirect manually
|
||||
.danger_accept_invalid_certs(false) // TODO: Make this configurable
|
||||
.connection_verbose(true) // TODO: Capture this log somehow
|
||||
.tls_info(true) // TODO: Capture this log somehow
|
||||
// .use_rustls_tls() // TODO: Make this configurable
|
||||
.build()
|
||||
.expect("Failed to build client");
|
||||
|
||||
@@ -237,6 +240,9 @@ pub async fn actually_send_request(
|
||||
}
|
||||
Ok(response)
|
||||
}
|
||||
Err(e) => response_err(response, e.to_string(), app_handle, pool).await,
|
||||
Err(e) => {
|
||||
println!("Yo: {}", e);
|
||||
response_err(response, e.to_string(), app_handle, pool).await
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user